From 626907bf520e8c88d82696b8817886263f9a589f Mon Sep 17 00:00:00 2001 From: Stas Maksimov Date: Mon, 6 Nov 2023 21:34:09 +0000 Subject: [PATCH 001/119] add dependabot config (#153) * add dependabot config * change dependabot to daily * add 12.0.5 to dependabot --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..efa1d22cfad --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + target-branch: "slack-vitess-r14.0.5" + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + target-branch: "slack-vitess-r12.0.5" From e6ad43bed5a3b16091c91d20fa8f6da309074380 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Tue, 7 Nov 2023 12:38:06 -0800 Subject: [PATCH 002/119] examples: fix flag syntax for zkctl (#14469) Signed-off-by: deepthi --- .github/workflows/local_example.yml | 2 +- examples/common/scripts/zk-down.sh | 2 +- examples/common/scripts/zk-up.sh | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index bd6bbb247e3..348e191abff 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -8,7 +8,7 @@ jobs: runs-on: gh-hosted-runners-16cores-1 strategy: matrix: - topo: [consul,etcd,k8s] + topo: [consul,etcd,zk2] steps: - name: Skip CI diff --git a/examples/common/scripts/zk-down.sh b/examples/common/scripts/zk-down.sh index a9fa1e80a30..f244f2b0f05 100755 --- a/examples/common/scripts/zk-down.sh +++ b/examples/common/scripts/zk-down.sh @@ -21,6 +21,6 @@ source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh" # Stop ZooKeeper servers. echo "Stopping zk servers..." for zkid in $zkids; do - zkctl -zk.myid $zkid -zk.cfg $zkcfg -log_dir $VTDATAROOT/tmp shutdown + zkctl --zk.myid $zkid --zk.cfg $zkcfg --log_dir $VTDATAROOT/tmp shutdown done diff --git a/examples/common/scripts/zk-up.sh b/examples/common/scripts/zk-up.sh index 519d5305b25..3137ed724cc 100755 --- a/examples/common/scripts/zk-up.sh +++ b/examples/common/scripts/zk-up.sh @@ -19,7 +19,6 @@ source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh" cell=${CELL:-'test'} - # Start ZooKeeper servers. # The "zkctl init" command won't return until the server is able to contact its # peers, so we need to start them all in the background and then wait for them. @@ -32,7 +31,7 @@ for zkid in $zkids; do echo " $VTDATAROOT/$zkdir" action='start' fi - zkctl -zk.myid $zkid -zk.cfg $zkcfg -log_dir $VTDATAROOT/tmp $action \ + zkctl --zk.myid $zkid --zk.cfg $zkcfg --log_dir $VTDATAROOT/tmp $action \ > $VTDATAROOT/tmp/zkctl_$zkid.out 2>&1 & pids[$zkid]=$! done From cb30f78c8f6ae3070213f94f05f924d3d5a07605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Wed, 8 Nov 2023 11:28:27 +0100 Subject: [PATCH 003/119] Add support for AVG on sharded queries (#14419) --- .../queries/aggregation/aggregation_test.go | 50 +++-- go/vt/vtgate/engine/opcode/constants.go | 6 +- .../operators/aggregation_pushing.go | 109 +++++++-- go/vt/vtgate/planbuilder/operators/phases.go | 59 ++--- .../planbuilder/operators/queryprojection.go | 104 +++++---- .../planbuilder/testdata/aggr_cases.json | 211 ++++++++++++++++++ .../planbuilder/testdata/tpch_cases.json | 45 +++- .../testdata/unsupported_cases.json | 5 - 8 files changed, 482 insertions(+), 107 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go index ed917efda4c..b1123e634e8 100644 --- a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go +++ b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go @@ -73,6 +73,7 @@ func TestAggregateTypes(t *testing.T) { mcmp.AssertMatches("select val1 as a, count(*) from aggr_test group by a order by a", `[[VARCHAR("a") INT64(2)] [VARCHAR("b") INT64(1)] [VARCHAR("c") INT64(2)] [VARCHAR("d") INT64(1)] [VARCHAR("e") INT64(2)]]`) mcmp.AssertMatches("select val1 as a, count(*) from aggr_test group by a order by 2, a", `[[VARCHAR("b") INT64(1)] [VARCHAR("d") INT64(1)] [VARCHAR("a") INT64(2)] [VARCHAR("c") INT64(2)] [VARCHAR("e") INT64(2)]]`) mcmp.AssertMatches("select sum(val1) from aggr_test", `[[FLOAT64(0)]]`) + mcmp.AssertMatches("select avg(val1) from aggr_test", `[[FLOAT64(0)]]`) } func TestGroupBy(t *testing.T) { @@ -172,6 +173,13 @@ func TestAggrOnJoin(t *testing.T) { mcmp.AssertMatches("select a.val1 from aggr_test a join t3 t on a.val2 = t.id7 group by a.val1 having count(*) = 4", `[[VARCHAR("a")]]`) + + mcmp.AssertMatches(`select avg(a1.val2), avg(a2.val2) from aggr_test a1 join aggr_test a2 on a1.val2 = a2.id join t3 t on a2.val2 = t.id7`, + "[[DECIMAL(1.5000) DECIMAL(1.0000)]]") + + mcmp.AssertMatches(`select a1.val1, avg(a1.val2) from aggr_test a1 join aggr_test a2 on a1.val2 = a2.id join t3 t on a2.val2 = t.id7 group by a1.val1`, + `[[VARCHAR("a") DECIMAL(1.0000)] [VARCHAR("b") DECIMAL(1.0000)] [VARCHAR("c") DECIMAL(3.0000)]]`) + } func TestNotEqualFilterOnScatter(t *testing.T) { @@ -314,22 +322,26 @@ func TestAggOnTopOfLimit(t *testing.T) { for _, workload := range []string{"oltp", "olap"} { t.Run(workload, func(t *testing.T) { utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = '%s'", workload)) - mcmp.AssertMatches(" select count(*) from (select id, val1 from aggr_test where val2 < 4 limit 2) as x", "[[INT64(2)]]") - mcmp.AssertMatches(" select count(val1) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2)]]") - mcmp.AssertMatches(" select count(*) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(2)]]") - mcmp.AssertMatches(" select count(val1) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(1)]]") - mcmp.AssertMatches(" select count(val2) from (select id, val2 from aggr_test where val2 is null limit 2) as x", "[[INT64(0)]]") - mcmp.AssertMatches(" select val1, count(*) from (select id, val1 from aggr_test where val2 < 4 order by val1 limit 2) as x group by val1", `[[NULL INT64(1)] [VARCHAR("a") INT64(1)]]`) - mcmp.AssertMatchesNoOrder(" select val1, count(val2) from (select val1, val2 from aggr_test limit 8) as x group by val1", `[[NULL INT64(1)] [VARCHAR("a") INT64(2)] [VARCHAR("b") INT64(1)] [VARCHAR("c") INT64(2)]]`) + mcmp.AssertMatches("select count(*) from (select id, val1 from aggr_test where val2 < 4 limit 2) as x", "[[INT64(2)]]") + mcmp.AssertMatches("select count(val1) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2)]]") + mcmp.AssertMatches("select count(*) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(2)]]") + mcmp.AssertMatches("select count(val1) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(1)]]") + mcmp.AssertMatches("select count(val2) from (select id, val2 from aggr_test where val2 is null limit 2) as x", "[[INT64(0)]]") + mcmp.AssertMatches("select avg(val2) from (select id, val2 from aggr_test where val2 is null limit 2) as x", "[[NULL]]") + mcmp.AssertMatches("select val1, count(*) from (select id, val1 from aggr_test where val2 < 4 order by val1 limit 2) as x group by val1", `[[NULL INT64(1)] [VARCHAR("a") INT64(1)]]`) + mcmp.AssertMatchesNoOrder("select val1, count(val2) from (select val1, val2 from aggr_test limit 8) as x group by val1", `[[NULL INT64(1)] [VARCHAR("a") INT64(2)] [VARCHAR("b") INT64(1)] [VARCHAR("c") INT64(2)]]`) + mcmp.AssertMatchesNoOrder("select val1, avg(val2) from (select val1, val2 from aggr_test limit 8) as x group by val1", `[[NULL DECIMAL(2.0000)] [VARCHAR("a") DECIMAL(3.5000)] [VARCHAR("b") DECIMAL(1.0000)] [VARCHAR("c") DECIMAL(3.5000)]]`) // mysql returns FLOAT64(0), vitess returns DECIMAL(0) - mcmp.AssertMatchesNoCompare(" select count(*), sum(val1) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2) FLOAT64(0)]]", "[[INT64(2) FLOAT64(0)]]") - mcmp.AssertMatches(" select count(val1), sum(id) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2) DECIMAL(7)]]") - mcmp.AssertMatches(" select count(*), sum(id) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(2) DECIMAL(14)]]") - mcmp.AssertMatches(" select count(val1), sum(id) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(1) DECIMAL(14)]]") - mcmp.AssertMatches(" select count(val2), sum(val2) from (select id, val2 from aggr_test where val2 is null limit 2) as x", "[[INT64(0) NULL]]") - mcmp.AssertMatches(" select val1, count(*), sum(id) from (select id, val1 from aggr_test where val2 < 4 order by val1 limit 2) as x group by val1", `[[NULL INT64(1) DECIMAL(7)] [VARCHAR("a") INT64(1) DECIMAL(2)]]`) - mcmp.AssertMatchesNoOrder(" select val1, count(val2), sum(val2) from (select val1, val2 from aggr_test limit 8) as x group by val1", `[[NULL INT64(1) DECIMAL(2)] [VARCHAR("a") INT64(2) DECIMAL(7)] [VARCHAR("b") INT64(1) DECIMAL(1)] [VARCHAR("c") INT64(2) DECIMAL(7)]]`) + mcmp.AssertMatches("select count(*), sum(val1), avg(val1) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2) FLOAT64(0) FLOAT64(0)]]") + mcmp.AssertMatches("select count(val1), sum(id) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2) DECIMAL(7)]]") + mcmp.AssertMatches("select count(val1), sum(id), avg(id) from (select id, val1 from aggr_test where val2 < 4 order by val1 desc limit 2) as x", "[[INT64(2) DECIMAL(7) DECIMAL(3.5000)]]") + mcmp.AssertMatches("select count(*), sum(id) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(2) DECIMAL(14)]]") + mcmp.AssertMatches("select count(val1), sum(id) from (select id, val1 from aggr_test where val2 is null limit 2) as x", "[[INT64(1) DECIMAL(14)]]") + mcmp.AssertMatches("select count(val2), sum(val2) from (select id, val2 from aggr_test where val2 is null limit 2) as x", "[[INT64(0) NULL]]") + mcmp.AssertMatches("select val1, count(*), sum(id) from (select id, val1 from aggr_test where val2 < 4 order by val1 limit 2) as x group by val1", `[[NULL INT64(1) DECIMAL(7)] [VARCHAR("a") INT64(1) DECIMAL(2)]]`) + mcmp.AssertMatchesNoOrder("select val1, count(val2), sum(val2), avg(val2) from (select val1, val2 from aggr_test limit 8) as x group by val1", + `[[NULL INT64(1) DECIMAL(2) DECIMAL(2.0000)] [VARCHAR("a") INT64(2) DECIMAL(7) DECIMAL(3.5000)] [VARCHAR("b") INT64(1) DECIMAL(1) DECIMAL(1.0000)] [VARCHAR("c") INT64(2) DECIMAL(7) DECIMAL(3.5000)]]`) }) } } @@ -343,6 +355,8 @@ func TestEmptyTableAggr(t *testing.T) { utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", workload)) mcmp.AssertMatches(" select count(*) from t1 inner join t2 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") mcmp.AssertMatches(" select count(*) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") + mcmp.AssertMatches(" select count(t1.value) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") + mcmp.AssertMatches(" select avg(t1.value) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[NULL]]") mcmp.AssertMatches(" select t1.`name`, count(*) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo' group by t1.`name`", "[]") mcmp.AssertMatches(" select t1.`name`, count(*) from t1 inner join t2 on (t1.t1_id = t2.id) where t1.value = 'foo' group by t1.`name`", "[]") }) @@ -355,8 +369,10 @@ func TestEmptyTableAggr(t *testing.T) { utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", workload)) mcmp.AssertMatches(" select count(*) from t1 inner join t2 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") mcmp.AssertMatches(" select count(*) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") - mcmp.AssertMatches(" select t1.`name`, count(*) from t1 inner join t2 on (t1.t1_id = t2.id) where t1.value = 'foo' group by t1.`name`", "[]") + mcmp.AssertMatches(" select count(t1.value) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[INT64(0)]]") + mcmp.AssertMatches(" select avg(t1.value) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo'", "[[NULL]]") mcmp.AssertMatches(" select t1.`name`, count(*) from t2 inner join t1 on (t1.t1_id = t2.id) where t1.value = 'foo' group by t1.`name`", "[]") + mcmp.AssertMatches(" select t1.`name`, count(*) from t1 inner join t2 on (t1.t1_id = t2.id) where t1.value = 'foo' group by t1.`name`", "[]") }) } @@ -398,6 +414,8 @@ func TestAggregateLeftJoin(t *testing.T) { mcmp.AssertMatches("SELECT count(*) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[INT64(2)]]`) mcmp.AssertMatches("SELECT sum(t1.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(1)]]`) mcmp.AssertMatches("SELECT sum(t2.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(1)]]`) + mcmp.AssertMatches("SELECT avg(t1.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(0.5000)]]`) + mcmp.AssertMatches("SELECT avg(t2.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(1.0000)]]`) mcmp.AssertMatches("SELECT count(*) FROM t2 LEFT JOIN t1 ON t1.t1_id = t2.id WHERE IFNULL(t1.name, 'NOTSET') = 'r'", `[[INT64(1)]]`) } @@ -426,6 +444,7 @@ func TestScalarAggregate(t *testing.T) { mcmp.Exec("insert into aggr_test(id, val1, val2) values(1,'a',1), (2,'A',1), (3,'b',1), (4,'c',3), (5,'c',4)") mcmp.AssertMatches("select count(distinct val1) from aggr_test", `[[INT64(3)]]`) + mcmp.AssertMatches("select avg(val1) from aggr_test", `[[FLOAT64(0)]]`) } func TestAggregationRandomOnAnAggregatedValue(t *testing.T) { @@ -478,6 +497,7 @@ func TestComplexAggregation(t *testing.T) { mcmp.Exec(`SELECT 1+COUNT(t1_id) FROM t1`) mcmp.Exec(`SELECT COUNT(t1_id)+1 FROM t1`) mcmp.Exec(`SELECT COUNT(t1_id)+MAX(shardkey) FROM t1`) + mcmp.Exec(`SELECT COUNT(t1_id)+MAX(shardkey)+AVG(t1_id) FROM t1`) mcmp.Exec(`SELECT shardkey, MIN(t1_id)+MAX(t1_id) FROM t1 GROUP BY shardkey`) mcmp.Exec(`SELECT shardkey + MIN(t1_id)+MAX(t1_id) FROM t1 GROUP BY shardkey`) mcmp.Exec(`SELECT name+COUNT(t1_id)+1 FROM t1 GROUP BY name`) diff --git a/go/vt/vtgate/engine/opcode/constants.go b/go/vt/vtgate/engine/opcode/constants.go index dd73a78974d..8a70df79d0c 100644 --- a/go/vt/vtgate/engine/opcode/constants.go +++ b/go/vt/vtgate/engine/opcode/constants.go @@ -74,6 +74,7 @@ const ( AggregateAnyValue AggregateCountStar AggregateGroupConcat + AggregateAvg _NumOfOpCodes // This line must be last of the opcodes! ) @@ -85,6 +86,7 @@ var ( AggregateCountStar: sqltypes.Int64, AggregateSumDistinct: sqltypes.Decimal, AggregateSum: sqltypes.Decimal, + AggregateAvg: sqltypes.Decimal, AggregateGtid: sqltypes.VarChar, } ) @@ -96,6 +98,7 @@ var SupportedAggregates = map[string]AggregateOpcode{ "sum": AggregateSum, "min": AggregateMin, "max": AggregateMax, + "avg": AggregateAvg, // These functions don't exist in mysql, but are used // to display the plan. "count_distinct": AggregateCountDistinct, @@ -117,6 +120,7 @@ var AggregateName = map[AggregateOpcode]string{ AggregateCountStar: "count_star", AggregateGroupConcat: "group_concat", AggregateAnyValue: "any_value", + AggregateAvg: "avg", } func (code AggregateOpcode) String() string { @@ -148,7 +152,7 @@ func (code AggregateOpcode) Type(typ querypb.Type) querypb.Type { return sqltypes.Text case AggregateMax, AggregateMin, AggregateAnyValue: return typ - case AggregateSumDistinct, AggregateSum: + case AggregateSumDistinct, AggregateSum, AggregateAvg: if typ == sqltypes.Unknown { return sqltypes.Unknown } diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index 85c50427364..0127e81b4c4 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -34,22 +34,33 @@ func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) if aggregator.Pushed { return aggregator, rewrite.SameTree, nil } + + // this rewrite is always valid, and we should do it whenever possible + if route, ok := aggregator.Source.(*Route); ok && (route.IsSingleShard() || overlappingUniqueVindex(ctx, aggregator.Grouping)) { + return rewrite.Swap(aggregator, route, "push down aggregation under route - remove original") + } + + // other rewrites require us to have reached this phase before we can consider them + if !reachedPhase(ctx, delegateAggregation) { + return aggregator, rewrite.SameTree, nil + } + + // if we have not yet been able to push this aggregation down, + // we need to turn AVG into SUM/COUNT to support this over a sharded keyspace + if needAvgBreaking(aggregator.Aggregations) { + return splitAvgAggregations(ctx, aggregator) + } + switch src := aggregator.Source.(type) { case *Route: // if we have a single sharded route, we can push it down output, applyResult, err = pushAggregationThroughRoute(ctx, aggregator, src) case *ApplyJoin: - if reachedPhase(ctx, delegateAggregation) { - output, applyResult, err = pushAggregationThroughJoin(ctx, aggregator, src) - } + output, applyResult, err = pushAggregationThroughJoin(ctx, aggregator, src) case *Filter: - if reachedPhase(ctx, delegateAggregation) { - output, applyResult, err = pushAggregationThroughFilter(ctx, aggregator, src) - } + output, applyResult, err = pushAggregationThroughFilter(ctx, aggregator, src) case *SubQueryContainer: - if reachedPhase(ctx, delegateAggregation) { - output, applyResult, err = pushAggregationThroughSubquery(ctx, aggregator, src) - } + output, applyResult, err = pushAggregationThroughSubquery(ctx, aggregator, src) default: return aggregator, rewrite.SameTree, nil } @@ -135,15 +146,6 @@ func pushAggregationThroughRoute( aggregator *Aggregator, route *Route, ) (ops.Operator, *rewrite.ApplyResult, error) { - // If the route is single-shard, or we are grouping by sharding keys, we can just push down the aggregation - if route.IsSingleShard() || overlappingUniqueVindex(ctx, aggregator.Grouping) { - return rewrite.Swap(aggregator, route, "push down aggregation under route - remove original") - } - - if !reachedPhase(ctx, delegateAggregation) { - return nil, nil, nil - } - // Create a new aggregator to be placed below the route. aggrBelowRoute := aggregator.SplitAggregatorBelowRoute(route.Inputs()) aggrBelowRoute.Aggregations = nil @@ -806,3 +808,74 @@ func initColReUse(size int) []int { } func extractExpr(expr *sqlparser.AliasedExpr) sqlparser.Expr { return expr.Expr } + +func needAvgBreaking(aggrs []Aggr) bool { + for _, aggr := range aggrs { + if aggr.OpCode == opcode.AggregateAvg { + return true + } + } + return false +} + +// splitAvgAggregations takes an aggregator that has AVG aggregations in it and splits +// these into sum/count expressions that can be spread out to shards +func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (ops.Operator, *rewrite.ApplyResult, error) { + proj := newAliasedProjection(aggr) + + var columns []*sqlparser.AliasedExpr + var aggregations []Aggr + + for offset, col := range aggr.Columns { + avg, ok := col.Expr.(*sqlparser.Avg) + if !ok { + proj.addColumnWithoutPushing(ctx, col, false /* addToGroupBy */) + continue + } + + if avg.Distinct { + panic(vterrors.VT12001("AVG(distinct <>)")) + } + + // We have an AVG that we need to split + sumExpr := &sqlparser.Sum{Arg: avg.Arg} + countExpr := &sqlparser.Count{Args: []sqlparser.Expr{avg.Arg}} + calcExpr := &sqlparser.BinaryExpr{ + Operator: sqlparser.DivOp, + Left: sumExpr, + Right: countExpr, + } + + outputColumn := aeWrap(col.Expr) + outputColumn.As = sqlparser.NewIdentifierCI(col.ColumnName()) + _, err := proj.addUnexploredExpr(sqlparser.CloneRefOfAliasedExpr(col), calcExpr) + if err != nil { + return nil, nil, err + } + col.Expr = sumExpr + found := false + for aggrOffset, aggregation := range aggr.Aggregations { + if offset == aggregation.ColOffset { + // We have found the AVG column. We'll change it to SUM, and then we add a COUNT as well + aggr.Aggregations[aggrOffset].OpCode = opcode.AggregateSum + + countExprAlias := aeWrap(countExpr) + countAggr := NewAggr(opcode.AggregateCount, countExpr, countExprAlias, sqlparser.String(countExpr)) + countAggr.ColOffset = len(aggr.Columns) + len(columns) + aggregations = append(aggregations, countAggr) + columns = append(columns, countExprAlias) + found = true + break // no need to search the remaining aggregations + } + } + if !found { + // if we get here, it's because we didn't find the aggregation. Something is wrong + panic(vterrors.VT13001("no aggregation pointing to this column was found")) + } + } + + aggr.Columns = append(aggr.Columns, columns...) + aggr.Aggregations = append(aggr.Aggregations, aggregations...) + + return proj, rewrite.NewTree("split avg aggregation", proj), nil +} diff --git a/go/vt/vtgate/planbuilder/operators/phases.go b/go/vt/vtgate/planbuilder/operators/phases.go index ba13a828d0b..36149f89985 100644 --- a/go/vt/vtgate/planbuilder/operators/phases.go +++ b/go/vt/vtgate/planbuilder/operators/phases.go @@ -19,6 +19,7 @@ package operators import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -56,9 +57,9 @@ func (p Phase) String() string { return "optimize Distinct operations" case subquerySettling: return "settle subqueries" + default: + panic(vterrors.VT13001("unhandled default case")) } - - return "unknown" } func (p Phase) shouldRun(s semantics.QuerySignature) bool { @@ -73,8 +74,9 @@ func (p Phase) shouldRun(s semantics.QuerySignature) bool { return s.Distinct case subquerySettling: return s.SubQueries + default: + return true } - return true } func (p Phase) act(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { @@ -84,14 +86,14 @@ func (p Phase) act(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Opera case delegateAggregation: return enableDelegateAggregation(ctx, op) case addAggrOrdering: - return addOrderBysForAggregations(ctx, op) + return addOrderingForAllAggregations(ctx, op) case cleanOutPerfDistinct: return removePerformanceDistinctAboveRoute(ctx, op) case subquerySettling: return settleSubqueries(ctx, op), nil + default: + return op, nil } - - return op, nil } // getPhases returns the ordered phases that the planner will undergo. @@ -120,7 +122,8 @@ func enableDelegateAggregation(ctx *plancontext.PlanningContext, op ops.Operator return addColumnsToInput(ctx, op) } -func addOrderBysForAggregations(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { +// addOrderingForAllAggregations is run we have pushed down Aggregators as far down as possible. +func addOrderingForAllAggregations(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { aggrOp, ok := in.(*Aggregator) if !ok { @@ -131,30 +134,36 @@ func addOrderBysForAggregations(ctx *plancontext.PlanningContext, root ops.Opera if err != nil { return nil, nil, err } - if !requireOrdering { - return in, rewrite.SameTree, nil - } - orderBys := slice.Map(aggrOp.Grouping, func(from GroupBy) ops.OrderBy { - return from.AsOrderBy() - }) - if aggrOp.DistinctExpr != nil { - orderBys = append(orderBys, ops.OrderBy{ - Inner: &sqlparser.Order{ - Expr: aggrOp.DistinctExpr, - }, - SimplifiedExpr: aggrOp.DistinctExpr, - }) - } - aggrOp.Source = &Ordering{ - Source: aggrOp.Source, - Order: orderBys, + + var res *rewrite.ApplyResult + if requireOrdering { + addOrderingFor(aggrOp) + res = rewrite.NewTree("added ordering before aggregation", in) } - return in, rewrite.NewTree("added ordering before aggregation", in), nil + return in, res, nil } return rewrite.BottomUp(root, TableID, visitor, stopAtRoute) } +func addOrderingFor(aggrOp *Aggregator) { + orderBys := slice.Map(aggrOp.Grouping, func(from GroupBy) ops.OrderBy { + return from.AsOrderBy() + }) + if aggrOp.DistinctExpr != nil { + orderBys = append(orderBys, ops.OrderBy{ + Inner: &sqlparser.Order{ + Expr: aggrOp.DistinctExpr, + }, + SimplifiedExpr: aggrOp.DistinctExpr, + }) + } + aggrOp.Source = &Ordering{ + Source: aggrOp.Source, + Order: orderBys, + } +} + func needsOrdering(ctx *plancontext.PlanningContext, in *Aggregator) (bool, error) { requiredOrder := slice.Map(in.Grouping, func(from GroupBy) sqlparser.Expr { return from.SimplifiedExpr diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index b7040807300..ff188d6c895 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -686,25 +686,13 @@ func (qp *QueryProjection) NeedsDistinct() bool { } func (qp *QueryProjection) AggregationExpressions(ctx *plancontext.PlanningContext, allowComplexExpression bool) (out []Aggr, complex bool, err error) { -orderBy: - for _, orderExpr := range qp.OrderExprs { - orderExpr := orderExpr.SimplifiedExpr - for _, expr := range qp.SelectExprs { - col, ok := expr.Col.(*sqlparser.AliasedExpr) - if !ok { - continue - } - if ctx.SemTable.EqualsExprWithDeps(col.Expr, orderExpr) { - continue orderBy // we found the expression we were looking for! - } - } - qp.SelectExprs = append(qp.SelectExprs, SelectExpr{ - Col: &sqlparser.AliasedExpr{Expr: orderExpr}, - Aggr: containsAggr(orderExpr), - }) - qp.AddedColumn++ + qp.addOrderByToSelect(ctx) + addAggr := func(a Aggr) { + out = append(out, a) + } + makeComplex := func() { + complex = true } - // Here we go over the expressions we are returning. Since we know we are aggregating, // all expressions have to be either grouping expressions or aggregate expressions. // If we find an expression that is neither, we treat is as a special aggregation function AggrRandom @@ -733,34 +721,66 @@ orderBy: return nil, false, vterrors.VT12001("in scatter query: complex aggregate expression") } - sqlparser.CopyOnRewrite(aliasedExpr.Expr, func(node, parent sqlparser.SQLNode) bool { - ex, isExpr := node.(sqlparser.Expr) - if !isExpr { - return true - } - if aggr, isAggr := node.(sqlparser.AggrFunc); isAggr { - ae := aeWrap(aggr) - if aggr == aliasedExpr.Expr { - ae = aliasedExpr - } - aggrFunc := createAggrFromAggrFunc(aggr, ae) - aggrFunc.Index = &idxCopy - out = append(out, aggrFunc) - return false + sqlparser.CopyOnRewrite(aliasedExpr.Expr, qp.extractAggr(ctx, idx, aliasedExpr, addAggr, makeComplex), nil, nil) + } + return +} + +func (qp *QueryProjection) extractAggr( + ctx *plancontext.PlanningContext, + idx int, + aliasedExpr *sqlparser.AliasedExpr, + addAggr func(a Aggr), + makeComplex func(), +) func(node sqlparser.SQLNode, parent sqlparser.SQLNode) bool { + return func(node, parent sqlparser.SQLNode) bool { + ex, isExpr := node.(sqlparser.Expr) + if !isExpr { + return true + } + if aggr, isAggr := node.(sqlparser.AggrFunc); isAggr { + ae := aeWrap(aggr) + if aggr == aliasedExpr.Expr { + ae = aliasedExpr } - if containsAggr(node) { - complex = true - return true + aggrFunc := createAggrFromAggrFunc(aggr, ae) + aggrFunc.Index = &idx + addAggr(aggrFunc) + return false + } + if containsAggr(node) { + makeComplex() + return true + } + if !qp.isExprInGroupByExprs(ctx, ex) { + aggr := NewAggr(opcode.AggregateAnyValue, nil, aeWrap(ex), "") + aggr.Index = &idx + addAggr(aggr) + } + return false + } +} + +func (qp *QueryProjection) addOrderByToSelect(ctx *plancontext.PlanningContext) { +orderBy: + // We need to return all columns that are being used for ordering + for _, orderExpr := range qp.OrderExprs { + orderExpr := orderExpr.SimplifiedExpr + for _, expr := range qp.SelectExprs { + col, ok := expr.Col.(*sqlparser.AliasedExpr) + if !ok { + continue } - if !qp.isExprInGroupByExprs(ctx, ex) { - aggr := NewAggr(opcode.AggregateAnyValue, nil, aeWrap(ex), "") - aggr.Index = &idxCopy - out = append(out, aggr) + if ctx.SemTable.EqualsExprWithDeps(col.Expr, orderExpr) { + continue orderBy // we found the expression we were looking for! } - return false - }, nil, nil) + } + qp.SelectExprs = append(qp.SelectExprs, SelectExpr{ + Col: &sqlparser.AliasedExpr{Expr: orderExpr}, + Aggr: containsAggr(orderExpr), + }) + qp.AddedColumn++ } - return } func createAggrFromAggrFunc(fnc sqlparser.AggrFunc, aliasedExpr *sqlparser.AliasedExpr) Aggr { diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index e47b17cd2ae..827c64464f8 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6038,5 +6038,216 @@ "user.user_extra" ] } + }, + { + "comment": "avg function on scatter query", + "query": "select avg(id) from user", + "plan": { + "QueryType": "SELECT", + "Original": "select avg(id) from user", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "sum(id) / count(id) as avg(id)" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "sum(0) AS avg(id), sum_count(1) AS count(id)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select sum(id), count(id) from `user` where 1 != 1", + "Query": "select sum(id), count(id) from `user`", + "Table": "`user`" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "avg function on scatter query deep inside the output expression", + "query": "select avg(id)+count(foo)+bar from user group by bar", + "plan": { + "QueryType": "SELECT", + "Original": "select avg(id)+count(foo)+bar from user group by bar", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "avg(id) + count(foo) + bar as avg(id) + count(foo) + bar" + ], + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + ":0 as bar", + "sum(id) / count(id) as avg(id)", + ":2 as count(foo)" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "sum(1) AS avg(id), sum_count(2) AS count(foo), sum_count(3) AS count(id)", + "GroupBy": "(0|4)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select bar, sum(id), count(foo), count(id), weight_string(bar) from `user` where 1 != 1 group by bar, weight_string(bar)", + "OrderBy": "(0|4) ASC", + "Query": "select bar, sum(id), count(foo), count(id), weight_string(bar) from `user` group by bar, weight_string(bar) order by bar asc", + "Table": "`user`" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "avg function on scatter query deep inside the output expression", + "query": "select avg(id)+count(foo)+bar from user group by bar", + "plan": { + "QueryType": "SELECT", + "Original": "select avg(id)+count(foo)+bar from user group by bar", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "avg(id) + count(foo) + bar as avg(id) + count(foo) + bar" + ], + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + ":0 as bar", + "sum(id) / count(id) as avg(id)", + ":2 as count(foo)" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "sum(1) AS avg(id), sum_count(2) AS count(foo), sum_count(3) AS count(id)", + "GroupBy": "(0|4)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select bar, sum(id), count(foo), count(id), weight_string(bar) from `user` where 1 != 1 group by bar, weight_string(bar)", + "OrderBy": "(0|4) ASC", + "Query": "select bar, sum(id), count(foo), count(id), weight_string(bar) from `user` group by bar, weight_string(bar) order by bar asc", + "Table": "`user`" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "two avg aggregations", + "query": "select avg(foo), avg(bar) from user", + "plan": { + "QueryType": "SELECT", + "Original": "select avg(foo), avg(bar) from user", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "sum(foo) / count(foo) as avg(foo)", + "sum(bar) / count(bar) as avg(bar)" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "sum(0) AS avg(foo), sum(1) AS avg(bar), sum_count(2) AS count(foo), sum_count(3) AS count(bar)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select sum(foo), sum(bar), count(foo), count(bar) from `user` where 1 != 1", + "Query": "select sum(foo), sum(bar), count(foo), count(bar) from `user`", + "Table": "`user`" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "avg and count on the same argument", + "query": "select avg(foo), count(foo) from user", + "plan": { + "QueryType": "SELECT", + "Original": "select avg(foo), count(foo) from user", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "sum(foo) / count(foo) as avg(foo)", + ":1 as count(foo)" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "sum(0) AS avg(foo), sum_count(1) AS count(foo), sum_count(2) AS count(foo)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select sum(foo), count(foo), count(foo) from `user` where 1 != 1", + "Query": "select sum(foo), count(foo), count(foo) from `user`", + "Table": "`user`" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json index f40ea961334..61f602c4e33 100644 --- a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json @@ -2,7 +2,50 @@ { "comment": "TPC-H query 1", "query": "select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order from lineitem where l_shipdate <= '1998-12-01' - interval '108' day group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus", - "plan": "VT12001: unsupported: in scatter query: aggregation function 'avg(l_quantity) as avg_qty'" + "plan": { + "QueryType": "SELECT", + "Original": "select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order from lineitem where l_shipdate <= '1998-12-01' - interval '108' day group by l_returnflag, l_linestatus order by l_returnflag, l_linestatus", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + ":0 as l_returnflag", + ":1 as l_linestatus", + ":2 as sum_qty", + ":3 as sum_base_price", + ":4 as sum_disc_price", + ":5 as sum_charge", + "sum(l_quantity) / count(l_quantity) as avg_qty", + "sum(l_extendedprice) / count(l_extendedprice) as avg_price", + "sum(l_discount) / count(l_discount) as avg_disc", + ":9 as count_order" + ], + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "sum(2) AS sum_qty, sum(3) AS sum_base_price, sum(4) AS sum_disc_price, sum(5) AS sum_charge, sum(6) AS avg_qty, sum(7) AS avg_price, sum(8) AS avg_disc, sum_count_star(9) AS count_order, sum_count(10) AS count(l_quantity), sum_count(11) AS count(l_extendedprice), sum_count(12) AS count(l_discount)", + "GroupBy": "(0|13), (1|14)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "main", + "Sharded": true + }, + "FieldQuery": "select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, sum(l_quantity) as avg_qty, sum(l_extendedprice) as avg_price, sum(l_discount) as avg_disc, count(*) as count_order, count(l_quantity), count(l_extendedprice), count(l_discount), weight_string(l_returnflag), weight_string(l_linestatus) from lineitem where 1 != 1 group by l_returnflag, l_linestatus, weight_string(l_returnflag), weight_string(l_linestatus)", + "OrderBy": "(0|13) ASC, (1|14) ASC", + "Query": "select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, sum(l_quantity) as avg_qty, sum(l_extendedprice) as avg_price, sum(l_discount) as avg_disc, count(*) as count_order, count(l_quantity), count(l_extendedprice), count(l_discount), weight_string(l_returnflag), weight_string(l_linestatus) from lineitem where l_shipdate <= '1998-12-01' - interval '108' day group by l_returnflag, l_linestatus, weight_string(l_returnflag), weight_string(l_linestatus) order by l_returnflag asc, l_linestatus asc", + "Table": "lineitem" + } + ] + } + ] + }, + "TablesUsed": [ + "main.lineitem" + ] + } }, { "comment": "TPC-H query 2", diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index 923e7804782..6fb4e6d36ab 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -224,11 +224,6 @@ "query": "create view main.view_a as select * from user.user_extra", "plan": "VT12001: unsupported: Select query does not belong to the same keyspace as the view statement" }, - { - "comment": "avg function on scatter query", - "query": "select avg(id) from user", - "plan": "VT12001: unsupported: in scatter query: aggregation function 'avg(id)'" - }, { "comment": "outer and inner subquery route reference the same \"uu.id\" name\n# but they refer to different things. The first reference is to the outermost query,\n# and the second reference is to the innermost 'from' subquery.\n# This query will never work as the inner derived table is only selecting one of the column", "query": "select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select col from (select id from user_extra where user_id = 5) uu where uu.user_id = uu.id))", From df8b42833cdfdef32983cd058b4c15df80f1ed8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:42:28 -0600 Subject: [PATCH 004/119] Bump google.golang.org/grpc from 1.55.0-dev to 1.56.3 (#14364) Signed-off-by: dependabot[bot] Signed-off-by: Florent Poinsard Signed-off-by: Dirkjan Bussink Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Florent Poinsard Co-authored-by: Dirkjan Bussink --- go.mod | 34 ++++----- go.sum | 70 ++++++++++--------- go/flags/endtoend/mysqlctl.txt | 6 +- go/flags/endtoend/mysqlctld.txt | 6 +- go/flags/endtoend/topo2topo.txt | 6 +- go/flags/endtoend/vtaclcheck.txt | 6 +- go/flags/endtoend/vtbackup.txt | 6 +- go/flags/endtoend/vtcombo.txt | 6 +- go/flags/endtoend/vtctlclient.txt | 8 ++- go/flags/endtoend/vtctld.txt | 6 +- go/flags/endtoend/vtctldclient.txt | 8 ++- go/flags/endtoend/vtexplain.txt | 6 +- go/flags/endtoend/vtgate.txt | 6 +- go/flags/endtoend/vtgateclienttest.txt | 6 +- go/flags/endtoend/vtorc.txt | 6 +- go/flags/endtoend/vttablet.txt | 6 +- go/flags/endtoend/vttestserver.txt | 6 +- go/flags/endtoend/zkctl.txt | 6 +- go/test/endtoend/cluster/mysqlctld_process.go | 12 +++- go/test/endtoend/cluster/topo_process.go | 45 ++++++++---- go/test/endtoend/cluster/vtctld_process.go | 11 ++- go/test/endtoend/cluster/vtgate_process.go | 6 +- go/test/endtoend/cluster/vtorc_process.go | 17 ++++- .../endtoend/recovery/pitr/binlog_server.go | 8 ++- go/vt/proto/binlogdata/binlogdata.pb.go | 2 +- go/vt/proto/binlogservice/binlogservice.pb.go | 2 +- go/vt/proto/logutil/logutil.pb.go | 2 +- go/vt/proto/mysqlctl/mysqlctl.pb.go | 2 +- go/vt/proto/query/query.pb.go | 2 +- go/vt/proto/queryservice/queryservice.pb.go | 2 +- .../replicationdata/replicationdata.pb.go | 2 +- go/vt/proto/tableacl/tableacl.pb.go | 2 +- .../tabletmanagerdata/tabletmanagerdata.pb.go | 2 +- .../tabletmanagerservice.pb.go | 2 +- go/vt/proto/throttlerdata/throttlerdata.pb.go | 2 +- .../throttlerservice/throttlerservice.pb.go | 2 +- go/vt/proto/topodata/topodata.pb.go | 2 +- go/vt/proto/vschema/vschema.pb.go | 2 +- go/vt/proto/vtadmin/vtadmin.pb.go | 2 +- go/vt/proto/vtctldata/vtctldata.pb.go | 2 +- go/vt/proto/vtctlservice/vtctlservice.pb.go | 2 +- go/vt/proto/vtgate/vtgate.pb.go | 2 +- go/vt/proto/vtgateservice/vtgateservice.pb.go | 2 +- go/vt/proto/vtrpc/vtrpc.pb.go | 2 +- go/vt/proto/vttest/vttest.pb.go | 2 +- go/vt/proto/vttime/vttime.pb.go | 2 +- 46 files changed, 207 insertions(+), 140 deletions(-) diff --git a/go.mod b/go.mod index 19fec748de8..7a396338352 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module vitess.io/vitess go 1.21 require ( - cloud.google.com/go/storage v1.29.0 + cloud.google.com/go/storage v1.30.1 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 github.com/Azure/azure-pipeline-go v0.2.3 github.com/Azure/azure-storage-blob-go v0.15.0 @@ -19,12 +19,12 @@ require ( github.com/evanphx/json-patch v5.6.0+incompatible github.com/fsnotify/fsnotify v1.6.0 github.com/go-sql-driver/mysql v1.7.0 - github.com/golang/glog v1.0.0 + github.com/golang/glog v1.1.2 github.com/golang/protobuf v1.5.3 github.com/golang/snappy v0.0.4 github.com/google/go-cmp v0.5.9 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -74,18 +74,18 @@ require ( golang.org/x/crypto v0.14.0 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 - golang.org/x/oauth2 v0.7.0 - golang.org/x/sys v0.13.0 + golang.org/x/oauth2 v0.11.0 + golang.org/x/sys v0.14.0 golang.org/x/term v0.13.0 - golang.org/x/text v0.13.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 - google.golang.org/api v0.121.0 - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0-dev + google.golang.org/api v0.128.0 + google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect + google.golang.org/grpc v1.59.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/grpc/examples v0.0.0-20210430044426-28078834f35b - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.31.0 gopkg.in/DataDog/dd-trace-go.v1 v1.50.1 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/ldap.v2 v2.5.1 @@ -114,10 +114,10 @@ require ( ) require ( - cloud.google.com/go v0.110.0 // indirect - cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go v0.110.9 // indirect + cloud.google.com/go/compute v1.23.2 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v0.13.0 // indirect + cloud.google.com/go/iam v1.1.4 // indirect github.com/DataDog/appsec-internal-go v1.0.0 // indirect github.com/DataDog/datadog-agent/pkg/obfuscate v0.43.1 // indirect github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.45.0-rc.1 // indirect @@ -138,9 +138,9 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/s2a-go v0.1.3 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.8.0 // indirect + github.com/google/s2a-go v0.1.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect @@ -177,6 +177,8 @@ require ( go4.org/unsafe/assume-no-moving-gc v0.0.0-20230426161633-7e06285ff160 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index f0b6cc35a35..395f8439090 100644 --- a/go.sum +++ b/go.sum @@ -17,24 +17,22 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.9 h1:e7ITSqGFFk4rbz/JFIqZh3G4VEHguhAL4BQcFlWtU68= +cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.23.2 h1:nWEMDhgbBkBJjfpVySqU4jgWdc22PLR0o4vEexZHers= +cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/iam v1.1.4 h1:K6n/GZHFTtEoKT5aUG3l9diPi0VduZNQ1PfdnpkkIFk= +cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -45,8 +43,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= @@ -210,8 +208,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -285,22 +283,22 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8= github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU= 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.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.4 h1:uGy6JWR/uMIILU8wbf+OkstIrNiMjGpEIyhx8f6W7s4= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc= -github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -769,8 +767,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -856,8 +854,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -875,8 +873,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -965,8 +963,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.121.0 h1:8Oopoo8Vavxx6gt+sgs8s8/X60WBAtKQq6JqnkF+xow= -google.golang.org/api v0.121.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1014,8 +1012,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1036,8 +1038,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.55.0-dev h1:b3WG8LoyS+X/C5ZbIWsJGjt8Hhqq0wUVX8+rPF/BHZo= -google.golang.org/grpc v1.55.0-dev/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/grpc/examples v0.0.0-20210430044426-28078834f35b h1:D/GTYPo6I1oEo08Bfpuj3xl5XE+UGHj7//5fVyKxhsQ= @@ -1055,8 +1057,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/DataDog/dd-trace-go.v1 v1.50.1 h1:DUpHhh+MHtpYnUyGr5rpfvKUXkRg93TSEHii/LZVF6g= gopkg.in/DataDog/dd-trace-go.v1 v1.50.1/go.mod h1:sw4gV8LIXseC5ISMbDJmm79OJDdl8I2Hhtelb6lpHuQ= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/go/flags/endtoend/mysqlctl.txt b/go/flags/endtoend/mysqlctl.txt index a8f832d3345..518c3f49d4a 100644 --- a/go/flags/endtoend/mysqlctl.txt +++ b/go/flags/endtoend/mysqlctl.txt @@ -64,7 +64,7 @@ Flags: --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -86,12 +86,12 @@ Flags: --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --service_map strings comma separated list of services to enable (or disable if prefixed with '-') Example: grpc-queryservice --socket_file string Local unix socket file to listen on - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. --tablet_uid uint32 Tablet UID. (default 41983) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging Use "mysqlctl [command] --help" for more information about a command. diff --git a/go/flags/endtoend/mysqlctld.txt b/go/flags/endtoend/mysqlctld.txt index 06b48347bf6..141c6697070 100644 --- a/go/flags/endtoend/mysqlctld.txt +++ b/go/flags/endtoend/mysqlctld.txt @@ -89,7 +89,7 @@ Flags: --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -111,11 +111,11 @@ Flags: --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --service_map strings comma separated list of services to enable (or disable if prefixed with '-') Example: grpc-queryservice --socket_file string Local unix socket file to listen on - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. --tablet_uid uint32 Tablet UID (default 41983) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --wait_time duration How long to wait for mysqld startup or shutdown (default 5m0s) diff --git a/go/flags/endtoend/topo2topo.txt b/go/flags/endtoend/topo2topo.txt index 4391a32a1a8..a96d3cfda61 100644 --- a/go/flags/endtoend/topo2topo.txt +++ b/go/flags/endtoend/topo2topo.txt @@ -27,7 +27,7 @@ Flags: -h, --help help for topo2topo --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -35,10 +35,10 @@ Flags: --pprof strings enable profiling --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --to_implementation string topology implementation to copy data to --to_root string topology server root to copy data to --to_server string topology server address to copy data to --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging diff --git a/go/flags/endtoend/vtaclcheck.txt b/go/flags/endtoend/vtaclcheck.txt index 34bef9a05f9..a7ba7604f46 100644 --- a/go/flags/endtoend/vtaclcheck.txt +++ b/go/flags/endtoend/vtaclcheck.txt @@ -15,7 +15,7 @@ Flags: -h, --help help for vtaclcheck --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -24,7 +24,7 @@ Flags: --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --static-auth-file string The path of the auth_server_static JSON file to check - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index 2dd6bf3ef28..8610606eca2 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -147,7 +147,7 @@ Flags: --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -201,7 +201,7 @@ Flags: --stats_common_tags strings Comma-separated list of common tags for the stats backend. It provides both label and values. Example: label1:value1,label2:value2 --stats_drop_variables string Variables to be dropped from the list of exported variables. --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --tablet_manager_grpc_ca string the server ca to use to validate servers when connecting --tablet_manager_grpc_cert string the cert to use to connect --tablet_manager_grpc_concurrency int concurrency to use to talk to a vttablet server for performance-sensitive RPCs (like ExecuteFetchAs{Dba,AllPrivs,App}) (default 8) @@ -230,7 +230,7 @@ Flags: --upgrade-safe Whether to use innodb_fast_shutdown=0 for the backup so it is safe to use for MySQL upgrades. --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --xbstream_restore_flags string Flags to pass to xbstream command during restore. These should be space separated and will be added to the end of the command. These need to match the ones used for backup e.g. --compress / --decompress, --encrypt / --decrypt --xtrabackup_backup_flags string Flags to pass to backup command. These should be space separated and will be added to the end of the command --xtrabackup_prepare_flags string Flags to pass to prepare command. These should be space separated and will be added to the end of the command diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index 71c11c54088..5a029b8dd84 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -189,7 +189,7 @@ Flags: --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) --lock_heartbeat_time duration If there is lock function used. This will keep the lock connection active by using this heartbeat (default 5s) --lock_tables_timeout duration How long to keep the table locked before timing out (default 1m0s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_queries_to_file string Enable query logging to the specified file @@ -329,7 +329,7 @@ Flags: --stats_common_tags strings Comma-separated list of common tags for the stats backend. It provides both label and values. Example: label1:value1,label2:value2 --stats_drop_variables string Variables to be dropped from the list of exported variables. --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --stream_buffer_size int the number of bytes sent from vtgate for each stream call. It's recommended to keep this value in sync with vttablet's query-server-config-stream-buffer-size. (default 32768) --stream_health_buffer_size uint max streaming health entries to buffer per streaming health client (default 20) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class @@ -395,7 +395,7 @@ Flags: --unhealthy_threshold duration replication lag after which a replica is considered unhealthy (default 2h0m0s) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vreplication-parallel-insert-workers int Number of parallel insertion workers to use during copy phase. Set <= 1 to disable parallelism, or > 1 to enable concurrent insertion during copy phase. (default 1) --vreplication_copy_phase_duration duration Duration for each copy phase loop (before running the next catchup: default 1h) (default 1h0m0s) --vreplication_copy_phase_max_innodb_history_list_length int The maximum InnoDB transaction history that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 1000000) diff --git a/go/flags/endtoend/vtctlclient.txt b/go/flags/endtoend/vtctlclient.txt index 7fa186acbd0..4a4e44763f1 100644 --- a/go/flags/endtoend/vtctlclient.txt +++ b/go/flags/endtoend/vtctlclient.txt @@ -22,23 +22,25 @@ Usage of vtctlclient: --jaeger-agent-host string host and port to send spans to. if empty, no tracing will be done --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors + --log_link string If non-empty, add symbolic links in this directory to the log files --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) + --logbuflevel int Buffer log messages logged at this level or lower (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms. --logtostderr log to standard error instead of files --pprof strings enable profiling --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --server string server to use for connection - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --tracer string tracing service to use (default "noop") --tracing-enable-logging whether to enable logging in the tracing service --tracing-sampling-rate float sampling rate for the probabilistic jaeger sampler (default 0.1) --tracing-sampling-type string sampling strategy to use for jaeger. possible values are 'const', 'probabilistic', 'rateLimiting', or 'remote' (default "const") --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") --vtctld_grpc_ca string the server ca to use to validate servers when connecting --vtctld_grpc_cert string the cert to use to connect diff --git a/go/flags/endtoend/vtctld.txt b/go/flags/endtoend/vtctld.txt index a9a5cebb0f3..82895637c69 100644 --- a/go/flags/endtoend/vtctld.txt +++ b/go/flags/endtoend/vtctld.txt @@ -88,7 +88,7 @@ Flags: --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -126,7 +126,7 @@ Flags: --stats_common_tags strings Comma-separated list of common tags for the stats backend. It provides both label and values. Example: label1:value1,label2:value2 --stats_drop_variables string Variables to be dropped from the list of exported variables. --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. --tablet_grpc_ca string the server ca to use to validate servers when connecting @@ -171,5 +171,5 @@ Flags: --tracing-sampling-type string sampling strategy to use for jaeger. possible values are 'const', 'probabilistic', 'rateLimiting', or 'remote' (default "const") --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vtctld_sanitize_log_messages When true, vtctld sanitizes logging. diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt index 7fddb7eebfe..f70f17f8136 100644 --- a/go/flags/endtoend/vtctldclient.txt +++ b/go/flags/endtoend/vtctldclient.txt @@ -115,18 +115,20 @@ Flags: -h, --help help for vtctldclient --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory + --log_link string If non-empty, add symbolic links in this directory to the log files --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) + --logbuflevel int Buffer log messages logged at this level or lower (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms. --logtostderr log to standard error instead of files --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --server string server to use for the connection (required) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) -v, --v Level log level for V logs --version version for vtctldclient - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") --vtctld_grpc_ca string the server ca to use to validate servers when connecting --vtctld_grpc_cert string the cert to use to connect diff --git a/go/flags/endtoend/vtexplain.txt b/go/flags/endtoend/vtexplain.txt index f75559474c0..748856a97a6 100644 --- a/go/flags/endtoend/vtexplain.txt +++ b/go/flags/endtoend/vtexplain.txt @@ -54,7 +54,7 @@ Flags: --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --ks-shard-map string JSON map of keyspace name -> shard name -> ShardReference object. The inner map is the same as the output of FindAllShardsInKeyspace --ks-shard-map-file string File containing json blob of keyspace name -> shard name -> ShardReference object - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -74,9 +74,9 @@ Flags: --sql-file string Identifies the file that contains the SQL commands to analyze --sql-max-length-errors int truncate queries in error logs to the given length (default unlimited) --sql-max-length-ui int truncate queries in debug UIs to the given length (default 512) (default 512) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema string Identifies the VTGate routing schema --vschema-file string Identifies the VTGate routing schema file diff --git a/go/flags/endtoend/vtgate.txt b/go/flags/endtoend/vtgate.txt index 6bad7c768aa..55974504d5e 100644 --- a/go/flags/endtoend/vtgate.txt +++ b/go/flags/endtoend/vtgate.txt @@ -105,7 +105,7 @@ Flags: --legacy_replication_lag_algorithm Use the legacy algorithm when selecting vttablets for serving. (default true) --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) --lock_heartbeat_time duration If there is lock function used. This will keep the lock connection active by using this heartbeat (default 5s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_queries_to_file string Enable query logging to the specified file @@ -188,7 +188,7 @@ Flags: --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) --statsd_address string Address for statsd client --statsd_sample_rate float Sample rate for statsd metrics (default 1) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --stream_buffer_size int the number of bytes sent from vtgate for each stream call. It's recommended to keep this value in sync with vttablet's query-server-config-stream-buffer-size. (default 32768) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_filters strings Specifies a comma-separated list of 'keyspace|shard_name or keyrange' values to filter the tablets to watch. @@ -228,7 +228,7 @@ Flags: --truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema_ddl_authorized_users string List of users authorized to execute vschema ddl operations, or '%' to allow all users. --vtgate-config-terse-errors prevent bind vars from escaping in returned errors --warming-reads-concurrency int Number of concurrent warming reads allowed (default 500) diff --git a/go/flags/endtoend/vtgateclienttest.txt b/go/flags/endtoend/vtgateclienttest.txt index 4580d4d6ce7..6a05d975466 100644 --- a/go/flags/endtoend/vtgateclienttest.txt +++ b/go/flags/endtoend/vtgateclienttest.txt @@ -44,7 +44,7 @@ Flags: --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -59,9 +59,9 @@ Flags: --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --service_map strings comma separated list of services to enable (or disable if prefixed with '-') Example: grpc-queryservice - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema_ddl_authorized_users string List of users authorized to execute vschema ddl operations, or '%' to allow all users. diff --git a/go/flags/endtoend/vtorc.txt b/go/flags/endtoend/vtorc.txt index b13756e793c..0bbe8ef7469 100644 --- a/go/flags/endtoend/vtorc.txt +++ b/go/flags/endtoend/vtorc.txt @@ -50,7 +50,7 @@ Flags: --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -76,7 +76,7 @@ Flags: --stats_common_tags strings Comma-separated list of common tags for the stats backend. It provides both label and values. Example: label1:value1,label2:value2 --stats_drop_variables string Variables to be dropped from the list of exported variables. --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_manager_grpc_ca string the server ca to use to validate servers when connecting --tablet_manager_grpc_cert string the cert to use to connect @@ -106,5 +106,5 @@ Flags: --topo_zk_tls_key string the key to use to connect to the zk topo server, enables TLS --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --wait-replicas-timeout duration Duration for which to wait for replica's to respond when issuing RPCs (default 30s) diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index 30fe5e41172..7f18d8dc76b 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -213,7 +213,7 @@ Flags: --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) --lock-timeout duration Maximum time for which a shard/keyspace lock can be acquired for (default 45s) --lock_tables_timeout duration How long to keep the table locked before timing out (default 1m0s) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_queries Enable query logging to syslog. @@ -331,7 +331,7 @@ Flags: --stats_emit_period duration Interval between emitting stats to all registered backends (default 1m0s) --statsd_address string Address for statsd client --statsd_sample_rate float Sample rate for statsd metrics (default 1) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --stream_health_buffer_size uint max streaming health entries to buffer per streaming health client (default 20) --table-acl-config string path to table access checker config file; send SIGHUP to reload this file --table-acl-config-reload-interval duration Ticker to reload ACLs. Duration flag, format e.g.: 30s. Default: do not reload @@ -400,7 +400,7 @@ Flags: --unhealthy_threshold duration replication lag after which a replica is considered unhealthy (default 2h0m0s) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vreplication-parallel-insert-workers int Number of parallel insertion workers to use during copy phase. Set <= 1 to disable parallelism, or > 1 to enable concurrent insertion during copy phase. (default 1) --vreplication_copy_phase_duration duration Duration for each copy phase loop (before running the next catchup: default 1h) (default 1h0m0s) --vreplication_copy_phase_max_innodb_history_list_length int The maximum InnoDB transaction history that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 1000000) diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index fb9c42d932a..f6b9332a95e 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -75,7 +75,7 @@ Flags: --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --keyspaces strings Comma separated list of keyspaces (default [test_keyspace]) --lameduck-period duration keep running at least this long after SIGTERM before stopping (default 50ms) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -112,7 +112,7 @@ Flags: --snapshot_file string A MySQL DB snapshot file --sql-max-length-errors int truncate queries in error logs to the given length (default unlimited) --sql-max-length-ui int truncate queries in debug UIs to the given length (default 512) (default 512) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. --tablet_hostname string The hostname to use for the tablet otherwise it will be derived from OS' hostname (default "localhost") @@ -138,7 +138,7 @@ Flags: --transaction_mode string Transaction mode MULTI (default), SINGLE or TWOPC (default "MULTI") --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema_ddl_authorized_users string Comma separated list of users authorized to execute vschema ddl operations via vtgate --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") --vtctld_grpc_ca string the server ca to use to validate servers when connecting diff --git a/go/flags/endtoend/zkctl.txt b/go/flags/endtoend/zkctl.txt index d1aea061ea5..727c0f28191 100644 --- a/go/flags/endtoend/zkctl.txt +++ b/go/flags/endtoend/zkctl.txt @@ -22,17 +22,17 @@ Flags: -h, --help help for zkctl --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) --logtostderr log to standard error instead of files --pprof strings enable profiling --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --zk.cfg string zkid@server1:leaderPort1:electionPort1:clientPort1,...) (default "6@:3801:3802:3803") --zk.extra stringArray extra config line(s) to append verbatim to config (flag can be specified more than once) --zk.myid uint which server do you want to be? only needed when running multiple instance on one box, otherwise myid is implied by hostname diff --git a/go/test/endtoend/cluster/mysqlctld_process.go b/go/test/endtoend/cluster/mysqlctld_process.go index 60d30bc6cc0..08409c1246d 100644 --- a/go/test/endtoend/cluster/mysqlctld_process.go +++ b/go/test/endtoend/cluster/mysqlctld_process.go @@ -92,7 +92,15 @@ func (mysqlctld *MysqlctldProcess) Start() error { "--init_db_sql_file", mysqlctld.InitDBFile) } - errFile, _ := os.Create(path.Join(mysqlctld.LogDirectory, "mysqlctld-stderr.txt")) + err := os.MkdirAll(mysqlctld.LogDirectory, 0755) + if err != nil { + log.Errorf("Failed to create directory for mysqlctld logs: %v", err) + return err + } + errFile, err := os.Create(path.Join(mysqlctld.LogDirectory, "mysqlctld-stderr.txt")) + if err != nil { + log.Errorf("Failed to create directory for mysqlctld stderr: %v", err) + } tempProcess.Stderr = errFile tempProcess.Env = append(tempProcess.Env, os.Environ()...) @@ -103,7 +111,7 @@ func (mysqlctld *MysqlctldProcess) Start() error { log.Infof("%v", strings.Join(tempProcess.Args, " ")) - err := tempProcess.Start() + err = tempProcess.Start() if err != nil { return err } diff --git a/go/test/endtoend/cluster/topo_process.go b/go/test/endtoend/cluster/topo_process.go index 45a2e6586fa..776ed7da27e 100644 --- a/go/test/endtoend/cluster/topo_process.go +++ b/go/test/endtoend/cluster/topo_process.go @@ -145,10 +145,10 @@ func (topo *TopoProcess) SetupEtcd() (err error) { // SetupZookeeper spawns a new zookeeper topo service and initializes it with the defaults. // The service is kept running in the background until TearDown() is called. -func (topo *TopoProcess) SetupZookeeper(cluster *LocalProcessCluster) (err error) { +func (topo *TopoProcess) SetupZookeeper(cluster *LocalProcessCluster) error { host, err := os.Hostname() if err != nil { - return + return err } topo.ZKPorts = fmt.Sprintf("%d:%d:%d", cluster.GetAndReservePort(), cluster.GetAndReservePort(), topo.Port) @@ -160,16 +160,21 @@ func (topo *TopoProcess) SetupZookeeper(cluster *LocalProcessCluster) (err error "init", ) - errFile, _ := os.Create(path.Join(topo.DataDirectory, "topo-stderr.txt")) + err = os.MkdirAll(topo.LogDirectory, 0755) + if err != nil { + log.Errorf("Failed to create log directory for zookeeper: %v", err) + return err + } + errFile, err := os.Create(path.Join(topo.LogDirectory, "topo-stderr.txt")) + if err != nil { + log.Errorf("Failed to create file for zookeeper stderr: %v", err) + return err + } topo.proc.Stderr = errFile topo.proc.Env = append(topo.proc.Env, os.Environ()...) log.Infof("Starting zookeeper with args %v", strings.Join(topo.proc.Args, " ")) - err = topo.proc.Run() - if err != nil { - return - } - return + return topo.proc.Run() } // ConsulConfigs are the configurations that are added the config files which are used by consul @@ -193,13 +198,25 @@ type PortsInfo struct { 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) + err = os.MkdirAll(topo.LogDirectory, os.ModePerm) + if err != nil { + log.Errorf("Failed to create directory for consul logs: %v", err) + return + } + err = os.MkdirAll(topo.DataDirectory, os.ModePerm) + if err != nil { + log.Errorf("Failed to create directory for consul data: %v", err) + return + } configFile := path.Join(os.Getenv("VTDATAROOT"), "consul.json") logFile := path.Join(topo.LogDirectory, "/consul.log") - _, _ = os.Create(logFile) + _, err = os.Create(logFile) + if err != nil { + log.Errorf("Failed to create file for consul logs: %v", err) + return + } var config []byte configs := ConsulConfigs{ @@ -233,7 +250,11 @@ func (topo *TopoProcess) SetupConsul(cluster *LocalProcessCluster) (err error) { "-config-file", configFile, ) - errFile, _ := os.Create(path.Join(topo.DataDirectory, "topo-stderr.txt")) + errFile, err := os.Create(path.Join(topo.LogDirectory, "topo-stderr.txt")) + if err != nil { + log.Errorf("Failed to create file for consul stderr: %v", err) + return + } topo.proc.Stderr = errFile topo.proc.Env = append(topo.proc.Env, os.Environ()...) diff --git a/go/test/endtoend/cluster/vtctld_process.go b/go/test/endtoend/cluster/vtctld_process.go index d0b2e5ab93e..d87427af9b9 100644 --- a/go/test/endtoend/cluster/vtctld_process.go +++ b/go/test/endtoend/cluster/vtctld_process.go @@ -79,7 +79,16 @@ func (vtctld *VtctldProcess) Setup(cell string, extraArgs ...string) (err error) } vtctld.proc.Args = append(vtctld.proc.Args, extraArgs...) - errFile, _ := os.Create(path.Join(vtctld.LogDir, "vtctld-stderr.txt")) + err = os.MkdirAll(vtctld.LogDir, 0755) + if err != nil { + log.Errorf("cannot create log directory for vtctld: %v", err) + return err + } + errFile, err := os.Create(path.Join(vtctld.LogDir, "vtctld-stderr.txt")) + if err != nil { + log.Errorf("cannot create error log file for vtctld: %v", err) + return err + } vtctld.proc.Stderr = errFile vtctld.ErrorLog = errFile.Name() diff --git a/go/test/endtoend/cluster/vtgate_process.go b/go/test/endtoend/cluster/vtgate_process.go index ab82a32f651..d1877fb89bb 100644 --- a/go/test/endtoend/cluster/vtgate_process.go +++ b/go/test/endtoend/cluster/vtgate_process.go @@ -130,7 +130,11 @@ func (vtgate *VtgateProcess) Setup() (err error) { vtgate.proc.Args = append(vtgate.proc.Args, vtgate.ExtraArgs...) - errFile, _ := os.Create(path.Join(vtgate.LogDir, "vtgate-stderr.txt")) + errFile, err := os.Create(path.Join(vtgate.LogDir, "vtgate-stderr.txt")) + if err != nil { + log.Errorf("cannot create error log file for vtgate: %v", err) + return err + } vtgate.proc.Stderr = errFile vtgate.proc.Env = append(vtgate.proc.Env, os.Environ()...) diff --git a/go/test/endtoend/cluster/vtorc_process.go b/go/test/endtoend/cluster/vtorc_process.go index f80690d8d60..25bbb74c36c 100644 --- a/go/test/endtoend/cluster/vtorc_process.go +++ b/go/test/endtoend/cluster/vtorc_process.go @@ -86,7 +86,16 @@ func (orc *VTOrcProcess) Setup() (err error) { // create the configuration file timeNow := time.Now().UnixNano() - configFile, _ := os.Create(path.Join(orc.LogDir, fmt.Sprintf("orc-config-%d.json", timeNow))) + err = os.MkdirAll(orc.LogDir, 0755) + if err != nil { + log.Errorf("cannot create log directory for vtorc: %v", err) + return err + } + configFile, err := os.Create(path.Join(orc.LogDir, fmt.Sprintf("orc-config-%d.json", timeNow))) + if err != nil { + log.Errorf("cannot create config file for vtorc: %v", err) + return err + } orc.ConfigPath = configFile.Name() // Add the default configurations and print them out @@ -135,7 +144,11 @@ func (orc *VTOrcProcess) Setup() (err error) { if orc.LogFileName == "" { orc.LogFileName = fmt.Sprintf("orc-stderr-%d.txt", timeNow) } - errFile, _ := os.Create(path.Join(orc.LogDir, orc.LogFileName)) + errFile, err := os.Create(path.Join(orc.LogDir, orc.LogFileName)) + if err != nil { + log.Errorf("cannot create error log file for vtorc: %v", err) + return err + } orc.proc.Stderr = errFile orc.proc.Env = append(orc.proc.Env, os.Environ()...) diff --git a/go/test/endtoend/recovery/pitr/binlog_server.go b/go/test/endtoend/recovery/pitr/binlog_server.go index 764af2b57cf..3b78b0d4ad7 100644 --- a/go/test/endtoend/recovery/pitr/binlog_server.go +++ b/go/test/endtoend/recovery/pitr/binlog_server.go @@ -93,14 +93,18 @@ func (bs *binLogServer) start(source mysqlSource) error { bs.proc.Args = append(bs.proc.Args, fmt.Sprintf("-ripple_master_password=%s", source.password)) } - errFile, _ := os.Create(path.Join(bs.dataDirectory, "log.txt")) + errFile, err := os.Create(path.Join(bs.dataDirectory, "log.txt")) + if err != nil { + log.Errorf("cannot create error log file for binlog server: %v", err) + return err + } bs.proc.Stderr = errFile bs.proc.Env = append(bs.proc.Env, os.Environ()...) log.Infof("Running binlog server with command: %v", strings.Join(bs.proc.Args, " ")) - err := bs.proc.Start() + err = bs.proc.Start() if err != nil { return err } diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index c0a4bd08860..21855e871cc 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -19,7 +19,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: binlogdata.proto diff --git a/go/vt/proto/binlogservice/binlogservice.pb.go b/go/vt/proto/binlogservice/binlogservice.pb.go index 4eac50296c1..4ff35fbe17d 100644 --- a/go/vt/proto/binlogservice/binlogservice.pb.go +++ b/go/vt/proto/binlogservice/binlogservice.pb.go @@ -19,7 +19,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: binlogservice.proto diff --git a/go/vt/proto/logutil/logutil.pb.go b/go/vt/proto/logutil/logutil.pb.go index b2675716168..619328301bc 100644 --- a/go/vt/proto/logutil/logutil.pb.go +++ b/go/vt/proto/logutil/logutil.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: logutil.proto diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index 19f70887681..87d07442c8c 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: mysqlctl.proto diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index b8e7e4fe05e..1f1091cd7a3 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: query.proto diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go index babedcde966..aeb80f854bf 100644 --- a/go/vt/proto/queryservice/queryservice.pb.go +++ b/go/vt/proto/queryservice/queryservice.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: queryservice.proto diff --git a/go/vt/proto/replicationdata/replicationdata.pb.go b/go/vt/proto/replicationdata/replicationdata.pb.go index ec90d6943ac..30a7bb93b54 100644 --- a/go/vt/proto/replicationdata/replicationdata.pb.go +++ b/go/vt/proto/replicationdata/replicationdata.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: replicationdata.proto diff --git a/go/vt/proto/tableacl/tableacl.pb.go b/go/vt/proto/tableacl/tableacl.pb.go index 3b26ace8157..53fbd4714bd 100644 --- a/go/vt/proto/tableacl/tableacl.pb.go +++ b/go/vt/proto/tableacl/tableacl.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: tableacl.proto diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index c9039a3cfd9..b35347b3892 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: tabletmanagerdata.proto diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go index 608282049ba..6cb55ecf221 100644 --- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go +++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: tabletmanagerservice.proto diff --git a/go/vt/proto/throttlerdata/throttlerdata.pb.go b/go/vt/proto/throttlerdata/throttlerdata.pb.go index fb12bc09ce8..a109402cd9e 100644 --- a/go/vt/proto/throttlerdata/throttlerdata.pb.go +++ b/go/vt/proto/throttlerdata/throttlerdata.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: throttlerdata.proto diff --git a/go/vt/proto/throttlerservice/throttlerservice.pb.go b/go/vt/proto/throttlerservice/throttlerservice.pb.go index 9bca73e067c..7bf95215939 100644 --- a/go/vt/proto/throttlerservice/throttlerservice.pb.go +++ b/go/vt/proto/throttlerservice/throttlerservice.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: throttlerservice.proto diff --git a/go/vt/proto/topodata/topodata.pb.go b/go/vt/proto/topodata/topodata.pb.go index 43ecdbce963..e2a97369ba7 100644 --- a/go/vt/proto/topodata/topodata.pb.go +++ b/go/vt/proto/topodata/topodata.pb.go @@ -20,7 +20,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: topodata.proto diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index 8726fb35745..b45f7010c56 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vschema.proto diff --git a/go/vt/proto/vtadmin/vtadmin.pb.go b/go/vt/proto/vtadmin/vtadmin.pb.go index 3e41edd5f7e..2fc1e14a7f2 100644 --- a/go/vt/proto/vtadmin/vtadmin.pb.go +++ b/go/vt/proto/vtadmin/vtadmin.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtadmin.proto diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 5f70d625ffa..a1d8ce39ec1 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtctldata.proto diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 41231828a3d..fc2221d7074 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtctlservice.proto diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go index aee90d134a4..6b9bca8e118 100644 --- a/go/vt/proto/vtgate/vtgate.pb.go +++ b/go/vt/proto/vtgate/vtgate.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtgate.proto diff --git a/go/vt/proto/vtgateservice/vtgateservice.pb.go b/go/vt/proto/vtgateservice/vtgateservice.pb.go index 2008d486dc9..ba174dec2ea 100644 --- a/go/vt/proto/vtgateservice/vtgateservice.pb.go +++ b/go/vt/proto/vtgateservice/vtgateservice.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtgateservice.proto diff --git a/go/vt/proto/vtrpc/vtrpc.pb.go b/go/vt/proto/vtrpc/vtrpc.pb.go index 0c82dc34bf5..e45d6f37849 100644 --- a/go/vt/proto/vtrpc/vtrpc.pb.go +++ b/go/vt/proto/vtrpc/vtrpc.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vtrpc.proto diff --git a/go/vt/proto/vttest/vttest.pb.go b/go/vt/proto/vttest/vttest.pb.go index 4b4f269d38c..18ab7a83bb9 100644 --- a/go/vt/proto/vttest/vttest.pb.go +++ b/go/vt/proto/vttest/vttest.pb.go @@ -41,7 +41,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vttest.proto diff --git a/go/vt/proto/vttime/vttime.pb.go b/go/vt/proto/vttime/vttime.pb.go index 5cdf3f616ce..ae64898857b 100644 --- a/go/vt/proto/vttime/vttime.pb.go +++ b/go/vt/proto/vttime/vttime.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.31.0 // protoc v3.21.3 // source: vttime.proto From 9b1ce78866a9a12ba074d3d963974143068dad53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 9 Nov 2023 10:57:35 +0100 Subject: [PATCH 005/119] Refactor: use NonEmpty() instead of !IsEmpty() (#14499) --- .../vreplication/materialize/create.go | 2 +- go/vt/sqlparser/ast_format.go | 24 +++++++++---------- go/vt/sqlparser/ast_format_fast.go | 24 +++++++++---------- go/vt/sqlparser/ast_funcs.go | 16 ++++++++++--- go/vt/sqlparser/ast_rewriting.go | 2 +- go/vt/sqlparser/utils.go | 4 ++-- go/vt/topotools/vschema_ddl.go | 2 +- go/vt/vtgate/planbuilder/builder.go | 2 +- go/vt/vtgate/planbuilder/call_proc.go | 2 +- go/vt/vtgate/planbuilder/delete.go | 2 +- .../planbuilder/operators/projection.go | 4 ++-- .../planbuilder/operators/queryprojection.go | 4 ++-- go/vt/vtgate/planbuilder/operators/table.go | 2 +- go/vt/vtgate/planbuilder/show.go | 10 ++++---- go/vt/vtgate/semantics/derived_table.go | 4 ++-- go/vt/vtgate/semantics/early_rewriter.go | 4 ++-- go/vt/vtgate/semantics/scoper.go | 2 +- go/vt/vtgate/semantics/table_set.go | 2 +- go/vt/vtgate/semantics/vtable.go | 2 +- .../tabletmanager/vdiff/table_plan.go | 12 +++++----- go/vt/vttablet/tabletserver/schema/tracker.go | 2 +- .../tabletserver/vstreamer/planbuilder.go | 6 ++--- go/vt/wrangler/vdiff.go | 6 ++--- 23 files changed, 75 insertions(+), 65 deletions(-) diff --git a/go/cmd/vtctldclient/command/vreplication/materialize/create.go b/go/cmd/vtctldclient/command/vreplication/materialize/create.go index d835b0f3426..51f3ee42ee9 100644 --- a/go/cmd/vtctldclient/command/vreplication/materialize/create.go +++ b/go/cmd/vtctldclient/command/vreplication/materialize/create.go @@ -167,7 +167,7 @@ func (ts *tableSettings) Set(v string) error { err = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { switch node := node.(type) { case sqlparser.TableName: - if !node.Name.IsEmpty() { + if node.Name.NotEmpty() { if seenSourceTables[node.Name.String()] { return false, fmt.Errorf("multiple source_expression queries use the same table: %q", node.Name.String()) } diff --git a/go/vt/sqlparser/ast_format.go b/go/vt/sqlparser/ast_format.go index 3176ea2c12e..299ca3bed51 100644 --- a/go/vt/sqlparser/ast_format.go +++ b/go/vt/sqlparser/ast_format.go @@ -831,7 +831,7 @@ func (idx *IndexDefinition) Format(buf *TrackedBuffer) { // Format formats the node. func (ii *IndexInfo) Format(buf *TrackedBuffer) { - if !ii.ConstraintName.IsEmpty() { + if ii.ConstraintName.NotEmpty() { buf.astPrintf(ii, "constraint %v ", ii.ConstraintName) } switch ii.Type { @@ -847,7 +847,7 @@ func (ii *IndexInfo) Format(buf *TrackedBuffer) { case IndexTypeFullText: buf.astPrintf(ii, "%s %s", keywordStrings[FULLTEXT], keywordStrings[KEY]) } - if !ii.Name.IsEmpty() { + if ii.Name.NotEmpty() { buf.astPrintf(ii, " %v", ii.Name) } } @@ -883,7 +883,7 @@ func (node VindexParam) Format(buf *TrackedBuffer) { // Format formats the node. func (c *ConstraintDefinition) Format(buf *TrackedBuffer) { - if !c.Name.IsEmpty() { + if c.Name.NotEmpty() { buf.astPrintf(c, "constraint %v ", c.Name) } c.Details.Format(buf) @@ -1114,7 +1114,7 @@ func (node *StarExpr) Format(buf *TrackedBuffer) { // Format formats the node. func (node *AliasedExpr) Format(buf *TrackedBuffer) { buf.astPrintf(node, "%v", node.Expr) - if !node.As.IsEmpty() { + if node.As.NotEmpty() { buf.astPrintf(node, " as %v", node.As) } } @@ -1163,7 +1163,7 @@ func (node TableExprs) Format(buf *TrackedBuffer) { // Format formats the node. func (node *AliasedTableExpr) Format(buf *TrackedBuffer) { buf.astPrintf(node, "%v%v", node.Expr, node.Partitions) - if !node.As.IsEmpty() { + if node.As.NotEmpty() { buf.astPrintf(node, " as %v", node.As) if len(node.Columns) != 0 { buf.astPrintf(node, "%v", node.Columns) @@ -1189,7 +1189,7 @@ func (node TableName) Format(buf *TrackedBuffer) { if node.IsEmpty() { return } - if !node.Qualifier.IsEmpty() { + if node.Qualifier.NotEmpty() { buf.astPrintf(node, "%v.", node.Qualifier) } buf.astPrintf(node, "%v", node.Name) @@ -1544,7 +1544,7 @@ func (node *CollateExpr) Format(buf *TrackedBuffer) { // Format formats the node. func (node *FuncExpr) Format(buf *TrackedBuffer) { - if !node.Qualifier.IsEmpty() { + if node.Qualifier.NotEmpty() { buf.astPrintf(node, "%v.", node.Qualifier) } // Function names should not be back-quoted even @@ -1598,7 +1598,7 @@ func (node *JSONStorageSizeExpr) Format(buf *TrackedBuffer) { // Format formats the node func (node *OverClause) Format(buf *TrackedBuffer) { buf.WriteString("over") - if !node.WindowName.IsEmpty() { + if node.WindowName.NotEmpty() { buf.astPrintf(node, " %v", node.WindowName) } if node.WindowSpec != nil { @@ -1608,7 +1608,7 @@ func (node *OverClause) Format(buf *TrackedBuffer) { // Format formats the node func (node *WindowSpecification) Format(buf *TrackedBuffer) { - if !node.Name.IsEmpty() { + if node.Name.NotEmpty() { buf.astPrintf(node, " %v", node.Name) } if node.PartitionClause != nil { @@ -2020,7 +2020,7 @@ func (node *ShowBasic) Format(buf *TrackedBuffer) { if !node.Tbl.IsEmpty() { buf.astPrintf(node, " from %v", node.Tbl) } - if !node.DbName.IsEmpty() { + if node.DbName.NotEmpty() { buf.astPrintf(node, " from %v", node.DbName) } buf.astPrintf(node, "%v", node.Filter) @@ -2070,7 +2070,7 @@ func (node *CreateDatabase) Format(buf *TrackedBuffer) { // Format formats the node. func (node *AlterDatabase) Format(buf *TrackedBuffer) { buf.literal("alter database") - if !node.DBName.IsEmpty() { + if node.DBName.NotEmpty() { buf.astPrintf(node, " %v", node.DBName) } if node.UpdateDataDirectory { @@ -2354,7 +2354,7 @@ func (node *DropColumn) Format(buf *TrackedBuffer) { // Format formats the node func (node *DropKey) Format(buf *TrackedBuffer) { buf.astPrintf(node, "drop %s", node.Type.ToString()) - if !node.Name.IsEmpty() { + if node.Name.NotEmpty() { buf.astPrintf(node, " %v", node.Name) } } diff --git a/go/vt/sqlparser/ast_format_fast.go b/go/vt/sqlparser/ast_format_fast.go index b99c96c87ab..c951636d3f9 100644 --- a/go/vt/sqlparser/ast_format_fast.go +++ b/go/vt/sqlparser/ast_format_fast.go @@ -1128,7 +1128,7 @@ func (idx *IndexDefinition) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (ii *IndexInfo) FormatFast(buf *TrackedBuffer) { - if !ii.ConstraintName.IsEmpty() { + if ii.ConstraintName.NotEmpty() { buf.WriteString("constraint ") ii.ConstraintName.FormatFast(buf) buf.WriteByte(' ') @@ -1154,7 +1154,7 @@ func (ii *IndexInfo) FormatFast(buf *TrackedBuffer) { buf.WriteByte(' ') buf.WriteString(keywordStrings[KEY]) } - if !ii.Name.IsEmpty() { + if ii.Name.NotEmpty() { buf.WriteByte(' ') ii.Name.FormatFast(buf) } @@ -1196,7 +1196,7 @@ func (node VindexParam) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (c *ConstraintDefinition) FormatFast(buf *TrackedBuffer) { - if !c.Name.IsEmpty() { + if c.Name.NotEmpty() { buf.WriteString("constraint ") c.Name.FormatFast(buf) buf.WriteByte(' ') @@ -1474,7 +1474,7 @@ func (node *StarExpr) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (node *AliasedExpr) FormatFast(buf *TrackedBuffer) { node.Expr.FormatFast(buf) - if !node.As.IsEmpty() { + if node.As.NotEmpty() { buf.WriteString(" as ") node.As.FormatFast(buf) } @@ -1530,7 +1530,7 @@ func (node TableExprs) FormatFast(buf *TrackedBuffer) { func (node *AliasedTableExpr) FormatFast(buf *TrackedBuffer) { node.Expr.FormatFast(buf) node.Partitions.FormatFast(buf) - if !node.As.IsEmpty() { + if node.As.NotEmpty() { buf.WriteString(" as ") node.As.FormatFast(buf) if len(node.Columns) != 0 { @@ -1558,7 +1558,7 @@ func (node TableName) FormatFast(buf *TrackedBuffer) { if node.IsEmpty() { return } - if !node.Qualifier.IsEmpty() { + if node.Qualifier.NotEmpty() { node.Qualifier.FormatFast(buf) buf.WriteByte('.') } @@ -2064,7 +2064,7 @@ func (node *CollateExpr) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (node *FuncExpr) FormatFast(buf *TrackedBuffer) { - if !node.Qualifier.IsEmpty() { + if node.Qualifier.NotEmpty() { node.Qualifier.FormatFast(buf) buf.WriteByte('.') } @@ -2138,7 +2138,7 @@ func (node *JSONStorageSizeExpr) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node func (node *OverClause) FormatFast(buf *TrackedBuffer) { buf.WriteString("over") - if !node.WindowName.IsEmpty() { + if node.WindowName.NotEmpty() { buf.WriteByte(' ') node.WindowName.FormatFast(buf) } @@ -2151,7 +2151,7 @@ func (node *OverClause) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node func (node *WindowSpecification) FormatFast(buf *TrackedBuffer) { - if !node.Name.IsEmpty() { + if node.Name.NotEmpty() { buf.WriteByte(' ') node.Name.FormatFast(buf) } @@ -2690,7 +2690,7 @@ func (node *ShowBasic) FormatFast(buf *TrackedBuffer) { buf.WriteString(" from ") node.Tbl.FormatFast(buf) } - if !node.DbName.IsEmpty() { + if node.DbName.NotEmpty() { buf.WriteString(" from ") node.DbName.FormatFast(buf) } @@ -2751,7 +2751,7 @@ func (node *CreateDatabase) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (node *AlterDatabase) FormatFast(buf *TrackedBuffer) { buf.WriteString("alter database") - if !node.DBName.IsEmpty() { + if node.DBName.NotEmpty() { buf.WriteByte(' ') node.DBName.FormatFast(buf) } @@ -3118,7 +3118,7 @@ func (node *DropColumn) FormatFast(buf *TrackedBuffer) { func (node *DropKey) FormatFast(buf *TrackedBuffer) { buf.WriteString("drop ") buf.WriteString(node.Type.ToString()) - if !node.Name.IsEmpty() { + if node.Name.NotEmpty() { buf.WriteByte(' ') node.Name.FormatFast(buf) } diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 951d9879bdb..6a1d5600740 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -400,7 +400,7 @@ func (node *AliasedTableExpr) RemoveHints() *AliasedTableExpr { // TableName returns a TableName pointing to this table expr func (node *AliasedTableExpr) TableName() (TableName, error) { - if !node.As.IsEmpty() { + if node.As.NotEmpty() { return TableName{Name: node.As}, nil } @@ -868,6 +868,11 @@ func (node IdentifierCI) IsEmpty() bool { return node.val == "" } +// NonEmpty returns true if the name is not empty. +func (node IdentifierCI) NotEmpty() bool { + return !node.IsEmpty() +} + // String returns the unescaped column name. It must // not be used for SQL generation. Use sqlparser.String // instead. The Stringer conformance is for usage @@ -935,6 +940,11 @@ func (node IdentifierCS) IsEmpty() bool { return node.v == "" } +// NonEmpty returns true if TabIdent is not empty. +func (node IdentifierCS) NotEmpty() bool { + return !node.IsEmpty() +} + // String returns the unescaped table name. It must // not be used for SQL generation. Use sqlparser.String // instead. The Stringer conformance is for usage @@ -2099,7 +2109,7 @@ func GetAllSelects(selStmt SelectStatement) []*Select { // ColumnName returns the alias if one was provided, otherwise prints the AST func (ae *AliasedExpr) ColumnName() string { - if !ae.As.IsEmpty() { + if ae.As.NotEmpty() { return ae.As.String() } @@ -2131,7 +2141,7 @@ func RemoveKeyspace(in SQLNode) { _ = Walk(func(node SQLNode) (kontinue bool, err error) { switch col := node.(type) { case *ColName: - if !col.Qualifier.Qualifier.IsEmpty() { + if col.Qualifier.Qualifier.NotEmpty() { col.Qualifier.Qualifier = NewIdentifierCS("") } } diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index 45711f8d535..f3255143dbb 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -307,7 +307,7 @@ func (er *astRewriter) visitSelect(node *Select) { } aliasedExpr, ok := col.(*AliasedExpr) - if !ok || !aliasedExpr.As.IsEmpty() { + if !ok || aliasedExpr.As.NotEmpty() { continue } buf := NewTrackedBuffer(nil) diff --git a/go/vt/sqlparser/utils.go b/go/vt/sqlparser/utils.go index 0f3c66f2ea3..2258eb2fd02 100644 --- a/go/vt/sqlparser/utils.go +++ b/go/vt/sqlparser/utils.go @@ -135,14 +135,14 @@ func ReplaceTableQualifiers(query, olddb, newdb string) (string, error) { upd := Rewrite(in, func(cursor *Cursor) bool { switch node := cursor.Node().(type) { case TableName: - if !node.Qualifier.IsEmpty() && + if node.Qualifier.NotEmpty() && node.Qualifier.String() == oldQualifier.String() { node.Qualifier = newQualifier cursor.Replace(node) modified = true } case *ShowBasic: // for things like 'show tables from _vt' - if !node.DbName.IsEmpty() && + if node.DbName.NotEmpty() && node.DbName.String() == oldQualifier.String() { node.DbName = newQualifier cursor.Replace(node) diff --git a/go/vt/topotools/vschema_ddl.go b/go/vt/topotools/vschema_ddl.go index ff4d9f4ad04..3c6f5bced3c 100644 --- a/go/vt/topotools/vschema_ddl.go +++ b/go/vt/topotools/vschema_ddl.go @@ -124,7 +124,7 @@ func ApplyVSchemaDDL(ksName string, ks *vschemapb.Keyspace, alterVschema *sqlpar // already exists. spec := alterVschema.VindexSpec name := spec.Name.String() - if !spec.Type.IsEmpty() { + if spec.Type.NotEmpty() { owner, params := spec.ParseParams() if vindex, ok := ks.Vindexes[name]; ok { if vindex.Type != spec.Type.String() { diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index a67878d7119..2777181907d 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -246,7 +246,7 @@ func buildAnalyzePlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vsche var err error dest := key.Destination(key.DestinationAllShards{}) - if !analyzeStmt.Table.Qualifier.IsEmpty() && sqlparser.SystemSchema(analyzeStmt.Table.Qualifier.String()) { + if analyzeStmt.Table.Qualifier.NotEmpty() && sqlparser.SystemSchema(analyzeStmt.Table.Qualifier.String()) { ks, err = vschema.AnyKeyspace() if err != nil { return nil, err diff --git a/go/vt/vtgate/planbuilder/call_proc.go b/go/vt/vtgate/planbuilder/call_proc.go index 13fe5cc60e4..34f475689aa 100644 --- a/go/vt/vtgate/planbuilder/call_proc.go +++ b/go/vt/vtgate/planbuilder/call_proc.go @@ -25,7 +25,7 @@ import ( func buildCallProcPlan(stmt *sqlparser.CallProc, vschema plancontext.VSchema) (*planResult, error) { var ks string - if !stmt.Name.Qualifier.IsEmpty() { + if stmt.Name.Qualifier.NotEmpty() { ks = stmt.Name.Qualifier.String() } diff --git a/go/vt/vtgate/planbuilder/delete.go b/go/vt/vtgate/planbuilder/delete.go index 188c1485d1d..e8b71ea9a0e 100644 --- a/go/vt/vtgate/planbuilder/delete.go +++ b/go/vt/vtgate/planbuilder/delete.go @@ -95,7 +95,7 @@ func rewriteSingleTbl(del *sqlparser.Delete) (*sqlparser.Delete, error) { if !ok { return del, nil } - if !atExpr.As.IsEmpty() && !sqlparser.Equals.IdentifierCS(del.Targets[0].Name, atExpr.As) { + if atExpr.As.NotEmpty() && !sqlparser.Equals.IdentifierCS(del.Targets[0].Name, atExpr.As) { // Unknown table in MULTI DELETE return nil, vterrors.VT03003(del.Targets[0].Name.String()) } diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 1c751467890..bad9cb0e87e 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -166,7 +166,7 @@ func (ap AliasedProjections) AddColumn(col *sqlparser.AliasedExpr) (ProjCols, in func (pe *ProjExpr) String() string { var alias, expr, info string - if !pe.Original.As.IsEmpty() { + if pe.Original.As.NotEmpty() { alias = " AS " + pe.Original.As.String() } if sqlparser.Equals.Expr(pe.EvalExpr, pe.ColExpr) { @@ -399,7 +399,7 @@ func (p *Projection) GetSelectExprs(*plancontext.PlanningContext) sqlparser.Sele var output sqlparser.SelectExprs for _, pe := range cols { ae := &sqlparser.AliasedExpr{Expr: pe.EvalExpr} - if !pe.Original.As.IsEmpty() { + if pe.Original.As.NotEmpty() { ae.As = pe.Original.As } else if !sqlparser.Equals.Expr(ae.Expr, pe.Original.Expr) { ae.As = sqlparser.NewIdentifierCI(pe.Original.ColumnName()) diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index ff188d6c895..e3f4d349d2a 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -515,7 +515,7 @@ func (qp *QueryProjection) GetSimplifiedExpr(ctx *plancontext.PlanningContext, e if !ok { continue } - aliased := !ae.As.IsEmpty() + aliased := ae.As.NotEmpty() if aliased { if in.Name.Equal(ae.As) { err = check(ae.Expr) @@ -818,7 +818,7 @@ func (qp *QueryProjection) FindSelectExprIndexForExpr(ctx *plancontext.PlanningC continue } if isCol { - isAliasExpr := !aliasedExpr.As.IsEmpty() + isAliasExpr := aliasedExpr.As.NotEmpty() if isAliasExpr && colExpr.Name.Equal(aliasedExpr.As) { return &idx, aliasedExpr } diff --git a/go/vt/vtgate/planbuilder/operators/table.go b/go/vt/vtgate/planbuilder/operators/table.go index 09a99170932..e731ec54201 100644 --- a/go/vt/vtgate/planbuilder/operators/table.go +++ b/go/vt/vtgate/planbuilder/operators/table.go @@ -130,7 +130,7 @@ func addColumn(ctx *plancontext.PlanningContext, op ColNameColumns, e sqlparser. func (to *Table) ShortDescription() string { tbl := to.VTable.String() var alias, where string - if !to.QTable.Alias.As.IsEmpty() { + if to.QTable.Alias.As.NotEmpty() { alias = " AS " + to.QTable.Alias.As.String() } diff --git a/go/vt/vtgate/planbuilder/show.go b/go/vt/vtgate/planbuilder/show.go index aba5b1a9016..6e5fad4023a 100644 --- a/go/vt/vtgate/planbuilder/show.go +++ b/go/vt/vtgate/planbuilder/show.go @@ -164,7 +164,7 @@ func buildVariablePlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) ( } func buildShowTblPlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) (engine.Primitive, error) { - if !show.DbName.IsEmpty() { + if show.DbName.NotEmpty() { show.Tbl.Qualifier = sqlparser.NewIdentifierCS(show.DbName.String()) // Remove Database Name from the query. show.DbName = sqlparser.NewIdentifierCS("") @@ -174,7 +174,7 @@ func buildShowTblPlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) (e var ks *vindexes.Keyspace var err error - if !show.Tbl.Qualifier.IsEmpty() && sqlparser.SystemSchema(show.Tbl.Qualifier.String()) { + if show.Tbl.Qualifier.NotEmpty() && sqlparser.SystemSchema(show.Tbl.Qualifier.String()) { ks, err = vschema.AnyKeyspace() if err != nil { return nil, err @@ -486,7 +486,7 @@ func buildCreateTblPlan(show *sqlparser.ShowCreate, vschema plancontext.VSchema) var ks *vindexes.Keyspace var err error - if !show.Op.Qualifier.IsEmpty() && sqlparser.SystemSchema(show.Op.Qualifier.String()) { + if show.Op.Qualifier.NotEmpty() && sqlparser.SystemSchema(show.Op.Qualifier.String()) { ks, err = vschema.AnyKeyspace() if err != nil { return nil, err @@ -519,7 +519,7 @@ func buildCreateTblPlan(show *sqlparser.ShowCreate, vschema plancontext.VSchema) func buildCreatePlan(show *sqlparser.ShowCreate, vschema plancontext.VSchema) (engine.Primitive, error) { dbName := "" - if !show.Op.Qualifier.IsEmpty() { + if show.Op.Qualifier.NotEmpty() { dbName = show.Op.Qualifier.String() } @@ -567,7 +567,7 @@ func buildShowVGtidPlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) func buildShowGtidPlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) (engine.Primitive, error) { dbName := "" - if !show.DbName.IsEmpty() { + if show.DbName.NotEmpty() { dbName = show.DbName.String() } dest, ks, _, err := vschema.TargetDestination(dbName) diff --git a/go/vt/vtgate/semantics/derived_table.go b/go/vt/vtgate/semantics/derived_table.go index 9001848f6b4..732a75ac696 100644 --- a/go/vt/vtgate/semantics/derived_table.go +++ b/go/vt/vtgate/semantics/derived_table.go @@ -77,7 +77,7 @@ func handleAliasedExpr(vTbl *DerivedTable, expr *sqlparser.AliasedExpr, cols sql return } - if !expr.As.IsEmpty() { + if expr.As.NotEmpty() { vTbl.columnNames = append(vTbl.columnNames, expr.As.String()) return } @@ -161,7 +161,7 @@ func (dt *DerivedTable) getColumns() []ColumnInfo { } func (dt *DerivedTable) hasStar() bool { - return dt.tables.NonEmpty() + return dt.tables.NotEmpty() } // GetTables implements the TableInfo interface diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index 36060ed8334..d3c5f312426 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -67,7 +67,7 @@ func (r *earlyRewriter) down(cursor *sqlparser.Cursor) error { func (r *earlyRewriter) handleAliasedTable(node *sqlparser.AliasedTableExpr) error { tbl, ok := node.Expr.(sqlparser.TableName) - if !ok || !tbl.Qualifier.IsEmpty() { + if !ok || tbl.Qualifier.NotEmpty() { return nil } scope := r.scoper.currentScope() @@ -348,7 +348,7 @@ func (r *earlyRewriter) rewriteOrderByExpr(node *sqlparser.Literal) (sqlparser.E return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "don't know how to handle %s", sqlparser.String(node)) } - if !aliasedExpr.As.IsEmpty() { + if aliasedExpr.As.NotEmpty() { return sqlparser.NewColName(aliasedExpr.As.String()), nil } diff --git a/go/vt/vtgate/semantics/scoper.go b/go/vt/vtgate/semantics/scoper.go index 458e08b1f15..c782da03678 100644 --- a/go/vt/vtgate/semantics/scoper.go +++ b/go/vt/vtgate/semantics/scoper.go @@ -320,7 +320,7 @@ func checkForInvalidAliasUse(cte *sqlparser.CommonTableExpr, name string) (err e // TODO I'm sure there is a better. way, but we need to do this to stop infinite loops from occurring down := func(node sqlparser.SQLNode, parent sqlparser.SQLNode) bool { tbl, ok := node.(sqlparser.TableName) - if !ok || !tbl.Qualifier.IsEmpty() { + if !ok || tbl.Qualifier.NotEmpty() { return err == nil } if tbl.Name.String() == name { diff --git a/go/vt/vtgate/semantics/table_set.go b/go/vt/vtgate/semantics/table_set.go index 0ddbc87a224..acc83306869 100644 --- a/go/vt/vtgate/semantics/table_set.go +++ b/go/vt/vtgate/semantics/table_set.go @@ -57,7 +57,7 @@ func (ts TableSet) NumberOfTables() int { } // NonEmpty returns true if there are tables in the tableset -func (ts TableSet) NonEmpty() bool { +func (ts TableSet) NotEmpty() bool { return !ts.IsEmpty() } diff --git a/go/vt/vtgate/semantics/vtable.go b/go/vt/vtgate/semantics/vtable.go index 48439694b47..271da126cd4 100644 --- a/go/vt/vtgate/semantics/vtable.go +++ b/go/vt/vtgate/semantics/vtable.go @@ -94,7 +94,7 @@ func (v *vTableInfo) getColumns() []ColumnInfo { } func (v *vTableInfo) hasStar() bool { - return v.tables.NonEmpty() + return v.tables.NotEmpty() } // GetTables implements the TableInfo interface diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_plan.go b/go/vt/vttablet/tabletmanager/vdiff/table_plan.go index e669dbd9a33..f636eea5cae 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_plan.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_plan.go @@ -88,14 +88,14 @@ func (td *tableDiffer) buildTablePlan(dbClient binlogplayer.DBClient, dbName str } case *sqlparser.AliasedExpr: var targetCol *sqlparser.ColName - if !selExpr.As.IsEmpty() { - targetCol = &sqlparser.ColName{Name: selExpr.As} - } else { + if selExpr.As.IsEmpty() { if colAs, ok := selExpr.Expr.(*sqlparser.ColName); ok { targetCol = colAs } else { return nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(selExpr)) } + } else { + targetCol = &sqlparser.ColName{Name: selExpr.As} } // If the input was "select a as b", then source will use "a" and target will use "b". sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) @@ -157,7 +157,7 @@ func (td *tableDiffer) buildTablePlan(dbClient binlogplayer.DBClient, dbName str return nil, err } // Remove in_keyrange. It's not understood by mysql. - sourceSelect.Where = sel.Where //removeKeyrange(sel.Where) + sourceSelect.Where = sel.Where // removeKeyrange(sel.Where) // The source should also perform the group by. sourceSelect.GroupBy = sel.GroupBy sourceSelect.OrderBy = tp.orderBy @@ -186,8 +186,8 @@ func (tp *tablePlan) findPKs(dbClient binlogplayer.DBClient, targetSelect *sqlpa switch ct := expr.(type) { case *sqlparser.ColName: colname = ct.Name.String() - case *sqlparser.FuncExpr: //eg. weight_string() - //no-op + case *sqlparser.FuncExpr: // eg. weight_string() + // no-op default: log.Warningf("Not considering column %v for PK, type %v not handled", selExpr, ct) } diff --git a/go/vt/vttablet/tabletserver/schema/tracker.go b/go/vt/vttablet/tabletserver/schema/tracker.go index 9b4deaff6c4..684bb6d317d 100644 --- a/go/vt/vttablet/tabletserver/schema/tracker.go +++ b/go/vt/vttablet/tabletserver/schema/tracker.go @@ -263,7 +263,7 @@ func MustReloadSchemaOnDDL(sql string, dbname string) bool { if table.IsEmpty() { continue } - if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname { + if table.Qualifier.NotEmpty() && table.Qualifier.String() != dbname { continue } tableName := table.Name.String() diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 30fbfdb7a01..fc9408d050e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -338,7 +338,7 @@ func ruleMatches(tableName string, filter *binlogdatapb.Filter) bool { // tableMatches is similar to buildPlan below and MatchTable in vreplication/table_plan_builder.go. func tableMatches(table sqlparser.TableName, dbname string, filter *binlogdatapb.Filter) bool { - if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname { + if table.Qualifier.NotEmpty() && table.Qualifier.String() != dbname { return false } return ruleMatches(table.Name.String(), filter) @@ -528,7 +528,7 @@ func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) er if !ok { return fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } - //StrVal is varbinary, we do not support varchar since we would have to implement all collation types + // StrVal is varbinary, we do not support varchar since we would have to implement all collation types if val.Type != sqlparser.IntVal && val.Type != sqlparser.StrVal { return fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } @@ -702,7 +702,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp return ColExpr{}, fmt.Errorf("unsupported function: %v", sqlparser.String(inner)) } case *sqlparser.Literal: - //allow only intval 1 + // allow only intval 1 if inner.Type != sqlparser.IntVal { return ColExpr{}, fmt.Errorf("only integer literals are supported") } diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 2d6e49b73d7..2cbe5032c92 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -672,14 +672,14 @@ func (df *vdiff) buildTablePlan(table *tabletmanagerdatapb.TableDefinition, quer } case *sqlparser.AliasedExpr: var targetCol *sqlparser.ColName - if !selExpr.As.IsEmpty() { - targetCol = &sqlparser.ColName{Name: selExpr.As} - } else { + if selExpr.As.IsEmpty() { if colAs, ok := selExpr.Expr.(*sqlparser.ColName); ok { targetCol = colAs } else { return nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(selExpr)) } + } else { + targetCol = &sqlparser.ColName{Name: selExpr.As} } // If the input was "select a as b", then source will use "a" and target will use "b". sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) From f653ae10d904c2335f011eb73a553819f01997c2 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 10 Nov 2023 12:54:48 +0530 Subject: [PATCH 006/119] Foreign key on update action with non literal values (#14278) Signed-off-by: Harshit Gangal Signed-off-by: Manan Gupta Co-authored-by: Manan Gupta --- .../vtgate/foreignkey/fk_fuzz_test.go | 170 ++--- go/test/endtoend/vtgate/foreignkey/fk_test.go | 176 +++++ .../endtoend/vtgate/foreignkey/utils_test.go | 114 ++++ go/vt/vtgate/engine/cached_size.go | 21 +- go/vt/vtgate/engine/fk_cascade.go | 163 +++-- go/vt/vtgate/engine/fk_cascade_test.go | 80 ++- go/vt/vtgate/engine/fk_verify.go | 15 +- go/vt/vtgate/engine/fk_verify_test.go | 6 +- .../planbuilder/operator_transformers.go | 7 +- .../vtgate/planbuilder/operators/ast_to_op.go | 19 +- go/vt/vtgate/planbuilder/operators/delete.go | 8 +- .../planbuilder/operators/fk_cascade.go | 15 +- go/vt/vtgate/planbuilder/operators/update.go | 215 ++++-- .../testdata/foreignkey_cases.json | 635 +++++++++++++++++- .../testdata/postprocess_cases.json | 4 +- go/vt/vtgate/planbuilder/update.go | 7 + go/vt/vtgate/semantics/analyzer.go | 40 +- go/vt/vtgate/semantics/analyzer_fk_test.go | 582 ++++++++++++++++ go/vt/vtgate/semantics/analyzer_test.go | 554 --------------- go/vt/vtgate/semantics/early_rewriter.go | 41 ++ go/vt/vtgate/semantics/semantic_state.go | 89 +++ go/vt/vtgate/semantics/semantic_state_test.go | 233 ++++++- go/vt/vtgate/vindexes/foreign_keys.go | 16 +- 23 files changed, 2333 insertions(+), 877 deletions(-) create mode 100644 go/vt/vtgate/semantics/analyzer_fk_test.go diff --git a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go index 134b9cfa180..f7d7340d6a4 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go @@ -28,9 +28,7 @@ import ( _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/require" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" "vitess.io/vitess/go/vt/log" ) @@ -39,6 +37,7 @@ type QueryFormat string const ( SQLQueries QueryFormat = "SQLQueries" + OlapSQLQueries QueryFormat = "OlapSQLQueries" PreparedStatmentQueries QueryFormat = "PreparedStatmentQueries" PreparedStatementPacket QueryFormat = "PreparedStatementPacket" ) @@ -95,7 +94,7 @@ func (fz *fuzzer) generateQuery() []string { val := rand.Intn(fz.insertShare + fz.updateShare + fz.deleteShare) if val < fz.insertShare { switch fz.queryFormat { - case SQLQueries: + case OlapSQLQueries, SQLQueries: return []string{fz.generateInsertDMLQuery()} case PreparedStatmentQueries: return fz.getPreparedInsertQueries() @@ -105,7 +104,7 @@ func (fz *fuzzer) generateQuery() []string { } if val < fz.insertShare+fz.updateShare { switch fz.queryFormat { - case SQLQueries: + case OlapSQLQueries, SQLQueries: return []string{fz.generateUpdateDMLQuery()} case PreparedStatmentQueries: return fz.getPreparedUpdateQueries() @@ -114,7 +113,7 @@ func (fz *fuzzer) generateQuery() []string { } } switch fz.queryFormat { - case SQLQueries: + case OlapSQLQueries, SQLQueries: return []string{fz.generateDeleteDMLQuery()} case PreparedStatmentQueries: return fz.getPreparedDeleteQueries() @@ -131,41 +130,43 @@ func (fz *fuzzer) generateInsertDMLQuery() string { if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col, col2) values (%v, %v, %v)", tableName, idValue, convertColValueToString(colValue), convertColValueToString(col2Value)) + return fmt.Sprintf("insert into %v (id, col, col2) values (%v, %v, %v)", tableName, idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)) } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, cola, colb) values (%v, %v, %v)", tableName, idValue, convertColValueToString(colaValue), convertColValueToString(colbValue)) + return fmt.Sprintf("insert into %v (id, cola, colb) values (%v, %v, %v)", tableName, idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)) } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col) values (%v, %v)", tableName, idValue, convertColValueToString(colValue)) + return fmt.Sprintf("insert into %v (id, col) values (%v, %v)", tableName, idValue, convertIntValueToString(colValue)) } } -// convertColValueToString converts the given value to a string -func convertColValueToString(value int) string { - if value == 0 { - return "NULL" - } - return fmt.Sprintf("%d", value) -} - // generateUpdateDMLQuery generates an UPDATE query from the parameters for the fuzzer. func (fz *fuzzer) generateUpdateDMLQuery() string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] if tableName == "fk_t20" { - colValue := rand.Intn(1 + fz.maxValForCol) - col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set col = %v, col2 = %v where id = %v", tableName, convertColValueToString(colValue), convertColValueToString(col2Value), idValue) + colValue := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) + col2Value := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) + return fmt.Sprintf("update %v set col = %v, col2 = %v where id = %v", tableName, colValue, col2Value, idValue) } else if isMultiColFkTable(tableName) { - colaValue := rand.Intn(1 + fz.maxValForCol) - colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set cola = %v, colb = %v where id = %v", tableName, convertColValueToString(colaValue), convertColValueToString(colbValue), idValue) + if rand.Intn(2) == 0 { + colaValue := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) + colbValue := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) + if fz.concurrency > 1 { + colaValue = fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") + colbValue = fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") + } + return fmt.Sprintf("update %v set cola = %v, colb = %v where id = %v", tableName, colaValue, colbValue, idValue) + } else { + colValue := fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") + colToUpdate := []string{"cola", "colb"}[rand.Intn(2)] + return fmt.Sprintf("update %v set %v = %v where id = %v", tableName, colToUpdate, colValue, idValue) + } } else { - colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set col = %v where id = %v", tableName, convertColValueToString(colValue), idValue) + colValue := fz.generateExpression(rand.Intn(4)+1, "col", "id") + return fmt.Sprintf("update %v set col = %v where id = %v", tableName, colValue, idValue) } } @@ -222,13 +223,16 @@ func (fz *fuzzer) runFuzzerThread(t *testing.T, sharded bool, fuzzerThreadId int _, _ = vitessDb.Exec("use `uks`") } } + if fz.queryFormat == OlapSQLQueries { + _ = utils.Exec(t, mcmp.VtConn, "set workload = olap") + } for { // If fuzzer thread is marked to be stopped, then we should exit this go routine. if fz.shouldStop.Load() == true { return } switch fz.queryFormat { - case SQLQueries, PreparedStatmentQueries: + case OlapSQLQueries, SQLQueries, PreparedStatmentQueries: if fz.generateAndExecuteStatementQuery(t, mcmp) { return } @@ -338,8 +342,8 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { return []string{ "prepare stmt_insert from 'insert into fk_t20 (id, col, col2) values (?, ?, ?)'", fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @col = %v", convertColValueToString(colValue)), - fmt.Sprintf("SET @col2 = %v", convertColValueToString(col2Value)), + fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), + fmt.Sprintf("SET @col2 = %v", convertIntValueToString(col2Value)), "execute stmt_insert using @id, @col, @col2", } } else if isMultiColFkTable(tableName) { @@ -348,8 +352,8 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { return []string{ fmt.Sprintf("prepare stmt_insert from 'insert into %v (id, cola, colb) values (?, ?, ?)'", tableName), fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @cola = %v", convertColValueToString(colaValue)), - fmt.Sprintf("SET @colb = %v", convertColValueToString(colbValue)), + fmt.Sprintf("SET @cola = %v", convertIntValueToString(colaValue)), + fmt.Sprintf("SET @colb = %v", convertIntValueToString(colbValue)), "execute stmt_insert using @id, @cola, @colb", } } else { @@ -357,7 +361,7 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { return []string{ fmt.Sprintf("prepare stmt_insert from 'insert into %v (id, col) values (?, ?)'", tableName), fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @col = %v", convertColValueToString(colValue)), + fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), "execute stmt_insert using @id, @col", } } @@ -374,8 +378,8 @@ func (fz *fuzzer) getPreparedUpdateQueries() []string { return []string{ "prepare stmt_update from 'update fk_t20 set col = ?, col2 = ? where id = ?'", fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @col = %v", convertColValueToString(colValue)), - fmt.Sprintf("SET @col2 = %v", convertColValueToString(col2Value)), + fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), + fmt.Sprintf("SET @col2 = %v", convertIntValueToString(col2Value)), "execute stmt_update using @col, @col2, @id", } } else if isMultiColFkTable(tableName) { @@ -384,8 +388,8 @@ func (fz *fuzzer) getPreparedUpdateQueries() []string { return []string{ fmt.Sprintf("prepare stmt_update from 'update %v set cola = ?, colb = ? where id = ?'", tableName), fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @cola = %v", convertColValueToString(colaValue)), - fmt.Sprintf("SET @colb = %v", convertColValueToString(colbValue)), + fmt.Sprintf("SET @cola = %v", convertIntValueToString(colaValue)), + fmt.Sprintf("SET @colb = %v", convertIntValueToString(colbValue)), "execute stmt_update using @cola, @colb, @id", } } else { @@ -393,7 +397,7 @@ func (fz *fuzzer) getPreparedUpdateQueries() []string { return []string{ fmt.Sprintf("prepare stmt_update from 'update %v set col = ? where id = ?'", tableName), fmt.Sprintf("SET @id = %v", idValue), - fmt.Sprintf("SET @col = %v", convertColValueToString(colValue)), + fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), "execute stmt_update using @col, @id", } } @@ -419,14 +423,14 @@ func (fz *fuzzer) generateParameterizedInsertQuery() (query string, params []any if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col, col2) values (?, ?, ?)", tableName), []any{idValue, convertColValueToString(colValue), convertColValueToString(col2Value)} + return fmt.Sprintf("insert into %v (id, col, col2) values (?, ?, ?)", tableName), []any{idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)} } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, cola, colb) values (?, ?, ?)", tableName), []any{idValue, convertColValueToString(colaValue), convertColValueToString(colbValue)} + return fmt.Sprintf("insert into %v (id, cola, colb) values (?, ?, ?)", tableName), []any{idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)} } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col) values (?, ?)", tableName), []any{idValue, convertColValueToString(colValue)} + return fmt.Sprintf("insert into %v (id, col) values (?, ?)", tableName), []any{idValue, convertIntValueToString(colValue)} } } @@ -438,14 +442,14 @@ func (fz *fuzzer) generateParameterizedUpdateQuery() (query string, params []any if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set col = ?, col2 = ? where id = ?", tableName), []any{convertColValueToString(colValue), convertColValueToString(col2Value), idValue} + return fmt.Sprintf("update %v set col = ?, col2 = ? where id = ?", tableName), []any{convertIntValueToString(colValue), convertIntValueToString(col2Value), idValue} } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set cola = ?, colb = ? where id = ?", tableName), []any{convertColValueToString(colaValue), convertColValueToString(colbValue), idValue} + return fmt.Sprintf("update %v set cola = ?, colb = ? where id = ?", tableName), []any{convertIntValueToString(colaValue), convertIntValueToString(colbValue), idValue} } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("update %v set col = ? where id = ?", tableName), []any{convertColValueToString(colValue), idValue} + return fmt.Sprintf("update %v set col = ? where id = ?", tableName), []any{convertIntValueToString(colValue), idValue} } } @@ -606,7 +610,7 @@ func TestFkFuzzTest(t *testing.T) { for _, tt := range testcases { for _, testSharded := range []bool{false, true} { - for _, queryFormat := range []QueryFormat{SQLQueries, PreparedStatmentQueries, PreparedStatementPacket} { + for _, queryFormat := range []QueryFormat{OlapSQLQueries, SQLQueries, PreparedStatmentQueries, PreparedStatementPacket} { t.Run(getTestName(tt.name, testSharded)+fmt.Sprintf(" QueryFormat - %v", queryFormat), func(t *testing.T) { mcmp, closer := start(t) defer closer() @@ -650,85 +654,3 @@ func TestFkFuzzTest(t *testing.T) { } } } - -// ensureDatabaseState ensures that the database is either empty or not. -func ensureDatabaseState(t *testing.T, vtconn *mysql.Conn, empty bool) { - results := collectFkTablesState(vtconn) - isEmpty := true - for _, res := range results { - if len(res.Rows) > 0 { - isEmpty = false - } - } - require.Equal(t, isEmpty, empty) -} - -// verifyDataIsCorrect verifies that the data in MySQL database matches the data in the Vitess database. -func verifyDataIsCorrect(t *testing.T, mcmp utils.MySQLCompare, concurrency int) { - // For single concurrent thread, we run all the queries on both MySQL and Vitess, so we can verify correctness - // by just checking if the data in MySQL and Vitess match. - if concurrency == 1 { - for _, table := range fkTables { - query := fmt.Sprintf("SELECT * FROM %v ORDER BY id", table) - mcmp.Exec(query) - } - } else { - // For higher concurrency, we don't have MySQL data to verify everything is fine, - // so we'll have to do something different. - // We run LEFT JOIN queries on all the parent and child tables linked by foreign keys - // to make sure that nothing is broken in the database. - for _, reference := range fkReferences { - query := fmt.Sprintf("select %v.id from %v left join %v on (%v.col = %v.col) where %v.col is null and %v.col is not null", reference.childTable, reference.childTable, reference.parentTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable) - if isMultiColFkTable(reference.childTable) { - query = fmt.Sprintf("select %v.id from %v left join %v on (%v.cola = %v.cola and %v.colb = %v.colb) where %v.cola is null and %v.cola is not null and %v.colb is not null", reference.childTable, reference.childTable, reference.parentTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable, reference.childTable) - } - res, err := mcmp.VtConn.ExecuteFetch(query, 1000, false) - require.NoError(t, err) - require.Zerof(t, len(res.Rows), "Query %v gave non-empty results", query) - } - } - // We also verify that the results in Primary and Replica table match as is. - for _, keyspace := range clusterInstance.Keyspaces { - for _, shard := range keyspace.Shards { - var primaryTab, replicaTab *cluster.Vttablet - for _, vttablet := range shard.Vttablets { - if vttablet.Type == "primary" { - primaryTab = vttablet - } else { - replicaTab = vttablet - } - } - require.NotNil(t, primaryTab) - require.NotNil(t, replicaTab) - checkReplicationHealthy(t, replicaTab) - cluster.WaitForReplicationPos(t, primaryTab, replicaTab, true, 60.0) - primaryConn, err := utils.GetMySQLConn(primaryTab, fmt.Sprintf("vt_%v", keyspace.Name)) - require.NoError(t, err) - replicaConn, err := utils.GetMySQLConn(replicaTab, fmt.Sprintf("vt_%v", keyspace.Name)) - require.NoError(t, err) - primaryRes := collectFkTablesState(primaryConn) - replicaRes := collectFkTablesState(replicaConn) - verifyDataMatches(t, primaryRes, replicaRes) - } - } -} - -// verifyDataMatches verifies that the two list of results are the same. -func verifyDataMatches(t *testing.T, resOne []*sqltypes.Result, resTwo []*sqltypes.Result) { - require.EqualValues(t, len(resTwo), len(resOne), "Res 1 - %v, Res 2 - %v", resOne, resTwo) - for idx, resultOne := range resOne { - resultTwo := resTwo[idx] - require.True(t, resultOne.Equal(resultTwo), "Data for %v doesn't match\nRows 1\n%v\nRows 2\n%v", fkTables[idx], resultOne.Rows, resultTwo.Rows) - } -} - -// collectFkTablesState collects the data stored in the foreign key tables for the given connection. -func collectFkTablesState(conn *mysql.Conn) []*sqltypes.Result { - var tablesData []*sqltypes.Result - for _, table := range fkTables { - query := fmt.Sprintf("SELECT * FROM %v ORDER BY id", table) - res, _ := conn.ExecuteFetch(query, 10000, true) - tablesData = append(tablesData, res) - } - return tablesData -} diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index 46bbc2ed433..ff7ddef66ff 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/log" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/vtgate/vtgateconn" @@ -775,6 +776,181 @@ func TestFkScenarios(t *testing.T) { } } +// TestFkQueries is for testing a specific set of queries one after the other. +func TestFkQueries(t *testing.T) { + // Wait for schema-tracking to be complete. + waitForSchemaTrackingForFkTables(t) + // Remove all the foreign key constraints for all the replicas. + // We can then verify that the replica, and the primary have the same data, to ensure + // that none of the queries ever lead to cascades/updates on MySQL level. + for _, ks := range []string{shardedKs, unshardedKs} { + replicas := getReplicaTablets(ks) + for _, replica := range replicas { + removeAllForeignKeyConstraints(t, replica, ks) + } + } + + testcases := []struct { + name string + queries []string + }{ + { + name: "Non-literal update", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "update fk_t10 set col = id + 3", + }, + }, { + name: "Non-literal update with order by", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "update fk_t10 set col = id + 3 order by id desc", + }, + }, { + name: "Non-literal update with order by that require parent and child foreign keys verification - success", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t12 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t13 (id, col) values (1,1),(2,2)", + "update fk_t11 set col = id + 3 where id >= 3", + }, + }, { + name: "Non-literal update with order by that require parent and child foreign keys verification - parent fails", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t12 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "update fk_t11 set col = id + 3", + }, + }, { + name: "Non-literal update with order by that require parent and child foreign keys verification - child fails", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t12 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t13 (id, col) values (1,1),(2,2)", + "update fk_t11 set col = id + 3", + }, + }, { + name: "Single column update in a multi-col table - success", + queries: []string{ + "insert into fk_multicol_t1 (id, cola, colb) values (1, 1, 1), (2, 2, 2)", + "insert into fk_multicol_t2 (id, cola, colb) values (1, 1, 1)", + "update fk_multicol_t1 set colb = 4 + (colb) where id = 2", + }, + }, { + name: "Single column update in a multi-col table - restrict failure", + queries: []string{ + "insert into fk_multicol_t1 (id, cola, colb) values (1, 1, 1), (2, 2, 2)", + "insert into fk_multicol_t2 (id, cola, colb) values (1, 1, 1)", + "update fk_multicol_t1 set colb = 4 + (colb) where id = 1", + }, + }, { + name: "Single column update in multi-col table - cascade and set null", + queries: []string{ + "insert into fk_multicol_t15 (id, cola, colb) values (1, 1, 1), (2, 2, 2)", + "insert into fk_multicol_t16 (id, cola, colb) values (1, 1, 1), (2, 2, 2)", + "insert into fk_multicol_t17 (id, cola, colb) values (1, 1, 1), (2, 2, 2)", + "update fk_multicol_t15 set colb = 4 + (colb) where id = 1", + }, + }, { + name: "Non literal update that evaluates to NULL - restricted", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t13 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "update fk_t10 set col = id + null where id = 1", + }, + }, { + name: "Non literal update that evaluates to NULL - success", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "insert into fk_t12 (id, col) values (1,1),(2,2),(3,3),(4,4),(5,5)", + "update fk_t10 set col = id + null where id = 1", + }, + }, { + name: "Multi column foreign key update with one literal and one non-literal update", + queries: []string{ + "insert into fk_multicol_t15 (id, cola, colb) values (1,1,1),(2,2,2)", + "insert into fk_multicol_t16 (id, cola, colb) values (1,1,1),(2,2,2)", + "update fk_multicol_t15 set cola = 3, colb = (id * 2) - 2", + }, + }, + } + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + mcmp, closer := start(t) + defer closer() + _ = utils.Exec(t, mcmp.VtConn, "use `uks`") + + // Ensure that the Vitess database is originally empty + ensureDatabaseState(t, mcmp.VtConn, true) + ensureDatabaseState(t, mcmp.MySQLConn, true) + + for _, query := range testcase.queries { + _, _ = mcmp.ExecAllowAndCompareError(query) + if t.Failed() { + break + } + } + + // ensure Vitess database has some data. This ensures not all the commands failed. + ensureDatabaseState(t, mcmp.VtConn, false) + // Verify the consistency of the data. + verifyDataIsCorrect(t, mcmp, 1) + }) + } +} + +// TestFkOneCase is for testing a specific set of queries. On the CI this test won't run since we'll keep the queries empty. +func TestFkOneCase(t *testing.T) { + queries := []string{} + if len(queries) == 0 { + t.Skip("No queries to test") + } + // Wait for schema-tracking to be complete. + waitForSchemaTrackingForFkTables(t) + // Remove all the foreign key constraints for all the replicas. + // We can then verify that the replica, and the primary have the same data, to ensure + // that none of the queries ever lead to cascades/updates on MySQL level. + for _, ks := range []string{shardedKs, unshardedKs} { + replicas := getReplicaTablets(ks) + for _, replica := range replicas { + removeAllForeignKeyConstraints(t, replica, ks) + } + } + + mcmp, closer := start(t) + defer closer() + _ = utils.Exec(t, mcmp.VtConn, "use `uks`") + + // Ensure that the Vitess database is originally empty + ensureDatabaseState(t, mcmp.VtConn, true) + ensureDatabaseState(t, mcmp.MySQLConn, true) + + for _, query := range queries { + _, _ = mcmp.ExecAllowAndCompareError(query) + if t.Failed() { + log.Errorf("Query failed - %v", query) + break + } + } + vitessData := collectFkTablesState(mcmp.VtConn) + for idx, table := range fkTables { + log.Errorf("Vitess data for %v -\n%v", table, vitessData[idx].Rows) + } + + // ensure Vitess database has some data. This ensures not all the commands failed. + ensureDatabaseState(t, mcmp.VtConn, false) + // Verify the consistency of the data. + verifyDataIsCorrect(t, mcmp, 1) +} + func TestCyclicFks(t *testing.T) { mcmp, closer := start(t) defer closer() diff --git a/go/test/endtoend/vtgate/foreignkey/utils_test.go b/go/test/endtoend/vtgate/foreignkey/utils_test.go index 5e0b4a8a3cc..b97e57d685c 100644 --- a/go/test/endtoend/vtgate/foreignkey/utils_test.go +++ b/go/test/endtoend/vtgate/foreignkey/utils_test.go @@ -19,15 +19,21 @@ package foreignkey import ( "database/sql" "fmt" + "math/rand" "strings" "testing" + "time" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" ) +var supportedOpps = []string{"*", "+", "-"} + // getTestName prepends whether the test is for a sharded keyspace or not to the test name. func getTestName(testName string, testSharded bool) string { if testSharded { @@ -41,6 +47,32 @@ func isMultiColFkTable(tableName string) bool { return strings.Contains(tableName, "multicol") } +func (fz *fuzzer) generateExpression(length int, cols ...string) string { + expr := fz.getColOrInt(cols...) + if length == 1 { + return expr + } + rhsExpr := fz.generateExpression(length-1, cols...) + op := supportedOpps[rand.Intn(len(supportedOpps))] + return fmt.Sprintf("%v %s (%v)", expr, op, rhsExpr) +} + +// getColOrInt gets a column or an integer/NULL literal with equal probability. +func (fz *fuzzer) getColOrInt(cols ...string) string { + if len(cols) == 0 || rand.Intn(2) == 0 { + return convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) + } + return cols[rand.Intn(len(cols))] +} + +// convertIntValueToString converts the given value to a string +func convertIntValueToString(value int) string { + if value == 0 { + return "NULL" + } + return fmt.Sprintf("%d", value) +} + // waitForSchemaTrackingForFkTables waits for schema tracking to have run and seen the tables used // for foreign key tests. func waitForSchemaTrackingForFkTables(t *testing.T) { @@ -142,3 +174,85 @@ func compareVitessAndMySQLErrors(t *testing.T, vtErr, mysqlErr error) { out := fmt.Sprintf("Vitess and MySQL are not erroring the same way.\nVitess error: %v\nMySQL error: %v", vtErr, mysqlErr) t.Error(out) } + +// ensureDatabaseState ensures that the database is either empty or not. +func ensureDatabaseState(t *testing.T, vtconn *mysql.Conn, empty bool) { + results := collectFkTablesState(vtconn) + isEmpty := true + for _, res := range results { + if len(res.Rows) > 0 { + isEmpty = false + } + } + require.Equal(t, isEmpty, empty) +} + +// verifyDataIsCorrect verifies that the data in MySQL database matches the data in the Vitess database. +func verifyDataIsCorrect(t *testing.T, mcmp utils.MySQLCompare, concurrency int) { + // For single concurrent thread, we run all the queries on both MySQL and Vitess, so we can verify correctness + // by just checking if the data in MySQL and Vitess match. + if concurrency == 1 { + for _, table := range fkTables { + query := fmt.Sprintf("SELECT * FROM %v ORDER BY id", table) + mcmp.Exec(query) + } + } else { + // For higher concurrency, we don't have MySQL data to verify everything is fine, + // so we'll have to do something different. + // We run LEFT JOIN queries on all the parent and child tables linked by foreign keys + // to make sure that nothing is broken in the database. + for _, reference := range fkReferences { + query := fmt.Sprintf("select %v.id from %v left join %v on (%v.col = %v.col) where %v.col is null and %v.col is not null", reference.childTable, reference.childTable, reference.parentTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable) + if isMultiColFkTable(reference.childTable) { + query = fmt.Sprintf("select %v.id from %v left join %v on (%v.cola = %v.cola and %v.colb = %v.colb) where %v.cola is null and %v.cola is not null and %v.colb is not null", reference.childTable, reference.childTable, reference.parentTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable, reference.parentTable, reference.childTable, reference.childTable) + } + res, err := mcmp.VtConn.ExecuteFetch(query, 1000, false) + require.NoError(t, err) + require.Zerof(t, len(res.Rows), "Query %v gave non-empty results", query) + } + } + // We also verify that the results in Primary and Replica table match as is. + for _, keyspace := range clusterInstance.Keyspaces { + for _, shard := range keyspace.Shards { + var primaryTab, replicaTab *cluster.Vttablet + for _, vttablet := range shard.Vttablets { + if vttablet.Type == "primary" { + primaryTab = vttablet + } else { + replicaTab = vttablet + } + } + require.NotNil(t, primaryTab) + require.NotNil(t, replicaTab) + checkReplicationHealthy(t, replicaTab) + cluster.WaitForReplicationPos(t, primaryTab, replicaTab, true, 1*time.Minute) + primaryConn, err := utils.GetMySQLConn(primaryTab, fmt.Sprintf("vt_%v", keyspace.Name)) + require.NoError(t, err) + replicaConn, err := utils.GetMySQLConn(replicaTab, fmt.Sprintf("vt_%v", keyspace.Name)) + require.NoError(t, err) + primaryRes := collectFkTablesState(primaryConn) + replicaRes := collectFkTablesState(replicaConn) + verifyDataMatches(t, primaryRes, replicaRes) + } + } +} + +// verifyDataMatches verifies that the two list of results are the same. +func verifyDataMatches(t *testing.T, resOne []*sqltypes.Result, resTwo []*sqltypes.Result) { + require.EqualValues(t, len(resTwo), len(resOne), "Res 1 - %v, Res 2 - %v", resOne, resTwo) + for idx, resultOne := range resOne { + resultTwo := resTwo[idx] + require.True(t, resultOne.Equal(resultTwo), "Data for %v doesn't match\nRows 1\n%v\nRows 2\n%v", fkTables[idx], resultOne.Rows, resultTwo.Rows) + } +} + +// collectFkTablesState collects the data stored in the foreign key tables for the given connection. +func collectFkTablesState(conn *mysql.Conn) []*sqltypes.Result { + var tablesData []*sqltypes.Result + for _, table := range fkTables { + query := fmt.Sprintf("SELECT * FROM %v ORDER BY id", table) + res, _ := conn.ExecuteFetch(query, 10000, true) + tablesData = append(tablesData, res) + } + return tablesData +} diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index b70f83b192d..d878650c63e 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -280,7 +280,7 @@ func (cached *FkChild) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(64) + size += int64(80) } // field BVName string size += hack.RuntimeAllocSize(int64(len(cached.BVName))) @@ -288,6 +288,13 @@ func (cached *FkChild) CachedSize(alloc bool) int64 { { size += hack.RuntimeAllocSize(int64(cap(cached.Cols)) * int64(8)) } + // field NonLiteralInfo []vitess.io/vitess/go/vt/vtgate/engine.NonLiteralUpdateInfo + { + size += hack.RuntimeAllocSize(int64(cap(cached.NonLiteralInfo)) * int64(32)) + for _, elem := range cached.NonLiteralInfo { + size += elem.CachedSize(false) + } + } // field Exec vitess.io/vitess/go/vt/vtgate/engine.Primitive if cc, ok := cached.Exec.(cachedObject); ok { size += cc.CachedSize(true) @@ -612,6 +619,18 @@ func (cached *MergeSort) CachedSize(alloc bool) int64 { } return size } +func (cached *NonLiteralUpdateInfo) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(32) + } + // field UpdateExprBvName string + size += hack.RuntimeAllocSize(int64(len(cached.UpdateExprBvName))) + return size +} func (cached *OnlineDDL) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/engine/fk_cascade.go b/go/vt/vtgate/engine/fk_cascade.go index d0bddbea8f9..691e326fec7 100644 --- a/go/vt/vtgate/engine/fk_cascade.go +++ b/go/vt/vtgate/engine/fk_cascade.go @@ -19,6 +19,7 @@ package engine import ( "context" "fmt" + "maps" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -29,9 +30,24 @@ import ( // FkChild contains the Child Primitive to be executed collecting the values from the Selection Primitive using the column indexes. // BVName is used to pass the value as bind variable to the Child Primitive. type FkChild struct { + // BVName is the bind variable name for the tuple bind variable used in the primitive. BVName string - Cols []int // indexes - Exec Primitive + // Cols are the indexes of the column that need to be selected from the SELECT query to create the tuple bind variable. + Cols []int + // NonLiteralInfo stores the information that is needed to run an update query with non-literal values. + NonLiteralInfo []NonLiteralUpdateInfo + Exec Primitive +} + +// NonLiteralUpdateInfo stores the information required to process non-literal update queries. +// It stores 3 information- +// 1. UpdateExprCol- The index of the updated expression in the select query. +// 2. UpdateExprBvName- The bind variable name to store the updated expression into. +// 3. CompExprCol- The index of the comparison expression in the select query to know if the row value is actually being changed or not. +type NonLiteralUpdateInfo struct { + UpdateExprCol int + UpdateExprBvName string + CompExprCol int } // FkCascade is a primitive that implements foreign key cascading using Selection as values required to execute the FkChild Primitives. @@ -82,81 +98,110 @@ func (fkc *FkCascade) TryExecute(ctx context.Context, vcursor VCursor, bindVars } for _, child := range fkc.Children { - // We create a bindVariable for each Child - // that stores the tuple of columns involved in the fk constraint. - bv := &querypb.BindVariable{ - Type: querypb.Type_TUPLE, + // Having non-empty UpdateExprBvNames is an indication that we have an update query with non-literal expressions in it. + // We need to run this query differently because we need to run an update for each row we get back from the SELECT. + if len(child.NonLiteralInfo) > 0 { + err = fkc.executeNonLiteralExprFkChild(ctx, vcursor, bindVars, wantfields, selectionRes, child) + } else { + err = fkc.executeLiteralExprFkChild(ctx, vcursor, bindVars, wantfields, selectionRes, child, false) } - for _, row := range selectionRes.Rows { - var tupleValues []sqltypes.Value - for _, colIdx := range child.Cols { - tupleValues = append(tupleValues, row[colIdx]) - } - bv.Values = append(bv.Values, sqltypes.TupleToProto(tupleValues)) - } - // Execute the child primitive, and bail out incase of failure. - // Since this Primitive is always executed in a transaction, the changes should - // be rolled back incase of an error. - bindVars[child.BVName] = bv - _, err = vcursor.ExecutePrimitive(ctx, child.Exec, bindVars, wantfields) if err != nil { return nil, err } - delete(bindVars, child.BVName) } // All the children are modified successfully, we can now execute the Parent Primitive. return vcursor.ExecutePrimitive(ctx, fkc.Parent, bindVars, wantfields) } -// TryStreamExecute implements the Primitive interface. -func (fkc *FkCascade) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - // We create a bindVariable for each Child - // that stores the tuple of columns involved in the fk constraint. - var bindVariables []*querypb.BindVariable - for range fkc.Children { - bindVariables = append(bindVariables, &querypb.BindVariable{ - Type: querypb.Type_TUPLE, - }) +func (fkc *FkCascade) executeLiteralExprFkChild(ctx context.Context, vcursor VCursor, in map[string]*querypb.BindVariable, wantfields bool, selectionRes *sqltypes.Result, child *FkChild, isStreaming bool) error { + bindVars := maps.Clone(in) + // We create a bindVariable that stores the tuple of columns involved in the fk constraint. + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, } + for _, row := range selectionRes.Rows { + var tupleValues []sqltypes.Value - // Execute the Selection primitive to find the rows that are going to modified. - // This will be used to find the rows that need modification on the children. - err := vcursor.StreamExecutePrimitive(ctx, fkc.Selection, bindVars, wantfields, func(result *sqltypes.Result) error { - if len(result.Rows) == 0 { - return nil - } - for idx, child := range fkc.Children { - for _, row := range result.Rows { - var tupleValues []sqltypes.Value - for _, colIdx := range child.Cols { - tupleValues = append(tupleValues, row[colIdx]) - } - bindVariables[idx].Values = append(bindVariables[idx].Values, sqltypes.TupleToProto(tupleValues)) - } + for _, colIdx := range child.Cols { + tupleValues = append(tupleValues, row[colIdx]) } - return nil - }) - if err != nil { - return err + bv.Values = append(bv.Values, sqltypes.TupleToProto(tupleValues)) } - // Execute the child primitive, and bail out incase of failure. // Since this Primitive is always executed in a transaction, the changes should // be rolled back incase of an error. - for idx, child := range fkc.Children { - bindVars[child.BVName] = bindVariables[idx] - err = vcursor.StreamExecutePrimitive(ctx, child.Exec, bindVars, wantfields, func(result *sqltypes.Result) error { - return nil - }) + bindVars[child.BVName] = bv + var err error + if isStreaming { + err = vcursor.StreamExecutePrimitive(ctx, child.Exec, bindVars, wantfields, func(result *sqltypes.Result) error { return nil }) + } else { + _, err = vcursor.ExecutePrimitive(ctx, child.Exec, bindVars, wantfields) + } + if err != nil { + return err + } + return nil +} + +func (fkc *FkCascade) executeNonLiteralExprFkChild(ctx context.Context, vcursor VCursor, in map[string]*querypb.BindVariable, wantfields bool, selectionRes *sqltypes.Result, child *FkChild) error { + // For each row in the SELECT we need to run the child primitive. + for _, row := range selectionRes.Rows { + bindVars := maps.Clone(in) + // First we check if any of the columns is being updated at all. + skipRow := true + for _, info := range child.NonLiteralInfo { + // We use a null-safe comparison, so the value is guaranteed to be not null. + // We check if the column has updated or not. + isUnchanged, err := row[info.CompExprCol].ToBool() + if err != nil { + return err + } + if !isUnchanged { + // If any column has changed, then we can't skip this row. + // We need to execute the child primitive. + skipRow = false + break + } + } + // If none of the columns have changed, then there is no update to cascade, we can move on. + if skipRow { + continue + } + // We create a bindVariable that stores the tuple of columns involved in the fk constraint. + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + } + // Create a tuple from the Row. + var tupleValues []sqltypes.Value + for _, colIdx := range child.Cols { + tupleValues = append(tupleValues, row[colIdx]) + } + bv.Values = append(bv.Values, sqltypes.TupleToProto(tupleValues)) + // Execute the child primitive, and bail out incase of failure. + // Since this Primitive is always executed in a transaction, the changes should + // be rolled back in case of an error. + bindVars[child.BVName] = bv + + // Next, we need to copy the updated expressions value into the bind variables map. + for _, info := range child.NonLiteralInfo { + bindVars[info.UpdateExprBvName] = sqltypes.ValueBindVariable(row[info.UpdateExprCol]) + } + _, err := vcursor.ExecutePrimitive(ctx, child.Exec, bindVars, wantfields) if err != nil { return err } - delete(bindVars, child.BVName) } + return nil +} - // All the children are modified successfully, we can now execute the Parent Primitive. - return vcursor.StreamExecutePrimitive(ctx, fkc.Parent, bindVars, wantfields, callback) +// TryStreamExecute implements the Primitive interface. +func (fkc *FkCascade) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + res, err := fkc.TryExecute(ctx, vcursor, bindVars, wantfields) + if err != nil { + return err + } + return callback(res) } // Inputs implements the Primitive interface. @@ -168,11 +213,15 @@ func (fkc *FkCascade) Inputs() ([]Primitive, []map[string]any) { inputName: "Selection", }) for idx, child := range fkc.Children { - inputsMap = append(inputsMap, map[string]any{ + childInfoMap := map[string]any{ inputName: fmt.Sprintf("CascadeChild-%d", idx+1), "BvName": child.BVName, "Cols": child.Cols, - }) + } + if len(child.NonLiteralInfo) > 0 { + childInfoMap["NonLiteralUpdateInfo"] = child.NonLiteralInfo + } + inputsMap = append(inputsMap, childInfoMap) inputs = append(inputs, child.Exec) } inputs = append(inputs, fkc.Parent) diff --git a/go/vt/vtgate/engine/fk_cascade_test.go b/go/vt/vtgate/engine/fk_cascade_test.go index ddd381003b1..942fe44a709 100644 --- a/go/vt/vtgate/engine/fk_cascade_test.go +++ b/go/vt/vtgate/engine/fk_cascade_test.go @@ -80,7 +80,7 @@ func TestDeleteCascade(t *testing.T) { require.NoError(t, err) vc.ExpectLog(t, []string{ `ResolveDestinations ks [] Destinations:DestinationAllShards()`, - `StreamExecuteMulti select cola, colb from parent where foo = 48 ks.0: {} `, + `ExecuteMultiShard ks.0: select cola, colb from parent where foo = 48 {} false false`, `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.0: delete from child where (ca, cb) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x011\x950\x01a"} values:{type:TUPLE value:"\x89\x02\x012\x950\x01b"}} true true`, `ResolveDestinations ks [] Destinations:DestinationAllShards()`, @@ -141,7 +141,7 @@ func TestUpdateCascade(t *testing.T) { require.NoError(t, err) vc.ExpectLog(t, []string{ `ResolveDestinations ks [] Destinations:DestinationAllShards()`, - `StreamExecuteMulti select cola, colb from parent where foo = 48 ks.0: {} `, + `ExecuteMultiShard ks.0: select cola, colb from parent where foo = 48 {} false false`, `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.0: update child set ca = :vtg1 where (ca, cb) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x011\x950\x01a"} values:{type:TUPLE value:"\x89\x02\x012\x950\x01b"}} true true`, `ResolveDestinations ks [] Destinations:DestinationAllShards()`, @@ -149,6 +149,82 @@ func TestUpdateCascade(t *testing.T) { }) } +// TestNonLiteralUpdateCascade tests that FkCascade executes the child and parent primitives for a non-literal update cascade. +func TestNonLiteralUpdateCascade(t *testing.T) { + fakeRes := sqltypes.MakeTestResult(sqltypes.MakeTestFields("cola|cola <=> colb + 2|colb + 2", "int64|int64|int64"), "1|1|3", "2|0|5", "3|0|7") + + inputP := &Route{ + Query: "select cola, cola <=> colb + 2, colb + 2, from parent where foo = 48", + RoutingParameters: &RoutingParameters{ + Opcode: Unsharded, + Keyspace: &vindexes.Keyspace{Name: "ks"}, + }, + } + childP := &Update{ + DML: &DML{ + Query: "update child set ca = :fkc_upd where (ca) in ::__vals", + RoutingParameters: &RoutingParameters{ + Opcode: Unsharded, + Keyspace: &vindexes.Keyspace{Name: "ks"}, + }, + }, + } + parentP := &Update{ + DML: &DML{ + Query: "update parent set cola = colb + 2 where foo = 48", + RoutingParameters: &RoutingParameters{ + Opcode: Unsharded, + Keyspace: &vindexes.Keyspace{Name: "ks"}, + }, + }, + } + fkc := &FkCascade{ + Selection: inputP, + Children: []*FkChild{{ + BVName: "__vals", + Cols: []int{0}, + NonLiteralInfo: []NonLiteralUpdateInfo{ + { + UpdateExprBvName: "fkc_upd", + UpdateExprCol: 2, + CompExprCol: 1, + }, + }, + Exec: childP, + }}, + Parent: parentP, + } + + vc := newDMLTestVCursor("0") + vc.results = []*sqltypes.Result{fakeRes} + _, err := fkc.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, true) + require.NoError(t, err) + vc.ExpectLog(t, []string{ + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: select cola, cola <=> colb + 2, colb + 2, from parent where foo = 48 {} false false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update child set ca = :fkc_upd where (ca) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x012"} fkc_upd: type:INT64 value:"5"} true true`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update child set ca = :fkc_upd where (ca) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x013"} fkc_upd: type:INT64 value:"7"} true true`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update parent set cola = colb + 2 where foo = 48 {} true true`, + }) + + vc.Rewind() + err = fkc.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, true, func(result *sqltypes.Result) error { return nil }) + require.NoError(t, err) + vc.ExpectLog(t, []string{ + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: select cola, cola <=> colb + 2, colb + 2, from parent where foo = 48 {} false false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update child set ca = :fkc_upd where (ca) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x012"} fkc_upd: type:INT64 value:"5"} true true`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update child set ca = :fkc_upd where (ca) in ::__vals {__vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x013"} fkc_upd: type:INT64 value:"7"} true true`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ks.0: update parent set cola = colb + 2 where foo = 48 {} true true`, + }) +} + // TestNeedsTransactionInExecPrepared tests that if we have a foreign key cascade inside an ExecStmt plan, then we do mark the plan to require a transaction. func TestNeedsTransactionInExecPrepared(t *testing.T) { // Even if FkCascade is wrapped in ExecStmt, the plan should be marked such that it requires a transaction. diff --git a/go/vt/vtgate/engine/fk_verify.go b/go/vt/vtgate/engine/fk_verify.go index 350aeec59e0..8625fbe2362 100644 --- a/go/vt/vtgate/engine/fk_verify.go +++ b/go/vt/vtgate/engine/fk_verify.go @@ -83,18 +83,11 @@ func (f *FkVerify) TryExecute(ctx context.Context, vcursor VCursor, bindVars map // TryStreamExecute implements the Primitive interface func (f *FkVerify) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - for _, v := range f.Verify { - err := vcursor.StreamExecutePrimitive(ctx, v.Exec, bindVars, wantfields, func(qr *sqltypes.Result) error { - if len(qr.Rows) > 0 { - return getError(v.Typ) - } - return nil - }) - if err != nil { - return err - } + res, err := f.TryExecute(ctx, vcursor, bindVars, wantfields) + if err != nil { + return err } - return vcursor.StreamExecutePrimitive(ctx, f.Exec, bindVars, wantfields, callback) + return callback(res) } // Inputs implements the Primitive interface diff --git a/go/vt/vtgate/engine/fk_verify_test.go b/go/vt/vtgate/engine/fk_verify_test.go index 5635a32bc2c..5c9ff83c2ec 100644 --- a/go/vt/vtgate/engine/fk_verify_test.go +++ b/go/vt/vtgate/engine/fk_verify_test.go @@ -74,7 +74,7 @@ func TestFKVerifyUpdate(t *testing.T) { require.NoError(t, err) vc.ExpectLog(t, []string{ `ResolveDestinations ks [] Destinations:DestinationAllShards()`, - `StreamExecuteMulti select 1 from child c left join parent p on p.cola = 1 and p.colb = 'a' where p.cola is null and p.colb is null ks.0: {} `, + `ExecuteMultiShard ks.0: select 1 from child c left join parent p on p.cola = 1 and p.colb = 'a' where p.cola is null and p.colb is null {} false false`, `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.0: update child set cola = 1, colb = 'a' where foo = 48 {} true true`, }) @@ -97,7 +97,7 @@ func TestFKVerifyUpdate(t *testing.T) { require.ErrorContains(t, err, "Cannot add or update a child row: a foreign key constraint fails") vc.ExpectLog(t, []string{ `ResolveDestinations ks [] Destinations:DestinationAllShards()`, - `StreamExecuteMulti select 1 from child c left join parent p on p.cola = 1 and p.colb = 'a' where p.cola is null and p.colb is null ks.0: {} `, + `ExecuteMultiShard ks.0: select 1 from child c left join parent p on p.cola = 1 and p.colb = 'a' where p.cola is null and p.colb is null {} false false`, }) }) @@ -119,7 +119,7 @@ func TestFKVerifyUpdate(t *testing.T) { require.ErrorContains(t, err, "Cannot delete or update a parent row: a foreign key constraint fails") vc.ExpectLog(t, []string{ `ResolveDestinations ks [] Destinations:DestinationAllShards()`, - `StreamExecuteMulti select 1 from grandchild g join child c on g.cola = c.cola and g.colb = c.colb where c.foo = 48 ks.0: {} `, + `ExecuteMultiShard ks.0: select 1 from grandchild g join child c on g.cola = c.cola and g.colb = c.colb where c.foo = 48 {} false false`, }) }) } diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index a04c4b00c2c..59200e92e2a 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -139,9 +139,10 @@ func transformFkCascade(ctx *plancontext.PlanningContext, fkc *operators.FkCasca childEngine := childLP.Primitive() children = append(children, &engine.FkChild{ - BVName: child.BVName, - Cols: child.Cols, - Exec: childEngine, + BVName: child.BVName, + Cols: child.Cols, + NonLiteralInfo: child.NonLiteralInfo, + Exec: childEngine, }) } diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index bc4aaf8a4e6..64d9826a80e 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -28,6 +28,7 @@ import ( ) const foreignKeyConstraintValues = "fkc_vals" +const foreignKeyUpdateExpr = "fkc_upd" // translateQueryToOp creates an operator tree that represents the input SELECT or UNION query func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) (op ops.Operator, err error) { @@ -213,7 +214,10 @@ func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement // we should augment the semantic analysis to also tell us whether the given query has any cross shard parent foreign keys to validate. // If there are, then we have to run the query with FOREIGN_KEY_CHECKS off because we can't be sure if the DML will succeed on MySQL with the checks on. // So, we should set VerifyAllFKs to true. i.e. we should add `|| ctx.SemTable.RequireForeignKeyChecksOff()` to the below condition. - ctx.VerifyAllFKs = verifyAllFKs + if verifyAllFKs { + // If ctx.VerifyAllFKs is already true we don't want to turn it off. + ctx.VerifyAllFKs = verifyAllFKs + } // From all the parent foreign keys involved, we should remove the one that we need to ignore. err = ctx.SemTable.RemoveParentForeignKey(fkToIgnore) @@ -397,6 +401,7 @@ func createSelectionOp( selectExprs []sqlparser.SelectExpr, tableExprs sqlparser.TableExprs, where *sqlparser.Where, + orderBy sqlparser.OrderBy, limit *sqlparser.Limit, lock sqlparser.Lock, ) (ops.Operator, error) { @@ -404,20 +409,10 @@ func createSelectionOp( SelectExprs: selectExprs, From: tableExprs, Where: where, + OrderBy: orderBy, Limit: limit, Lock: lock, } // There are no foreign keys to check for a select query, so we can pass anything for verifyAllFKs and fkToIgnore. return createOpFromStmt(ctx, selectionStmt, false /* verifyAllFKs */, "" /* fkToIgnore */) } - -func selectParentColumns(fk vindexes.ChildFKInfo, lastOffset int) ([]int, []sqlparser.SelectExpr) { - var cols []int - var exprs []sqlparser.SelectExpr - for _, column := range fk.ParentColumns { - cols = append(cols, lastOffset) - exprs = append(exprs, aeWrap(sqlparser.NewColName(column.String()))) - lastOffset++ - } - return cols, exprs -} diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index f02444671c1..dd37ed5db01 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -181,16 +181,16 @@ func createFkCascadeOpForDelete(ctx *plancontext.PlanningContext, parentOp ops.O } // We need to select all the parent columns for the foreign key constraint, to use in the update of the child table. - cols, exprs := selectParentColumns(fk, len(selectExprs)) - selectExprs = append(selectExprs, exprs...) + var offsets []int + offsets, selectExprs = addColumns(ctx, fk.ParentColumns, selectExprs) - fkChild, err := createFkChildForDelete(ctx, fk, cols) + fkChild, err := createFkChildForDelete(ctx, fk, offsets) if err != nil { return nil, err } fkChildren = append(fkChildren, fkChild) } - selectionOp, err := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, sqlparser.ForUpdateLock) + selectionOp, err := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, nil, sqlparser.ForUpdateLock) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/operators/fk_cascade.go b/go/vt/vtgate/planbuilder/operators/fk_cascade.go index 90c797d55e8..73b902a4980 100644 --- a/go/vt/vtgate/planbuilder/operators/fk_cascade.go +++ b/go/vt/vtgate/planbuilder/operators/fk_cascade.go @@ -19,15 +19,17 @@ package operators import ( "slices" + "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // FkChild is used to represent a foreign key child table operation type FkChild struct { - BVName string - Cols []int // indexes - Op ops.Operator + BVName string + Cols []int // indexes + NonLiteralInfo []engine.NonLiteralUpdateInfo + Op ops.Operator noColumns noPredicates @@ -88,9 +90,10 @@ func (fkc *FkCascade) Clone(inputs []ops.Operator) ops.Operator { } newFkc.Children = append(newFkc.Children, &FkChild{ - BVName: fkc.Children[idx-2].BVName, - Cols: slices.Clone(fkc.Children[idx-2].Cols), - Op: operator, + BVName: fkc.Children[idx-2].BVName, + Cols: slices.Clone(fkc.Children[idx-2].Cols), + NonLiteralInfo: slices.Clone(fkc.Children[idx-2].NonLiteralInfo), + Op: operator, }) } return newFkc diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 743812f9dd7..b7a3a4da2d6 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -125,6 +125,12 @@ func createOperatorFromUpdate(ctx *plancontext.PlanningContext, updStmt *sqlpars return nil, vterrors.VT12001("update with limit with foreign key constraints") } + // Now we check if any of the foreign key columns that are being udpated have dependencies on other updated columns. + // This is unsafe, and we currently don't support this in Vitess. + if err = ctx.SemTable.ErrIfFkDependentColumnUpdated(updStmt.Exprs); err != nil { + return nil, err + } + return buildFkOperator(ctx, updOp, updClone, parentFks, childFks, vindexTable) } @@ -203,11 +209,6 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U } func buildFkOperator(ctx *plancontext.PlanningContext, updOp ops.Operator, updClone *sqlparser.Update, parentFks []vindexes.ParentFKInfo, childFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table) (ops.Operator, error) { - // We only support simple expressions in update queries for foreign key handling. - if isNonLiteral(updClone.Exprs, parentFks, childFks) { - return nil, vterrors.VT12001("update expression with non-literal values with foreign key constraints") - } - restrictChildFks, cascadeChildFks := splitChildFks(childFks) op, err := createFKCascadeOp(ctx, updOp, updClone, cascadeChildFks, updatedTable) @@ -218,25 +219,6 @@ func buildFkOperator(ctx *plancontext.PlanningContext, updOp ops.Operator, updCl return createFKVerifyOp(ctx, op, updClone, parentFks, restrictChildFks) } -func isNonLiteral(updExprs sqlparser.UpdateExprs, parentFks []vindexes.ParentFKInfo, childFks []vindexes.ChildFKInfo) bool { - for _, updateExpr := range updExprs { - if sqlparser.IsLiteral(updateExpr.Expr) { - continue - } - for _, parentFk := range parentFks { - if parentFk.ChildColumns.FindColumn(updateExpr.Name.Name) >= 0 { - return true - } - } - for _, childFk := range childFks { - if childFk.ParentColumns.FindColumn(updateExpr.Name.Name) >= 0 { - return true - } - } - } - return false -} - // splitChildFks splits the child foreign keys into restrict and cascade list as restrict is handled through Verify operator and cascade is handled through Cascade operator. func splitChildFks(fks []vindexes.ChildFKInfo) (restrictChildFks, cascadeChildFks []vindexes.ChildFKInfo) { for _, fk := range fks { @@ -271,17 +253,33 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, } // We need to select all the parent columns for the foreign key constraint, to use in the update of the child table. - cols, exprs := selectParentColumns(fk, len(selectExprs)) - selectExprs = append(selectExprs, exprs...) + var selectOffsets []int + selectOffsets, selectExprs = addColumns(ctx, fk.ParentColumns, selectExprs) + + // If we are updating a foreign key column to a non-literal value then, need information about + // 1. whether the new value is different from the old value + // 2. the new value itself. + // 3. the bind variable to assign to this value. + var nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo + ue := ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)) + // We only need to store these offsets and add these expressions to SELECT when there are non-literal updates present. + if hasNonLiteralUpdate(ue) { + for _, updExpr := range ue { + // We add the expression and a comparison expression to the SELECT exprssion while storing their offsets. + var info engine.NonLiteralUpdateInfo + info, selectExprs = addNonLiteralUpdExprToSelect(ctx, updExpr, selectExprs) + nonLiteralUpdateInfo = append(nonLiteralUpdateInfo, info) + } + } - fkChild, err := createFkChildForUpdate(ctx, fk, updStmt, cols, updatedTable) + fkChild, err := createFkChildForUpdate(ctx, fk, selectOffsets, nonLiteralUpdateInfo, updatedTable) if err != nil { return nil, err } fkChildren = append(fkChildren, fkChild) } - selectionOp, err := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, nil, sqlparser.ForUpdateLock) + selectionOp, err := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, updStmt.OrderBy, nil, sqlparser.ForUpdateLock) if err != nil { return nil, err } @@ -293,8 +291,73 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, }, nil } +// hasNonLiteralUpdate checks if any of the update expressions have a non-literal update. +func hasNonLiteralUpdate(exprs sqlparser.UpdateExprs) bool { + for _, expr := range exprs { + if !sqlparser.IsLiteral(expr.Expr) { + return true + } + } + return false +} + +// addColumns adds the given set of columns to the select expressions provided. It tries to reuse the columns if already present in it. +// It returns the list of offsets for the columns and the updated select expressions. +func addColumns(ctx *plancontext.PlanningContext, columns sqlparser.Columns, exprs []sqlparser.SelectExpr) ([]int, []sqlparser.SelectExpr) { + var offsets []int + selectExprs := exprs + for _, column := range columns { + ae := aeWrap(sqlparser.NewColName(column.String())) + exists := false + for idx, expr := range exprs { + if ctx.SemTable.EqualsExpr(expr.(*sqlparser.AliasedExpr).Expr, ae.Expr) { + offsets = append(offsets, idx) + exists = true + break + } + } + if !exists { + offsets = append(offsets, len(selectExprs)) + selectExprs = append(selectExprs, ae) + + } + } + return offsets, selectExprs +} + +// For an update query having non-literal updates, we add the updated expression and a comparison expression to the select query. +// For example, for a query like `update fk_table set col = id * 100 + 1` +// We would add the expression `id * 100 + 1` and the comparison expression `col <=> id * 100 + 1` to the select query. +func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sqlparser.UpdateExpr, exprs []sqlparser.SelectExpr) (engine.NonLiteralUpdateInfo, []sqlparser.SelectExpr) { + // Create the comparison expression. + compExpr := sqlparser.NewComparisonExpr(sqlparser.NullSafeEqualOp, updExpr.Name, updExpr.Expr, nil) + info := engine.NonLiteralUpdateInfo{ + CompExprCol: -1, + UpdateExprCol: -1, + } + // Add the expressions to the select expressions. We make sure to reuse the offset if it has already been added once. + for idx, selectExpr := range exprs { + if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, compExpr) { + info.CompExprCol = idx + } + if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, updExpr.Expr) { + info.UpdateExprCol = idx + } + } + // If the expression doesn't exist, then we add the expression and store the offset. + if info.CompExprCol == -1 { + info.CompExprCol = len(exprs) + exprs = append(exprs, aeWrap(compExpr)) + } + if info.UpdateExprCol == -1 { + info.UpdateExprCol = len(exprs) + exprs = append(exprs, aeWrap(updExpr.Expr)) + } + return info, exprs +} + // createFkChildForUpdate creates the update query operator for the child table based on the foreign key constraints. -func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, updStmt *sqlparser.Update, cols []int, updatedTable *vindexes.Table) (*FkChild, error) { +func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, selectOffsets []int, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) (*FkChild, error) { // Create a ValTuple of child column names var valTuple sqlparser.ValTuple for _, column := range fk.ChildColumns { @@ -307,13 +370,22 @@ func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildF compExpr := sqlparser.NewComparisonExpr(sqlparser.InOp, valTuple, sqlparser.NewListArg(bvName), nil) var childWhereExpr sqlparser.Expr = compExpr + // In the case of non-literal updates, we need to assign bindvariables for storing the updated value of the columns + // coming from the SELECT query. + if len(nonLiteralUpdateInfo) > 0 { + for idx, info := range nonLiteralUpdateInfo { + info.UpdateExprBvName = ctx.ReservedVars.ReserveVariable(foreignKeyUpdateExpr) + nonLiteralUpdateInfo[idx] = info + } + } + var childOp ops.Operator var err error switch fk.OnUpdate { case sqlparser.Cascade: - childOp, err = buildChildUpdOpForCascade(ctx, fk, updStmt, childWhereExpr, updatedTable) + childOp, err = buildChildUpdOpForCascade(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) case sqlparser.SetNull: - childOp, err = buildChildUpdOpForSetNull(ctx, fk, updStmt, childWhereExpr) + childOp, err = buildChildUpdOpForSetNull(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) case sqlparser.SetDefault: return nil, vterrors.VT09016() } @@ -322,9 +394,10 @@ func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildF } return &FkChild{ - BVName: bvName, - Cols: cols, - Op: childOp, + BVName: bvName, + Cols: selectOffsets, + Op: childOp, + NonLiteralInfo: nonLiteralUpdateInfo, }, nil } @@ -332,11 +405,11 @@ func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildF // The query looks like this - // // `UPDATE SET WHERE IN ()` -func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, updStmt *sqlparser.Update, childWhereExpr sqlparser.Expr, updatedTable *vindexes.Table) (ops.Operator, error) { +func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, childWhereExpr sqlparser.Expr, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) (ops.Operator, error) { // The update expressions are the same as the update expressions in the parent update query // with the column names replaced with the child column names. var childUpdateExprs sqlparser.UpdateExprs - for _, updateExpr := range updStmt.Exprs { + for idx, updateExpr := range ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)) { colIdx := fk.ParentColumns.FindColumn(updateExpr.Name.Name) if colIdx == -1 { continue @@ -344,9 +417,13 @@ func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.Chi // The where condition is the same as the comparison expression above // with the column names replaced with the child column names. + childUpdateExpr := updateExpr.Expr + if len(nonLiteralUpdateInfo) > 0 && nonLiteralUpdateInfo[idx].UpdateExprBvName != "" { + childUpdateExpr = sqlparser.NewArgument(nonLiteralUpdateInfo[idx].UpdateExprBvName) + } childUpdateExprs = append(childUpdateExprs, &sqlparser.UpdateExpr{ Name: sqlparser.NewColName(fk.ChildColumns[colIdx].String()), - Expr: updateExpr.Expr, + Expr: childUpdateExpr, }) } // Because we could be updating the child to a non-null value, @@ -373,7 +450,13 @@ func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.Chi // `UPDATE SET // WHERE IN () // [AND ({ IS NULL OR}... NOT IN ())]` -func buildChildUpdOpForSetNull(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, updStmt *sqlparser.Update, childWhereExpr sqlparser.Expr) (ops.Operator, error) { +func buildChildUpdOpForSetNull( + ctx *plancontext.PlanningContext, + fk vindexes.ChildFKInfo, + childWhereExpr sqlparser.Expr, + nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, + updatedTable *vindexes.Table, +) (ops.Operator, error) { // For the SET NULL type constraint, we need to set all the child columns to NULL. var childUpdateExprs sqlparser.UpdateExprs for _, column := range fk.ChildColumns { @@ -392,7 +475,7 @@ func buildChildUpdOpForSetNull(ctx *plancontext.PlanningContext, fk vindexes.Chi // For example, if we are setting `update parent cola = :v1 and colb = :v2`, then on the child, the where condition would look something like this - // `:v1 IS NULL OR :v2 IS NULL OR (child_cola, child_colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). - compExpr := nullSafeNotInComparison(updStmt.Exprs, fk) + compExpr := nullSafeNotInComparison(ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)), fk, updatedTable.GetTableName(), nonLiteralUpdateInfo) if compExpr != nil { childWhereExpr = &sqlparser.AndExpr{ Left: childWhereExpr, @@ -408,7 +491,13 @@ func buildChildUpdOpForSetNull(ctx *plancontext.PlanningContext, fk vindexes.Chi } // createFKVerifyOp creates the verify operator for the parent foreign key constraints. -func createFKVerifyOp(ctx *plancontext.PlanningContext, childOp ops.Operator, updStmt *sqlparser.Update, parentFks []vindexes.ParentFKInfo, restrictChildFks []vindexes.ChildFKInfo) (ops.Operator, error) { +func createFKVerifyOp( + ctx *plancontext.PlanningContext, + childOp ops.Operator, + updStmt *sqlparser.Update, + parentFks []vindexes.ParentFKInfo, + restrictChildFks []vindexes.ChildFKInfo, +) (ops.Operator, error) { if len(parentFks) == 0 && len(restrictChildFks) == 0 { return childOp, nil } @@ -445,13 +534,13 @@ func createFKVerifyOp(ctx *plancontext.PlanningContext, childOp ops.Operator, up // Each parent foreign key constraint is verified by an anti join query of the form: // select 1 from child_tbl left join parent_tbl on -// where and and limit 1 +// where and and and limit 1 // E.g: // Child (c1, c2) references Parent (p1, p2) -// update Child set c1 = 1 where id = 1 +// update Child set c1 = c2 + 1 where id = 1 // verify query: -// select 1 from Child left join Parent on Parent.p1 = 1 and Parent.p2 = Child.c2 -// where Parent.p1 is null and Parent.p2 is null and Child.id = 1 +// select 1 from Child left join Parent on Parent.p1 = Child.c2 + 1 and Parent.p2 = Child.c2 +// where Parent.p1 is null and Parent.p2 is null and Child.id = 1 and Child.c2 + 1 is not null // and Child.c2 is not null // limit 1 func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) (ops.Operator, error) { @@ -479,7 +568,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS var joinExpr sqlparser.Expr if matchedExpr == nil { predicate = &sqlparser.AndExpr{ - Left: parentIsNullExpr, + Left: predicate, Right: &sqlparser.IsExpr{ Left: sqlparser.NewColNameWithQualifier(pFK.ChildColumns[idx].String(), childTbl), Right: sqlparser.IsNotNullOp, @@ -491,10 +580,18 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS Right: sqlparser.NewColNameWithQualifier(pFK.ChildColumns[idx].String(), childTbl), } } else { + prefixedMatchExpr := prefixColNames(childTbl, matchedExpr.Expr) joinExpr = &sqlparser.ComparisonExpr{ Operator: sqlparser.EqualOp, Left: sqlparser.NewColNameWithQualifier(pFK.ParentColumns[idx].String(), parentTbl), - Right: prefixColNames(childTbl, matchedExpr.Expr), + Right: prefixedMatchExpr, + } + predicate = &sqlparser.AndExpr{ + Left: predicate, + Right: &sqlparser.IsExpr{ + Left: prefixedMatchExpr, + Right: sqlparser.IsNotNullOp, + }, } } @@ -519,6 +616,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS sqlparser.NewJoinCondition(joinCond, nil)), }, sqlparser.NewWhere(sqlparser.WhereClause, whereCond), + nil, sqlparser.NewLimitWithoutOffset(1), sqlparser.ShareModeLock) } @@ -527,10 +625,10 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS // select 1 from child_tbl join parent_tbl on where [AND ({ IS NULL OR}... NOT IN ())] limit 1 // E.g: // Child (c1, c2) references Parent (p1, p2) -// update Parent set p1 = 1 where id = 1 +// update Parent set p1 = col + 1 where id = 1 // verify query: // select 1 from Child join Parent on Parent.p1 = Child.c1 and Parent.p2 = Child.c2 -// where Parent.id = 1 and (1 IS NULL OR (child.c1) NOT IN ((1))) limit 1 +// where Parent.id = 1 and ((Parent.col + 1) IS NULL OR (child.c1) NOT IN ((Parent.col + 1))) limit 1 func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, cFk vindexes.ChildFKInfo) (ops.Operator, error) { // ON UPDATE RESTRICT foreign keys that require validation, should only be allowed in the case where we // are verifying all the FKs on vtgate level. @@ -573,7 +671,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt // For example, if we are setting `update child cola = :v1 and colb = :v2`, then on the parent, the where condition would look something like this - // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). - compExpr := nullSafeNotInComparison(updStmt.Exprs, cFk) + compExpr := nullSafeNotInComparison(updStmt.Exprs, cFk, parentTbl, nil) if compExpr != nil { whereCond = sqlparser.AndExpressions(whereCond, compExpr) } @@ -588,6 +686,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt sqlparser.NewJoinCondition(joinCond, nil)), }, sqlparser.NewWhere(sqlparser.WhereClause, whereCond), + nil, sqlparser.NewLimitWithoutOffset(1), sqlparser.ShareModeLock) } @@ -597,22 +696,24 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL) // This expression is used in cascading SET NULLs and in verifying whether an update should be restricted. -func nullSafeNotInComparison(updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo) sqlparser.Expr { +func nullSafeNotInComparison(updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo, parentTbl sqlparser.TableName, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo) sqlparser.Expr { + var valTuple sqlparser.ValTuple var updateValues sqlparser.ValTuple - for _, updateExpr := range updateExprs { + for idx, updateExpr := range updateExprs { colIdx := cFk.ParentColumns.FindColumn(updateExpr.Name.Name) if colIdx >= 0 { if sqlparser.IsNull(updateExpr.Expr) { return nil } - updateValues = append(updateValues, updateExpr.Expr) + childUpdateExpr := prefixColNames(parentTbl, updateExpr.Expr) + if len(nonLiteralUpdateInfo) > 0 && nonLiteralUpdateInfo[idx].UpdateExprBvName != "" { + childUpdateExpr = sqlparser.NewArgument(nonLiteralUpdateInfo[idx].UpdateExprBvName) + } + updateValues = append(updateValues, childUpdateExpr) + valTuple = append(valTuple, sqlparser.NewColNameWithQualifier(cFk.ChildColumns[colIdx].String(), cFk.Table.GetTableName())) } } - // Create a ValTuple of child column names - var valTuple sqlparser.ValTuple - for _, column := range cFk.ChildColumns { - valTuple = append(valTuple, sqlparser.NewColNameWithQualifier(column.String(), cFk.Table.GetTableName())) - } + var finalExpr sqlparser.Expr = sqlparser.NewComparisonExpr(sqlparser.NotInOp, valTuple, sqlparser.ValTuple{updateValues}, nil) for _, value := range updateValues { finalExpr = &sqlparser.OrExpr{ diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index 065691d2356..afe42a45720 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -656,8 +656,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 from u_tbl1 where 1 != 1", - "Query": "select col1, col1 from u_tbl1 for update", + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 for update", "Table": "u_tbl1" }, { @@ -715,7 +715,7 @@ "OperatorType": "FkCascade", "BvName": "fkc_vals2", "Cols": [ - 1 + 0 ], "Inputs": [ { @@ -789,17 +789,248 @@ "plan": "VT12001: unsupported: update with limit with foreign key constraints" }, { - "comment": "update in a table with non-literal value - set null fail due to child update where condition", + "comment": "update in a table with non-literal value - set null", "query": "update u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", - "plan": "VT12001: unsupported: update expression with non-literal values with foreign key constraints" + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", + "Table": "u_tbl1, u_tbl2" + }, + { + "InputName": "PostVerify", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2, col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", + "Query": "select col2, col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd", + "CompExprCol": 1 + } + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", + "Table": "u_tbl2" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } }, { - "comment": "update in a table with non-literal value - with cascade fail as the cascade value is not known", + "comment": "update in a table with non-literal value - with cascade", "query": "update u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", - "plan": "VT12001: unsupported: update expression with non-literal values with foreign key constraints" + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where id = 1 for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd", + "CompExprCol": 1 + } + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = :fkc_upd where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd1", + "CompExprCol": 1 + } + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1))) for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1)))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = u_tbl1.x + 'bar' where id = 1", + "Table": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } }, { - "comment": "update in a table with set null, non-literal value on non-foreign key column - allowed", + "comment": "update in a table with set null, non-literal value on non-foreign key column", "query": "update u_tbl2 set m = col1 + 'bar', col2 = 2 where id = 1", "plan": { "QueryType": "UPDATE", @@ -856,7 +1087,7 @@ } }, { - "comment": "update in a table with cascade, non-literal value on non-foreign key column - allowed", + "comment": "update in a table with cascade, non-literal value on non-foreign key column", "query": "update u_tbl1 set m = x + 'bar', col1 = 2 where id = 1", "plan": { "QueryType": "UPDATE", @@ -872,8 +1103,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 from u_tbl1 where 1 != 1", - "Query": "select col1, col1 from u_tbl1 where id = 1 for update", + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where id = 1 for update", "Table": "u_tbl1" }, { @@ -931,7 +1162,7 @@ "OperatorType": "FkCascade", "BvName": "fkc_vals2", "Cols": [ - 1 + 0 ], "Inputs": [ { @@ -1010,9 +1241,87 @@ "plan": "VT12001: unsupported: foreign keys management at vitess with limit" }, { - "comment": "update with fk on cross-shard with a where condition on non-literal value - disallowed", + "comment": "update with fk on cross-shard with a update condition on non-literal value", "query": "update tbl3 set coly = colx + 10 where coly = 10", - "plan": "VT12001: unsupported: update expression with non-literal values with foreign key constraints" + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl3 set coly = colx + 10 where coly = 10", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Limit", + "Count": "1", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "1 as 1" + ], + "Inputs": [ + { + "OperatorType": "Filter", + "Predicate": "tbl1.t1col1 is null", + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "R:0,R:0", + "JoinVars": { + "tbl3_colx": 0 + }, + "TableName": "tbl3_tbl1", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl3.colx from tbl3 where 1 != 1", + "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and tbl3.coly = 10 lock in share mode", + "Table": "tbl3" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 lock in share mode", + "Table": "tbl1" + } + ] + } + ] + } + ] + } + ] + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set coly = tbl3.colx + 10 where tbl3.coly = 10", + "Table": "tbl3" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1", + "sharded_fk_allow.tbl3" + ] + } }, { "comment": "update with fk on cross-shard with a where condition", @@ -1297,7 +1606,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", "Table": "u_tbl3, u_tbl4" }, { @@ -1653,5 +1962,301 @@ "sharded_fk_allow.tbl5" ] } + }, + { + "comment": "foreign key column updated by using a column which is also getting updated", + "query": "update u_tbl1 set foo = 100, col1 = baz + 1 + foo where bar = 42", + "plan": "VT12001: unsupported: foo column referenced in foreign key column col1 is itself updated" + }, + { + "comment": "foreign key column updated by using a column which is also getting updated - self reference column is allowed", + "query": "update u_tbl7 set foo = 100, col7 = baz + 1 + col7 where bar = 42", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl7 set foo = 100, col7 = baz + 1 + col7 where bar = 42", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where 1 != 1", + "Query": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where bar = 42 for update", + "Table": "u_tbl7" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FKVerify", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd", + "CompExprCol": 1 + } + ], + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Table": "u_tbl3, u_tbl4" + }, + { + "InputName": "VerifyChild-2", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:fkc_upd is null or (u_tbl9.col9) not in ((:fkc_upd))) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Table": "u_tbl4, u_tbl9" + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals", + "Table": "u_tbl4" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl7 set foo = 100, col7 = baz + 1 + col7 where bar = 42", + "Table": "u_tbl7" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl4", + "unsharded_fk_allow.u_tbl7", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "Single column updated in a multi-col table", + "query": "update u_multicol_tbl1 set cola = cola + 3 where id = 3", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_multicol_tbl1 set cola = cola + 3 where id = 3", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb, cola <=> u_multicol_tbl1.cola + 3, u_multicol_tbl1.cola + 3 from u_multicol_tbl1 where 1 != 1", + "Query": "select cola, colb, cola <=> u_multicol_tbl1.cola + 3, u_multicol_tbl1.cola + 3 from u_multicol_tbl1 where id = 3 for update", + "Table": "u_multicol_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 3, + "UpdateExprBvName": "fkc_upd", + "CompExprCol": 2 + } + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (u_multicol_tbl2.cola) not in ((:fkc_upd))) for update", + "Table": "u_multicol_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0, + 1 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl3 set cola = null, colb = null where (cola, colb) in ::fkc_vals1", + "Table": "u_multicol_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (u_multicol_tbl2.cola) not in ((:fkc_upd)))", + "Table": "u_multicol_tbl2" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl1 set cola = u_multicol_tbl1.cola + 3 where id = 3", + "Table": "u_multicol_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1", + "unsharded_fk_allow.u_multicol_tbl2", + "unsharded_fk_allow.u_multicol_tbl3" + ] + } + }, + { + "comment": "updating multiple columns of a fk constraint such that one uses the other", + "query": "update u_multicol_tbl3 set cola = id, colb = 5 * (cola + (1 - (cola))) where id = 2", + "plan": "VT12001: unsupported: cola column referenced in foreign key column colb is itself updated" + }, + { + "comment": "multicol foreign key updates with one literal and one non-literal update", + "query": "update u_multicol_tbl2 set cola = 2, colb = colc - (2) where id = 7", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_multicol_tbl2 set cola = 2, colb = colc - (2) where id = 7", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where 1 != 1", + "Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 lock in share mode", + "Table": "u_multicol_tbl1, u_multicol_tbl2" + }, + { + "InputName": "PostVerify", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb, cola <=> 2, 2, colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb, cola <=> 2, 2, colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where u_multicol_tbl2.id = 7 for update", + "Table": "u_multicol_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1 + ], + "NonLiteralUpdateInfo": [ + { + "UpdateExprCol": 3, + "UpdateExprBvName": "fkc_upd", + "CompExprCol": 2 + }, + { + "UpdateExprCol": 5, + "UpdateExprBvName": "fkc_upd1", + "CompExprCol": 4 + } + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl3 set cola = :fkc_upd, colb = :fkc_upd1 where (cola, colb) in ::fkc_vals", + "Table": "u_multicol_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl2 set cola = 2, colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.id = 7", + "Table": "u_multicol_tbl2" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1", + "unsharded_fk_allow.u_multicol_tbl2", + "unsharded_fk_allow.u_multicol_tbl3" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json index cad8e9be1eb..9373ae35a29 100644 --- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json @@ -88,7 +88,7 @@ "Sharded": true }, "FieldQuery": "select `user`.col1 as a, `user`.col2 from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2 from `user` where `user`.col1 = 1 and `user`.col1 = `user`.col2 and 1 = 1", + "Query": "select `user`.col1 as a, `user`.col2 from `user` where `user`.col1 = 1 and `user`.col1 = `user`.col2", "Table": "`user`" }, { @@ -99,7 +99,7 @@ "Sharded": true }, "FieldQuery": "select user_extra.col3 from user_extra where 1 != 1", - "Query": "select user_extra.col3 from user_extra where user_extra.col3 = 1 and 1 = 1", + "Query": "select user_extra.col3 from user_extra where user_extra.col3 = 1", "Table": "user_extra" } ] diff --git a/go/vt/vtgate/planbuilder/update.go b/go/vt/vtgate/planbuilder/update.go index eced4251ab3..dfb841a4d11 100644 --- a/go/vt/vtgate/planbuilder/update.go +++ b/go/vt/vtgate/planbuilder/update.go @@ -46,6 +46,13 @@ func gen4UpdateStmtPlanner( return nil, err } + // If there are non-literal foreign key updates, we have to run the query with foreign key checks off. + if ctx.SemTable.HasNonLiteralForeignKeyUpdate(updStmt.Exprs) { + // Since we are running the query with foreign key checks off, we have to verify all the foreign keys validity on vtgate. + ctx.VerifyAllFKs = true + updStmt.Comments = updStmt.Comments.Prepend("/*+ SET_VAR(foreign_key_checks=OFF) */").Parsed() + } + // Remove all the foreign keys that don't require any handling. err = ctx.SemTable.RemoveNonRequiredForeignKeys(ctx.VerifyAllFKs, vindexes.UpdateAction) if err != nil { diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index e524b1a33cf..96c604d76a1 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -108,7 +108,7 @@ func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID columns[union] = info.exprs } - childFks, parentFks, err := a.getInvolvedForeignKeys(statement) + childFks, parentFks, childFkToUpdExprs, err := a.getInvolvedForeignKeys(statement) if err != nil { return nil, err } @@ -130,6 +130,7 @@ func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID QuerySignature: a.sig, childForeignKeysInvolved: childFks, parentForeignKeysInvolved: parentFks, + childFkToUpdExprs: childFkToUpdExprs, }, nil } @@ -317,14 +318,14 @@ func (a *analyzer) noteQuerySignature(node sqlparser.SQLNode) { } // getInvolvedForeignKeys gets the foreign keys that might require taking care off when executing the given statement. -func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, error) { +func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, map[string]sqlparser.UpdateExprs, error) { // There are only the DML statements that require any foreign keys handling. switch stmt := statement.(type) { case *sqlparser.Delete: // For DELETE statements, none of the parent foreign keys require handling. // So we collect all the child foreign keys. allChildFks, _, err := a.getAllManagedForeignKeys() - return allChildFks, nil, err + return allChildFks, nil, nil, err case *sqlparser.Insert: // For INSERT statements, we have 3 different cases: // 1. REPLACE statement: REPLACE statements are essentially DELETEs and INSERTs rolled into one. @@ -334,35 +335,35 @@ func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement) (map[Ta // 3. INSERT with ON DUPLICATE KEY UPDATE: This might trigger an update on the columns specified in the ON DUPLICATE KEY UPDATE clause. allChildFks, allParentFKs, err := a.getAllManagedForeignKeys() if err != nil { - return nil, nil, err + return nil, nil, nil, err } if stmt.Action == sqlparser.ReplaceAct { - return allChildFks, allParentFKs, nil + return allChildFks, allParentFKs, nil, nil } if len(stmt.OnDup) == 0 { - return nil, allParentFKs, nil + return nil, allParentFKs, nil, nil } // If only a certain set of columns are being updated, then there might be some child foreign keys that don't need any consideration since their columns aren't being updated. // So, we filter these child foreign keys out. We can't filter any parent foreign keys because the statement will INSERT a row too, which requires validating all the parent foreign keys. - updatedChildFks, _ := a.filterForeignKeysUsingUpdateExpressions(allChildFks, nil, sqlparser.UpdateExprs(stmt.OnDup)) - return updatedChildFks, allParentFKs, nil + updatedChildFks, _, childFkToUpdExprs := a.filterForeignKeysUsingUpdateExpressions(allChildFks, nil, sqlparser.UpdateExprs(stmt.OnDup)) + return updatedChildFks, allParentFKs, childFkToUpdExprs, nil case *sqlparser.Update: // For UPDATE queries we get all the parent and child foreign keys, but we can filter some of them out if the columns that they consist off aren't being updated or are set to NULLs. allChildFks, allParentFks, err := a.getAllManagedForeignKeys() if err != nil { - return nil, nil, err + return nil, nil, nil, err } - childFks, parentFks := a.filterForeignKeysUsingUpdateExpressions(allChildFks, allParentFks, stmt.Exprs) - return childFks, parentFks, nil + childFks, parentFks, childFkToUpdExprs := a.filterForeignKeysUsingUpdateExpressions(allChildFks, allParentFks, stmt.Exprs) + return childFks, parentFks, childFkToUpdExprs, nil default: - return nil, nil, nil + return nil, nil, nil, nil } } // filterForeignKeysUsingUpdateExpressions filters the child and parent foreign key constraints that don't require any validations/cascades given the updated expressions. -func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[TableSet][]vindexes.ChildFKInfo, allParentFks map[TableSet][]vindexes.ParentFKInfo, updExprs sqlparser.UpdateExprs) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo) { +func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[TableSet][]vindexes.ChildFKInfo, allParentFks map[TableSet][]vindexes.ParentFKInfo, updExprs sqlparser.UpdateExprs) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, map[string]sqlparser.UpdateExprs) { if len(allChildFks) == 0 && len(allParentFks) == 0 { - return nil, nil + return nil, nil, nil } pFksRequired := make(map[TableSet][]bool, len(allParentFks)) @@ -377,6 +378,9 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table // updExprToTableSet stores the tables that the updated expressions are from. updExprToTableSet := make(map[*sqlparser.ColName]TableSet) + // childFKToUpdExprs stores child foreign key to update expressions mapping. + childFKToUpdExprs := map[string]sqlparser.UpdateExprs{} + // Go over all the update expressions for _, updateExpr := range updExprs { deps := a.binder.direct.dependencies(updateExpr.Name) @@ -393,6 +397,10 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table for idx, childFk := range childFks { if childFk.ParentColumns.FindColumn(updateExpr.Name.Name) >= 0 { cFksRequired[deps][idx] = true + tbl, _ := a.tables.tableInfoFor(deps) + ue := childFKToUpdExprs[childFk.String(tbl.GetVindexTable())] + ue = append(ue, updateExpr) + childFKToUpdExprs[childFk.String(tbl.GetVindexTable())] = ue } } // If we are setting a column to NULL, then we don't need to verify the existance of an @@ -434,7 +442,6 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table } } pFksNeedsHandling[ts] = pFKNeeded - } for ts, childFks := range allChildFks { var cFKNeeded []vindexes.ChildFKInfo @@ -444,9 +451,8 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table } } cFksNeedsHandling[ts] = cFKNeeded - } - return cFksNeedsHandling, pFksNeedsHandling + return cFksNeedsHandling, pFksNeedsHandling, childFKToUpdExprs } // getAllManagedForeignKeys gets all the foreign keys for the query we are analyzing that Vitess is reposible for managing. diff --git a/go/vt/vtgate/semantics/analyzer_fk_test.go b/go/vt/vtgate/semantics/analyzer_fk_test.go new file mode 100644 index 00000000000..5ba6041ef5c --- /dev/null +++ b/go/vt/vtgate/semantics/analyzer_fk_test.go @@ -0,0 +1,582 @@ +/* +Copyright 2023 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 semantics + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +var parentTbl = &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("parentt"), + Keyspace: &vindexes.Keyspace{ + Name: "ks", + }, +} + +var tbl = map[string]TableInfo{ + "t0": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t0"), + Keyspace: &vindexes.Keyspace{Name: "ks"}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(parentTbl, []string{"col"}, []string{"col"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), + }, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + }, + "t1": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: "ks_unmanaged", Sharded: true}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(parentTbl, []string{"cola"}, []string{"cola"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola1", "cola2"}, []string{"ccola1", "ccola2"}, sqlparser.SetNull), + }, + }, + }, + "t2": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t2"), + Keyspace: &vindexes.Keyspace{Name: "ks"}, + }, + }, + "t3": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t3"), + Keyspace: &vindexes.Keyspace{Name: "undefined_ks", Sharded: true}, + }, + }, + "t4": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t4"), + Keyspace: &vindexes.Keyspace{Name: "ks"}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(parentTbl, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), + ckInfo(parentTbl, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), + ckInfo(parentTbl, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), + }, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(parentTbl, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), + pkInfo(parentTbl, []string{"pcolc"}, []string{"colc"}), + pkInfo(parentTbl, []string{"pcolb", "pcola"}, []string{"colb", "cola"}), + pkInfo(parentTbl, []string{"pcolb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"pcola"}, []string{"cola"}), + pkInfo(parentTbl, []string{"pcolb", "pcolx"}, []string{"colb", "colx"}), + }, + }, + }, + "t5": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t5"), + Keyspace: &vindexes.Keyspace{Name: "ks"}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(parentTbl, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), + ckInfo(parentTbl, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), + }, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(parentTbl, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), + pkInfo(parentTbl, []string{"pcola"}, []string{"cola"}), + pkInfo(parentTbl, []string{"pcold", "pcolc"}, []string{"cold", "colc"}), + pkInfo(parentTbl, []string{"pcold"}, []string{"cold"}), + pkInfo(parentTbl, []string{"pcold", "pcolx"}, []string{"cold", "colx"}), + }, + }, + }, + "t6": &RealTable{ + Table: &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("t6"), + Keyspace: &vindexes.Keyspace{Name: "ks"}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(parentTbl, []string{"col"}, []string{"col"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), + ckInfo(parentTbl, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), + ckInfo(parentTbl, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), + ckInfo(parentTbl, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), + }, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + }, +} + +// TestGetAllManagedForeignKeys tests the functionality of getAllManagedForeignKeys. +func TestGetAllManagedForeignKeys(t *testing.T) { + tests := []struct { + name string + analyzer *analyzer + childFkWanted map[TableSet][]vindexes.ChildFKInfo + parentFkWanted map[TableSet][]vindexes.ParentFKInfo + expectedErr string + }{ + { + name: "Collect all foreign key constraints", + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t0"], + tbl["t1"], + &DerivedTable{}, + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + }, + }, + }, + childFkWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"col"}, []string{"col"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), + }, + }, + parentFkWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + }, + { + name: "keyspace not found in schema information", + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t2"], + tbl["t3"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + }, + }, + }, + }, + expectedErr: "undefined_ks keyspace not found", + }, + { + name: "Cyclic fk constraints error", + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t0"], tbl["t1"], + &DerivedTable{}, + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + KsError: map[string]error{ + "ks": fmt.Errorf("VT09019: ks has cyclic foreign keys"), + }, + }, + }, + }, + expectedErr: "VT09019: ks has cyclic foreign keys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + childFk, parentFk, err := tt.analyzer.getAllManagedForeignKeys() + if tt.expectedErr != "" { + require.EqualError(t, err, tt.expectedErr) + return + } + require.EqualValues(t, tt.childFkWanted, childFk) + require.EqualValues(t, tt.parentFkWanted, parentFk) + }) + } +} + +// TestFilterForeignKeysUsingUpdateExpressions tests the functionality of filterForeignKeysUsingUpdateExpressions. +func TestFilterForeignKeysUsingUpdateExpressions(t *testing.T) { + cola := sqlparser.NewColName("cola") + colb := sqlparser.NewColName("colb") + colc := sqlparser.NewColName("colc") + cold := sqlparser.NewColName("cold") + a := &analyzer{ + binder: &binder{ + direct: map[sqlparser.Expr]TableSet{ + cola: SingleTableSet(0), + colb: SingleTableSet(0), + colc: SingleTableSet(1), + cold: SingleTableSet(1), + }, + }, + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t4"], + tbl["t5"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + }, + }, + }, + } + updateExprs := sqlparser.UpdateExprs{ + &sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}, + &sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}, + &sqlparser.UpdateExpr{Name: colc, Expr: sqlparser.NewIntLiteral("1")}, + &sqlparser.UpdateExpr{Name: cold, Expr: &sqlparser.NullVal{}}, + } + tests := []struct { + name string + analyzer *analyzer + allChildFks map[TableSet][]vindexes.ChildFKInfo + allParentFks map[TableSet][]vindexes.ParentFKInfo + updExprs sqlparser.UpdateExprs + childFksWanted map[TableSet][]vindexes.ChildFKInfo + parentFksWanted map[TableSet][]vindexes.ParentFKInfo + }{ + { + name: "Child Foreign Keys Filtering", + analyzer: a, + allParentFks: nil, + allChildFks: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): tbl["t4"].(*RealTable).Table.ChildForeignKeys, + SingleTableSet(1): tbl["t5"].(*RealTable).Table.ChildForeignKeys, + }, + updExprs: updateExprs, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), + }, + SingleTableSet(1): { + ckInfo(parentTbl, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), + }, + }, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{}, + }, { + name: "Parent Foreign Keys Filtering", + analyzer: a, + allParentFks: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): tbl["t4"].(*RealTable).Table.ParentForeignKeys, + SingleTableSet(1): tbl["t5"].(*RealTable).Table.ParentForeignKeys, + }, + allChildFks: nil, + updExprs: updateExprs, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{}, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), + pkInfo(parentTbl, []string{"pcola"}, []string{"cola"}), + }, + SingleTableSet(1): { + pkInfo(parentTbl, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + childFks, parentFks, _ := tt.analyzer.filterForeignKeysUsingUpdateExpressions(tt.allChildFks, tt.allParentFks, tt.updExprs) + require.EqualValues(t, tt.childFksWanted, childFks) + require.EqualValues(t, tt.parentFksWanted, parentFks) + }) + } +} + +// TestGetInvolvedForeignKeys tests the functionality of getInvolvedForeignKeys. +func TestGetInvolvedForeignKeys(t *testing.T) { + cola := sqlparser.NewColName("cola") + colb := sqlparser.NewColName("colb") + colc := sqlparser.NewColName("colc") + cold := sqlparser.NewColName("cold") + tests := []struct { + name string + stmt sqlparser.Statement + analyzer *analyzer + childFksWanted map[TableSet][]vindexes.ChildFKInfo + parentFksWanted map[TableSet][]vindexes.ParentFKInfo + childFkUpdateExprsWanted map[string]sqlparser.UpdateExprs + expectedErr string + }{ + { + name: "Delete Query", + stmt: &sqlparser.Delete{}, + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t0"], + tbl["t1"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + }, + }, + }, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"col"}, []string{"col"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), + }, + }, + }, + { + name: "Update statement", + stmt: &sqlparser.Update{ + Exprs: sqlparser.UpdateExprs{ + &sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}, + &sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}, + &sqlparser.UpdateExpr{Name: colc, Expr: sqlparser.NewIntLiteral("1")}, + &sqlparser.UpdateExpr{Name: cold, Expr: &sqlparser.NullVal{}}, + }, + }, + analyzer: &analyzer{ + binder: &binder{ + direct: map[sqlparser.Expr]TableSet{ + cola: SingleTableSet(0), + colb: SingleTableSet(0), + colc: SingleTableSet(1), + cold: SingleTableSet(1), + }, + }, + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t4"], + tbl["t5"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + }, + }, + }, + }, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), + }, + SingleTableSet(1): { + ckInfo(parentTbl, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), + }, + }, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), + pkInfo(parentTbl, []string{"pcola"}, []string{"cola"}), + }, + SingleTableSet(1): { + pkInfo(parentTbl, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), + }, + }, + childFkUpdateExprsWanted: map[string]sqlparser.UpdateExprs{ + "ks.parentt|child_cola|child_colx||ks.t4|cola|colx": {&sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}}, + "ks.parentt|child_colb||ks.t4|colb": {&sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}}, + "ks.parentt|child_colc|child_colx||ks.t5|colc|colx": {&sqlparser.UpdateExpr{Name: colc, Expr: sqlparser.NewIntLiteral("1")}}, + "ks.parentt|child_cold||ks.t5|cold": {&sqlparser.UpdateExpr{Name: cold, Expr: &sqlparser.NullVal{}}}, + }, + }, + { + name: "Replace Query", + stmt: &sqlparser.Insert{ + Action: sqlparser.ReplaceAct, + }, + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t0"], + tbl["t1"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + }, + }, + }, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"col"}, []string{"col"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), + }, + }, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + }, + { + name: "Insert Query", + stmt: &sqlparser.Insert{ + Action: sqlparser.InsertAct, + }, + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t0"], + tbl["t1"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + }, + }, + }, + childFksWanted: nil, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + }, + { + name: "Insert Query with On Duplicate", + stmt: &sqlparser.Insert{ + Action: sqlparser.InsertAct, + OnDup: sqlparser.OnDup{ + &sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}, + &sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}, + }, + }, + analyzer: &analyzer{ + binder: &binder{ + direct: map[sqlparser.Expr]TableSet{ + cola: SingleTableSet(0), + colb: SingleTableSet(0), + }, + }, + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t6"], + tbl["t1"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + "ks_unmanaged": vschemapb.Keyspace_unmanaged, + }, + }, + }, + }, + childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ + SingleTableSet(0): { + ckInfo(parentTbl, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), + ckInfo(parentTbl, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), + }, + }, + parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ + SingleTableSet(0): { + pkInfo(parentTbl, []string{"colb"}, []string{"colb"}), + pkInfo(parentTbl, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), + }, + }, + childFkUpdateExprsWanted: map[string]sqlparser.UpdateExprs{ + "ks.parentt|child_cola|child_colx||ks.t6|cola|colx": {&sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}}, + "ks.parentt|child_colb||ks.t6|colb": {&sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}}, + }, + }, + { + name: "Insert error", + stmt: &sqlparser.Insert{}, + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t2"], + tbl["t3"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + }, + }, + }, + }, + expectedErr: "undefined_ks keyspace not found", + }, + { + name: "Update error", + stmt: &sqlparser.Update{}, + analyzer: &analyzer{ + tables: &tableCollector{ + Tables: []TableInfo{ + tbl["t2"], + tbl["t3"], + }, + si: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + "ks": vschemapb.Keyspace_managed, + }, + }, + }, + }, + expectedErr: "undefined_ks keyspace not found", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + childFks, parentFks, childFkUpdateExprs, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt) + if tt.expectedErr != "" { + require.EqualError(t, err, tt.expectedErr) + return + } + require.EqualValues(t, tt.childFksWanted, childFks) + require.EqualValues(t, tt.childFkUpdateExprsWanted, childFkUpdateExprs) + require.EqualValues(t, tt.parentFksWanted, parentFks) + }) + } +} + +func ckInfo(cTable *vindexes.Table, pCols []string, cCols []string, refAction sqlparser.ReferenceAction) vindexes.ChildFKInfo { + return vindexes.ChildFKInfo{ + Table: cTable, + ParentColumns: sqlparser.MakeColumns(pCols...), + ChildColumns: sqlparser.MakeColumns(cCols...), + OnDelete: refAction, + } +} + +func pkInfo(parentTable *vindexes.Table, pCols []string, cCols []string) vindexes.ParentFKInfo { + return vindexes.ParentFKInfo{ + Table: parentTable, + ParentColumns: sqlparser.MakeColumns(pCols...), + ChildColumns: sqlparser.MakeColumns(cCols...), + } +} diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go index c8251dd36c3..cb19d5deafd 100644 --- a/go/vt/vtgate/semantics/analyzer_test.go +++ b/go/vt/vtgate/semantics/analyzer_test.go @@ -17,7 +17,6 @@ limitations under the License. package semantics import ( - "fmt" "testing" "github.com/stretchr/testify/assert" @@ -25,7 +24,6 @@ import ( "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -1627,555 +1625,3 @@ func fakeSchemaInfo() *FakeSI { } return si } - -var tbl = map[string]TableInfo{ - "t0": &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks"}, - ChildForeignKeys: []vindexes.ChildFKInfo{ - ckInfo(nil, []string{"col"}, []string{"col"}, sqlparser.Restrict), - ckInfo(nil, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), - }, - ParentForeignKeys: []vindexes.ParentFKInfo{ - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - "t1": &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks_unmanaged", Sharded: true}, - ChildForeignKeys: []vindexes.ChildFKInfo{ - ckInfo(nil, []string{"cola"}, []string{"cola"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola1", "cola2"}, []string{"ccola1", "ccola2"}, sqlparser.SetNull), - }, - }, - }, - "t2": &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks"}, - }, - }, - "t3": &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "undefined_ks", Sharded: true}, - }, - }, -} - -// TestGetAllManagedForeignKeys tests the functionality of getAllManagedForeignKeys. -func TestGetAllManagedForeignKeys(t *testing.T) { - tests := []struct { - name string - analyzer *analyzer - childFkWanted map[TableSet][]vindexes.ChildFKInfo - parentFkWanted map[TableSet][]vindexes.ParentFKInfo - expectedErr string - }{ - { - name: "Collect all foreign key constraints", - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{tbl["t0"], tbl["t1"], - &DerivedTable{}, - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - }, - }, - }, - childFkWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"col"}, []string{"col"}, sqlparser.Restrict), - ckInfo(nil, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), - }, - }, - parentFkWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - { - name: "keyspace not found in schema information", - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t2"], - tbl["t3"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - }, - }, - }, - }, - expectedErr: "undefined_ks keyspace not found", - }, - { - name: "Cyclic fk constraints error", - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t0"], tbl["t1"], - &DerivedTable{}, - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - KsError: map[string]error{ - "ks": fmt.Errorf("VT09019: ks has cyclic foreign keys"), - }, - }, - }, - }, - expectedErr: "VT09019: ks has cyclic foreign keys", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - childFk, parentFk, err := tt.analyzer.getAllManagedForeignKeys() - if tt.expectedErr != "" { - require.EqualError(t, err, tt.expectedErr) - return - } - require.EqualValues(t, tt.childFkWanted, childFk) - require.EqualValues(t, tt.parentFkWanted, parentFk) - }) - } -} - -// TestFilterForeignKeysUsingUpdateExpressions tests the functionality of filterForeignKeysUsingUpdateExpressions. -func TestFilterForeignKeysUsingUpdateExpressions(t *testing.T) { - cola := sqlparser.NewColName("cola") - colb := sqlparser.NewColName("colb") - colc := sqlparser.NewColName("colc") - cold := sqlparser.NewColName("cold") - a := &analyzer{ - binder: &binder{ - direct: map[sqlparser.Expr]TableSet{ - cola: SingleTableSet(0), - colb: SingleTableSet(0), - colc: SingleTableSet(1), - cold: SingleTableSet(1), - }, - }, - } - updateExprs := sqlparser.UpdateExprs{ - &sqlparser.UpdateExpr{Name: cola, Expr: sqlparser.NewIntLiteral("1")}, - &sqlparser.UpdateExpr{Name: colb, Expr: &sqlparser.NullVal{}}, - &sqlparser.UpdateExpr{Name: colc, Expr: sqlparser.NewIntLiteral("1")}, - &sqlparser.UpdateExpr{Name: cold, Expr: &sqlparser.NullVal{}}, - } - tests := []struct { - name string - analyzer *analyzer - allChildFks map[TableSet][]vindexes.ChildFKInfo - allParentFks map[TableSet][]vindexes.ParentFKInfo - updExprs sqlparser.UpdateExprs - childFksWanted map[TableSet][]vindexes.ChildFKInfo - parentFksWanted map[TableSet][]vindexes.ParentFKInfo - }{ - { - name: "Child Foreign Keys Filtering", - analyzer: a, - allParentFks: nil, - allChildFks: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - ckInfo(nil, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - }, - SingleTableSet(1): { - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - ckInfo(nil, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), - ckInfo(nil, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), - }, - }, - updExprs: updateExprs, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - }, - SingleTableSet(1): { - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - ckInfo(nil, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), - }, - }, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{}, - }, { - name: "Parent Foreign Keys Filtering", - analyzer: a, - allParentFks: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), - pkInfo(nil, []string{"pcolc"}, []string{"colc"}), - pkInfo(nil, []string{"pcolb", "pcola"}, []string{"colb", "cola"}), - pkInfo(nil, []string{"pcolb"}, []string{"colb"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - pkInfo(nil, []string{"pcolb", "pcolx"}, []string{"colb", "colx"}), - }, - SingleTableSet(1): { - pkInfo(nil, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - pkInfo(nil, []string{"pcold", "pcolc"}, []string{"cold", "colc"}), - pkInfo(nil, []string{"pcold"}, []string{"cold"}), - pkInfo(nil, []string{"pcold", "pcolx"}, []string{"cold", "colx"}), - }, - }, - allChildFks: nil, - updExprs: updateExprs, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{}, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - }, - SingleTableSet(1): { - pkInfo(nil, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - childFks, parentFks := tt.analyzer.filterForeignKeysUsingUpdateExpressions(tt.allChildFks, tt.allParentFks, tt.updExprs) - require.EqualValues(t, tt.childFksWanted, childFks) - require.EqualValues(t, tt.parentFksWanted, parentFks) - }) - } -} - -// TestGetInvolvedForeignKeys tests the functionality of getInvolvedForeignKeys. -func TestGetInvolvedForeignKeys(t *testing.T) { - cola := sqlparser.NewColName("cola") - colb := sqlparser.NewColName("colb") - colc := sqlparser.NewColName("colc") - cold := sqlparser.NewColName("cold") - tests := []struct { - name string - stmt sqlparser.Statement - analyzer *analyzer - childFksWanted map[TableSet][]vindexes.ChildFKInfo - parentFksWanted map[TableSet][]vindexes.ParentFKInfo - expectedErr string - }{ - { - name: "Delete Query", - stmt: &sqlparser.Delete{}, - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t0"], - tbl["t1"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - }, - }, - }, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"col"}, []string{"col"}, sqlparser.Restrict), - ckInfo(nil, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), - }, - }, - }, - { - name: "Update statement", - stmt: &sqlparser.Update{ - Exprs: sqlparser.UpdateExprs{ - &sqlparser.UpdateExpr{ - Name: cola, - Expr: sqlparser.NewIntLiteral("1"), - }, - &sqlparser.UpdateExpr{ - Name: colb, - Expr: &sqlparser.NullVal{}, - }, - &sqlparser.UpdateExpr{ - Name: colc, - Expr: sqlparser.NewIntLiteral("1"), - }, - &sqlparser.UpdateExpr{ - Name: cold, - Expr: &sqlparser.NullVal{}, - }, - }, - }, - analyzer: &analyzer{ - binder: &binder{ - direct: map[sqlparser.Expr]TableSet{ - cola: SingleTableSet(0), - colb: SingleTableSet(0), - colc: SingleTableSet(1), - cold: SingleTableSet(1), - }, - }, - tables: &tableCollector{ - Tables: []TableInfo{ - &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks"}, - ChildForeignKeys: []vindexes.ChildFKInfo{ - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - ckInfo(nil, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - }, - ParentForeignKeys: []vindexes.ParentFKInfo{ - pkInfo(nil, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), - pkInfo(nil, []string{"pcolc"}, []string{"colc"}), - pkInfo(nil, []string{"pcolb", "pcola"}, []string{"colb", "cola"}), - pkInfo(nil, []string{"pcolb"}, []string{"colb"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - pkInfo(nil, []string{"pcolb", "pcolx"}, []string{"colb", "colx"}), - }, - }, - }, - &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks"}, - ChildForeignKeys: []vindexes.ChildFKInfo{ - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - ckInfo(nil, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), - ckInfo(nil, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), - }, - ParentForeignKeys: []vindexes.ParentFKInfo{ - pkInfo(nil, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - pkInfo(nil, []string{"pcold", "pcolc"}, []string{"cold", "colc"}), - pkInfo(nil, []string{"pcold"}, []string{"cold"}), - pkInfo(nil, []string{"pcold", "pcolx"}, []string{"cold", "colx"}), - }, - }, - }, - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - }, - }, - }, - }, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - }, - SingleTableSet(1): { - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - ckInfo(nil, []string{"colc", "colx"}, []string{"child_colc", "child_colx"}, sqlparser.SetNull), - }, - }, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"pcola", "pcolx"}, []string{"cola", "colx"}), - pkInfo(nil, []string{"pcola"}, []string{"cola"}), - }, - SingleTableSet(1): { - pkInfo(nil, []string{"pcolc", "pcolx"}, []string{"colc", "colx"}), - }, - }, - }, - { - name: "Replace Query", - stmt: &sqlparser.Insert{ - Action: sqlparser.ReplaceAct, - }, - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t0"], - tbl["t1"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - }, - }, - }, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"col"}, []string{"col"}, sqlparser.Restrict), - ckInfo(nil, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), - }, - }, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - { - name: "Insert Query", - stmt: &sqlparser.Insert{ - Action: sqlparser.InsertAct, - }, - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t0"], - tbl["t1"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - }, - }, - }, - childFksWanted: nil, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - { - name: "Insert Query with On Duplicate", - stmt: &sqlparser.Insert{ - Action: sqlparser.InsertAct, - OnDup: sqlparser.OnDup{ - &sqlparser.UpdateExpr{ - Name: cola, - Expr: sqlparser.NewIntLiteral("1"), - }, - &sqlparser.UpdateExpr{ - Name: colb, - Expr: &sqlparser.NullVal{}, - }, - }, - }, - analyzer: &analyzer{ - binder: &binder{ - direct: map[sqlparser.Expr]TableSet{ - cola: SingleTableSet(0), - colb: SingleTableSet(0), - }, - }, - tables: &tableCollector{ - Tables: []TableInfo{ - &RealTable{ - Table: &vindexes.Table{ - Keyspace: &vindexes.Keyspace{Name: "ks"}, - ChildForeignKeys: []vindexes.ChildFKInfo{ - ckInfo(nil, []string{"col"}, []string{"col"}, sqlparser.Restrict), - ckInfo(nil, []string{"col1", "col2"}, []string{"ccol1", "ccol2"}, sqlparser.SetNull), - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - ckInfo(nil, []string{"colx", "coly"}, []string{"child_colx", "child_coly"}, sqlparser.Cascade), - ckInfo(nil, []string{"cold"}, []string{"child_cold"}, sqlparser.Restrict), - }, - ParentForeignKeys: []vindexes.ParentFKInfo{ - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - tbl["t1"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - "ks_unmanaged": vschemapb.Keyspace_unmanaged, - }, - }, - }, - }, - childFksWanted: map[TableSet][]vindexes.ChildFKInfo{ - SingleTableSet(0): { - ckInfo(nil, []string{"colb"}, []string{"child_colb"}, sqlparser.Restrict), - ckInfo(nil, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}, sqlparser.SetNull), - }, - }, - parentFksWanted: map[TableSet][]vindexes.ParentFKInfo{ - SingleTableSet(0): { - pkInfo(nil, []string{"colb"}, []string{"colb"}), - pkInfo(nil, []string{"colb1", "colb2"}, []string{"ccolb1", "ccolb2"}), - }, - }, - }, - { - name: "Insert error", - stmt: &sqlparser.Insert{}, - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t2"], - tbl["t3"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - }, - }, - }, - }, - expectedErr: "undefined_ks keyspace not found", - }, - { - name: "Update error", - stmt: &sqlparser.Update{}, - analyzer: &analyzer{ - tables: &tableCollector{ - Tables: []TableInfo{ - tbl["t2"], - tbl["t3"], - }, - si: &FakeSI{ - KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ - "ks": vschemapb.Keyspace_managed, - }, - }, - }, - }, - expectedErr: "undefined_ks keyspace not found", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - childFks, parentFks, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt) - if tt.expectedErr != "" { - require.EqualError(t, err, tt.expectedErr) - return - } - require.EqualValues(t, tt.childFksWanted, childFks) - require.EqualValues(t, tt.parentFksWanted, parentFks) - }) - } -} - -func ckInfo(cTable *vindexes.Table, pCols []string, cCols []string, refAction sqlparser.ReferenceAction) vindexes.ChildFKInfo { - return vindexes.ChildFKInfo{ - Table: cTable, - ParentColumns: sqlparser.MakeColumns(pCols...), - ChildColumns: sqlparser.MakeColumns(cCols...), - OnDelete: refAction, - } -} - -func pkInfo(parentTable *vindexes.Table, pCols []string, cCols []string) vindexes.ParentFKInfo { - return vindexes.ParentFKInfo{ - Table: parentTable, - ParentColumns: sqlparser.MakeColumns(pCols...), - ChildColumns: sqlparser.MakeColumns(cCols...), - } -} diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index d3c5f312426..0349ef3f79d 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -47,6 +47,8 @@ func (r *earlyRewriter) down(cursor *sqlparser.Cursor) error { handleOrderBy(r, cursor, node) case *sqlparser.OrExpr: rewriteOrExpr(cursor, node) + case *sqlparser.AndExpr: + rewriteAndExpr(cursor, node) case *sqlparser.NotExpr: rewriteNotExpr(cursor, node) case sqlparser.GroupBy: @@ -176,6 +178,45 @@ func rewriteOrExpr(cursor *sqlparser.Cursor, node *sqlparser.OrExpr) { } } +// rewriteAndExpr rewrites AND expressions when either side is TRUE. +func rewriteAndExpr(cursor *sqlparser.Cursor, node *sqlparser.AndExpr) { + newNode := rewriteAndTrue(*node) + if newNode != nil { + cursor.ReplaceAndRevisit(newNode) + } +} + +func rewriteAndTrue(andExpr sqlparser.AndExpr) sqlparser.Expr { + // we are looking for the pattern `WHERE c = 1 AND 1 = 1` + isTrue := func(subExpr sqlparser.Expr) bool { + evalEnginePred, err := evalengine.Translate(subExpr, nil) + if err != nil { + return false + } + + env := evalengine.EmptyExpressionEnv() + res, err := env.Evaluate(evalEnginePred) + if err != nil { + return false + } + + boolValue, err := res.Value(collations.Default()).ToBool() + if err != nil { + return false + } + + return boolValue + } + + if isTrue(andExpr.Left) { + return andExpr.Right + } else if isTrue(andExpr.Right) { + return andExpr.Left + } + + return nil +} + // handleLiteral processes literals within the context of ORDER BY expressions. func handleLiteral(r *earlyRewriter, cursor *sqlparser.Cursor, node *sqlparser.Literal) error { newNode, err := r.rewriteOrderByExpr(node) diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 94b1302b357..48ab4322bc8 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -137,6 +137,7 @@ type ( // The map is keyed by the tableset of the table that each of the foreign key belongs to. childForeignKeysInvolved map[TableSet][]vindexes.ChildFKInfo parentForeignKeysInvolved map[TableSet][]vindexes.ParentFKInfo + childFkToUpdExprs map[string]sqlparser.UpdateExprs } columnName struct { @@ -196,6 +197,11 @@ func (st *SemTable) GetParentForeignKeysList() []vindexes.ParentFKInfo { return parentFkInfos } +// GetUpdateExpressionsForFk gets the update expressions for the given serialized foreign key constraint. +func (st *SemTable) GetUpdateExpressionsForFk(foreignKey string) sqlparser.UpdateExprs { + return st.childFkToUpdExprs[foreignKey] +} + // RemoveParentForeignKey removes the given foreign key from the parent foreign keys that sem table stores. func (st *SemTable) RemoveParentForeignKey(fkToIgnore string) error { for ts, fkInfos := range st.parentForeignKeysInvolved { @@ -279,6 +285,89 @@ func (st *SemTable) RemoveNonRequiredForeignKeys(verifyAllFks bool, getAction fu return nil } +// ErrIfFkDependentColumnUpdated checks if a foreign key column that is being updated is dependent on another column which also being updated. +func (st *SemTable) ErrIfFkDependentColumnUpdated(updateExprs sqlparser.UpdateExprs) error { + // Go over all the update expressions + for _, updateExpr := range updateExprs { + deps := st.RecursiveDeps(updateExpr.Name) + if deps.NumberOfTables() != 1 { + panic("expected to have single table dependency") + } + // Get all the child and parent foreign keys for the given table that the update expression belongs to. + childFks := st.childForeignKeysInvolved[deps] + parentFKs := st.parentForeignKeysInvolved[deps] + + involvedInFk := false + // Check if this updated column is part of any child or parent foreign key. + for _, childFk := range childFks { + if childFk.ParentColumns.FindColumn(updateExpr.Name.Name) >= 0 { + involvedInFk = true + break + } + } + for _, parentFk := range parentFKs { + if parentFk.ChildColumns.FindColumn(updateExpr.Name.Name) >= 0 { + involvedInFk = true + break + } + } + + if !involvedInFk { + continue + } + + // We cannot support updating a foreign key column that is using a column which is also being updated for 2 reasons— + // 1. For the child foreign keys, we aren't sure what the final value of the updated foreign key column will be. So we don't know + // what to cascade to the child. The selection that we do isn't enough to know if the updated value, since one of the columns used in the update is also being updated. + // 2. For the parent foreign keys, we don't know if we need to reject this update. Because we don't know the final updated value, the update might need to be failed, + // but we can't say for certain. + var dependencyUpdatedErr error + _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + col, ok := node.(*sqlparser.ColName) + if !ok { + return true, nil + } + // self reference column dependency is not considered a dependent column being updated. + if st.EqualsExpr(updateExpr.Name, col) { + return true, nil + } + for _, updExpr := range updateExprs { + if st.EqualsExpr(updExpr.Name, col) { + dependencyUpdatedErr = vterrors.VT12001(fmt.Sprintf("%v column referenced in foreign key column %v is itself updated", sqlparser.String(col), sqlparser.String(updateExpr.Name))) + return false, nil + } + } + return false, nil + }, updateExpr.Expr) + if dependencyUpdatedErr != nil { + return dependencyUpdatedErr + } + } + return nil +} + +// HasNonLiteralForeignKeyUpdate checks for non-literal updates in expressions linked to a foreign key. +func (st *SemTable) HasNonLiteralForeignKeyUpdate(updExprs sqlparser.UpdateExprs) bool { + for _, updateExpr := range updExprs { + if sqlparser.IsLiteral(updateExpr.Expr) { + continue + } + parentFks := st.parentForeignKeysInvolved[st.RecursiveDeps(updateExpr.Name)] + for _, parentFk := range parentFks { + if parentFk.ChildColumns.FindColumn(updateExpr.Name.Name) >= 0 { + return true + } + } + childFks := st.childForeignKeysInvolved[st.RecursiveDeps(updateExpr.Name)] + for _, childFk := range childFks { + if childFk.ParentColumns.FindColumn(updateExpr.Name.Name) >= 0 { + return true + } + } + } + return false +} + // isShardScoped checks if the foreign key constraint is shard-scoped or not. It uses the vindex information to make this call. func isShardScoped(pTable *vindexes.Table, cTable *vindexes.Table, pCols sqlparser.Columns, cCols sqlparser.Columns) bool { if !pTable.Keyspace.Sharded { diff --git a/go/vt/vtgate/semantics/semantic_state_test.go b/go/vt/vtgate/semantics/semantic_state_test.go index ab855322d76..b904f3656de 100644 --- a/go/vt/vtgate/semantics/semantic_state_test.go +++ b/go/vt/vtgate/semantics/semantic_state_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" querypb "vitess.io/vitess/go/vt/proto/query" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -418,7 +419,7 @@ func TestRemoveParentForeignKey(t *testing.T) { }, }, }, - fkToIgnore: "ks.t2child_coldks.t3cold", + fkToIgnore: "ks.t2|child_cold||ks.t3|cold", parentFksWanted: []vindexes.ParentFKInfo{ pkInfo(t3Table, []string{"colb"}, []string{"child_colb"}), pkInfo(t3Table, []string{"cola", "colx"}, []string{"child_cola", "child_colx"}), @@ -748,3 +749,233 @@ func TestRemoveNonRequiredForeignKeys(t *testing.T) { }) } } + +func TestIsFkDependentColumnUpdated(t *testing.T) { + keyspaceName := "ks" + t3Table := &vindexes.Table{ + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + Name: sqlparser.NewIdentifierCS("t3"), + } + tests := []struct { + name string + query string + fakeSi *FakeSI + updatedErr string + }{ + { + name: "updated child foreign key column is dependent on another updated column", + query: "update t1 set col = id + 1, id = 6 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(t3Table, []string{"col"}, []string{"col"}, sqlparser.Cascade), + }, + }, + }, + }, + updatedErr: "VT12001: unsupported: id column referenced in foreign key column col is itself updated", + }, { + name: "updated parent foreign key column is dependent on another updated column", + query: "update t1 set col = id + 1, id = 6 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + updatedErr: "VT12001: unsupported: id column referenced in foreign key column col is itself updated", + }, { + name: "no foreign key column is dependent on a updated value", + query: "update t1 set col = id + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + updatedErr: "", + }, { + name: "self-referenced foreign key", + query: "update t1 set col = col + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + updatedErr: "", + }, { + name: "no foreign keys", + query: "update t1 set col = id + 1, id = 6 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + }, + }, + }, + updatedErr: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + stmt, err := sqlparser.Parse(tt.query) + require.NoError(t, err) + semTable, err := Analyze(stmt, keyspaceName, tt.fakeSi) + require.NoError(t, err) + got := semTable.ErrIfFkDependentColumnUpdated(stmt.(*sqlparser.Update).Exprs) + if tt.updatedErr == "" { + require.NoError(t, got) + } else { + require.EqualError(t, got, tt.updatedErr) + } + }) + } +} + +func TestHasNonLiteralForeignKeyUpdate(t *testing.T) { + keyspaceName := "ks" + t3Table := &vindexes.Table{ + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + Name: sqlparser.NewIdentifierCS("t3"), + } + tests := []struct { + name string + query string + fakeSi *FakeSI + hasNonLiteral bool + }{ + { + name: "non literal child foreign key update", + query: "update t1 set col = id + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ChildForeignKeys: []vindexes.ChildFKInfo{ + ckInfo(t3Table, []string{"col"}, []string{"col"}, sqlparser.Cascade), + }, + }, + }, + }, + hasNonLiteral: true, + }, { + name: "non literal parent foreign key update", + query: "update t1 set col = id + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + hasNonLiteral: true, + }, { + name: "literal updates only", + query: "update t1 set col = 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + hasNonLiteral: false, + }, { + name: "self-referenced foreign key", + query: "update t1 set col = col + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + ParentForeignKeys: []vindexes.ParentFKInfo{ + pkInfo(t3Table, []string{"col"}, []string{"col"}), + }, + }, + }, + }, + hasNonLiteral: true, + }, { + name: "no foreign keys", + query: "update t1 set col = id + 1 where foo = 3", + fakeSi: &FakeSI{ + KsForeignKeyMode: map[string]vschemapb.Keyspace_ForeignKeyMode{ + keyspaceName: vschemapb.Keyspace_managed, + }, + Tables: map[string]*vindexes.Table{ + "t1": { + Name: sqlparser.NewIdentifierCS("t1"), + Keyspace: &vindexes.Keyspace{Name: keyspaceName}, + }, + }, + }, + hasNonLiteral: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + stmt, err := sqlparser.Parse(tt.query) + require.NoError(t, err) + semTable, err := Analyze(stmt, keyspaceName, tt.fakeSi) + require.NoError(t, err) + got := semTable.HasNonLiteralForeignKeyUpdate(stmt.(*sqlparser.Update).Exprs) + require.EqualValues(t, tt.hasNonLiteral, got) + }) + } +} diff --git a/go/vt/vtgate/vindexes/foreign_keys.go b/go/vt/vtgate/vindexes/foreign_keys.go index db984462b25..74f9ce74844 100644 --- a/go/vt/vtgate/vindexes/foreign_keys.go +++ b/go/vt/vtgate/vindexes/foreign_keys.go @@ -46,13 +46,13 @@ func (fk *ParentFKInfo) MarshalJSON() ([]byte, error) { func (fk *ParentFKInfo) String(childTable *Table) string { var str strings.Builder - str.WriteString(childTable.String()) + str.WriteString(sqlparser.String(childTable.GetTableName())) for _, column := range fk.ChildColumns { - str.WriteString(column.String()) + str.WriteString("|" + sqlparser.String(column)) } - str.WriteString(fk.Table.String()) + str.WriteString("||" + sqlparser.String(fk.Table.GetTableName())) for _, column := range fk.ParentColumns { - str.WriteString(column.String()) + str.WriteString("|" + sqlparser.String(column)) } return str.String() } @@ -91,13 +91,13 @@ func (fk *ChildFKInfo) MarshalJSON() ([]byte, error) { func (fk *ChildFKInfo) String(parentTable *Table) string { var str strings.Builder - str.WriteString(fk.Table.String()) + str.WriteString(sqlparser.String(fk.Table.GetTableName())) for _, column := range fk.ChildColumns { - str.WriteString(column.String()) + str.WriteString("|" + sqlparser.String(column)) } - str.WriteString(parentTable.String()) + str.WriteString("||" + sqlparser.String(parentTable.GetTableName())) for _, column := range fk.ParentColumns { - str.WriteString(column.String()) + str.WriteString("|" + sqlparser.String(column)) } return str.String() } From 8c80b7fff3ce461e14b506d4c224e15f7cf15e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Fri, 10 Nov 2023 08:56:15 +0100 Subject: [PATCH 007/119] planbuilder bugfix: expose columns through derived tables (#14501) Signed-off-by: Andres Taylor --- .../informationschema_test.go | 29 +++++++++++ .../planbuilder/operators/aggregator.go | 8 +++- go/vt/vtgate/planbuilder/operators/horizon.go | 8 +++- .../planbuilder/operators/route_planning.go | 6 +-- .../planbuilder/testdata/aggr_cases.json | 48 +++++++++++++++++++ .../testdata/info_schema57_cases.json | 42 ++++++++++++++++ .../testdata/info_schema80_cases.json | 42 ++++++++++++++++ .../planbuilder/testdata/select_cases.json | 45 +++++++++++++++++ .../testdata/unsupported_cases.json | 4 +- 9 files changed, 225 insertions(+), 7 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go b/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go index e33daf061bc..0be8a50b328 100644 --- a/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go +++ b/go/test/endtoend/vtgate/queries/informationschema/informationschema_test.go @@ -257,3 +257,32 @@ FROM (SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME `[[VARCHAR("t1") VARCHAR("id1") BLOB("bigint")] [VARCHAR("t7_xxhash") VARCHAR("uid") BLOB("varchar")]]`, ) } + +func TestJoinWithSingleShardQueryOnRHS(t *testing.T) { + // This test checks that we can run queries like this, where the RHS is a single shard query + mcmp, closer := start(t) + defer closer() + + query := `SELECT + c.column_name as column_name, + c.data_type as data_type, + c.table_name as table_name, + c.table_schema as table_schema +FROM + information_schema.columns c + JOIN ( + SELECT + table_name + FROM + information_schema.tables + WHERE + table_schema != 'information_schema' + LIMIT + 1 + ) AS tables ON tables.table_name = c.table_name +ORDER BY + c.table_name` + + res := utils.Exec(t, mcmp.VtConn, query) + require.NotEmpty(t, res.Rows) +} diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index 45ccb041ddd..33846f83365 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -121,7 +121,13 @@ func (a *Aggregator) isDerived() bool { return a.DT != nil } -func (a *Aggregator) FindCol(ctx *plancontext.PlanningContext, in sqlparser.Expr, _ bool) int { +func (a *Aggregator) FindCol(ctx *plancontext.PlanningContext, in sqlparser.Expr, underRoute bool) int { + if underRoute && a.isDerived() { + // We don't want to use columns on this operator if it's a derived table under a route. + // In this case, we need to add a Projection on top of this operator to make the column available + return -1 + } + expr := a.DT.RewriteExpression(ctx, in) if offset, found := canReuseColumn(ctx, a.Columns, expr, extractExpr); found { return offset diff --git a/go/vt/vtgate/planbuilder/operators/horizon.go b/go/vt/vtgate/planbuilder/operators/horizon.go index 919767d550f..c58db4f3964 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon.go +++ b/go/vt/vtgate/planbuilder/operators/horizon.go @@ -145,7 +145,13 @@ func canReuseColumn[T any]( return } -func (h *Horizon) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, _ bool) int { +func (h *Horizon) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int { + if underRoute && h.IsDerived() { + // We don't want to use columns on this operator if it's a derived table under a route. + // In this case, we need to add a Projection on top of this operator to make the column available + return -1 + } + for idx, se := range sqlparser.GetFirstSelect(h.Query).SelectExprs { ae, ok := se.(*sqlparser.AliasedExpr) if !ok { diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index 079813388b3..306158a06da 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -370,11 +370,11 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPr if len(joinPredicates) > 0 && requiresSwitchingSides(ctx, rhs) { if !inner { - return nil, nil, vterrors.VT12001("LEFT JOIN with derived tables") + return nil, nil, vterrors.VT12001("LEFT JOIN with LIMIT on the outer side") } if requiresSwitchingSides(ctx, lhs) { - return nil, nil, vterrors.VT12001("JOIN between derived tables") + return nil, nil, vterrors.VT12001("JOIN between derived tables with LIMIT") } join := NewApplyJoin(Clone(rhs), Clone(lhs), nil, !inner) @@ -382,7 +382,7 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPr if err != nil { return nil, nil, err } - return newOp, rewrite.NewTree("logical join to applyJoin, switching side because derived table", newOp), nil + return newOp, rewrite.NewTree("logical join to applyJoin, switching side because LIMIT", newOp), nil } join := NewApplyJoin(Clone(lhs), Clone(rhs), nil, !inner) diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index 827c64464f8..3302ca09fc7 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6249,5 +6249,53 @@ "user.user" ] } + }, + { + "comment": "GROUP BY inside derived table on the RHS should not be a problem", + "query": "SELECT c.column_name FROM user c JOIN (SELECT table_name FROM user WHERE id = 143 GROUP BY 1) AS tables ON tables.table_name = c.table_name", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT c.column_name FROM user c JOIN (SELECT table_name FROM user WHERE id = 143 GROUP BY 1) AS tables ON tables.table_name = c.table_name", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "tables_table_name": 0 + }, + "TableName": "`user`_`user`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select table_name from (select table_name from `user` where 1 != 1 group by table_name) as `tables` where 1 != 1", + "Query": "select table_name from (select table_name from `user` where id = 143 group by table_name) as `tables`", + "Table": "`user`", + "Values": [ + "143" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select c.column_name from `user` as c where 1 != 1", + "Query": "select c.column_name from `user` as c where c.table_name = :tables_table_name", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json index 50234d5ed73..2084d1a6e91 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json @@ -1139,5 +1139,47 @@ "Table": "information_schema.apa" } } + }, + { + "comment": "LIMIT 1 inside derived table on the RHS should not be a problem", + "query": "SELECT c.column_name FROM information_schema.columns c JOIN ( SELECT table_name FROM information_schema.tables WHERE table_schema != 'information_schema' LIMIT 1 ) AS tables ON tables.table_name = c.table_name", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT c.column_name FROM information_schema.columns c JOIN ( SELECT table_name FROM information_schema.tables WHERE table_schema != 'information_schema' LIMIT 1 ) AS tables ON tables.table_name = c.table_name", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "tables_table_name": 0 + }, + "TableName": "information_schema.`tables`_information_schema.`columns`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", + "Query": "select table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", + "Table": "information_schema.`tables`" + }, + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select c.column_name from information_schema.`columns` as c where 1 != 1", + "Query": "select c.column_name from information_schema.`columns` as c where c.table_name = :c_table_name /* VARCHAR */", + "SysTableTableName": "[c_table_name::tables_table_name]", + "Table": "information_schema.`columns`" + } + ] + } + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json index b37804b9584..66449a2cc8c 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json @@ -1261,5 +1261,47 @@ "Table": "information_schema.apa" } } + }, + { + "comment": "LIMIT 1 inside derived table on the RHS should not be a problem", + "query": "SELECT c.column_name FROM information_schema.columns c JOIN ( SELECT table_name FROM information_schema.tables WHERE table_schema != 'information_schema' LIMIT 1 ) AS tables ON tables.table_name = c.table_name", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT c.column_name FROM information_schema.columns c JOIN ( SELECT table_name FROM information_schema.tables WHERE table_schema != 'information_schema' LIMIT 1 ) AS tables ON tables.table_name = c.table_name", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "tables_table_name": 0 + }, + "TableName": "information_schema.`tables`_information_schema.`columns`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", + "Query": "select table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", + "Table": "information_schema.`tables`" + }, + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select c.column_name from information_schema.`columns` as c where 1 != 1", + "Query": "select c.column_name from information_schema.`columns` as c where c.table_name = :c_table_name /* VARCHAR */", + "SysTableTableName": "[c_table_name::tables_table_name]", + "Table": "information_schema.`columns`" + } + ] + } + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index f26cfc4f065..f5090e40880 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -4830,5 +4830,50 @@ "user.user_extra" ] } + }, + { + "comment": "Derived tables going to a single shard still need to expand derived table columns", + "query": "SELECT c.column_name FROM user c JOIN (SELECT table_name FROM unsharded LIMIT 1) AS tables ON tables.table_name = c.table_name", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT c.column_name FROM user c JOIN (SELECT table_name FROM unsharded LIMIT 1) AS tables ON tables.table_name = c.table_name", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0", + "JoinVars": { + "tables_table_name": 0 + }, + "TableName": "unsharded_`user`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select table_name from (select table_name from unsharded where 1 != 1) as `tables` where 1 != 1", + "Query": "select table_name from (select table_name from unsharded limit 1) as `tables`", + "Table": "unsharded" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select c.column_name from `user` as c where 1 != 1", + "Query": "select c.column_name from `user` as c where c.table_name = :tables_table_name", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "main.unsharded", + "user.user" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index 6fb4e6d36ab..1ea07455486 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -332,12 +332,12 @@ { "comment": "cant switch sides for outer joins", "query": "select id from user left join (select user_id from user_extra limit 10) ue on user.id = ue.user_id", - "plan": "VT12001: unsupported: LEFT JOIN with derived tables" + "plan": "VT12001: unsupported: LEFT JOIN with LIMIT on the outer side" }, { "comment": "limit on both sides means that we can't evaluate this at all", "query": "select id from (select id from user limit 10) u join (select user_id from user_extra limit 10) ue on u.id = ue.user_id", - "plan": "VT12001: unsupported: JOIN between derived tables" + "plan": "VT12001: unsupported: JOIN between derived tables with LIMIT" }, { "comment": "multi-shard union", From eeac346cc78c19a621001d29aa223ec900501eac Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:50:34 +0530 Subject: [PATCH 008/119] [main] Upgrade the Golang version to `go1.21.4` (#14488) Signed-off-by: GitHub Signed-off-by: Harshit Gangal Co-authored-by: frouioui Co-authored-by: Harshit Gangal --- .github/workflows/assign_milestone.yml | 2 +- .github/workflows/check_make_vtadmin_authz_testgen.yml | 2 +- .github/workflows/check_make_vtadmin_web_proto.yml | 2 +- .github/workflows/cluster_endtoend_12.yml | 2 +- .github/workflows/cluster_endtoend_13.yml | 2 +- .github/workflows/cluster_endtoend_15.yml | 2 +- .github/workflows/cluster_endtoend_18.yml | 2 +- .github/workflows/cluster_endtoend_21.yml | 2 +- .github/workflows/cluster_endtoend_22.yml | 2 +- .github/workflows/cluster_endtoend_backup_pitr.yml | 2 +- .github/workflows/cluster_endtoend_backup_pitr_mysql57.yml | 2 +- .../workflows/cluster_endtoend_backup_pitr_xtrabackup.yml | 2 +- .../cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml | 2 +- .../cluster_endtoend_ers_prs_newfeatures_heavy.yml | 2 +- .github/workflows/cluster_endtoend_mysql80.yml | 2 +- .github/workflows/cluster_endtoend_mysql_server_vault.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_ghost.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_revert.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_revert_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_scheduler.yml | 2 +- .../cluster_endtoend_onlineddl_scheduler_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_vrepl.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_stress.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_stress_suite.yml | 2 +- ...luster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_suite.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_schemadiff_vrepl.yml | 2 +- .../workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_tabletmanager_consul.yml | 2 +- .../workflows/cluster_endtoend_tabletmanager_tablegc.yml | 2 +- .../cluster_endtoend_tabletmanager_tablegc_mysql57.yml | 2 +- .../cluster_endtoend_tabletmanager_throttler_topo.yml | 2 +- .../workflows/cluster_endtoend_topo_connection_cache.yml | 2 +- .../cluster_endtoend_vreplication_across_db_versions.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_basic.yml | 2 +- .../workflows/cluster_endtoend_vreplication_cellalias.yml | 2 +- ...ster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml | 2 +- .../workflows/cluster_endtoend_vreplication_multicell.yml | 2 +- ...uster_endtoend_vreplication_partial_movetables_basic.yml | 2 +- ...r_endtoend_vreplication_partial_movetables_sequences.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_v2.yml | 2 +- .github/workflows/cluster_endtoend_vstream_failover.yml | 2 +- .../cluster_endtoend_vstream_stoponreshard_false.yml | 2 +- .../cluster_endtoend_vstream_stoponreshard_true.yml | 2 +- .../cluster_endtoend_vstream_with_keyspaces_to_watch.yml | 2 +- .github/workflows/cluster_endtoend_vtbackup.yml | 2 +- ...uster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_concurrentdml.yml | 2 +- .../workflows/cluster_endtoend_vtgate_foreignkey_stress.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_gen4.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_general_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_godriver.yml | 2 +- .../workflows/cluster_endtoend_vtgate_partial_keyspace.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_queries.yml | 2 +- .../workflows/cluster_endtoend_vtgate_readafterwrite.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_reservedconn.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_schema.yml | 2 +- .../workflows/cluster_endtoend_vtgate_schema_tracker.yml | 2 +- .../cluster_endtoend_vtgate_tablet_healthcheck_cache.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_consul.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_etcd.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_transaction.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_unsharded.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vschema.yml | 2 +- .github/workflows/cluster_endtoend_vtorc.yml | 2 +- .github/workflows/cluster_endtoend_vtorc_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_vttablet_prscomplex.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery_mysql57.yml | 2 +- .github/workflows/codeql_analysis.yml | 2 +- .github/workflows/create_release.yml | 2 +- .github/workflows/docker_test_cluster_10.yml | 2 +- .github/workflows/docker_test_cluster_25.yml | 2 +- .github/workflows/e2e_race.yml | 2 +- .github/workflows/endtoend.yml | 2 +- .github/workflows/local_example.yml | 2 +- .github/workflows/region_example.yml | 2 +- .github/workflows/static_checks_etc.yml | 2 +- .github/workflows/unit_race.yml | 2 +- .github/workflows/unit_test_mysql57.yml | 2 +- .github/workflows/unit_test_mysql80.yml | 2 +- .github/workflows/update_golang_version.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_e2e_next_release.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_backups_manual_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_queries.yml | 2 +- ...de_downgrade_test_query_serving_queries_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_schema.yml | 2 +- ...ade_downgrade_test_query_serving_schema_next_release.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_new_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_new_vttablet.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_old_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_old_vttablet.yml | 2 +- Makefile | 2 +- build.env | 2 +- docker/base/Dockerfile | 2 +- docker/base/Dockerfile.mysql57 | 2 +- docker/base/Dockerfile.percona57 | 2 +- docker/base/Dockerfile.percona80 | 2 +- docker/bootstrap/CHANGELOG.md | 6 +++++- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile.mysql57 | 2 +- docker/lite/Dockerfile.mysql80 | 2 +- docker/lite/Dockerfile.percona57 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/lite/Dockerfile.testing | 2 +- docker/lite/Dockerfile.ubi7.mysql57 | 2 +- docker/lite/Dockerfile.ubi7.mysql80 | 2 +- docker/lite/Dockerfile.ubi7.percona57 | 2 +- docker/lite/Dockerfile.ubi7.percona80 | 2 +- docker/lite/Dockerfile.ubi8.arm64.mysql80 | 2 +- docker/lite/Dockerfile.ubi8.mysql80 | 2 +- docker/local/Dockerfile | 2 +- docker/vttestserver/Dockerfile.mysql57 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- test.go | 2 +- test/templates/cluster_endtoend_test.tpl | 2 +- test/templates/cluster_endtoend_test_docker.tpl | 2 +- test/templates/cluster_endtoend_test_mysql57.tpl | 2 +- test/templates/dockerfile.tpl | 2 +- test/templates/unit_test.tpl | 2 +- 130 files changed, 134 insertions(+), 130 deletions(-) diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml index 7c56f45728f..686655b9284 100644 --- a/.github/workflows/assign_milestone.yml +++ b/.github/workflows/assign_milestone.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Checkout code uses: actions/checkout@v3 diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml index 8f9199e7658..064a700d833 100644 --- a/.github/workflows/check_make_vtadmin_authz_testgen.yml +++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml @@ -50,7 +50,7 @@ jobs: uses: actions/setup-go@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml index 5f3302fc97c..7db6bceeeeb 100644 --- a/.github/workflows/check_make_vtadmin_web_proto.yml +++ b/.github/workflows/check_make_vtadmin_web_proto.yml @@ -52,7 +52,7 @@ jobs: uses: actions/setup-go@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Setup Node if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index 5ce650f1ea6..7496577ef0d 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index fa98916736f..c93f7e5526d 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index 2501f26ab58..469cfaf3080 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 234e672afb0..d76a5ada83d 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index feeedcd46b8..23d570a2b98 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_22.yml b/.github/workflows/cluster_endtoend_22.yml index f4cee992fb2..9cba996f309 100644 --- a/.github/workflows/cluster_endtoend_22.yml +++ b/.github/workflows/cluster_endtoend_22.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index b3b6e0d56f6..75e0c552d84 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml b/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml index fb9946fdb0b..d5a0f529d80 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index 6cad7922321..e1f66a29eb9 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml index b895a19a8d0..e9ae31c02c9 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index f65d2625c28..5c0e1e3a012 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index 5c3739aafd0..ea82738337d 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index 793e7372309..5d14faee1af 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml index af61a6a5059..f51032f2a34 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml index 43dc184c204..d69865221e0 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index d2c6e23ee86..42fcb0ac100 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml index ac93c1ac532..e3b4e0960dc 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index 38031f4441e..087d33bf9b6 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml index 0a205266c4f..5e21df5ac38 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index d83fb7010b8..fb1b980793e 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml index a941c9faef0..1fc42939924 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index a51cb6c33fe..38f09912b51 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml index 77626919a89..dbd670e82b5 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index 1230fcd3518..86f22cf8610 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml index 86ef8eec019..f0c8d0b7bda 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index 34e521d648f..b20cc1f901d 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml index a400ea99677..8568b13288b 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index 68a25ee46ec..b937e72ef82 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml index ba57948d162..2dae908d301 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 0fe0d4e18da..341eae60951 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index 5af0e2ff852..13c3ae789ed 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml index e1ae8eeb69c..3d6b40bd8a7 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index 8b6826f257c..cc6b02e2324 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index bb59336df48..142d2358b47 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index ec3d101629e..965c29d6bad 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index ea6219bf869..7f77747477f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index 5ef46750668..7dddf5f34d1 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml index d8961314a46..412113b055f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_multicell.yml b/.github/workflows/cluster_endtoend_vreplication_multicell.yml index 328c062e1d0..01b1c242b91 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multicell.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multicell.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml index 28dca240332..c9d8f74c5ce 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml index c002a72d1e7..501cd17ca62 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 9229b34a5bf..61fb9971f0b 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_failover.yml b/.github/workflows/cluster_endtoend_vstream_failover.yml index a620b8caad9..23c384fb5dc 100644 --- a/.github/workflows/cluster_endtoend_vstream_failover.yml +++ b/.github/workflows/cluster_endtoend_vstream_failover.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml b/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml index 5db27dad710..36e4cec2f6b 100644 --- a/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml +++ b/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml b/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml index 32e7685bf8f..fc9bea5efe8 100644 --- a/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml +++ b/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml b/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml index 27620919d99..5135354ee13 100644 --- a/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml +++ b/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 8f2dcd3768b..4b954911a5f 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index aad84a910c6..c1137849dd2 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index 19bb9efe86c..070936647e2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index e2824c5844d..ff6688e1878 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 205de4b5e68..8a12094028b 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index 98d59d60aee..a076b7b0a1a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index 2f4082d10d4..8b652338b51 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index 4a9f6e227fb..e8cbcf61a83 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index 6d41d922fc4..d908a13fe23 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index 028e1492029..6a027d039cf 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index 5972472402e..b0278160979 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index 68a2bd697be..3d99a03cace 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index 1c5d1e675f8..edbd27f3bf6 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index 26adb43fd74..2ab51d691c2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index 49945a607d8..ce316847045 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index ee72650dcbd..eac4ada3249 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index 4051373d9aa..7b108e5cbad 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index b7cc848692f..bbef397dea9 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index b6359682993..23151270d1e 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index 83fb2b2d829..ead14d0fd63 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index 4c2f3b2637d..9c6abdc0ad2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index 872576ab8b5..631bac6fda1 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml index 72baf7940b6..04248744a26 100644 --- a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml +++ b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index b56d4dc61a5..48b336a6c11 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index f24baaf31af..8a3158fadd9 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml b/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml index b85628a0dbe..e34ce3e1e8a 100644 --- a/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml +++ b/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index 3fbe34b0569..6f62db39ce8 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml b/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml index aaa2b034105..2a9fe0eba92 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index 8bafc62213a..2ec63e4fe5c 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -44,7 +44,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Get base dependencies run: | diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 52c90038680..86bd5b686a0 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Setup node uses: actions/setup-node@v3 diff --git a/.github/workflows/docker_test_cluster_10.yml b/.github/workflows/docker_test_cluster_10.yml index 3ff9a2a6e74..8b9d2e278ae 100644 --- a/.github/workflows/docker_test_cluster_10.yml +++ b/.github/workflows/docker_test_cluster_10.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/docker_test_cluster_25.yml b/.github/workflows/docker_test_cluster_25.yml index e01caf200b1..007035b6e71 100644 --- a/.github/workflows/docker_test_cluster_25.yml +++ b/.github/workflows/docker_test_cluster_25.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index 0d773d936e4..55b84fb378a 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 1c0b5f00342..57802c676a9 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 348e191abff..30ab7e3e335 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - uses: actions/setup-node@v3 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index 5d58a6bb5bf..6a87d0de54f 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - uses: actions/setup-node@v3 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 34714d00256..1854e8f052a 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -102,7 +102,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true') uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 80121299139..fe7fa7e684e 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index 5c5b9c2a206..a1bb1653775 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 0427ef18158..6c9416be543 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index a30ba27a5a7..4eddbf9841b 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index 9532995d49c..4ebca519d18 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -85,7 +85,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index cc8e3afb42a..09b5a80ce16 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -88,7 +88,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 6789dda2067..cd806eb3c4f 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 0120571a78e..5806fb83891 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index a3dc81f3723..9ddc8c44da3 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index 923c766e377..4d9db1b6776 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 14c8afaf87f..2b666e4cdb5 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index f22ece10010..d4e05e32967 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index 82d6f267856..09468aaf325 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index c5b6c964124..9e65388c10c 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index c4391efdef5..a2cf8dbce38 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index f3ffcaa2d17..1a1173ff5eb 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/Makefile b/Makefile index 625a28baac0..2b662f7aa34 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql57 mysql80 percona57 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=24 +BOOTSTRAP_VERSION=25 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 5986ee247b0..bcc6180814c 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.21.3 || echo "Go version reported: `go version`. Version 1.21.3+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.21.4 || echo "Go version reported: `go version`. Version 1.21.4+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index 75c51b4ad1b..f53b73ec372 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" diff --git a/docker/base/Dockerfile.mysql57 b/docker/base/Dockerfile.mysql57 index 586cf1d94da..b416553f5c0 100644 --- a/docker/base/Dockerfile.mysql57 +++ b/docker/base/Dockerfile.mysql57 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" diff --git a/docker/base/Dockerfile.percona57 b/docker/base/Dockerfile.percona57 index fce0412250b..971d021efaa 100644 --- a/docker/base/Dockerfile.percona57 +++ b/docker/base/Dockerfile.percona57 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" diff --git a/docker/base/Dockerfile.percona80 b/docker/base/Dockerfile.percona80 index a236035c511..2f600ad5f79 100644 --- a/docker/base/Dockerfile.percona80 +++ b/docker/base/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index e363dfc0ded..6fed662b8be 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -92,4 +92,8 @@ List of changes between bootstrap image versions. ## [24] - 2023-10-10 ### Changes -- Update build to golang 1.21.3 \ No newline at end of file +- Update build to golang 1.21.3 + +## [25] - 2023-11-08 +### Changes +- Update build to golang 1.21.4 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 39b0c16566a..69186240fbc 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.21.3-bullseye +FROM --platform=linux/amd64 golang:1.21.4-bullseye # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile.mysql57 b/docker/lite/Dockerfile.mysql57 index 8c07b1a4411..a10cdefd1a2 100644 --- a/docker/lite/Dockerfile.mysql57 +++ b/docker/lite/Dockerfile.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.mysql80 b/docker/lite/Dockerfile.mysql80 index bc4ad7861c8..98254bf3cdd 100644 --- a/docker/lite/Dockerfile.mysql80 +++ b/docker/lite/Dockerfile.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.percona57 b/docker/lite/Dockerfile.percona57 index 39d31542fe8..e4c3db5fff1 100644 --- a/docker/lite/Dockerfile.percona57 +++ b/docker/lite/Dockerfile.percona57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index e20359ea300..cb9e34d834d 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.testing b/docker/lite/Dockerfile.testing index 118db24699b..3aa24a1334b 100644 --- a/docker/lite/Dockerfile.testing +++ b/docker/lite/Dockerfile.testing @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.mysql57 b/docker/lite/Dockerfile.ubi7.mysql57 index 08ae84cfeb0..c1a20afe589 100644 --- a/docker/lite/Dockerfile.ubi7.mysql57 +++ b/docker/lite/Dockerfile.ubi7.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.mysql80 b/docker/lite/Dockerfile.ubi7.mysql80 index c11ac4a6ed4..2e1dd80cdc1 100644 --- a/docker/lite/Dockerfile.ubi7.mysql80 +++ b/docker/lite/Dockerfile.ubi7.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.percona57 b/docker/lite/Dockerfile.ubi7.percona57 index ef55a6b527a..1e3af0a686d 100644 --- a/docker/lite/Dockerfile.ubi7.percona57 +++ b/docker/lite/Dockerfile.ubi7.percona57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.percona80 b/docker/lite/Dockerfile.ubi7.percona80 index 61092685177..32f3cf8b0f4 100644 --- a/docker/lite/Dockerfile.ubi7.percona80 +++ b/docker/lite/Dockerfile.ubi7.percona80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi8.arm64.mysql80 b/docker/lite/Dockerfile.ubi8.arm64.mysql80 index 5c2e99c3b51..c4124a7f468 100644 --- a/docker/lite/Dockerfile.ubi8.arm64.mysql80 +++ b/docker/lite/Dockerfile.ubi8.arm64.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi8.mysql80 b/docker/lite/Dockerfile.ubi8.mysql80 index 094dc8fa712..38c85b8778d 100644 --- a/docker/lite/Dockerfile.ubi8.mysql80 +++ b/docker/lite/Dockerfile.ubi8.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/local/Dockerfile b/docker/local/Dockerfile index 6643799842d..24e79eb90bd 100644 --- a/docker/local/Dockerfile +++ b/docker/local/Dockerfile @@ -1,4 +1,4 @@ -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-common" FROM "${image}" diff --git a/docker/vttestserver/Dockerfile.mysql57 b/docker/vttestserver/Dockerfile.mysql57 index 195f0cd62e4..2eca5377d76 100644 --- a/docker/vttestserver/Dockerfile.mysql57 +++ b/docker/vttestserver/Dockerfile.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 2dcc190a957..5bbd7584eba 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/test.go b/test.go index c7594557161..a9528c1ddd9 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql57", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "24", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "25", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index b5c409d8f51..f1c825a0c12 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index f53c705e2c1..e42116fed69 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index f5bc482cda9..69a6028b316 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -77,7 +77,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 16ea54e724b..060dde341cd 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=24 +ARG bootstrap_version=25 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 7dffd83267b..73ce4737fcd 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -69,7 +69,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' From 5379551e3e244158bcc4e933dd9af530ab649634 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 13 Nov 2023 13:58:33 +0530 Subject: [PATCH 009/119] move over 16.0.6 and 17.0.4 release notes to main (#14508) Signed-off-by: Harshit Gangal --- changelog/16.0/16.0.6/changelog.md | 43 +++++++++++++++++++++++ changelog/16.0/16.0.6/release_notes.md | 7 ++++ changelog/16.0/README.md | 4 +++ changelog/17.0/17.0.4/changelog.md | 48 ++++++++++++++++++++++++++ changelog/17.0/17.0.4/release_notes.md | 7 ++++ changelog/17.0/README.md | 4 +++ 6 files changed, 113 insertions(+) create mode 100644 changelog/16.0/16.0.6/changelog.md create mode 100644 changelog/16.0/16.0.6/release_notes.md create mode 100644 changelog/17.0/17.0.4/changelog.md create mode 100644 changelog/17.0/17.0.4/release_notes.md diff --git a/changelog/16.0/16.0.6/changelog.md b/changelog/16.0/16.0.6/changelog.md new file mode 100644 index 00000000000..959bf2bd570 --- /dev/null +++ b/changelog/16.0/16.0.6/changelog.md @@ -0,0 +1,43 @@ +# Changelog of Vitess v16.0.6 + +### Bug fixes +#### CLI + * [release-16.0] Fix anonymous paths in cobra code-gen (#14185) [#14236](https://github.com/vitessio/vitess/pull/14236) +#### Examples + * [release-16.0] examples: fix flag syntax for zkctl (#14469) [#14485](https://github.com/vitessio/vitess/pull/14485) +#### Online DDL + * [Release 16.0]: Online DDL: timeouts for all gRPC calls (#14182) [#14191](https://github.com/vitessio/vitess/pull/14191) + * [release-16.0] schemadiff: fix missing `DROP CONSTRAINT` in duplicate/redundant constraints scenario. (#14387) [#14389](https://github.com/vitessio/vitess/pull/14389) +#### Query Serving + * [release-16.0] Rewrite `USING` to `ON` condition for joins (#13931) [#13940](https://github.com/vitessio/vitess/pull/13940) + * [release-16.0] Make column resolution closer to MySQL (#14426) [#14428](https://github.com/vitessio/vitess/pull/14428) + * [release-16.0] vtgate/engine: Fix race condition in join logic (#14435) [#14439](https://github.com/vitessio/vitess/pull/14439) + * [release-16.0] Ensure hexval and int don't share BindVar after Normalization (#14451) [#14477](https://github.com/vitessio/vitess/pull/14477) +#### Throttler + * [release-16.0] Tablet throttler: fix race condition by removing goroutine call (#14179) [#14200](https://github.com/vitessio/vitess/pull/14200) +#### VReplication + * [release-16.0] VDiff: wait for shard streams of one table diff to complete for before starting that of the next table (#14345) [#14380](https://github.com/vitessio/vitess/pull/14380) +### CI/Build +#### General + * [release-16.0] Upgrade the Golang version to `go1.20.9` [#14194](https://github.com/vitessio/vitess/pull/14194) + * [release-16.0] Upgrade the Golang version to `go1.20.10` [#14228](https://github.com/vitessio/vitess/pull/14228) +#### Online DDL + * [release-16.0] OnlineDDL: reduce vrepl_stress workload in forks (#14302) [#14347](https://github.com/vitessio/vitess/pull/14347) +### Dependabot +#### General + * [release-16.0] Bump github.com/cyphar/filepath-securejoin from 0.2.3 to 0.2.4 (#14239) [#14251](https://github.com/vitessio/vitess/pull/14251) + * [release-16.0] Bump golang.org/x/net from 0.14.0 to 0.17.0 (#14260) [#14262](https://github.com/vitessio/vitess/pull/14262) + * [release-16.0] Bump google.golang.org/grpc from 1.55.0-dev to 1.59.0 (#14364) [#14496](https://github.com/vitessio/vitess/pull/14496) +#### VTAdmin + * [release-16.0] Bump postcss from 8.4.21 to 8.4.31 in /web/vtadmin (#14173) [#14256](https://github.com/vitessio/vitess/pull/14256) + * [release-16.0] Bump @babel/traverse from 7.21.4 to 7.23.2 in /web/vtadmin (#14304) [#14306](https://github.com/vitessio/vitess/pull/14306) +### Enhancement +#### Build/CI + * [release-16.0] Automatic approval of `vitess-bot` clean backports (#14352) [#14355](https://github.com/vitessio/vitess/pull/14355) +### Release +#### General + * Code freeze of release-16.0 [#14409](https://github.com/vitessio/vitess/pull/14409) +### Testing +#### Query Serving + * [release-16.0] vtgate: Allow additional errors in warnings test (#14461) [#14463](https://github.com/vitessio/vitess/pull/14463) + diff --git a/changelog/16.0/16.0.6/release_notes.md b/changelog/16.0/16.0.6/release_notes.md new file mode 100644 index 00000000000..881ed26b348 --- /dev/null +++ b/changelog/16.0/16.0.6/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v16.0.6 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/16.0/16.0.6/changelog.md). + +The release includes 21 merged Pull Requests. + +Thanks to all our contributors: @app/github-actions, @app/vitess-bot, @harshit-gangal, @shlomi-noach + diff --git a/changelog/16.0/README.md b/changelog/16.0/README.md index d45a817ad48..2b25b22c476 100644 --- a/changelog/16.0/README.md +++ b/changelog/16.0/README.md @@ -1,5 +1,9 @@ ## v16.0 The dedicated team for this release can be found [here](team.md). +* **[16.0.6](16.0.6)** + * [Changelog](16.0.6/changelog.md) + * [Release Notes](16.0.6/release_notes.md) + * **[16.0.5](16.0.5)** * [Changelog](16.0.5/changelog.md) * [Release Notes](16.0.5/release_notes.md) diff --git a/changelog/17.0/17.0.4/changelog.md b/changelog/17.0/17.0.4/changelog.md new file mode 100644 index 00000000000..3aba7b735f9 --- /dev/null +++ b/changelog/17.0/17.0.4/changelog.md @@ -0,0 +1,48 @@ +# Changelog of Vitess v17.0.4 + +### Bug fixes +#### CLI + * [release-17.0] Fix anonymous paths in cobra code-gen (#14185) [#14237](https://github.com/vitessio/vitess/pull/14237) +#### Evalengine + * [release-17.0] evalengine: Misc bugs (#14351) [#14353](https://github.com/vitessio/vitess/pull/14353) +#### Examples + * [release-17.0] examples: fix flag syntax for zkctl (#14469) [#14486](https://github.com/vitessio/vitess/pull/14486) +#### General + * [release-17.0] viper: register dynamic config with both disk and live (#14453) [#14454](https://github.com/vitessio/vitess/pull/14454) +#### Online DDL + * [Release 17.0]: Online DDL: timeouts for all gRPC calls (#14182) [#14190](https://github.com/vitessio/vitess/pull/14190) + * [release-17.0] schemadiff: fix missing `DROP CONSTRAINT` in duplicate/redundant constraints scenario. (#14387) [#14390](https://github.com/vitessio/vitess/pull/14390) +#### Query Serving + * [release-17.0] Make column resolution closer to MySQL (#14426) [#14429](https://github.com/vitessio/vitess/pull/14429) + * [release-17.0] vtgate/engine: Fix race condition in join logic (#14435) [#14440](https://github.com/vitessio/vitess/pull/14440) + * [release-17.0] Ensure hexval and int don't share BindVar after Normalization (#14451) [#14478](https://github.com/vitessio/vitess/pull/14478) +#### Throttler + * [release-17.0] Tablet throttler: fix race condition by removing goroutine call (#14179) [#14199](https://github.com/vitessio/vitess/pull/14199) +#### VReplication + * [release-17.0] VDiff: wait for shard streams of one table diff to complete for before starting that of the next table (#14345) [#14381](https://github.com/vitessio/vitess/pull/14381) +### CI/Build +#### General + * [release-17.0] Upgrade the Golang version to `go1.20.9` [#14196](https://github.com/vitessio/vitess/pull/14196) + * [release-17.0] Upgrade the Golang version to `go1.20.10` [#14229](https://github.com/vitessio/vitess/pull/14229) +#### Online DDL + * [release-17.0] OnlineDDL: reduce vrepl_stress workload in forks (#14302) [#14348](https://github.com/vitessio/vitess/pull/14348) +### Dependabot +#### General + * [release-17.0] Bump github.com/cyphar/filepath-securejoin from 0.2.3 to 0.2.4 (#14239) [#14252](https://github.com/vitessio/vitess/pull/14252) + * [release-17.0] Bump golang.org/x/net from 0.14.0 to 0.17.0 (#14260) [#14263](https://github.com/vitessio/vitess/pull/14263) + * [release-17.0] Bump google.golang.org/grpc from 1.55.0-dev to 1.59.0 (#14364) [#14497](https://github.com/vitessio/vitess/pull/14497) +#### VTAdmin + * [release-17.0] Bump postcss from 8.4.21 to 8.4.31 in /web/vtadmin (#14173) [#14257](https://github.com/vitessio/vitess/pull/14257) + * [release-17.0] Bump @babel/traverse from 7.21.4 to 7.23.2 in /web/vtadmin (#14304) [#14307](https://github.com/vitessio/vitess/pull/14307) +### Enhancement +#### Build/CI + * [release-17.0] Automatic approval of `vitess-bot` clean backports (#14352) [#14356](https://github.com/vitessio/vitess/pull/14356) +### Release +#### General + * Code freeze of release-17.0 [#14407](https://github.com/vitessio/vitess/pull/14407) +### Testing +#### Cluster management + * Fix Upgrade downgrade reparent tests in release-17.0 [#14507](https://github.com/vitessio/vitess/pull/14507) +#### Query Serving + * [release-17.0] vtgate: Allow more errors for the warning check (#14421) [#14422](https://github.com/vitessio/vitess/pull/14422) + diff --git a/changelog/17.0/17.0.4/release_notes.md b/changelog/17.0/17.0.4/release_notes.md new file mode 100644 index 00000000000..30d3c9274e9 --- /dev/null +++ b/changelog/17.0/17.0.4/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v17.0.4 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/17.0/17.0.4/changelog.md). + +The release includes 23 merged Pull Requests. + +Thanks to all our contributors: @GuptaManan100, @app/github-actions, @app/vitess-bot, @mattlord, @shlomi-noach + diff --git a/changelog/17.0/README.md b/changelog/17.0/README.md index dcbba316bdd..655e9ac9349 100644 --- a/changelog/17.0/README.md +++ b/changelog/17.0/README.md @@ -1,4 +1,8 @@ ## v17.0 +* **[17.0.4](17.0.4)** + * [Changelog](17.0.4/changelog.md) + * [Release Notes](17.0.4/release_notes.md) + * **[17.0.3](17.0.3)** * [Changelog](17.0.3/changelog.md) * [Release Notes](17.0.3/release_notes.md) From cb45185a30d15aefa17345c1b1940d6cbb573ca5 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:09:57 +0530 Subject: [PATCH 010/119] Add `SHOW VSCHEMA KEYSPACES` query (#14505) Signed-off-by: Manan Gupta --- changelog/19.0/19.0.0/summary.md | 22 + go/test/endtoend/vtgate/foreignkey/fk_test.go | 13 + .../restarttablet/schema_restart_test.go | 2 + .../schematracker/sharded/st_sharded_test.go | 6 + go/vt/sqlparser/ast_funcs.go | 2 + go/vt/sqlparser/constants.go | 2 + go/vt/sqlparser/parse_test.go | 2 + go/vt/sqlparser/sql.go | 14716 ++++++++-------- go/vt/sqlparser/sql.y | 4 + go/vt/vtgate/planbuilder/show.go | 23 + .../planbuilder/testdata/show_cases.json | 18 + 11 files changed, 7482 insertions(+), 7328 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index 5d413c25cae..aa0d1a90227 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -6,6 +6,8 @@ - **[Deprecations and Deletions](#deprecations-and-deletions)** - **[Docker](#docker)** - [New MySQL Image](#mysql-image) + - **[Query Compatibility](#query-compatibility)** + - [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces) ## Major Changes @@ -21,3 +23,23 @@ In `v19.0` the Vitess team is shipping a new image: `vitess/mysql`. This lightweight image is a replacement of `vitess/lite` to only run `mysqld`. Several tags are available to let you choose what version of MySQL you want to use: `vitess/mysql:8.0.30`, `vitess/mysql:8.0.34`. + +### Query Compatibility + +#### `SHOW VSCHEMA KEYSPACES` Query + +A SQL query, `SHOW VSCHEMA KEYSPACES` is now supported in Vitess. This query prints the vschema information +for all the keyspaces. It is useful for seeing the foreign key mode, whether the keyspace is sharded, and if there is an +error in the VSchema for the keyspace. + +An example output of the query looks like - +```sql +mysql> show vschema keyspaces; ++---------------+---------+------------------+-------+ +| Keyspace Name | Sharded | Foreign Key Mode | Error | ++---------------+---------+------------------+-------+ +| uks | false | managed | | +| ks | true | managed | | ++---------------+---------+------------------+-------+ +2 rows in set (0.00 sec) +``` diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index ff7ddef66ff..afd04679066 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -18,6 +18,7 @@ package foreignkey import ( "context" + "fmt" "io" "testing" "time" @@ -907,6 +908,18 @@ func TestFkQueries(t *testing.T) { } } +// TestShowVschemaKeyspaces verifies the show vschema keyspaces query output for the keyspaces where the foreign keys are +func TestShowVschemaKeyspaces(t *testing.T) { + mcmp, closer := start(t) + conn := mcmp.VtConn + defer closer() + + res := utils.Exec(t, conn, "SHOW VSCHEMA KEYSPACES") + resStr := fmt.Sprintf("%v", res.Rows) + require.Contains(t, resStr, `[VARCHAR("uks") VARCHAR("false") VARCHAR("managed") VARCHAR("")]`) + require.Contains(t, resStr, `[VARCHAR("ks") VARCHAR("true") VARCHAR("managed") VARCHAR("")]`) +} + // TestFkOneCase is for testing a specific set of queries. On the CI this test won't run since we'll keep the queries empty. func TestFkOneCase(t *testing.T) { queries := []string{} diff --git a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go index b89b0916e37..3bb4f6dfd9f 100644 --- a/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go +++ b/go/test/endtoend/vtgate/schematracker/restarttablet/schema_restart_test.go @@ -129,6 +129,8 @@ func TestVSchemaTrackerInit(t *testing.T) { 100*time.Millisecond, 60*time.Second, "initial table list not complete") + + utils.AssertMatches(t, conn, "SHOW VSCHEMA KEYSPACES", `[[VARCHAR("ks") VARCHAR("false") VARCHAR("unmanaged") VARCHAR("")]]`) } // TestVSchemaTrackerKeyspaceReInit tests that the vschema tracker 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 1c9f4b0b6e2..8f8050bebe1 100644 --- a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go @@ -192,6 +192,12 @@ func TestInitAndUpdate(t *testing.T) { 30*time.Second, "initial table list not complete") + if vtgateVersion >= 19 { + utils.AssertMatches(t, conn, + "SHOW VSCHEMA KEYSPACES", + `[[VARCHAR("ks") VARCHAR("true") VARCHAR("unmanaged") VARCHAR("")]]`) + } + // Init _ = utils.Exec(t, conn, "create table test_sc (id bigint primary key)") expected = `[[VARCHAR("dual")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")] [VARCHAR("test_sc")]]` diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 6a1d5600740..4885f33ccec 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -1939,6 +1939,8 @@ func (ty ShowCommandType) ToString() string { return VitessVariablesStr case VschemaTables: return VschemaTablesStr + case VschemaKeyspaces: + return VschemaKeyspacesStr case VschemaVindexes: return VschemaVindexesStr case Warnings: diff --git a/go/vt/sqlparser/constants.go b/go/vt/sqlparser/constants.go index 3848c53f3e0..30effe51586 100644 --- a/go/vt/sqlparser/constants.go +++ b/go/vt/sqlparser/constants.go @@ -309,6 +309,7 @@ const ( VitessTargetStr = " vitess_target" VitessVariablesStr = " vitess_metadata variables" VschemaTablesStr = " vschema tables" + VschemaKeyspacesStr = " vschema keyspaces" VschemaVindexesStr = " vschema vindexes" WarningsStr = " warnings" @@ -881,6 +882,7 @@ const ( VitessTarget VitessVariables VschemaTables + VschemaKeyspaces VschemaVindexes Warnings Keyspace diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 1837a104e4c..ce5a5e14a3a 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -2369,6 +2369,8 @@ var ( input: "show vitess_targets", }, { input: "show vschema tables", + }, { + input: "show vschema keyspaces", }, { input: "show vschema vindexes", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index d837b38da7a..d4949c76839 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1505,17 +1505,17 @@ var yyExca = [...]int{ 347, 167, -2, 523, -1, 61, - 36, 774, - 241, 774, - 252, 774, - 287, 788, - 288, 788, - -2, 776, + 36, 775, + 241, 775, + 252, 775, + 287, 789, + 288, 789, + -2, 777, -1, 66, - 243, 812, - -2, 810, + 243, 813, + -2, 811, -1, 122, - 240, 1587, + 240, 1588, -2, 133, -1, 124, 1, 160, @@ -1534,18 +1534,18 @@ var yyExca = [...]int{ 164, 41, -2, 45, -1, 939, - 87, 1604, - -2, 1458, - -1, 940, 87, 1605, - 223, 1609, -2, 1459, + -1, 940, + 87, 1606, + 223, 1610, + -2, 1460, -1, 941, - 223, 1608, + 223, 1609, -2, 42, -1, 1024, - 60, 886, - -2, 901, + 60, 887, + -2, 902, -1, 1111, 251, 43, 256, 43, @@ -1554,56 +1554,56 @@ var yyExca = [...]int{ 1, 580, 732, 580, -2, 167, - -1, 1498, - 223, 1609, - -2, 1459, - -1, 1707, - 60, 887, - -2, 906, + -1, 1499, + 223, 1610, + -2, 1460, -1, 1708, 60, 888, -2, 907, - -1, 1759, + -1, 1709, + 60, 889, + -2, 908, + -1, 1760, 136, 167, 178, 167, 347, 167, -2, 458, - -1, 1840, + -1, 1841, 137, 408, 246, 408, -2, 512, - -1, 1849, + -1, 1850, 251, 44, 256, 44, -2, 420, - -1, 2287, - 223, 1613, - -2, 1607, -1, 2288, - 223, 1609, - -2, 1605, - -1, 2388, + 223, 1614, + -2, 1608, + -1, 2289, + 223, 1610, + -2, 1606, + -1, 2389, 136, 167, 178, 167, 347, 167, -2, 459, - -1, 2395, + -1, 2396, 26, 188, -2, 190, - -1, 2849, + -1, 2850, 78, 98, 88, 98, - -2, 965, - -1, 2918, + -2, 966, + -1, 2919, 707, 698, -2, 672, - -1, 3126, - 50, 1555, - -2, 1549, - -1, 3941, + -1, 3127, + 50, 1556, + -2, 1550, + -1, 3942, 707, 698, -2, 686, - -1, 4028, + -1, 4029, 90, 630, 95, 630, 105, 630, @@ -1649,383 +1649,383 @@ var yyExca = [...]int{ 219, 630, 220, 630, 221, 630, - -2, 1976, + -2, 1977, } const yyPrivate = 57344 -const yyLast = 54976 +const yyLast = 55495 var yyAct = [...]int{ - 955, 3603, 3604, 87, 3602, 4026, 4103, 3922, 943, 3278, - 4116, 4007, 4070, 1263, 950, 3554, 942, 2081, 4071, 2385, - 1968, 3995, 3906, 3831, 2316, 3178, 3407, 3185, 3227, 2093, - 3236, 3241, 3238, 3237, 3235, 3240, 1762, 1261, 3139, 2024, - 3904, 3239, 5, 3541, 2745, 2318, 3256, 3079, 2459, 737, - 3193, 3255, 3143, 3140, 3452, 3446, 3641, 2982, 2340, 3127, - 2809, 731, 3438, 764, 904, 2356, 903, 2422, 908, 3972, - 3258, 42, 1818, 732, 2883, 3285, 2964, 2915, 2447, 1722, - 3472, 2427, 2885, 2884, 2359, 2373, 1022, 1073, 87, 2490, - 2360, 1041, 163, 1143, 1019, 2834, 1865, 2815, 2361, 41, - 3137, 2271, 2785, 1709, 2801, 2239, 43, 1022, 2283, 2238, - 2077, 2116, 2468, 2956, 2446, 2032, 149, 2348, 2429, 1847, - 1106, 1101, 1083, 2507, 2876, 1751, 2851, 1731, 2363, 1119, - 100, 2822, 1688, 1510, 104, 2120, 2336, 105, 2052, 1437, - 1422, 1964, 1854, 747, 3142, 1077, 1080, 2444, 1109, 1112, - 1946, 1081, 2418, 2419, 1021, 1107, 1025, 1108, 1750, 1058, - 1736, 1060, 2189, 735, 3636, 2128, 1031, 2147, 1040, 742, - 3894, 2783, 2341, 107, 1470, 1043, 1028, 2023, 1252, 85, - 1976, 1813, 167, 127, 125, 126, 99, 1026, 1192, 905, - 1494, 1017, 1839, 132, 1027, 133, 1053, 741, 1029, 734, - 98, 4104, 1259, 3542, 1238, 2284, 106, 1514, 2461, 2462, - 2463, 84, 1519, 93, 3224, 3957, 2461, 724, 2938, 2937, - 2505, 2906, 3534, 1048, 1052, 4053, 1016, 2972, 2973, 3953, - 1034, 3952, 2313, 2314, 669, 128, 2039, 3497, 2038, 2037, - 1074, 3958, 2036, 2035, 2034, 1145, 134, 1148, 2007, 1208, - 666, 1684, 667, 4047, 2553, 2781, 3123, 4074, 1162, 1163, - 1164, 1931, 1167, 1168, 1169, 1170, 1123, 3083, 1173, 1174, + 955, 3604, 3605, 87, 3603, 4027, 4104, 3923, 943, 3279, + 4117, 4008, 4071, 1264, 950, 3555, 942, 2082, 4072, 2386, + 1969, 3996, 3907, 3832, 2317, 3179, 3408, 3186, 3228, 2094, + 3237, 3242, 3239, 3238, 3236, 3241, 1763, 1262, 3140, 2025, + 3905, 3240, 5, 3542, 2746, 2319, 3257, 3080, 2460, 737, + 3194, 3256, 3144, 3141, 3453, 3447, 3642, 2983, 2341, 3128, + 2810, 731, 3439, 764, 904, 2357, 903, 2423, 908, 3973, + 3259, 42, 1819, 732, 2884, 3286, 2965, 2916, 2448, 1723, + 3473, 2428, 2886, 2885, 2360, 2374, 1022, 1073, 87, 2491, + 2361, 1041, 163, 1143, 1019, 2835, 1866, 2816, 2362, 41, + 3138, 2272, 2786, 1710, 2802, 2240, 43, 1022, 2284, 2239, + 2078, 2117, 2469, 2957, 2447, 2033, 149, 2349, 2430, 1848, + 1106, 1101, 1083, 2508, 2877, 1752, 2852, 1732, 2364, 1119, + 100, 2823, 1689, 1511, 104, 2121, 2337, 105, 2053, 1438, + 1423, 1965, 1855, 747, 3143, 1077, 1080, 2445, 1109, 1112, + 1947, 1081, 2419, 2420, 1021, 1107, 1025, 1108, 1751, 1058, + 1737, 1060, 2190, 735, 3637, 2129, 1031, 2148, 1040, 742, + 3895, 2784, 2342, 107, 1471, 1043, 1028, 2024, 1252, 85, + 1977, 1814, 167, 127, 125, 126, 99, 1026, 1192, 905, + 1495, 1017, 1840, 132, 1027, 133, 1053, 741, 1029, 734, + 98, 4105, 1260, 3543, 84, 1238, 106, 1515, 2462, 2463, + 2464, 3958, 1520, 93, 3225, 2285, 2462, 2939, 2938, 2506, + 2907, 3535, 1016, 1048, 1052, 4054, 2973, 2974, 3954, 2040, + 1034, 3953, 2314, 2315, 669, 128, 3608, 3959, 724, 2039, + 1074, 3498, 2038, 2037, 2036, 1145, 134, 1148, 2035, 2008, + 1208, 1685, 666, 2554, 667, 2782, 4048, 1434, 1162, 1163, + 1164, 1932, 1167, 1168, 1169, 1170, 1123, 3124, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1122, 1067, 1035, 1156, 1068, - 725, 1018, 2811, 95, 1209, 3607, 2, 1020, 1090, 1085, - 709, 1098, 3931, 2908, 1149, 1152, 1153, 128, 1097, 1096, - 1095, 95, 3246, 4126, 1433, 4069, 4094, 1454, 2494, 4109, - 1042, 4057, 4055, 3412, 3411, 709, 727, 2931, 3907, 2928, - 2055, 2746, 3953, 2044, 95, 3607, 3304, 909, 3827, 3246, - 1165, 111, 112, 113, 4108, 116, 4056, 4054, 122, 190, - 1015, 191, 3243, 3826, 661, 703, 1066, 1070, 907, 1066, - 1070, 907, 2493, 1147, 1146, 4084, 722, 723, 3244, 190, - 703, 3547, 3837, 129, 3548, 128, 1010, 1011, 1012, 1013, - 4051, 95, 3606, 1024, 3566, 3555, 172, 959, 960, 961, - 3996, 4004, 1716, 129, 3250, 3244, 2487, 1099, 1424, 3836, - 2086, 703, 4031, 3324, 703, 1828, 172, 3175, 3176, 86, - 2782, 1055, 1056, 700, 959, 960, 961, 86, 3174, 2945, - 2946, 3250, 3606, 1245, 2860, 1247, 2971, 2859, 86, 2865, - 2861, 2559, 2562, 2825, 2380, 2381, 1752, 4008, 1753, 4036, - 2379, 2955, 169, 2016, 2017, 170, 1256, 1228, 2492, 1094, - 1008, 1201, 1202, 1451, 1007, 1452, 1453, 4034, 2826, 3923, - 1972, 685, 169, 1244, 1246, 170, 4040, 4041, 189, 1229, - 2872, 1222, 3282, 1216, 683, 3195, 3196, 3654, 1217, 2398, - 2397, 3936, 4035, 1204, 1233, 1234, 3565, 95, 189, 86, - 1191, 3017, 88, 703, 2438, 95, 703, 2560, 3280, 2818, - 2819, 703, 3312, 2315, 3310, 1216, 95, 1092, 3247, 4075, - 1217, 2551, 2015, 4012, 680, 717, 2019, 2432, 1215, 721, - 1214, 1748, 1692, 695, 715, 1471, 3286, 2957, 1434, 2983, - 4076, 3878, 703, 3879, 2916, 3247, 2344, 2469, 690, 2941, - 4012, 2508, 4106, 1921, 2344, 1947, 1249, 3301, 693, 1472, - 1473, 1474, 1475, 1476, 1477, 1478, 1480, 1479, 1481, 1482, - 1423, 1255, 3273, 1230, 3283, 1223, 704, 95, 1254, 1242, - 3274, 1231, 1232, 1243, 1166, 2512, 2554, 2555, 2557, 2556, - 1237, 704, 173, 1248, 3194, 1059, 1197, 1922, 1235, 1923, - 3281, 179, 2959, 2514, 3536, 3535, 3197, 1973, 1236, 2529, - 2532, 2530, 173, 2531, 1172, 1171, 2510, 1121, 1241, 3811, - 2472, 179, 704, 2985, 1832, 704, 670, 2511, 672, 686, - 3611, 706, 2357, 705, 676, 3449, 674, 678, 687, 679, - 2513, 673, 1103, 684, 3532, 1093, 675, 688, 689, 692, - 696, 697, 698, 694, 691, 1141, 682, 707, 2515, 4048, - 1102, 1140, 1139, 1138, 1103, 1137, 3018, 2521, 2517, 2519, - 2520, 2518, 2522, 2523, 1136, 1135, 2431, 1134, 1129, 1142, - 1695, 3197, 4081, 4127, 1485, 3082, 1069, 1063, 1061, 1069, - 1063, 1061, 1078, 2995, 2994, 2993, 1078, 1115, 2987, 1078, - 2991, 1151, 2986, 1076, 2984, 1114, 1965, 1114, 2445, 2989, - 1260, 1150, 1260, 1260, 704, 2909, 1054, 704, 2988, 2960, - 1120, 2498, 704, 2497, 3217, 164, 1114, 1117, 1118, 1961, - 1078, 1425, 1159, 2940, 1111, 1115, 2990, 2992, 2342, 2343, - 1826, 1825, 1824, 2926, 1962, 164, 2342, 2343, 1822, 1207, - 660, 2954, 4049, 704, 2953, 1110, 3919, 1749, 3486, 3531, - 1022, 1495, 1500, 1501, 3468, 1504, 1506, 1507, 1508, 1509, - 2976, 1512, 1513, 1515, 1515, 2943, 1515, 1515, 1520, 1520, - 1520, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, - 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, - 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, - 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, - 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, - 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, - 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, - 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, - 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, - 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, - 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, - 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, - 1642, 1643, 1644, 1492, 1250, 3930, 2907, 1645, 1415, 1647, - 1648, 1649, 1650, 1651, 1416, 1417, 956, 1488, 1489, 1490, - 1491, 1520, 1520, 1520, 1520, 1520, 1520, 1502, 3495, 3496, - 708, 2491, 2930, 3450, 956, 1100, 1658, 1659, 1660, 1661, - 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, - 1496, 701, 1933, 1932, 1934, 1935, 1936, 956, 1438, 89, - 2874, 1062, 165, 3605, 1062, 1505, 702, 1685, 4010, 177, - 1203, 1200, 3302, 4039, 1213, 1212, 2929, 1218, 1219, 1220, - 1221, 1516, 165, 1517, 1518, 1432, 3248, 3249, 94, 177, - 1438, 1521, 1522, 3395, 1195, 4010, 94, 2561, 3564, 3252, - 4009, 1257, 1258, 3605, 2435, 1132, 1853, 94, 1130, 2560, - 185, 2910, 2963, 3248, 3249, 1715, 1485, 4038, 1121, 1226, - 1691, 2786, 2788, 2856, 2489, 2821, 3252, 4009, 2758, 1022, - 185, 2089, 1951, 1022, 1682, 1486, 1487, 1089, 1740, 1022, - 1091, 1646, 1206, 3091, 2436, 3090, 2816, 1121, 1482, 668, - 124, 2434, 2386, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 1485, 1683, 1448, 3173, 94, 184, + 1020, 1018, 2812, 1717, 1209, 3608, 2, 4075, 1090, 1085, + 2495, 1098, 3084, 3932, 1149, 1152, 1153, 128, 1097, 1096, + 1095, 725, 3247, 2909, 1455, 4127, 4070, 4095, 3413, 3412, + 1042, 709, 4110, 3607, 2932, 709, 727, 3908, 4058, 1066, + 1070, 907, 3954, 4056, 95, 2747, 95, 909, 95, 3247, + 1165, 111, 112, 113, 2494, 116, 1015, 4109, 122, 190, + 2045, 191, 3244, 4057, 661, 703, 3305, 2056, 4055, 1066, + 1070, 907, 3828, 3827, 1147, 1146, 722, 723, 3245, 190, + 703, 4085, 3838, 129, 703, 128, 1010, 1011, 1012, 1013, + 4052, 95, 3607, 1024, 3567, 2929, 172, 959, 960, 961, + 1425, 3556, 3997, 129, 3251, 3245, 3548, 1099, 4005, 3549, + 2488, 3837, 2087, 4032, 703, 3325, 172, 2563, 1829, 3176, + 3177, 1055, 1056, 700, 959, 960, 961, 2783, 86, 3566, + 1094, 3251, 1201, 1202, 3175, 2493, 2381, 2382, 86, 2866, + 1089, 2972, 86, 1091, 1753, 2861, 1754, 4009, 2860, 4037, + 2560, 2862, 169, 2017, 2018, 170, 2380, 2956, 1228, 1257, + 1452, 1008, 1453, 1454, 1204, 1007, 2826, 4035, 1233, 1234, + 3924, 685, 169, 1229, 1216, 170, 4041, 4042, 189, 1217, + 1973, 1435, 2561, 1222, 683, 3196, 3197, 3655, 1092, 1216, + 2873, 2827, 4036, 3018, 1217, 2399, 2398, 703, 189, 3313, + 1191, 3311, 1215, 2439, 1214, 3283, 95, 3281, 2819, 2820, + 703, 703, 2552, 2316, 717, 703, 95, 2016, 3248, 2020, + 95, 721, 1749, 4013, 680, 715, 2433, 2942, 3287, 2958, + 1693, 2470, 3937, 695, 2917, 1953, 86, 1922, 3274, 88, + 2345, 4107, 1094, 2509, 1086, 3248, 3275, 3879, 690, 3880, + 4013, 1088, 1087, 2515, 2345, 1948, 2513, 1166, 693, 4076, + 1249, 1254, 1424, 1231, 1232, 1059, 1237, 1230, 1256, 1245, + 1197, 1247, 1235, 2960, 1255, 2511, 704, 1223, 3537, 3536, + 4077, 1923, 1236, 1924, 2533, 2555, 2556, 2558, 2557, 1172, + 1171, 704, 173, 1132, 3195, 704, 3812, 3284, 2512, 3282, + 1092, 179, 3533, 2530, 1696, 2531, 3198, 2532, 2516, 1244, + 1246, 2514, 173, 2473, 95, 1130, 1093, 1974, 1102, 3612, + 2358, 179, 1103, 1103, 1833, 704, 670, 4082, 672, 686, + 1141, 706, 1140, 705, 676, 1139, 674, 678, 687, 679, + 1138, 673, 1137, 684, 1136, 1135, 675, 688, 689, 692, + 696, 697, 698, 694, 691, 1142, 682, 707, 3019, 1069, + 1063, 1061, 4049, 2946, 2947, 1134, 1129, 3198, 4128, 1078, + 1114, 1472, 1486, 1486, 1115, 2432, 1151, 1078, 1078, 1966, + 2910, 1076, 1114, 2446, 1054, 2961, 1150, 3450, 3218, 1069, + 1063, 1061, 2499, 3302, 2498, 1473, 1474, 1475, 1476, 1477, + 1478, 1479, 1481, 1480, 1482, 1483, 1962, 1426, 704, 2941, + 1261, 1159, 1261, 1261, 1827, 1242, 1826, 3532, 1825, 1243, + 3083, 704, 704, 2927, 1963, 164, 704, 1823, 1093, 1248, + 1207, 660, 2343, 2344, 4050, 2522, 2518, 2520, 2521, 2519, + 2523, 2524, 1133, 1487, 1488, 164, 2343, 2344, 1750, 3920, + 1956, 3487, 1954, 1955, 1241, 1957, 1958, 3469, 2977, 2575, + 1022, 1496, 1501, 1502, 1131, 1505, 1507, 1508, 1509, 1510, + 2857, 1513, 1514, 1516, 1516, 2822, 1516, 1516, 1521, 1521, + 1521, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, + 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, + 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, + 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, + 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, + 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, + 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, + 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, + 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, + 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, + 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, + 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, + 1643, 1644, 1645, 1493, 3606, 1250, 3931, 1646, 2492, 1648, + 1649, 1650, 1651, 1652, 1417, 1418, 2908, 1489, 1490, 1491, + 1492, 1521, 1521, 1521, 1521, 1521, 1521, 1503, 1433, 1416, + 708, 3565, 3496, 3497, 1062, 1100, 1659, 1660, 1661, 1662, + 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, + 1497, 701, 1934, 1933, 1935, 1936, 1937, 956, 1439, 956, + 2875, 956, 165, 3606, 1062, 1506, 702, 1686, 4011, 177, + 1203, 1200, 2562, 4040, 1213, 1212, 2911, 1218, 1219, 1220, + 1221, 1517, 165, 1518, 1519, 3451, 3249, 3250, 2931, 177, + 3396, 1522, 1523, 1121, 2759, 4011, 89, 94, 1195, 3253, + 4010, 1258, 1259, 2436, 1158, 2561, 1854, 94, 1226, 2944, + 185, 94, 2964, 3249, 3250, 1716, 1121, 4039, 2787, 2789, + 1692, 2955, 2490, 2090, 2954, 1741, 3253, 4010, 1647, 1022, + 185, 1206, 2930, 1022, 1683, 3092, 1439, 3091, 1952, 1022, + 124, 2817, 668, 2437, 1121, 2387, 1486, 1483, 2586, 3174, + 2435, 1121, 1239, 166, 171, 168, 174, 175, 176, 178, + 180, 181, 182, 183, 4121, 1684, 1449, 1466, 1978, 184, 186, 187, 188, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 1716, 2437, 2585, 1465, 1037, 184, - 186, 187, 188, 1253, 1952, 2433, 3944, 1699, 1448, 119, - 1144, 1703, 2574, 4120, 1239, 1977, 3527, 1021, 1121, 1477, - 1478, 1480, 1479, 1481, 1482, 1852, 1211, 3462, 2509, 2028, - 1958, 1120, 3003, 1701, 1754, 2121, 1702, 104, 2129, 2121, - 105, 2594, 1683, 1652, 1653, 1654, 1655, 1656, 1657, 1094, - 2899, 1086, 2130, 1454, 1158, 4085, 1689, 3650, 1088, 1087, - 1120, 1094, 1190, 2057, 1133, 1124, 1114, 1131, 1676, 1453, - 1126, 1452, 1453, 2585, 1127, 1125, 107, 2058, 1483, 1484, - 2056, 3502, 120, 3501, 1444, 2966, 2476, 1436, 2966, 1862, - 2965, 1454, 1948, 2965, 1949, 1128, 2113, 1950, 1861, 1851, - 2787, 2486, 2484, 1132, 1130, 1454, 1697, 1092, 2566, 2567, - 2568, 4077, 1829, 1830, 1831, 3487, 1444, 1845, 1033, 3974, - 3912, 1120, 4122, 3561, 3319, 3562, 1194, 1114, 1117, 1118, - 2488, 1078, 1700, 1718, 1225, 1111, 1115, 4090, 1716, 2481, - 1970, 1916, 1838, 1454, 1686, 1227, 1867, 1018, 1868, 1721, - 1870, 1872, 1698, 1196, 1876, 1878, 1880, 1882, 1884, 1857, - 1020, 1898, 1240, 1978, 3975, 3913, 1121, 1855, 1855, 1260, - 1210, 3819, 1745, 1746, 1454, 1121, 2481, 3818, 2485, 1906, - 1907, 1856, 1941, 2127, 709, 1912, 1913, 3809, 3577, 1451, - 1716, 1452, 1453, 1821, 2105, 2094, 2095, 2096, 2097, 2107, - 2098, 2099, 2100, 2112, 2108, 2101, 2102, 2109, 2110, 2111, - 2103, 2104, 2106, 1848, 3576, 2483, 1716, 1835, 1836, 1955, - 1834, 1953, 1954, 2126, 1956, 1957, 3509, 1451, 1716, 1452, - 1453, 1193, 1859, 1939, 4118, 1093, 3005, 4119, 1454, 4117, - 1704, 1451, 1928, 1452, 1453, 2276, 1940, 1093, 86, 44, - 45, 88, 1902, 1454, 4128, 2046, 2048, 2049, 3840, 1894, - 2621, 3508, 1897, 3498, 1899, 1966, 1748, 3225, 92, 1120, - 3213, 1157, 48, 76, 77, 1154, 74, 78, 1120, 1451, - 2047, 1452, 1453, 1124, 1114, 75, 3277, 2881, 1126, 959, - 960, 961, 1127, 1125, 2880, 1454, 2879, 1938, 2441, 128, - 1097, 1096, 1095, 1454, 1942, 1926, 1927, 1827, 1925, 1924, - 1451, 1914, 1452, 1453, 62, 1473, 1474, 1475, 1476, 1477, - 1478, 1480, 1479, 1481, 1482, 1983, 95, 1475, 1476, 1477, - 1478, 1480, 1479, 1481, 1482, 1260, 1260, 4088, 1716, 1979, - 1980, 4129, 1908, 1905, 1904, 1419, 1903, 1874, 2005, 87, - 1696, 4078, 87, 1984, 3939, 1454, 3492, 709, 2863, 709, - 1991, 1992, 1993, 1458, 1459, 1460, 1461, 1462, 1463, 1464, - 1456, 2004, 83, 1471, 1451, 2975, 1452, 1453, 1443, 1440, - 1441, 1442, 1447, 1449, 1446, 3938, 1445, 4018, 1716, 1451, - 3916, 1452, 1453, 2457, 2456, 3915, 1439, 1472, 1473, 1474, - 1475, 1476, 1477, 1478, 1480, 1479, 1481, 1482, 2455, 2454, - 1443, 1440, 1441, 1442, 1447, 1449, 1446, 42, 1445, 3914, - 42, 2084, 2084, 2082, 2082, 2085, 3814, 1454, 1439, 3798, - 1471, 1451, 3797, 1452, 1453, 2453, 2452, 1981, 2591, 1451, - 4079, 1452, 1453, 1454, 1985, 3649, 1987, 1988, 1989, 1990, - 3647, 2050, 2633, 1994, 1472, 1473, 1474, 1475, 1476, 1477, - 1478, 1480, 1479, 1481, 1482, 2006, 51, 54, 57, 56, - 59, 3573, 73, 2807, 4105, 82, 79, 1472, 1473, 1474, - 1475, 1476, 1477, 1478, 1480, 1479, 1481, 1482, 1725, 1454, - 1471, 1451, 2167, 1452, 1453, 1682, 110, 4065, 1716, 61, - 91, 90, 3181, 1681, 71, 72, 58, 109, 1680, 108, - 1679, 2590, 80, 81, 1472, 1473, 1474, 1475, 1476, 1477, - 1478, 1480, 1479, 1481, 1482, 85, 1683, 3481, 85, 2029, - 2054, 1454, 2631, 2156, 1726, 1450, 1716, 2012, 2013, 2807, - 4003, 1716, 1450, 1716, 3932, 2807, 3982, 3182, 2276, 2807, - 3978, 3845, 2273, 2061, 63, 64, 110, 65, 66, 67, - 68, 2275, 2059, 1451, 3506, 1452, 1453, 109, 3491, 108, - 3287, 3184, 101, 4016, 1716, 954, 3284, 1716, 103, 1451, - 2287, 1452, 1453, 102, 3965, 1716, 3844, 2286, 2060, 3179, - 2062, 2063, 2064, 2065, 2066, 2067, 2069, 2071, 2072, 2073, - 2074, 2075, 2076, 3216, 2285, 1496, 2088, 3195, 3196, 3215, - 2131, 2132, 2133, 2134, 3180, 4014, 1716, 103, 60, 2890, - 2274, 2877, 2122, 2272, 2145, 1451, 1678, 1452, 1453, 2166, - 2542, 2148, 2541, 2115, 2117, 2503, 2150, 1716, 1716, 3802, - 2155, 2151, 3545, 3929, 2152, 2153, 2154, 2502, 3186, 2149, - 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 1471, - 1454, 2573, 3822, 1716, 101, 2339, 2365, 1451, 2321, 1452, - 1453, 103, 2181, 1454, 2287, 102, 1716, 2290, 2291, 2807, - 3810, 2354, 2008, 1472, 1473, 1474, 1475, 1476, 1477, 1478, - 1480, 1479, 1481, 1482, 104, 3545, 1716, 105, 2285, 2807, - 3543, 3801, 2395, 1454, 2481, 1716, 3466, 1716, 89, 1454, - 2713, 1716, 3206, 3205, 2823, 104, 3194, 1974, 105, 3203, - 3204, 3553, 2179, 1454, 2053, 3201, 3202, 2917, 3197, 1937, - 1716, 2895, 2190, 2332, 2367, 1454, 3201, 3200, 1083, 1454, - 2831, 1716, 2560, 2939, 3891, 1716, 2394, 2349, 2350, 1454, - 1817, 2920, 2404, 2405, 2406, 2407, 1929, 3889, 1716, 3461, - 2399, 1454, 2400, 2401, 2402, 2403, 2913, 2914, 2390, 1034, - 1454, 1083, 2389, 2289, 2320, 1919, 2292, 2293, 2410, 2411, - 2412, 2413, 2371, 1454, 2807, 2806, 2831, 3886, 1716, 2326, - 2308, 2327, 1915, 3868, 1716, 2482, 1451, 1911, 1452, 1453, - 2424, 2393, 2263, 2264, 2265, 2266, 2267, 2334, 1910, 1451, - 1909, 1452, 1453, 2470, 1727, 2430, 1251, 94, 2352, 3437, - 1716, 2587, 1716, 3430, 1716, 2087, 1716, 2376, 2377, 2375, - 2823, 1454, 2331, 3427, 1716, 109, 2392, 1067, 2391, 1451, - 1068, 1452, 1453, 1454, 3183, 1451, 3927, 1452, 1453, 1729, - 1817, 1816, 2467, 2481, 3425, 1716, 2440, 2310, 1454, 1451, - 1450, 1452, 1453, 2190, 1454, 3463, 2852, 3387, 1716, 3970, - 1454, 1451, 2852, 1452, 1453, 1451, 1454, 1452, 1453, 2425, - 2414, 2416, 2417, 2421, 3943, 1451, 2803, 1452, 1453, 2439, - 2807, 2475, 2443, 1123, 2478, 2451, 2479, 1451, 2581, 1452, - 1453, 103, 3461, 1855, 1450, 2495, 1451, 2831, 1452, 1453, - 1760, 1759, 1122, 3138, 2425, 1728, 2477, 2474, 2473, 1451, - 3168, 1452, 1453, 70, 3461, 3510, 3416, 3385, 1716, 2853, - 2560, 2496, 2830, 2499, 3203, 2853, 190, 2500, 2501, 2855, - 3111, 1454, 3381, 1716, 2378, 2560, 2587, 2911, 3378, 1716, - 2713, 2618, 1717, 1719, 3376, 1716, 2617, 2481, 2464, 2587, - 129, 1454, 151, 2347, 1720, 2565, 1454, 1451, 2311, 1452, - 1453, 2087, 2030, 172, 2014, 1960, 3511, 3512, 3513, 1451, - 2506, 1452, 1453, 1747, 3228, 1105, 1104, 2831, 1454, 1506, - 95, 1506, 4044, 3985, 1451, 3833, 1452, 1453, 1023, 1723, - 1451, 3799, 1452, 1453, 162, 1454, 1451, 2577, 1452, 1453, - 150, 3661, 1451, 1454, 1452, 1453, 3526, 3523, 3504, 3329, - 3328, 1819, 2423, 2287, 2535, 3374, 1716, 3275, 1454, 169, - 2286, 3230, 170, 3226, 1454, 2921, 2420, 1471, 2415, 2409, - 1467, 2408, 1468, 1944, 3514, 3372, 1716, 2580, 1454, 2887, - 3432, 1841, 1842, 161, 160, 189, 1469, 1483, 1484, 1466, - 1850, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1480, 1479, - 1481, 1482, 3370, 1716, 1846, 2550, 95, 1451, 1815, 1452, - 1453, 121, 1195, 2886, 3187, 1890, 3279, 1454, 3191, 3428, - 2558, 3515, 3516, 3517, 3834, 3190, 1454, 1451, 3806, 1452, - 1453, 2438, 1451, 2324, 1452, 1453, 2010, 1454, 3473, 3474, - 4100, 1454, 3368, 1716, 4098, 2569, 1454, 4072, 3366, 1716, - 2054, 3479, 2629, 3951, 1451, 1454, 1452, 1453, 3873, 3192, - 1454, 2887, 3364, 1716, 3188, 1454, 1891, 1892, 1893, 3189, - 3476, 1451, 2571, 1452, 1453, 1454, 3222, 3221, 3220, 1451, - 3138, 1452, 1453, 2900, 2536, 1454, 155, 1843, 158, 665, - 1840, 2583, 156, 157, 1451, 3478, 1452, 1453, 2011, 173, - 1451, 2582, 1452, 1453, 3631, 2593, 3630, 2570, 179, 2572, - 3362, 1716, 3157, 3156, 1451, 3947, 1452, 1453, 2575, 1724, - 2576, 3360, 1716, 3835, 2544, 2545, 1716, 2578, 2330, 2547, - 3358, 1716, 3160, 1454, 3467, 2338, 2757, 3161, 2548, 3356, - 1716, 1454, 3158, 3116, 3354, 1716, 3115, 3159, 3911, 3352, - 1716, 3640, 3642, 1451, 3629, 1452, 1453, 1454, 2627, 3350, - 1716, 3457, 1451, 726, 1452, 1453, 1454, 3125, 2789, 3348, - 1716, 1959, 1006, 1451, 3199, 1452, 1453, 1451, 1454, 1452, - 1453, 2870, 1451, 1454, 1452, 1453, 1022, 2084, 1454, 2082, - 2792, 1451, 3454, 1452, 1453, 2891, 1451, 1038, 1452, 1453, - 3453, 1451, 1161, 1452, 1453, 1039, 1160, 2828, 2829, 3295, - 2886, 1451, 1886, 1452, 1453, 2790, 2365, 3334, 1716, 1022, - 2848, 1451, 101, 1452, 1453, 3317, 1716, 2969, 1418, 2129, - 2600, 3459, 164, 102, 2793, 3162, 2795, 2840, 2841, 103, - 2927, 2778, 1716, 2130, 2053, 129, 2827, 2615, 2808, 4114, - 2776, 1716, 3218, 1454, 2539, 3128, 3130, 1454, 4023, 1887, - 1888, 1889, 2751, 1716, 3131, 3928, 1454, 2728, 1716, 1451, - 3829, 1452, 1453, 3528, 101, 42, 3198, 1451, 2844, 1452, - 1453, 103, 1454, 2335, 2845, 102, 2804, 2847, 2528, 1454, - 1689, 2817, 2527, 1451, 2780, 1452, 1453, 2349, 2350, 1454, - 2846, 2526, 1451, 3114, 1452, 1453, 1046, 1047, 2525, 2873, - 2875, 3113, 2800, 2524, 1451, 1683, 1452, 1453, 3899, 1451, - 3439, 1452, 1453, 1454, 1451, 2820, 1452, 1453, 159, 2805, - 2564, 2866, 108, 2925, 3898, 110, 2850, 2720, 1716, 3637, - 3876, 2711, 1716, 3648, 3646, 1454, 109, 109, 108, 2854, - 2709, 1716, 3645, 3638, 2857, 3524, 3458, 2430, 3456, 2864, - 1454, 2867, 3231, 2465, 1454, 1833, 2696, 1716, 1045, 2936, - 1454, 2124, 3447, 2694, 1716, 2889, 2125, 110, 2823, 3615, - 2892, 2893, 1454, 3393, 2878, 4102, 4101, 1454, 109, 1451, - 108, 1452, 1453, 1451, 1454, 1452, 1453, 2888, 4101, 103, - 110, 2803, 1451, 3019, 1452, 1453, 2619, 2692, 1716, 1454, - 2896, 109, 2185, 2901, 2902, 2903, 2322, 2897, 1451, 1741, - 1452, 1453, 1733, 4102, 2933, 1451, 3917, 1452, 1453, 2690, - 1716, 1838, 114, 115, 3490, 1451, 152, 1452, 1453, 153, - 1036, 3, 97, 1, 2688, 1716, 2922, 2923, 2686, 1716, - 2027, 1454, 2912, 10, 3389, 2979, 2980, 1454, 2932, 1451, - 2025, 1452, 1453, 9, 1014, 1421, 2684, 1716, 1454, 165, - 1420, 2682, 1716, 1454, 2026, 3494, 177, 8, 2680, 1716, - 4033, 1451, 681, 1452, 1453, 2312, 1687, 1454, 4073, 4029, - 2996, 2958, 2269, 2678, 1716, 1454, 1451, 2977, 1452, 1453, - 1451, 2961, 1452, 1453, 4030, 1930, 1451, 1920, 1452, 1453, - 3556, 2237, 3830, 3234, 2471, 3522, 2428, 185, 1451, 1113, - 1452, 1453, 2302, 1451, 154, 1452, 1453, 2387, 2388, 1454, - 1451, 3998, 1452, 1453, 1454, 2676, 1716, 2934, 118, 1717, - 2309, 2674, 1716, 1071, 2997, 1451, 117, 1452, 1453, 3000, - 1116, 1224, 2672, 1716, 2466, 3546, 2871, 2670, 1716, 2396, - 166, 171, 168, 174, 175, 176, 178, 180, 181, 182, - 183, 2668, 1716, 1766, 2333, 1454, 184, 186, 187, 188, - 2882, 1764, 1765, 1763, 1768, 1767, 3303, 1451, 2978, 1452, - 1453, 2620, 3021, 1451, 3394, 1452, 1453, 3077, 2967, 2018, - 716, 2968, 2843, 710, 1451, 192, 1452, 1453, 1755, 1451, - 1454, 1452, 1453, 2666, 1716, 1734, 3408, 1155, 2664, 1716, - 671, 3207, 2504, 1451, 677, 1452, 1453, 2981, 1503, 2009, - 3112, 1451, 2858, 1452, 1453, 2998, 1065, 1057, 2323, 2794, - 1064, 3807, 3146, 3084, 3451, 3124, 3095, 3126, 3086, 2810, - 3129, 3122, 3910, 3639, 2365, 3983, 1454, 3012, 2868, 2662, - 1716, 2274, 1730, 2274, 2272, 1451, 2272, 1452, 1453, 3057, - 1451, 3415, 1452, 1453, 2592, 2119, 2442, 3145, 1493, 87, - 2364, 3610, 2365, 2365, 2365, 2365, 2365, 1454, 2999, 3067, - 3068, 3069, 3070, 3071, 2657, 1716, 1454, 2045, 739, 738, - 736, 3085, 2365, 3087, 2796, 2365, 2824, 1457, 944, 3095, - 2784, 1451, 1742, 1452, 1453, 2835, 3094, 1454, 2833, 3150, - 1970, 2832, 2367, 2537, 3167, 1454, 2372, 3475, 3471, 4025, - 1454, 2366, 2362, 2802, 895, 894, 3110, 3106, 3119, 748, - 2653, 1716, 740, 1454, 730, 893, 1451, 1025, 1452, 1453, - 2367, 2367, 2367, 2367, 2367, 3117, 1454, 892, 3120, 3261, - 3132, 3133, 1454, 3262, 2942, 3276, 3107, 3108, 3109, 3251, - 2367, 3326, 3151, 2367, 2944, 3154, 3149, 2869, 1026, 3259, - 3325, 3152, 3153, 3118, 3155, 1027, 3169, 104, 3163, 3170, - 105, 3171, 1451, 1454, 1452, 1453, 3272, 1435, 1706, 1084, - 3300, 2651, 1716, 3934, 2563, 3323, 1705, 3941, 3177, 2644, - 1716, 3242, 3540, 1454, 2642, 1716, 3223, 3209, 3059, 3210, - 3061, 2918, 3208, 1451, 2458, 1452, 1453, 3322, 69, 46, - 3211, 3212, 1451, 3905, 1452, 1453, 3072, 3073, 3074, 3075, - 2774, 3135, 3260, 3263, 3971, 3264, 2773, 887, 884, 2430, - 1454, 3232, 3253, 1451, 3612, 1452, 1453, 3613, 3614, 3080, - 3270, 1451, 3081, 1452, 1453, 3141, 1451, 3954, 1452, 1453, - 3141, 1454, 3955, 883, 3956, 2174, 1431, 2769, 1428, 1451, - 4046, 1452, 1453, 2020, 3288, 96, 36, 3291, 3290, 35, - 34, 33, 1451, 32, 1452, 1453, 26, 2768, 1451, 3298, - 1452, 1453, 25, 24, 23, 3308, 3305, 3306, 3254, 3307, - 22, 29, 3309, 19, 3311, 21, 3313, 2836, 2839, 2840, - 2841, 2837, 20, 2838, 2842, 18, 3245, 3473, 3474, 1451, - 4068, 1452, 1453, 4113, 2767, 1471, 123, 55, 52, 1506, - 50, 131, 130, 1506, 2579, 53, 49, 1198, 2584, 1451, - 47, 1452, 1453, 31, 30, 2766, 3233, 17, 16, 1472, - 1473, 1474, 1475, 1476, 1477, 1478, 1480, 1479, 1481, 1482, - 15, 2588, 14, 2589, 3410, 13, 12, 11, 2596, 7, - 6, 3414, 2598, 2599, 39, 38, 1451, 37, 1452, 1453, - 3299, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, - 2614, 28, 2616, 27, 40, 4, 2905, 1451, 2460, 1452, - 1453, 0, 0, 0, 3144, 0, 0, 0, 0, 2365, - 0, 3440, 3441, 3443, 0, 2622, 2623, 2624, 2625, 2626, - 0, 2628, 3488, 3448, 0, 2630, 3455, 0, 0, 2635, - 2636, 728, 2637, 0, 1454, 2640, 0, 2641, 2643, 2645, - 2646, 2647, 2648, 2649, 2650, 2652, 2654, 2655, 2656, 2658, - 1454, 2660, 2661, 2663, 2665, 2667, 2669, 2671, 2673, 2675, - 2677, 2679, 2681, 2683, 2685, 2687, 2689, 2691, 2693, 2695, - 2697, 2698, 2699, 3482, 2701, 3477, 2703, 2367, 2705, 2706, - 3460, 2708, 2710, 2712, 3480, 3260, 3263, 2715, 3264, 3445, - 0, 2719, 3489, 3483, 0, 2724, 2725, 2726, 2727, 3505, - 0, 3507, 3293, 3294, 0, 0, 0, 0, 2738, 2739, - 2740, 2741, 2742, 2743, 3550, 3551, 2747, 2748, 2765, 1454, - 0, 0, 3470, 0, 2750, 3499, 3500, 2113, 3417, 2756, - 3419, 3420, 3421, 1454, 2764, 2759, 2760, 2761, 2762, 2763, - 1044, 3484, 3485, 1050, 1050, 0, 2770, 2771, 0, 2772, - 0, 0, 2775, 2777, 2333, 0, 2779, 0, 0, 0, - 1454, 0, 0, 0, 1454, 0, 2791, 0, 0, 0, - 1451, 0, 1452, 1453, 0, 1454, 0, 0, 3533, 1454, - 0, 0, 3537, 3538, 3539, 0, 1451, 0, 1452, 1453, - 1454, 3552, 2836, 2839, 2840, 2841, 2837, 0, 2838, 2842, - 0, 0, 0, 2755, 1454, 3568, 0, 3529, 3530, 0, - 0, 0, 0, 1454, 0, 0, 0, 2754, 0, 0, - 0, 1454, 0, 0, 0, 2105, 2094, 2095, 2096, 2097, - 2107, 2098, 2099, 2100, 2112, 2108, 2101, 2102, 2109, 2110, - 2111, 2103, 2104, 2106, 2753, 0, 1454, 0, 2752, 0, - 1454, 0, 0, 0, 0, 1451, 0, 1452, 1453, 2749, - 1454, 0, 0, 2744, 1454, 0, 0, 0, 0, 1451, - 1454, 1452, 1453, 0, 2737, 0, 0, 0, 1454, 3628, - 0, 3632, 3633, 1454, 0, 0, 0, 3618, 2736, 3619, - 3620, 3621, 1454, 3608, 0, 0, 1451, 2735, 1452, 1453, - 1451, 0, 1452, 1453, 3145, 2734, 87, 3634, 3145, 0, - 0, 1451, 0, 1452, 1453, 1451, 0, 1452, 1453, 0, - 1454, 0, 0, 0, 0, 0, 1451, 0, 1452, 1453, - 2733, 0, 3572, 0, 2732, 0, 2084, 0, 2082, 3663, - 1451, 3635, 1452, 1453, 2731, 3655, 3644, 3643, 2730, 1451, - 0, 1452, 1453, 0, 2729, 3651, 3653, 1451, 1454, 1452, - 1453, 0, 2723, 0, 0, 0, 0, 2722, 0, 1454, - 0, 0, 0, 3813, 42, 0, 2721, 0, 0, 0, - 3667, 0, 1451, 0, 1452, 1453, 1451, 0, 1452, 1453, - 0, 0, 0, 0, 0, 0, 1451, 0, 1452, 1453, - 1451, 0, 1452, 1453, 2718, 0, 1451, 0, 1452, 1453, - 0, 0, 0, 3805, 1451, 3804, 1452, 1453, 0, 1451, - 0, 1452, 1453, 0, 0, 3820, 0, 0, 1451, 0, - 1452, 1453, 3825, 3832, 3824, 0, 1714, 1710, 3803, 0, - 0, 0, 2717, 0, 3870, 3871, 3007, 3008, 3009, 3010, - 3011, 1711, 3657, 2716, 3664, 3665, 1451, 0, 1452, 1453, - 0, 0, 2084, 0, 2082, 3874, 3016, 0, 3815, 3816, - 3817, 0, 0, 0, 0, 0, 2328, 2329, 1713, 0, - 1712, 3599, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3141, 0, 0, 1451, 3145, 1452, 1453, 0, 0, - 3877, 0, 3659, 3808, 3880, 1451, 0, 1452, 1453, 1523, + 180, 181, 182, 183, 2438, 1037, 1717, 1253, 1121, 184, + 186, 187, 188, 3945, 2434, 3004, 1120, 1700, 1144, 119, + 3528, 1704, 1114, 1117, 1118, 94, 1078, 1021, 3303, 1211, + 1111, 1115, 3463, 2900, 2510, 1853, 1121, 2029, 1959, 1120, + 1755, 2122, 2122, 1702, 2595, 4086, 1703, 104, 2130, 1454, + 105, 1110, 1684, 1653, 1654, 1655, 1656, 1657, 1658, 3651, + 1453, 1454, 2131, 3503, 1449, 3502, 1690, 1120, 2047, 2049, + 2050, 2477, 1124, 1114, 1120, 1094, 1190, 1126, 1677, 1124, + 1114, 1127, 1125, 1863, 1126, 2586, 107, 2487, 1127, 1125, + 1862, 2967, 120, 2048, 1445, 2482, 2966, 1437, 2967, 1852, + 4078, 2485, 1128, 2966, 1132, 1130, 3488, 2788, 1949, 2482, + 1950, 1120, 1033, 1951, 2058, 4123, 1698, 1114, 1117, 1118, + 1240, 1078, 1830, 1831, 1832, 1111, 1115, 1846, 2059, 1484, + 1485, 2057, 1455, 1225, 2486, 3182, 1979, 4129, 2489, 1120, + 1194, 1157, 1701, 1719, 1227, 1154, 3820, 3975, 2484, 3913, + 1971, 1917, 1839, 1196, 3819, 3810, 1868, 1018, 1869, 1722, + 1871, 1873, 1699, 1020, 1877, 1879, 1881, 1883, 1885, 1858, + 3578, 1899, 1445, 1210, 3562, 1687, 3563, 1856, 1856, 1261, + 3183, 2157, 1746, 1747, 2567, 2568, 2569, 1472, 3577, 1907, + 1908, 1857, 3976, 2128, 3914, 1913, 1914, 1478, 1479, 1481, + 1480, 1482, 1483, 1822, 3185, 4119, 3510, 3509, 4120, 2634, + 4118, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, + 1482, 1483, 3180, 1849, 4130, 3499, 1942, 1836, 1837, 1455, + 1835, 1476, 1477, 1478, 1479, 1481, 1480, 1482, 1483, 3226, + 3196, 3197, 1860, 1940, 3214, 1193, 1455, 3181, 2882, 2881, + 1705, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, + 1483, 1093, 1903, 1455, 959, 960, 961, 2880, 1452, 1895, + 1453, 1454, 1898, 2442, 1900, 1967, 1717, 3006, 1943, 2149, + 1929, 3187, 3320, 2127, 2151, 2984, 1455, 1927, 2156, 2152, + 1941, 1455, 2153, 2154, 2155, 1472, 1926, 2150, 2158, 2159, + 2160, 2161, 2162, 2163, 2164, 2165, 2166, 1939, 2622, 128, + 1097, 1096, 1095, 4091, 1717, 1925, 1915, 1828, 1909, 1473, + 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, 1483, + 4089, 1717, 1906, 1905, 1904, 1984, 1459, 1460, 1461, 1462, + 1463, 1464, 1465, 1457, 1928, 1875, 1261, 1261, 1717, 3195, + 1980, 1981, 1697, 1455, 3493, 709, 4079, 2277, 2006, 1455, + 87, 3198, 3278, 87, 1985, 1452, 1455, 1453, 1454, 2986, + 2592, 1992, 1993, 1994, 709, 4019, 1717, 2630, 2864, 709, + 1749, 2005, 1452, 1420, 1453, 1454, 2458, 2457, 1444, 1441, + 1442, 1443, 1448, 1450, 1447, 1455, 1446, 2456, 2455, 1452, + 3940, 1453, 1454, 2454, 2453, 3939, 1440, 3917, 1455, 2114, + 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, + 1483, 3916, 1452, 3915, 1453, 1454, 3815, 1452, 42, 1453, + 1454, 42, 2085, 2085, 2083, 2083, 2086, 4017, 1717, 2996, + 2995, 2994, 2632, 2591, 2988, 1717, 2992, 1982, 2987, 1455, + 2985, 1717, 1451, 1717, 1986, 2990, 1988, 1989, 1990, 1991, + 2808, 4106, 2051, 1995, 2989, 3799, 1444, 1441, 1442, 1443, + 1448, 1450, 1447, 3798, 1446, 2007, 3650, 3184, 3648, 4015, + 1717, 1726, 2991, 2993, 1440, 101, 4066, 1717, 3933, 1452, + 3574, 1453, 1454, 1717, 3846, 1452, 102, 1453, 1454, 1451, + 1717, 3845, 1452, 2168, 1453, 1454, 1683, 2106, 2095, 2096, + 2097, 2098, 2108, 2099, 2100, 2101, 2113, 2109, 2102, 2103, + 2110, 2111, 2112, 2104, 2105, 2107, 1682, 1727, 2808, 4004, + 3803, 1452, 1681, 1453, 1454, 1455, 85, 1684, 1680, 85, + 2030, 2055, 1455, 3507, 1452, 3492, 1453, 1454, 2013, 2014, + 1472, 1717, 3802, 1468, 3288, 1469, 3285, 1455, 3217, 2350, + 2351, 2808, 3983, 3554, 2062, 3216, 2808, 3979, 2918, 1470, + 1484, 1485, 1467, 2060, 1473, 1474, 1475, 1476, 1477, 1478, + 1479, 1481, 1480, 1482, 1483, 1452, 2891, 1453, 1454, 3966, + 1717, 2288, 3546, 3930, 3823, 1717, 2808, 3811, 2287, 2061, + 2878, 2063, 2064, 2065, 2066, 2067, 2068, 2070, 2072, 2073, + 2074, 2075, 2076, 2077, 1455, 2286, 1497, 2089, 1472, 1455, + 2976, 2132, 2133, 2134, 2135, 1679, 3892, 1717, 3546, 1717, + 2896, 2275, 2543, 2123, 2273, 2146, 1472, 2542, 2574, 2504, + 2167, 3841, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, + 1480, 1482, 1483, 2503, 2116, 2118, 2808, 3544, 2482, 1717, + 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, + 1483, 1452, 2340, 1453, 1454, 101, 2322, 2366, 1452, 2009, + 1453, 1454, 103, 2182, 1455, 2288, 102, 2277, 2291, 2292, + 1975, 2274, 2355, 1452, 1938, 1453, 1454, 2804, 3890, 1717, + 2276, 3467, 1717, 3887, 1717, 104, 1930, 110, 105, 2286, + 2714, 1717, 103, 2396, 954, 3207, 3206, 3188, 109, 1920, + 108, 3192, 3204, 3205, 2395, 110, 104, 1916, 3191, 105, + 3202, 3203, 3169, 2180, 1912, 2054, 109, 103, 108, 3202, + 3201, 1717, 2561, 2191, 2333, 2368, 1455, 103, 1911, 1083, + 1452, 1910, 1453, 1454, 1728, 1452, 1251, 1453, 1454, 2832, + 1717, 2483, 3193, 2405, 2406, 2407, 2408, 3189, 3869, 1717, + 2588, 2400, 3190, 2401, 2402, 2403, 2404, 2561, 2940, 2391, + 1034, 1455, 1083, 2390, 3462, 2321, 1818, 2921, 1717, 2411, + 2412, 2413, 2414, 2372, 2290, 1455, 1717, 2293, 2294, 2853, + 2327, 2309, 2328, 2914, 2915, 95, 1717, 109, 2853, 2808, + 2807, 2425, 2394, 2264, 2265, 2266, 2267, 2268, 2335, 2482, + 1452, 1451, 1453, 1454, 2471, 2824, 2431, 2824, 1455, 2353, + 3438, 1717, 86, 44, 45, 88, 1455, 3464, 2377, 2378, + 2376, 1455, 2588, 1717, 2088, 1717, 2831, 2393, 1067, 2392, + 3971, 1068, 92, 2332, 1455, 3944, 48, 76, 77, 1455, + 74, 78, 2854, 2468, 2808, 3431, 1717, 2441, 2311, 75, + 1455, 2854, 2856, 2832, 2191, 1455, 1451, 1730, 3417, 3428, + 1717, 2561, 1452, 3204, 1453, 1454, 1818, 1817, 1761, 1760, + 2426, 2415, 2417, 2418, 2422, 3112, 2379, 2832, 62, 3462, + 2440, 2832, 2476, 2444, 1123, 2479, 2452, 2480, 1455, 2588, + 95, 3139, 3426, 1717, 1856, 2714, 2496, 1452, 2619, 1453, + 1454, 4080, 3462, 1122, 2618, 2426, 3928, 2478, 2475, 2474, + 2582, 1452, 1455, 1453, 1454, 3511, 2482, 2465, 3388, 1717, + 1455, 2348, 2497, 1729, 2500, 1721, 2312, 190, 2501, 2502, + 2088, 2031, 2015, 1961, 3386, 1717, 83, 1748, 2912, 3382, + 1717, 1105, 1718, 1720, 1452, 1104, 1453, 1454, 4045, 3986, + 1023, 129, 1452, 151, 1453, 1454, 2566, 1452, 1891, 1453, + 1454, 3834, 1455, 1724, 172, 3800, 3512, 3513, 3514, 1455, + 1452, 2507, 1453, 1454, 3662, 1452, 1455, 1453, 1454, 3527, + 1507, 3524, 1507, 3505, 3330, 3329, 1452, 1820, 1453, 1454, + 1455, 1452, 2424, 1453, 1454, 162, 3379, 1717, 2578, 1455, + 3276, 150, 3231, 1455, 3377, 1717, 3229, 1455, 3227, 1892, + 1893, 1894, 2922, 4101, 2288, 2536, 2421, 2416, 2410, 1455, + 169, 2287, 2409, 170, 1452, 1455, 1453, 1454, 95, 1945, + 51, 54, 57, 56, 59, 1851, 73, 1847, 2581, 82, + 79, 1816, 1842, 1843, 161, 160, 189, 3807, 1452, 121, + 1453, 1454, 2888, 3375, 1717, 1195, 1452, 3280, 1453, 1454, + 3373, 1717, 3835, 61, 91, 90, 2551, 2439, 71, 72, + 58, 3474, 3475, 4099, 3371, 1717, 80, 81, 1455, 2887, + 2325, 2559, 2011, 3369, 1717, 4073, 3952, 3367, 1717, 1455, + 3874, 3365, 1717, 3477, 3223, 1455, 3222, 3221, 1452, 1455, + 1453, 1454, 3139, 3363, 1717, 1452, 2570, 1453, 1454, 3361, + 1717, 2055, 1452, 2901, 1453, 1454, 1455, 2537, 63, 64, + 1455, 65, 66, 67, 68, 1455, 1452, 2888, 1453, 1454, + 3480, 3161, 3479, 2572, 3948, 1452, 3162, 1453, 1454, 1452, + 3158, 1453, 1454, 1452, 2012, 1453, 1454, 155, 1844, 158, + 3157, 1841, 2584, 156, 157, 1452, 3836, 1453, 1454, 3515, + 173, 1452, 2583, 1453, 1454, 665, 2594, 3159, 2571, 179, + 2573, 2339, 3160, 3359, 1717, 1887, 1725, 2331, 3468, 2576, + 3529, 2577, 60, 3357, 1717, 2545, 2546, 3117, 2579, 1455, + 2548, 3116, 3912, 3163, 1455, 2841, 2842, 2758, 3641, 2549, + 3355, 1717, 1455, 3643, 3353, 1717, 3516, 3517, 3518, 3351, + 1717, 3129, 3131, 3455, 1452, 3126, 1453, 1454, 1455, 2628, + 3132, 3454, 1888, 1889, 1890, 1452, 1455, 1453, 1454, 2790, + 1455, 1452, 3458, 1453, 1454, 1452, 1455, 1453, 1454, 726, + 3632, 1455, 3631, 2892, 1960, 1038, 1006, 1022, 2085, 3200, + 2083, 2793, 1452, 1039, 1453, 1454, 1452, 2871, 1453, 1454, + 1455, 1452, 3296, 1453, 1454, 1455, 1161, 1160, 2829, 2830, + 2130, 101, 89, 3349, 1717, 1455, 2791, 2366, 3335, 1717, + 1022, 2849, 102, 2887, 2131, 101, 3318, 1717, 2970, 2928, + 3630, 2601, 103, 164, 3460, 2794, 102, 2796, 1419, 129, + 2350, 2351, 2779, 1717, 103, 2054, 4115, 2828, 2616, 2809, + 2777, 1717, 3219, 2540, 2752, 1717, 4024, 3929, 3830, 3199, + 2729, 1717, 2845, 1455, 110, 1452, 2883, 1453, 1454, 2336, + 1452, 2529, 1453, 1454, 2528, 109, 42, 108, 1452, 2527, + 1453, 1454, 2526, 1455, 3482, 2846, 103, 2805, 2848, 2721, + 1717, 1690, 2818, 2525, 1452, 2781, 1453, 1454, 3440, 2712, + 1717, 2847, 1452, 1455, 1453, 1454, 1452, 1455, 1453, 1454, + 2874, 2876, 1452, 2801, 1453, 1454, 1684, 1452, 2565, 1453, + 1454, 94, 1455, 3115, 1046, 1047, 2821, 108, 109, 159, + 2806, 3114, 2867, 3900, 2926, 3899, 1452, 2851, 1453, 1454, + 3877, 1452, 3649, 1453, 1454, 1455, 110, 2710, 1717, 1455, + 2855, 1452, 3647, 1453, 1454, 2858, 3646, 109, 2431, 108, + 2865, 4102, 2868, 3639, 3525, 1455, 3459, 2697, 1717, 3457, + 2937, 1455, 2125, 3232, 2466, 1834, 2890, 2126, 1455, 110, + 1045, 2893, 2894, 1455, 3638, 2879, 3448, 2695, 1717, 1455, + 109, 2693, 1717, 2824, 1455, 4103, 4102, 4103, 2889, 1452, + 3918, 1453, 1454, 3616, 2804, 3491, 2691, 1717, 3020, 2620, + 1455, 2897, 2323, 2186, 2902, 2903, 2904, 1742, 2898, 1452, + 1734, 1453, 1454, 114, 115, 2934, 1036, 70, 2028, 2689, + 1717, 10, 1839, 2687, 1717, 2026, 3, 152, 9, 1452, + 153, 1453, 1454, 1452, 97, 1453, 1454, 2923, 2924, 2685, + 1717, 2027, 1455, 2913, 8, 3433, 2980, 2981, 1452, 2933, + 1453, 1454, 2683, 1717, 1, 1014, 1422, 2681, 1717, 1455, + 165, 1421, 3495, 2679, 1717, 1455, 4034, 177, 2677, 1717, + 681, 1452, 2313, 1453, 1454, 1452, 1688, 1453, 1454, 4074, + 4030, 2997, 2959, 2270, 2675, 1717, 4031, 1931, 2978, 1455, + 1921, 1452, 2962, 1453, 1454, 3557, 2238, 1452, 3831, 1453, + 1454, 3235, 1455, 2472, 1452, 3523, 1453, 1454, 185, 1452, + 2429, 1453, 1454, 2303, 1113, 1452, 154, 1453, 1454, 2388, + 1452, 2389, 1453, 1454, 3999, 1455, 2673, 1717, 2935, 118, + 1718, 2310, 1071, 1455, 117, 2998, 1452, 1116, 1453, 1454, + 3001, 1224, 2467, 2671, 1717, 3547, 2872, 2397, 1767, 2669, + 1717, 166, 171, 168, 174, 175, 176, 178, 180, 181, + 182, 183, 1765, 1766, 1764, 2334, 1455, 184, 186, 187, + 188, 1769, 1768, 2667, 1717, 3304, 2621, 3395, 1452, 2979, + 1453, 1454, 2019, 3022, 716, 2844, 2665, 1717, 3078, 710, + 2968, 1715, 1711, 2969, 192, 1452, 1756, 1453, 1454, 1735, + 3409, 1452, 1155, 1453, 1454, 671, 1712, 3208, 2505, 2663, + 1717, 677, 1504, 2010, 3113, 2859, 1065, 3429, 2982, 1057, + 2324, 2795, 1064, 3808, 3147, 1452, 2999, 1453, 1454, 3452, + 3125, 2329, 2330, 1714, 3085, 1713, 3127, 3096, 1452, 3087, + 1453, 1454, 2811, 3130, 3123, 2366, 3911, 1455, 3013, 3640, + 2658, 1717, 2275, 3984, 2275, 2273, 2869, 2273, 1731, 3416, + 3058, 1452, 2593, 1453, 1454, 2120, 1494, 2443, 3146, 1452, + 87, 1453, 1454, 2366, 2366, 2366, 2366, 2366, 1455, 3000, + 3068, 3069, 3070, 3071, 3072, 2365, 3611, 1455, 2046, 739, + 738, 736, 3086, 2366, 3088, 2797, 2366, 2825, 1458, 944, + 3096, 2785, 1452, 1743, 1453, 1454, 2836, 3095, 1455, 2834, + 3151, 1971, 2833, 2368, 2538, 3168, 1455, 2373, 3476, 3472, + 4026, 1455, 2367, 2363, 2803, 895, 894, 3111, 3107, 3120, + 748, 2654, 1717, 740, 1455, 730, 893, 892, 1025, 3262, + 3263, 2368, 2368, 2368, 2368, 2368, 3118, 1455, 2943, 3121, + 3277, 3133, 3134, 1455, 2945, 2870, 3273, 3108, 3109, 3110, + 3252, 2368, 3394, 3152, 2368, 1436, 3155, 3150, 1707, 1026, + 3260, 3390, 3153, 3154, 3119, 3156, 1027, 3170, 104, 3164, + 3171, 105, 3172, 1452, 1455, 1453, 1454, 1084, 3301, 3935, + 2564, 3324, 2652, 1717, 1706, 3942, 3243, 3541, 3224, 3178, + 2645, 1717, 2919, 2459, 1455, 2643, 1717, 69, 3210, 3060, + 3211, 3062, 46, 3209, 1452, 3906, 1453, 1454, 3327, 3972, + 887, 3212, 3213, 1452, 884, 1453, 1454, 3073, 3074, 3075, + 3076, 3326, 3136, 3261, 3264, 3613, 3265, 3323, 3614, 3615, + 2431, 1455, 3233, 3254, 1452, 3081, 1453, 1454, 3082, 3955, + 3956, 3271, 1452, 883, 1453, 1454, 3142, 1452, 3957, 1453, + 1454, 3142, 1455, 2175, 1432, 1429, 4047, 2021, 2775, 96, + 1452, 36, 1453, 1454, 35, 3289, 34, 33, 3292, 3291, + 32, 26, 25, 1452, 24, 1453, 1454, 23, 2774, 1452, + 3299, 1453, 1454, 22, 29, 19, 3309, 3306, 3307, 3255, + 3308, 21, 20, 3310, 18, 3312, 3246, 3314, 2837, 2840, + 2841, 2842, 2838, 4069, 2839, 2843, 4114, 123, 3474, 3475, + 1452, 55, 1453, 1454, 52, 2770, 1472, 50, 131, 130, + 1507, 53, 49, 1198, 1507, 2580, 47, 31, 30, 2585, + 1452, 17, 1453, 1454, 16, 15, 2769, 3234, 14, 13, + 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, + 1483, 12, 2589, 11, 2590, 3411, 7, 6, 39, 2597, + 38, 37, 3415, 2599, 2600, 28, 27, 1452, 40, 1453, + 1454, 3300, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, + 2614, 2615, 4, 2617, 2906, 2461, 0, 0, 1452, 0, + 1453, 1454, 0, 0, 0, 3145, 0, 0, 0, 0, + 2366, 0, 3441, 3442, 3444, 0, 2623, 2624, 2625, 2626, + 2627, 0, 2629, 3489, 3449, 0, 2631, 3456, 0, 0, + 2636, 2637, 728, 2638, 0, 1455, 2641, 0, 2642, 2644, + 2646, 2647, 2648, 2649, 2650, 2651, 2653, 2655, 2656, 2657, + 2659, 1455, 2661, 2662, 2664, 2666, 2668, 2670, 2672, 2674, + 2676, 2678, 2680, 2682, 2684, 2686, 2688, 2690, 2692, 2694, + 2696, 2698, 2699, 2700, 3483, 2702, 3478, 2704, 2368, 2706, + 2707, 3461, 2709, 2711, 2713, 3481, 3261, 3264, 2716, 3265, + 3446, 0, 2720, 3490, 3484, 0, 2725, 2726, 2727, 2728, + 3506, 0, 3508, 3294, 3295, 0, 0, 0, 0, 2739, + 2740, 2741, 2742, 2743, 2744, 3551, 3552, 2748, 2749, 2768, + 1455, 0, 0, 3471, 0, 2751, 3500, 3501, 2114, 3418, + 2757, 3420, 3421, 3422, 1455, 2767, 2760, 2761, 2762, 2763, + 2764, 1044, 3485, 3486, 1050, 1050, 0, 2771, 2772, 0, + 2773, 0, 0, 2776, 2778, 2334, 0, 2780, 0, 0, + 0, 1455, 0, 0, 0, 1455, 0, 2792, 0, 0, + 0, 1452, 0, 1453, 1454, 0, 1455, 0, 0, 3534, + 1455, 0, 0, 3538, 3539, 3540, 0, 1452, 0, 1453, + 1454, 1455, 3553, 2837, 2840, 2841, 2842, 2838, 0, 2839, + 2843, 0, 0, 0, 2766, 1455, 3569, 0, 3530, 3531, + 0, 0, 0, 0, 1455, 0, 0, 0, 2765, 0, + 0, 0, 1455, 0, 0, 0, 2106, 2095, 2096, 2097, + 2098, 2108, 2099, 2100, 2101, 2113, 2109, 2102, 2103, 2110, + 2111, 2112, 2104, 2105, 2107, 2756, 0, 1455, 0, 2755, + 0, 1455, 0, 0, 0, 0, 1452, 0, 1453, 1454, + 2754, 1455, 0, 0, 2753, 1455, 0, 0, 0, 0, + 1452, 1455, 1453, 1454, 0, 2750, 0, 0, 0, 1455, + 3629, 0, 3633, 3634, 1455, 0, 0, 0, 3619, 2745, + 3620, 3621, 3622, 1455, 3609, 0, 0, 1452, 2738, 1453, + 1454, 1452, 0, 1453, 1454, 3146, 2737, 87, 3635, 3146, + 0, 0, 1452, 0, 1453, 1454, 1452, 0, 1453, 1454, + 0, 1455, 0, 0, 0, 0, 0, 1452, 0, 1453, + 1454, 2736, 0, 3573, 0, 2735, 0, 2085, 0, 2083, + 3664, 1452, 3636, 1453, 1454, 2734, 3656, 3645, 3644, 2733, + 1452, 0, 1453, 1454, 0, 2732, 3652, 3654, 1452, 1455, + 1453, 1454, 0, 2731, 0, 0, 0, 0, 2730, 0, + 1455, 0, 0, 0, 3814, 42, 0, 2724, 0, 0, + 0, 3668, 0, 1452, 0, 1453, 1454, 1452, 0, 1453, + 1454, 0, 0, 0, 0, 0, 0, 1452, 0, 1453, + 1454, 1452, 0, 1453, 1454, 2723, 0, 1452, 0, 1453, + 1454, 0, 0, 0, 3806, 1452, 3805, 1453, 1454, 0, + 1452, 0, 1453, 1454, 0, 0, 3821, 0, 0, 1452, + 0, 1453, 1454, 3826, 3833, 3825, 0, 1715, 1711, 3804, + 0, 0, 0, 2722, 0, 3871, 3872, 3008, 3009, 3010, + 3011, 3012, 1712, 3658, 2719, 3665, 3666, 1452, 0, 1453, + 1454, 0, 0, 2085, 0, 2083, 3875, 3017, 0, 3816, + 3817, 3818, 0, 0, 0, 0, 0, 1708, 1709, 1714, + 0, 1713, 3600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3142, 0, 0, 1452, 3146, 1453, 1454, 0, + 0, 3878, 0, 3660, 3809, 3881, 1452, 0, 1453, 1454, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, - 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1543, 1544, + 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, @@ -2033,651 +2033,659 @@ var yyAct = [...]int{ 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1620, 1621, 1622, 1623, 1624, 1625, + 1615, 1616, 1617, 1618, 1619, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1641, 1642, 1643, 1644, 1658, 1659, 1660, 1661, 1662, 1663, - 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 3921, 3918, - 3903, 3144, 3875, 3900, 3901, 3144, 3902, 1454, 0, 1714, - 1710, 1454, 3935, 0, 0, 0, 1454, 0, 0, 0, - 0, 0, 0, 1454, 1711, 0, 0, 0, 3920, 0, - 87, 0, 0, 0, 3147, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1454, 1707, - 1708, 1713, 3165, 1712, 0, 0, 3924, 0, 0, 0, - 0, 3937, 0, 0, 0, 0, 3940, 0, 0, 3942, - 3812, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1454, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3909, 2714, 0, 0, 0, 2707, 0, 0, 42, 0, - 2704, 0, 0, 0, 0, 0, 0, 2702, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1455, 3960, 0, 3980, 3961, 0, 0, 0, 87, - 0, 0, 2700, 0, 0, 0, 3926, 0, 0, 0, - 0, 0, 0, 1451, 3969, 1452, 1453, 1451, 0, 1452, - 1453, 1511, 1451, 0, 1452, 1453, 3976, 0, 0, 1451, - 3986, 1452, 1453, 0, 2659, 4011, 0, 3997, 3984, 0, - 3945, 0, 3989, 3994, 3991, 3990, 3988, 3993, 0, 0, - 3297, 3832, 4000, 3992, 1451, 0, 1452, 1453, 0, 0, - 0, 0, 3144, 4021, 0, 0, 0, 42, 0, 0, - 0, 0, 3314, 3315, 4024, 3316, 4042, 3318, 3320, 4032, - 0, 4037, 4066, 4050, 0, 0, 1451, 4011, 1452, 1453, - 4052, 3327, 1783, 0, 4063, 0, 3331, 3332, 3333, 3335, + 1636, 1642, 1643, 1644, 1645, 1659, 1660, 1661, 1662, 1663, + 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 3922, + 3919, 3904, 3145, 3876, 3901, 3902, 3145, 3903, 1455, 0, + 0, 0, 1455, 3936, 0, 0, 0, 1455, 0, 0, + 0, 0, 0, 0, 1455, 0, 0, 0, 0, 3921, + 0, 87, 0, 0, 0, 3148, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1455, + 0, 0, 0, 3166, 0, 0, 0, 3925, 0, 0, + 0, 0, 3938, 0, 0, 0, 0, 3941, 0, 0, + 3943, 3813, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1455, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3910, 2718, 0, 0, 0, 2717, 0, 0, 42, + 0, 2715, 0, 0, 0, 0, 0, 0, 2708, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1456, 3961, 0, 3981, 3962, 0, 0, 0, + 87, 0, 0, 2705, 0, 0, 0, 3927, 0, 0, + 0, 0, 0, 0, 1452, 3970, 1453, 1454, 1452, 0, + 1453, 1454, 1512, 1452, 0, 1453, 1454, 3977, 0, 0, + 1452, 3987, 1453, 1454, 0, 2703, 4012, 0, 3998, 3985, + 0, 3946, 0, 3990, 3995, 3992, 3991, 3989, 3994, 0, + 0, 3298, 3833, 4001, 3993, 1452, 0, 1453, 1454, 0, + 0, 0, 0, 3145, 4022, 0, 0, 0, 42, 0, + 0, 0, 0, 3315, 3316, 4025, 3317, 4043, 3319, 3321, + 4033, 0, 4038, 0, 4051, 0, 0, 1452, 4012, 1453, + 1454, 4053, 3328, 0, 0, 4064, 0, 3332, 3333, 3334, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, - 3346, 3347, 3349, 3351, 3353, 3355, 3357, 3359, 3361, 3363, - 3365, 3367, 3369, 3371, 3373, 3375, 3377, 3379, 3380, 3382, - 3383, 3384, 3386, 1970, 4067, 3388, 4083, 3390, 3391, 3392, - 4082, 4093, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, - 3404, 3405, 3406, 2084, 4099, 2082, 4096, 4095, 4086, 4097, - 4092, 3413, 4062, 3981, 4011, 3418, 1454, 4107, 0, 3422, - 3423, 0, 3424, 3426, 4115, 3429, 3431, 3141, 3433, 3434, - 3435, 3436, 4123, 4121, 0, 1454, 3442, 0, 0, 1454, - 3949, 0, 0, 0, 1454, 0, 0, 0, 3959, 1454, - 0, 0, 4132, 4133, 3871, 4131, 0, 0, 1454, 0, - 0, 2084, 0, 2082, 4130, 0, 0, 0, 0, 3933, - 0, 3464, 3465, 0, 0, 3469, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1771, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2639, 4080, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2638, - 0, 0, 0, 2634, 0, 0, 0, 0, 2632, 0, - 0, 0, 4058, 2597, 0, 0, 0, 0, 0, 0, - 0, 0, 2586, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1451, 0, 1452, 1453, 0, 1732, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1451, 1784, 1452, 1453, 1451, 0, 1452, 1453, 0, - 1451, 3544, 1452, 1453, 0, 1451, 0, 1452, 1453, 0, - 0, 0, 0, 0, 1451, 1820, 1452, 1453, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3563, 0, 0, 3567, - 0, 0, 0, 0, 1797, 1800, 1801, 1802, 1803, 1804, - 1805, 0, 1806, 1807, 1809, 1810, 1808, 1811, 1812, 1785, - 1786, 1787, 1788, 1769, 1770, 1798, 3578, 1772, 0, 1773, - 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 0, 0, - 1782, 1789, 1790, 1791, 1792, 0, 1793, 1794, 1795, 1796, - 0, 0, 0, 1690, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 940, 0, 0, 0, 0, 0, 0, 0, 0, - 3601, 0, 0, 1975, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3609, 0, 0, 0, 0, 0, 0, - 0, 3616, 663, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1009, 0, 0, 0, 0, 195, 0, 0, - 195, 0, 0, 0, 714, 0, 0, 0, 0, 720, + 3346, 3347, 3348, 3350, 3352, 3354, 3356, 3358, 3360, 3362, + 3364, 3366, 3368, 3370, 3372, 3374, 3376, 3378, 3380, 3381, + 3383, 3384, 3385, 3387, 1971, 4068, 3389, 4084, 3391, 3392, + 3393, 4083, 4094, 3397, 3398, 3399, 3400, 3401, 3402, 3403, + 3404, 3405, 3406, 3407, 2085, 4100, 2083, 4097, 4096, 4087, + 4098, 4093, 3414, 4063, 3982, 4012, 3419, 1455, 4108, 0, + 3423, 3424, 0, 3425, 3427, 4116, 3430, 3432, 3142, 3434, + 3435, 3436, 3437, 4124, 4122, 0, 1455, 3443, 0, 0, + 1455, 3950, 0, 0, 0, 0, 0, 0, 0, 3960, + 1455, 0, 0, 4133, 4134, 3872, 4132, 0, 0, 1455, + 0, 0, 2085, 1455, 2083, 4131, 0, 1455, 0, 0, + 3934, 0, 3465, 3466, 0, 1455, 3470, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2701, 4081, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2660, 0, 0, 0, 2640, 1691, 0, 0, 0, 0, + 0, 0, 0, 4059, 2639, 0, 0, 0, 0, 0, + 0, 0, 0, 2635, 0, 0, 0, 2633, 0, 0, + 0, 2598, 0, 1452, 0, 1453, 1454, 0, 1733, 2587, + 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, + 2277, 0, 1452, 958, 1453, 1454, 1452, 0, 1453, 1454, + 0, 0, 3545, 2084, 663, 0, 1452, 0, 1453, 1454, + 0, 0, 0, 0, 0, 1452, 1821, 1453, 1454, 1452, + 0, 1453, 1454, 1452, 1009, 1453, 1454, 0, 0, 0, + 0, 1452, 0, 1453, 1454, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3564, 0, 0, + 3568, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1079, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3579, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 940, 0, 0, 0, 0, 0, 0, 0, + 0, 3602, 0, 0, 1976, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3610, 0, 0, 0, 0, 0, + 0, 0, 3617, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 0, 195, 0, 0, 0, 714, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1079, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 195, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 195, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3822, 0, 0, + 0, 0, 0, 0, 0, 0, 3829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3821, 0, 0, 0, - 0, 0, 0, 0, 0, 3828, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1799, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3838, 3839, 0, 3841, 0, - 3842, 3843, 0, 0, 0, 3846, 3847, 3848, 3849, 3850, + 0, 0, 0, 0, 0, 0, 3839, 3840, 0, 3842, + 0, 3843, 3844, 0, 0, 0, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, - 3861, 3862, 3863, 3864, 3865, 3866, 3867, 0, 3869, 3872, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3881, 3882, 3883, 3884, 3885, 3887, - 3888, 3890, 3892, 3893, 3895, 0, 0, 0, 0, 0, - 0, 0, 2040, 2041, 2042, 2043, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2051, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3925, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2090, 2091, 0, 0, 0, 0, 2114, 1050, - 1050, 2118, 0, 0, 0, 2123, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, - 0, 2146, 0, 0, 0, 2168, 2169, 2170, 2171, 2172, - 2173, 2175, 0, 2180, 0, 2182, 2183, 2184, 0, 2186, - 2187, 2188, 0, 2191, 2192, 2193, 2194, 2195, 2196, 2197, - 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, - 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, - 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, - 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2240, - 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, - 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, - 2261, 2262, 0, 0, 0, 0, 1783, 2268, 0, 2270, - 0, 2277, 2278, 2279, 2280, 2281, 2282, 1050, 0, 1050, - 1050, 1050, 1050, 1050, 0, 0, 0, 0, 0, 0, - 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 0, 2303, - 2304, 2305, 2306, 2307, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3950, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1050, 0, - 3966, 0, 0, 0, 0, 0, 3967, 3968, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2345, 2346, 0, 0, 0, 0, 0, 0, 3979, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2384, 0, 0, 0, - 0, 0, 0, 0, 4005, 4006, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 190, 0, 0, 4013, 4015, - 4017, 0, 1771, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, - 0, 151, 0, 4045, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 0, 0, 0, 0, 2426, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1199, 0, 1205, 0, 0, 0, - 0, 4064, 0, 162, 0, 0, 0, 0, 0, 150, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 195, 0, 1784, 0, 169, 0, - 0, 170, 0, 0, 0, 4087, 4089, 4091, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 138, 139, 161, 160, 189, 0, 1427, 0, 0, 0, - 0, 720, 0, 720, 720, 0, 0, 0, 4112, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 195, 0, 4124, 4125, 1797, 1800, - 1801, 1802, 1803, 1804, 1805, 0, 1806, 1807, 1809, 1810, - 1808, 1811, 1812, 1785, 1786, 1787, 1788, 1769, 1770, 1798, - 0, 1772, 1498, 1773, 1774, 1775, 1776, 1777, 1778, 1779, - 1780, 1781, 0, 0, 1782, 1789, 1790, 1791, 1792, 0, - 1793, 1794, 1795, 1796, 957, 0, 2276, 0, 0, 958, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2083, - 0, 0, 0, 0, 0, 155, 136, 158, 143, 135, - 0, 156, 157, 0, 0, 0, 0, 0, 173, 0, - 0, 0, 0, 0, 0, 0, 0, 179, 144, 0, + 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 0, 3870, + 3873, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3882, 3883, 3884, 3885, 3886, + 3888, 3889, 3891, 3893, 3894, 3896, 0, 0, 0, 0, + 0, 0, 0, 0, 2041, 2042, 2043, 2044, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2052, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3926, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2091, 2092, 0, 0, 0, 0, + 2115, 1050, 1050, 2119, 0, 0, 0, 2124, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, + 2144, 2145, 0, 2147, 0, 0, 0, 2169, 2170, 2171, + 2172, 2173, 2174, 2176, 0, 2181, 0, 2183, 2184, 2185, + 0, 2187, 2188, 2189, 0, 2192, 2193, 2194, 2195, 2196, + 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, + 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, + 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, + 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, + 2237, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, + 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, + 2260, 2261, 2262, 2263, 0, 0, 0, 0, 0, 2269, + 0, 2271, 0, 2278, 2279, 2280, 2281, 2282, 2283, 1050, + 0, 1050, 1050, 1050, 1050, 1050, 0, 0, 0, 0, + 0, 0, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, + 0, 2304, 2305, 2306, 2307, 2308, 1199, 0, 1205, 0, + 0, 0, 0, 0, 0, 0, 0, 3951, 0, 0, + 0, 0, 0, 0, 0, 0, 4067, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1784, 0, 0, 0, + 1050, 3967, 0, 0, 0, 0, 0, 3968, 3969, 190, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2346, 2347, 0, 0, 0, 0, 1428, 3980, + 0, 0, 0, 129, 0, 151, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 0, 2385, 0, + 0, 0, 0, 0, 0, 4006, 4007, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4014, + 4016, 4018, 0, 0, 0, 0, 0, 162, 0, 0, + 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4046, 0, 0, 0, 0, 0, + 0, 0, 169, 0, 0, 170, 0, 0, 0, 2427, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 139, 161, 160, 189, 0, + 0, 0, 4065, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1772, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4088, 4090, 4092, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 0, 720, 720, 0, 0, 0, 4113, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 195, 0, 4125, 4126, 0, + 0, 0, 0, 0, 0, 0, 1785, 0, 0, 155, + 136, 158, 143, 135, 0, 156, 157, 0, 0, 0, + 0, 0, 173, 1499, 0, 0, 0, 0, 0, 0, + 0, 179, 144, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 147, 145, 140, 141, + 142, 146, 0, 0, 0, 0, 0, 0, 137, 0, + 0, 0, 0, 0, 0, 0, 0, 148, 1798, 1801, + 1802, 1803, 1804, 1805, 1806, 0, 1807, 1808, 1810, 1811, + 1809, 1812, 1813, 1786, 1787, 1788, 1789, 1770, 1771, 1799, + 0, 1773, 0, 1774, 1775, 1776, 1777, 1778, 1779, 1780, + 1781, 1782, 0, 0, 1783, 1790, 1791, 1792, 1793, 0, + 1794, 1795, 1796, 1797, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1745, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 164, 0, 0, 1762, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2596, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2602, 2603, 2604, 2605, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1499, 0, 0, 0, 0, 0, 0, + 0, 0, 1784, 0, 0, 0, 0, 0, 0, 0, + 0, 1901, 0, 0, 0, 0, 0, 0, 1512, 0, + 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1946, 0, 0, 0, + 195, 0, 0, 0, 720, 720, 0, 0, 0, 0, + 0, 0, 0, 1972, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 1983, + 0, 0, 0, 0, 0, 0, 1987, 0, 0, 1800, + 0, 0, 0, 720, 0, 0, 195, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 0, 0, 0, 0, 720, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, + 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1772, 0, + 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 1499, 0, 0, 0, 177, + 0, 720, 720, 0, 720, 0, 720, 720, 0, 720, + 720, 720, 720, 720, 720, 0, 0, 0, 0, 0, + 0, 1733, 1499, 0, 0, 1499, 720, 1499, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 147, 145, 140, 141, 142, 146, 0, 0, - 0, 0, 0, 0, 137, 0, 0, 0, 0, 0, - 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, 0, 0, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2595, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2601, 2602, 2603, 2604, 0, 0, 0, - 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1498, 0, 0, 0, 0, 0, 0, 0, + 0, 720, 1785, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 195, + 195, 0, 0, 166, 171, 168, 174, 175, 176, 178, + 180, 181, 182, 183, 0, 0, 195, 0, 0, 184, + 186, 187, 188, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 720, 0, 2034, 1798, 1801, 1802, 1803, 1804, 1805, + 1806, 0, 1807, 1808, 1810, 1811, 1809, 1812, 1813, 1786, + 1787, 1788, 1789, 1770, 1771, 1799, 0, 1773, 0, 1774, + 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 0, 0, + 1783, 1790, 1791, 1792, 1793, 0, 1794, 1795, 1796, 1797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1511, 0, 0, 1799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 720, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1744, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 1761, 0, 0, 0, - 0, 0, 720, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1498, 0, 0, 0, 0, 1900, - 720, 720, 0, 720, 0, 720, 720, 0, 720, 720, - 720, 720, 720, 720, 0, 152, 0, 0, 153, 1732, - 0, 1498, 0, 0, 1498, 720, 1498, 195, 0, 0, - 0, 0, 0, 0, 1945, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 165, 0, - 0, 1971, 0, 0, 0, 177, 0, 0, 0, 0, - 720, 0, 195, 0, 0, 0, 0, 1982, 0, 0, - 0, 0, 0, 0, 1986, 0, 720, 0, 195, 195, - 0, 0, 0, 0, 0, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 0, 0, 0, 195, 185, 0, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 720, 0, 0, 0, 0, 0, 0, 0, 939, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, - 171, 168, 174, 175, 176, 178, 180, 181, 182, 183, - 0, 0, 0, 0, 0, 184, 186, 187, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1050, 0, 0, 3002, 3003, 0, 0, 3005, 0, + 0, 3007, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 720, + 0, 3014, 3015, 3016, 0, 0, 0, 0, 0, 0, + 0, 720, 0, 3021, 0, 0, 3023, 3024, 3025, 0, + 195, 0, 3026, 3027, 0, 0, 3028, 0, 3029, 0, + 0, 0, 0, 0, 0, 3030, 0, 3031, 0, 0, + 0, 3032, 0, 3033, 0, 0, 3034, 0, 3035, 0, + 3036, 0, 3037, 0, 3038, 0, 3039, 0, 3040, 0, + 3041, 0, 3042, 0, 3043, 0, 3044, 0, 3045, 720, + 3046, 0, 3047, 0, 3048, 0, 3049, 0, 3050, 1499, + 3051, 0, 0, 0, 3052, 1800, 3053, 0, 3054, 0, + 0, 3055, 0, 3056, 0, 3057, 1499, 2241, 3059, 0, + 0, 3061, 0, 0, 3063, 3064, 3065, 3066, 0, 0, + 0, 0, 3067, 2241, 2241, 2241, 2241, 2241, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3077, 0, + 2352, 0, 0, 0, 0, 0, 3090, 0, 2356, 3094, + 2359, 1050, 0, 2034, 0, 0, 0, 0, 3097, 3098, + 3099, 3100, 3101, 3102, 0, 0, 0, 3103, 3104, 0, + 3105, 0, 3106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 699, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2974, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 1050, - 0, 0, 3001, 3002, 0, 0, 3004, 0, 0, 3006, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2033, 0, 0, 0, 0, 0, 720, 720, 0, 3013, - 3014, 3015, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 3020, 0, 0, 3022, 3023, 3024, 0, 195, 0, - 3025, 3026, 0, 0, 3027, 0, 3028, 0, 0, 0, - 0, 0, 0, 3029, 0, 3030, 0, 0, 0, 3031, - 0, 3032, 0, 0, 3033, 0, 3034, 0, 3035, 0, - 3036, 0, 3037, 0, 3038, 0, 3039, 0, 3040, 0, - 3041, 0, 3042, 0, 3043, 0, 3044, 720, 3045, 0, - 3046, 0, 3047, 0, 3048, 0, 3049, 1498, 3050, 0, - 0, 0, 3051, 0, 3052, 0, 3053, 0, 0, 3054, - 0, 3055, 0, 3056, 1498, 2240, 3058, 0, 0, 3060, - 0, 0, 3062, 3063, 3064, 3065, 0, 0, 0, 0, - 3066, 2240, 2240, 2240, 2240, 2240, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3076, 0, 0, 0, - 0, 0, 0, 0, 3089, 0, 0, 3093, 0, 1050, - 0, 0, 0, 0, 0, 0, 3096, 3097, 3098, 3099, - 3100, 3101, 0, 0, 0, 3102, 3103, 0, 3104, 0, - 3105, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3136, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2288, 0, - 3166, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 957, 0, 0, 0, 0, 958, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2083, 0, - 0, 0, 195, 0, 0, 0, 0, 720, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2351, 0, 0, - 0, 3229, 0, 0, 0, 2355, 0, 2358, 0, 0, - 2033, 0, 195, 0, 0, 720, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 720, - 0, 0, 2288, 195, 0, 195, 0, 195, 195, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 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, 0, 0, 3321, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 3330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, - 0, 0, 720, 0, 0, 190, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1837, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, - 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 0, 0, 0, 0, 0, 0, 720, - 0, 0, 0, 0, 720, 0, 0, 0, 720, 720, - 0, 0, 0, 0, 0, 0, 0, 0, 2033, 0, - 0, 0, 0, 162, 0, 2516, 0, 0, 0, 150, - 0, 0, 0, 0, 2533, 2534, 0, 0, 2538, 0, - 0, 0, 0, 0, 0, 0, 195, 0, 169, 0, - 2543, 170, 0, 195, 0, 0, 0, 2546, 719, 1414, - 719, 719, 195, 195, 0, 0, 195, 0, 195, 0, - 1841, 1842, 161, 160, 189, 0, 0, 0, 195, 0, - 719, 0, 0, 2549, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1497, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 720, 0, 0, 0, 0, 0, 0, 0, 3525, 0, + 2289, 0, 3167, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 190, 0, 0, 0, 720, + 0, 0, 0, 0, 0, 0, 1838, 0, 0, 0, + 0, 0, 0, 3230, 0, 0, 0, 0, 0, 129, + 0, 151, 0, 0, 195, 0, 0, 720, 0, 0, + 0, 0, 172, 0, 0, 0, 0, 195, 0, 0, + 0, 720, 0, 0, 2289, 195, 0, 195, 0, 195, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2034, 0, 162, 720, 0, 0, 0, 2517, 150, + 0, 0, 0, 0, 0, 0, 0, 2534, 2535, 0, + 0, 2539, 0, 0, 0, 0, 0, 0, 169, 0, + 0, 170, 0, 2544, 0, 0, 0, 0, 0, 0, + 2547, 0, 0, 0, 0, 0, 0, 0, 0, 3322, + 1842, 1843, 161, 160, 189, 0, 0, 0, 0, 0, + 0, 720, 0, 3331, 0, 0, 2550, 0, 0, 0, + 0, 939, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 699, 0, 0, 0, 0, 0, 719, + 0, 720, 0, 0, 0, 0, 720, 0, 0, 0, + 720, 720, 0, 0, 0, 155, 1844, 158, 0, 1841, + 0, 156, 157, 0, 0, 0, 0, 0, 173, 0, + 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 0, 719, 0, 719, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 195, 0, 0, 195, 0, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 195, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, + 3526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3549, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155, 1843, 158, 0, 1840, - 0, 156, 157, 0, 0, 0, 0, 0, 173, 1498, - 0, 2288, 0, 0, 0, 0, 0, 179, 0, 0, + 0, 164, 0, 3550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3569, - 0, 3570, 0, 0, 3571, 0, 0, 3574, 3575, 0, - 0, 0, 0, 0, 0, 0, 3579, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 897, 0, 0, - 3580, 0, 3581, 0, 3582, 0, 3583, 0, 3584, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1499, 0, 2289, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3570, 0, 3571, 0, 0, 3572, 0, 0, 3575, + 3576, 0, 0, 0, 0, 0, 0, 0, 3580, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3581, 0, 3582, 0, 3583, 159, 3584, 0, 3585, 0, 3586, 0, 3587, 0, 3588, 0, 3589, 0, 3590, 0, 3591, 0, 3592, 0, 3593, 0, 3594, 0, - 3595, 0, 0, 3596, 0, 0, 0, 3597, 0, 3598, - 0, 0, 0, 0, 0, 3600, 0, 0, 0, 0, - 0, 0, 0, 193, 0, 0, 664, 0, 0, 1497, - 0, 0, 0, 0, 0, 0, 0, 0, 3617, 0, - 0, 164, 0, 0, 0, 0, 664, 3622, 0, 3623, - 3624, 0, 3625, 0, 3626, 0, 0, 0, 0, 3627, - 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1051, - 1051, 0, 0, 0, 3652, 0, 0, 0, 664, 0, - 719, 719, 0, 0, 0, 3660, 0, 0, 3662, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3666, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3800, 0, 0, 719, - 0, 0, 0, 195, 0, 0, 0, 159, 0, 0, - 0, 195, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 720, 0, 0, 1814, 0, 0, 0, 0, - 0, 0, 0, 720, 2849, 1823, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 719, 0, - 1849, 0, 195, 0, 0, 0, 0, 0, 1858, 0, - 0, 1497, 1860, 0, 0, 1863, 1864, 719, 719, 0, - 719, 0, 719, 719, 0, 719, 719, 719, 719, 719, - 719, 0, 0, 0, 0, 0, 0, 0, 1497, 1895, - 1896, 1497, 719, 1497, 0, 1901, 0, 0, 2898, 0, - 0, 0, 0, 0, 896, 152, 0, 0, 153, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3908, - 720, 0, 0, 0, 0, 0, 195, 719, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 165, 0, - 1963, 0, 0, 719, 0, 177, 0, 720, 0, 0, - 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 2947, 2948, 2949, 2950, 2951, 2952, - 0, 0, 718, 0, 0, 0, 0, 0, 0, 1498, - 0, 0, 0, 0, 0, 0, 185, 719, 0, 2033, - 2962, 0, 195, 195, 195, 195, 195, 195, 0, 0, + 3595, 0, 3596, 0, 0, 3597, 0, 2850, 0, 3598, + 0, 3599, 0, 0, 0, 0, 0, 3601, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2970, 0, 0, 195, 195, 0, - 0, 0, 0, 0, 1075, 0, 1082, 0, 0, 166, + 3618, 0, 0, 0, 0, 0, 0, 0, 0, 3623, + 0, 3624, 3625, 0, 3626, 0, 3627, 0, 0, 0, + 0, 3628, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2899, 0, 0, 0, 152, 3653, 0, 153, 0, + 0, 0, 0, 0, 0, 0, 0, 3661, 0, 0, + 3663, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3667, 0, 0, 0, 0, 0, 165, 0, + 0, 0, 0, 0, 0, 177, 0, 0, 3801, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 2948, 2949, 2950, + 2951, 2952, 2953, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 185, 0, 0, 0, + 0, 0, 2034, 2963, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, + 0, 0, 0, 0, 195, 0, 0, 2971, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 171, 168, 174, 175, 176, 178, 180, 181, 182, 183, - 0, 0, 195, 0, 0, 184, 186, 187, 188, 0, + 0, 0, 0, 0, 0, 184, 186, 187, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3909, 720, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, + 0, 1499, 0, 958, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2084, 195, 195, 195, 195, 195, 195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 1415, 719, 719, 0, 0, 0, 0, 195, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1498, 0, 0, 0, 0, 720, 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, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, + 897, 0, 0, 0, 3949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3963, 0, 0, 3964, 0, 3965, 193, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3220, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, + 0, 0, 0, 3258, 0, 0, 0, 0, 0, 0, + 720, 0, 1051, 1051, 0, 0, 0, 3272, 0, 0, + 0, 664, 720, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3290, 0, 0, + 3293, 0, 1498, 0, 0, 0, 0, 0, 0, 4044, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, - 0, 0, 3948, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 720, 0, 0, 0, 0, 0, 0, 4060, 0, + 4061, 0, 4062, 0, 0, 720, 0, 0, 0, 1499, + 0, 0, 720, 720, 1499, 195, 195, 195, 195, 195, + 0, 0, 0, 719, 719, 0, 0, 195, 0, 0, + 0, 0, 0, 195, 0, 195, 0, 0, 195, 195, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4111, 0, 4112, 0, 0, 719, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 1815, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 1824, 0, + 1499, 0, 0, 0, 0, 720, 0, 0, 0, 3445, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 896, 1850, 195, 0, 0, 0, 0, 0, + 0, 1859, 0, 0, 1498, 1861, 0, 0, 1864, 1865, + 719, 719, 0, 719, 195, 719, 719, 195, 719, 719, + 719, 719, 719, 719, 0, 0, 0, 0, 0, 0, + 0, 1498, 1896, 1897, 1498, 719, 1498, 0, 1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 3962, 0, - 0, 3963, 0, 3964, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 718, 0, 0, 0, 3504, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1964, 3519, 0, 719, 3520, 3521, 3522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1075, 0, 1082, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 720, 0, - 0, 0, 0, 0, 1497, 0, 0, 0, 0, 0, - 720, 0, 0, 2092, 0, 0, 0, 0, 0, 0, - 0, 1497, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4043, 0, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 664, 720, - 664, 0, 0, 0, 0, 0, 4059, 0, 4060, 0, - 4061, 0, 0, 720, 0, 0, 0, 1498, 0, 0, - 720, 720, 1498, 195, 195, 195, 195, 195, 0, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 195, 0, 195, 0, 0, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 664, 0, 0, 0, 3219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4110, 0, 4111, 0, 0, 0, 0, 0, 1499, 0, - 3257, 0, 195, 0, 0, 719, 0, 0, 0, 0, - 0, 0, 0, 0, 3271, 720, 0, 0, 1498, 0, - 0, 0, 0, 720, 0, 0, 0, 0, 195, 0, - 0, 0, 0, 0, 3289, 0, 0, 3292, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 195, 195, 195, 0, 0, 0, + 0, 0, 0, 0, 720, 720, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 720, 720, 720, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 664, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1498, 0, + 0, 0, 0, 0, 0, 0, 0, 2093, 0, 0, + 0, 0, 0, 0, 0, 1498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 720, - 0, 0, 0, 2448, 2449, 2450, 3444, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1499, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 719, - 1858, 0, 0, 1858, 195, 1858, 0, 0, 0, 0, - 0, 2480, 0, 0, 1262, 0, 1262, 1262, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1426, 0, 0, 0, - 0, 0, 0, 0, 0, 664, 719, 0, 0, 0, - 0, 719, 0, 0, 0, 719, 719, 0, 0, 0, - 195, 3503, 0, 0, 0, 0, 0, 0, 1032, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3518, 0, 0, 3519, 3520, 3521, 0, 0, 195, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 664, 0, 195, 195, 195, 0, 0, 0, 0, 0, - 0, 0, 720, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1499, 0, 0, 0, 0, 0, 0, 719, 0, 0, - 0, 720, 720, 720, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1499, 0, 0, - 1499, 0, 1499, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1917, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 0, 0, 0, 0, 1497, 0, 719, 0, - 0, 0, 0, 0, 1969, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 0, 0, 0, 0, 0, 1995, 1996, 664, - 664, 664, 664, 664, 664, 664, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1499, 0, 0, 0, 0, + 720, 0, 720, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1693, 1694, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1498, 0, 0, 0, 0, 720, 0, - 720, 0, 0, 0, 0, 1738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1756, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 720, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, - 0, 0, 0, 0, 1075, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 1866, 1866, 0, 1866, 720, 1866, 1866, - 0, 1875, 1866, 1866, 1866, 1866, 1866, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1075, 0, - 0, 0, 0, 0, 664, 0, 0, 0, 0, 719, + 0, 1500, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1943, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1967, - 720, 0, 0, 0, 720, 720, 0, 0, 0, 0, - 0, 0, 0, 1499, 0, 2862, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1051, 1051, 0, 0, 0, - 1499, 0, 0, 720, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 0, 0, 0, 720, 720, 0, 0, + 0, 0, 1263, 0, 1263, 1263, 0, 0, 664, 0, + 719, 3947, 0, 0, 0, 0, 0, 2449, 2450, 2451, + 0, 0, 0, 0, 1427, 720, 0, 0, 0, 0, + 0, 1032, 0, 0, 0, 0, 0, 719, 0, 0, + 0, 0, 0, 719, 1859, 0, 0, 1859, 0, 1859, + 0, 0, 0, 0, 664, 2481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 719, 0, 0, 0, 1858, 1858, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 719, 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1497, 2935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1051, 1969, 1051, 1051, 1051, 1051, 1051, - 0, 720, 0, 0, 0, 0, 0, 0, 3946, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 1500, 0, 0, 1500, 0, 1500, 664, 0, 0, 0, + 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1918, 0, 0, 195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 664, 0, 0, 0, 0, 0, 720, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 1970, 664, 0, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, + 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 1996, 1997, 664, 664, 664, 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 195, 0, 1917, 1262, - 1262, 0, 719, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2021, 0, 1051, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 1969, 664, - 719, 664, 0, 664, 2374, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 2078, 0, 0, 0, 0, 0, 0, 0, 0, 1498, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 1498, 1499, 719, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 2288, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 2289, 0, + 0, 0, 0, 0, 1694, 1695, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, + 0, 0, 0, 195, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 1739, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 720, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, - 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 0, 0, 1075, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 720, + 0, 1867, 1867, 0, 1867, 0, 1867, 1867, 664, 1876, + 1867, 1867, 1867, 1867, 1867, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1075, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 720, 0, 719, 0, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 719, 720, 0, 0, - 0, 1262, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 1497, 0, 0, 719, 719, 1497, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 664, - 0, 0, 664, 0, 2540, 0, 0, 0, 0, 0, - 2325, 0, 0, 0, 664, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2337, 0, - 3214, 0, 0, 0, 0, 0, 0, 664, 0, 0, - 0, 0, 1738, 0, 0, 1262, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 1497, 0, 0, 0, 0, - 719, 0, 0, 95, 0, 1075, 957, 0, 0, 0, - 945, 958, 959, 960, 961, 946, 0, 0, 947, 948, - 0, 949, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 954, 962, 963, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3296, 0, 0, 1499, 0, 1969, 0, 0, - 0, 0, 1082, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3265, 3266, 0, 0, 0, 1075, - 0, 0, 0, 0, 0, 1082, 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, 0, 0, - 0, 0, 1075, 0, 0, 0, 0, 2078, 0, 0, - 0, 2078, 2078, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1944, 0, 0, 0, 0, 0, 1500, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1968, 0, 1051, + 1051, 0, 0, 0, 1500, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3268, 3269, 0, 0, - 0, 0, 0, 2552, 0, 3493, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 1917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1051, 1970, 1051, + 1051, 1051, 1051, 1051, 0, 0, 0, 0, 719, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 1859, + 1859, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1498, 2936, 1918, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1051, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1263, 1263, + 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, + 0, 2022, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 1970, 664, 0, 664, 0, 664, 2375, 95, + 0, 0, 957, 0, 0, 0, 945, 958, 959, 960, + 961, 946, 0, 0, 947, 948, 0, 949, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 954, 962, 963, 0, 0, 0, 0, 0, 2079, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 3266, 3267, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 1263, 719, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 664, 0, 0, 664, 0, 2541, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, + 0, 0, 719, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2326, + 719, 0, 3269, 3270, 0, 0, 0, 0, 0, 0, + 0, 664, 0, 0, 719, 0, 0, 0, 1498, 0, + 0, 719, 719, 1498, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 1262, 0, 0, 0, 664, 0, - 910, 0, 0, 0, 0, 0, 914, 0, 0, 0, - 911, 912, 0, 0, 0, 913, 915, 0, 719, 719, - 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1739, 0, 0, 1263, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3215, 0, 910, 0, 0, 1500, + 0, 1970, 914, 0, 0, 0, 911, 912, 0, 0, + 0, 913, 915, 0, 0, 0, 719, 0, 0, 1498, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 1082, 0, 0, 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, 1082, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 2904, 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, 2079, 0, 0, 0, + 2079, 2079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1499, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 664, - 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1497, 0, 0, 0, 0, 719, 0, 719, 0, 0, - 0, 0, 0, 0, 0, 1051, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2797, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 1918, 2553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 3494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2894, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, - 2337, 719, 719, 0, 0, 0, 0, 2919, 0, 0, - 0, 0, 0, 0, 0, 1051, 2924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 2905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 719, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1499, 0, 0, 0, 0, 1499, 664, - 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, - 0, 3164, 0, 0, 0, 0, 0, 1917, 0, 664, - 0, 0, 664, 3172, 1969, 0, 0, 0, 2078, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 664, 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3688, 3690, 3689, 3753, 3754, 3755, 3756, 3757, - 3758, 3759, 789, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 0, 0, 0, 0, 2078, 0, 719, 0, - 0, 0, 0, 0, 1499, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, - 0, 3078, 0, 0, 0, 0, 1497, 0, 719, 0, - 0, 0, 0, 1262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1866, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 3121, 0, 0, 0, 0, 0, 0, 719, - 0, 0, 0, 0, 0, 0, 1262, 0, 0, 0, - 0, 0, 0, 3148, 1866, 0, 0, 0, 0, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 3694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 0, 3702, 3703, 0, 0, 3778, 3777, 3776, - 0, 0, 3774, 3775, 3773, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 719, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1075, 0, - 0, 0, 0, 0, 0, 664, 2337, 3779, 910, 0, - 765, 766, 3780, 3781, 914, 3782, 768, 769, 911, 912, - 0, 763, 767, 913, 915, 664, 0, 0, 664, 664, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3685, - 3686, 3687, 3691, 3692, 3693, 3704, 3751, 3752, 3760, 3762, - 866, 3761, 3763, 3764, 3765, 3768, 3769, 3770, 3771, 3766, - 3767, 3772, 3668, 3672, 3669, 3670, 3671, 3683, 3673, 3674, - 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3684, 3783, - 3784, 3785, 3786, 3787, 3788, 3697, 3701, 3700, 3698, 3699, - 3695, 3696, 3723, 3722, 3724, 3725, 3726, 3727, 3728, 3729, - 3731, 3730, 3732, 3733, 3734, 3735, 3736, 3737, 3705, 3706, - 3709, 3710, 3708, 3707, 3711, 3720, 3721, 3712, 3713, 3714, - 3715, 3716, 3717, 3719, 3718, 3738, 3739, 3740, 3741, 3742, - 3744, 3743, 3747, 3748, 3746, 3745, 3750, 3749, 0, 0, - 0, 0, 3409, 0, 0, 0, 0, 0, 0, 0, - 916, 0, 917, 0, 0, 921, 0, 0, 0, 923, - 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, - 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2798, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2813, 0, 0, 0, 0, + 0, 0, 0, 0, 1498, 0, 0, 0, 0, 719, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1917, 0, 0, 0, 0, 3789, 3790, 3791, 3792, 3793, - 3794, 3795, 3796, 0, 0, 0, 0, 0, 0, 1499, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, + 0, 0, 2895, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1051, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2338, + 0, 0, 0, 0, 0, 0, 2920, 0, 0, 0, + 0, 0, 0, 0, 0, 2925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 0, 0, 0, 719, 719, 1500, 0, 0, + 0, 0, 1500, 664, 664, 664, 664, 664, 0, 0, + 0, 0, 0, 0, 0, 3165, 0, 0, 0, 0, + 0, 1918, 0, 664, 719, 0, 664, 3173, 1970, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2337, 2337, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, + 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1917, 0, 0, + 0, 0, 664, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3557, 3558, 3559, 3560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3079, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1867, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1498, 3122, 719, 0, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1263, 0, 0, 0, 0, + 0, 0, 3149, 1867, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 1075, 0, 664, + 0, 0, 664, 664, 664, 2338, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 3689, 3691, + 3690, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 789, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2685,1299 +2693,693 @@ 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, 3656, 0, 3658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2337, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1917, 0, 0, 0, 3823, 0, 0, + 0, 3410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1262, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1500, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3695, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3703, + 3704, 0, 0, 3779, 3778, 3777, 0, 0, 3775, 3776, + 3774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3896, 0, 0, 0, 3896, 3896, 0, - 0, 0, 0, 0, 0, 1499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2337, 0, 0, 0, - 0, 0, 3999, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2338, 2338, 0, 0, 0, 0, + 0, 1918, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3780, 910, 0, 765, 766, 3781, 3782, + 914, 3783, 768, 769, 911, 912, 0, 763, 767, 913, + 915, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3558, 3559, 3560, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3686, 3687, 3688, 3692, 3693, + 3694, 3705, 3752, 3753, 3761, 3763, 866, 3762, 3764, 3765, + 3766, 3769, 3770, 3771, 3772, 3767, 3768, 3773, 3669, 3673, + 3670, 3671, 3672, 3684, 3674, 3675, 3676, 3677, 3678, 3679, + 3680, 3681, 3682, 3683, 3685, 3784, 3785, 3786, 3787, 3788, + 3789, 3698, 3702, 3701, 3699, 3700, 3696, 3697, 3724, 3723, + 3725, 3726, 3727, 3728, 3729, 3730, 3732, 3731, 3733, 3734, + 3735, 3736, 3737, 3738, 3706, 3707, 3710, 3711, 3709, 3708, + 3712, 3721, 3722, 3713, 3714, 3715, 3716, 3717, 3718, 3720, + 3719, 3739, 3740, 3741, 3742, 3743, 3745, 3744, 3748, 3749, + 3747, 3746, 3751, 3750, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 916, 0, 917, 0, + 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, + 885, 0, 0, 918, 919, 0, 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3657, 0, 3659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 0, + 0, 0, 0, 0, 0, 0, 0, 1918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2338, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3824, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2337, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3897, 0, 0, 0, 3897, 3897, 0, 0, + 0, 0, 0, 0, 0, 0, 4000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3973, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1262, 1262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1970, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4019, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3973, 0, 0, + 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 392, 3409, 0, - 4027, 1397, 1383, 520, 0, 1325, 1400, 1294, 1313, 1410, - 1316, 1319, 1362, 1272, 1340, 411, 1310, 1265, 1298, 1267, - 1305, 1268, 1296, 1327, 269, 1293, 1385, 1344, 1399, 362, - 266, 1274, 1299, 425, 1315, 203, 1364, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 1406, 366, 1350, 0, 491, 396, 0, 0, 0, - 1329, 1389, 1338, 1376, 1324, 1363, 1282, 1349, 1401, 1311, - 1359, 1402, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 4001, 941, 0, 0, 0, 0, 4002, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 1307, 1356, 1396, 1308, 1358, 264, 319, 271, 263, - 572, 1407, 1388, 1271, 1337, 1395, 1332, 0, 0, 228, - 1398, 1331, 0, 1361, 0, 1413, 1266, 1352, 0, 1269, - 1273, 1409, 1393, 1302, 274, 0, 0, 0, 0, 0, - 0, 0, 1328, 1339, 1373, 1377, 1322, 0, 0, 0, - 0, 0, 0, 0, 0, 1300, 0, 1348, 0, 0, - 0, 1278, 1270, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1326, 0, 0, 0, 0, - 1281, 0, 1301, 1374, 0, 1264, 296, 1275, 397, 256, - 0, 448, 1381, 1392, 1323, 616, 1394, 1321, 1320, 1368, - 1279, 1387, 1314, 361, 1277, 328, 197, 224, 0, 1312, - 407, 456, 468, 1386, 1297, 1306, 252, 1304, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 1347, 1366, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 1276, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 1292, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 1382, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 1371, - 1412, 420, 467, 239, 596, 490, 199, 1286, 1291, 1284, - 0, 253, 254, 1353, 567, 1287, 1285, 1342, 1343, 1288, - 1403, 1404, 1405, 1390, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 1375, 1280, 0, 1289, 1290, 1384, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 1346, 196, 220, - 364, 1408, 449, 287, 637, 606, 601, 205, 222, 1283, - 261, 1295, 1303, 0, 1309, 1317, 1318, 1330, 1333, 1334, - 1335, 1336, 1354, 1355, 1357, 1365, 1367, 1370, 1372, 1379, - 1391, 1411, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 1345, 1351, 377, 280, 303, 318, 1360, 605, 496, 226, - 461, 289, 250, 1378, 1380, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 1341, - 1369, 372, 568, 569, 314, 392, 0, 0, 0, 1397, - 1383, 520, 0, 1325, 1400, 1294, 1313, 1410, 1316, 1319, - 1362, 1272, 1340, 411, 1310, 1265, 1298, 1267, 1305, 1268, - 1296, 1327, 269, 1293, 1385, 1344, 1399, 362, 266, 1274, - 1299, 425, 1315, 203, 1364, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 1406, - 366, 1350, 0, 491, 396, 0, 0, 0, 1329, 1389, - 1338, 1376, 1324, 1363, 1282, 1349, 1401, 1311, 1359, 1402, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 1307, - 1356, 1396, 1308, 1358, 264, 319, 271, 263, 572, 1407, - 1388, 1271, 1337, 1395, 1332, 0, 0, 228, 1398, 1331, - 0, 1361, 0, 1413, 1266, 1352, 0, 1269, 1273, 1409, - 1393, 1302, 274, 0, 0, 0, 0, 0, 0, 0, - 1328, 1339, 1373, 1377, 1322, 0, 0, 0, 0, 0, - 0, 3173, 0, 1300, 0, 1348, 0, 0, 0, 1278, - 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1326, 0, 0, 0, 0, 1281, 0, - 1301, 1374, 0, 1264, 296, 1275, 397, 256, 0, 448, - 1381, 1392, 1323, 616, 1394, 1321, 1320, 1368, 1279, 1387, - 1314, 361, 1277, 328, 197, 224, 0, 1312, 407, 456, - 468, 1386, 1297, 1306, 252, 1304, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 1347, 1366, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 1276, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 1292, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 1382, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 1371, 1412, 420, - 467, 239, 596, 490, 199, 1286, 1291, 1284, 0, 253, - 254, 1353, 567, 1287, 1285, 1342, 1343, 1288, 1403, 1404, - 1405, 1390, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 1375, 1280, 0, 1289, 1290, 1384, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 1346, 196, 220, 364, 1408, - 449, 287, 637, 606, 601, 205, 222, 1283, 261, 1295, - 1303, 0, 1309, 1317, 1318, 1330, 1333, 1334, 1335, 1336, - 1354, 1355, 1357, 1365, 1367, 1370, 1372, 1379, 1391, 1411, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 1345, 1351, - 377, 280, 303, 318, 1360, 605, 496, 226, 461, 289, - 250, 1378, 1380, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 1341, 1369, 372, - 568, 569, 314, 392, 0, 0, 0, 1397, 1383, 520, - 0, 1325, 1400, 1294, 1313, 1410, 1316, 1319, 1362, 1272, - 1340, 411, 1310, 1265, 1298, 1267, 1305, 1268, 1296, 1327, - 269, 1293, 1385, 1344, 1399, 362, 266, 1274, 1299, 425, - 1315, 203, 1364, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 1406, 366, 1350, - 0, 491, 396, 0, 0, 0, 1329, 1389, 1338, 1376, - 1324, 1363, 1282, 1349, 1401, 1311, 1359, 1402, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 1307, 1356, 1396, - 1308, 1358, 264, 319, 271, 263, 572, 1407, 1388, 1271, - 1337, 1395, 1332, 0, 0, 228, 1398, 1331, 0, 1361, - 0, 1413, 1266, 1352, 0, 1269, 1273, 1409, 1393, 1302, - 274, 0, 0, 0, 0, 0, 0, 0, 1328, 1339, - 1373, 1377, 1322, 0, 0, 0, 0, 0, 0, 3134, - 0, 1300, 0, 1348, 0, 0, 0, 1278, 1270, 0, + 0, 0, 0, 0, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1326, 0, 0, 0, 0, 1281, 0, 1301, 1374, - 0, 1264, 296, 1275, 397, 256, 0, 448, 1381, 1392, - 1323, 616, 1394, 1321, 1320, 1368, 1279, 1387, 1314, 361, - 1277, 328, 197, 224, 0, 1312, 407, 456, 468, 1386, - 1297, 1306, 252, 1304, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 1347, 1366, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 1276, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 1292, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 1382, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 1371, 1412, 420, 467, 239, - 596, 490, 199, 1286, 1291, 1284, 0, 253, 254, 1353, - 567, 1287, 1285, 1342, 1343, 1288, 1403, 1404, 1405, 1390, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 1375, 1280, - 0, 1289, 1290, 1384, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 1346, 196, 220, 364, 1408, 449, 287, - 637, 606, 601, 205, 222, 1283, 261, 1295, 1303, 0, - 1309, 1317, 1318, 1330, 1333, 1334, 1335, 1336, 1354, 1355, - 1357, 1365, 1367, 1370, 1372, 1379, 1391, 1411, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 1345, 1351, 377, 280, - 303, 318, 1360, 605, 496, 226, 461, 289, 250, 1378, - 1380, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 1341, 1369, 372, 568, 569, - 314, 392, 0, 0, 0, 1397, 1383, 520, 0, 1325, - 1400, 1294, 1313, 1410, 1316, 1319, 1362, 1272, 1340, 411, - 1310, 1265, 1298, 1267, 1305, 1268, 1296, 1327, 269, 1293, - 1385, 1344, 1399, 362, 266, 1274, 1299, 425, 1315, 203, - 1364, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 1406, 366, 1350, 0, 491, - 396, 0, 0, 0, 1329, 1389, 1338, 1376, 1324, 1363, - 1282, 1349, 1401, 1311, 1359, 1402, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 941, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 1307, 1356, 1396, 1308, 1358, - 264, 319, 271, 263, 572, 1407, 1388, 1271, 1337, 1395, - 1332, 0, 0, 228, 1398, 1331, 0, 1361, 0, 1413, - 1266, 1352, 0, 1269, 1273, 1409, 1393, 1302, 274, 0, - 0, 0, 0, 0, 0, 0, 1328, 1339, 1373, 1377, - 1322, 0, 0, 0, 0, 0, 0, 2353, 0, 1300, - 0, 1348, 0, 0, 0, 1278, 1270, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1326, - 0, 0, 0, 0, 1281, 0, 1301, 1374, 0, 1264, - 296, 1275, 397, 256, 0, 448, 1381, 1392, 1323, 616, - 1394, 1321, 1320, 1368, 1279, 1387, 1314, 361, 1277, 328, - 197, 224, 0, 1312, 407, 456, 468, 1386, 1297, 1306, - 252, 1304, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 1347, 1366, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 1276, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 1292, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 1382, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 1371, 1412, 420, 467, 239, 596, 490, - 199, 1286, 1291, 1284, 0, 253, 254, 1353, 567, 1287, - 1285, 1342, 1343, 1288, 1403, 1404, 1405, 1390, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 1375, 1280, 0, 1289, - 1290, 1384, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 1346, 196, 220, 364, 1408, 449, 287, 637, 606, - 601, 205, 222, 1283, 261, 1295, 1303, 0, 1309, 1317, - 1318, 1330, 1333, 1334, 1335, 1336, 1354, 1355, 1357, 1365, - 1367, 1370, 1372, 1379, 1391, 1411, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 1345, 1351, 377, 280, 303, 318, - 1360, 605, 496, 226, 461, 289, 250, 1378, 1380, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 1341, 1369, 372, 568, 569, 314, 392, - 0, 0, 0, 1397, 1383, 520, 0, 1325, 1400, 1294, - 1313, 1410, 1316, 1319, 1362, 1272, 1340, 411, 1310, 1265, - 1298, 1267, 1305, 1268, 1296, 1327, 269, 1293, 1385, 1344, - 1399, 362, 266, 1274, 1299, 425, 1315, 203, 1364, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 1406, 366, 1350, 0, 491, 396, 0, - 0, 0, 1329, 1389, 1338, 1376, 1324, 1363, 1282, 1349, - 1401, 1311, 1359, 1402, 321, 247, 323, 202, 408, 492, - 285, 0, 95, 0, 0, 0, 709, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 1307, 1356, 1396, 1308, 1358, 264, 319, - 271, 263, 572, 1407, 1388, 1271, 1337, 1395, 1332, 0, - 0, 228, 1398, 1331, 0, 1361, 0, 1413, 1266, 1352, - 0, 1269, 1273, 1409, 1393, 1302, 274, 0, 0, 0, - 0, 0, 0, 0, 1328, 1339, 1373, 1377, 1322, 0, - 0, 0, 0, 0, 0, 0, 0, 1300, 0, 1348, - 0, 0, 0, 1278, 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1326, 0, 0, - 0, 0, 1281, 0, 1301, 1374, 0, 1264, 296, 1275, - 397, 256, 0, 448, 1381, 1392, 1323, 616, 1394, 1321, - 1320, 1368, 1279, 1387, 1314, 361, 1277, 328, 197, 224, - 0, 1312, 407, 456, 468, 1386, 1297, 1306, 252, 1304, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 1347, 1366, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 1276, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 1292, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 1382, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 1371, 1412, 420, 467, 239, 596, 490, 199, 1286, - 1291, 1284, 0, 253, 254, 1353, 567, 1287, 1285, 1342, - 1343, 1288, 1403, 1404, 1405, 1390, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 1375, 1280, 0, 1289, 1290, 1384, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 1346, - 196, 220, 364, 1408, 449, 287, 637, 606, 601, 205, - 222, 1283, 261, 1295, 1303, 0, 1309, 1317, 1318, 1330, - 1333, 1334, 1335, 1336, 1354, 1355, 1357, 1365, 1367, 1370, - 1372, 1379, 1391, 1411, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 1345, 1351, 377, 280, 303, 318, 1360, 605, - 496, 226, 461, 289, 250, 1378, 1380, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 1341, 1369, 372, 568, 569, 314, 392, 0, 0, - 0, 1397, 1383, 520, 0, 1325, 1400, 1294, 1313, 1410, - 1316, 1319, 1362, 1272, 1340, 411, 1310, 1265, 1298, 1267, - 1305, 1268, 1296, 1327, 269, 1293, 1385, 1344, 1399, 362, - 266, 1274, 1299, 425, 1315, 203, 1364, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 1406, 366, 1350, 0, 491, 396, 0, 0, 0, - 1329, 1389, 1338, 1376, 1324, 1363, 1282, 1349, 1401, 1311, - 1359, 1402, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 1307, 1356, 1396, 1308, 1358, 264, 319, 271, 263, - 572, 1407, 1388, 1271, 1337, 1395, 1332, 0, 0, 228, - 1398, 1331, 0, 1361, 0, 1413, 1266, 1352, 0, 1269, - 1273, 1409, 1393, 1302, 274, 0, 0, 0, 0, 0, - 0, 0, 1328, 1339, 1373, 1377, 1322, 0, 0, 0, - 0, 0, 0, 0, 0, 1300, 0, 1348, 0, 0, - 0, 1278, 1270, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1326, 0, 0, 0, 0, - 1281, 0, 1301, 1374, 0, 1264, 296, 1275, 397, 256, - 0, 448, 1381, 1392, 1323, 616, 1394, 1321, 1320, 1368, - 1279, 1387, 1314, 361, 1277, 328, 197, 224, 0, 1312, - 407, 456, 468, 1386, 1297, 1306, 252, 1304, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 1347, 1366, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 1276, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 1292, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 1382, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 1371, - 1412, 420, 467, 239, 596, 490, 199, 1286, 1291, 1284, - 0, 253, 254, 1353, 567, 1287, 1285, 1342, 1343, 1288, - 1403, 1404, 1405, 1390, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 1375, 1280, 0, 1289, 1290, 1384, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 1346, 196, 220, - 364, 1408, 449, 287, 637, 606, 601, 205, 222, 1283, - 261, 1295, 1303, 0, 1309, 1317, 1318, 1330, 1333, 1334, - 1335, 1336, 1354, 1355, 1357, 1365, 1367, 1370, 1372, 1379, - 1391, 1411, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 1345, 1351, 377, 280, 303, 318, 1360, 605, 496, 226, - 461, 289, 250, 1378, 1380, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 1341, - 1369, 372, 568, 569, 314, 392, 0, 0, 0, 1397, - 1383, 520, 0, 1325, 1400, 1294, 1313, 1410, 1316, 1319, - 1362, 1272, 1340, 411, 1310, 1265, 1298, 1267, 1305, 1268, - 1296, 1327, 269, 1293, 1385, 1344, 1399, 362, 266, 1274, - 1299, 425, 1315, 203, 1364, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 1406, - 366, 1350, 0, 491, 396, 0, 0, 0, 1329, 1389, - 1338, 1376, 1324, 1363, 1282, 1349, 1401, 1311, 1359, 1402, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 1307, - 1356, 1396, 1308, 1358, 264, 319, 271, 263, 572, 1407, - 1388, 1271, 1337, 1395, 1332, 0, 0, 228, 1398, 1331, - 0, 1361, 0, 1413, 1266, 1352, 0, 1269, 1273, 1409, - 1393, 1302, 274, 0, 0, 0, 0, 0, 0, 0, - 1328, 1339, 1373, 1377, 1322, 0, 0, 0, 0, 0, - 0, 0, 0, 1300, 0, 1348, 0, 0, 0, 1278, - 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1326, 0, 0, 0, 0, 1281, 0, - 1301, 1374, 0, 1264, 296, 1275, 397, 256, 0, 448, - 1381, 1392, 1323, 616, 1394, 1321, 1320, 1368, 1279, 1387, - 1314, 361, 1277, 328, 197, 224, 0, 1312, 407, 456, - 468, 1386, 1297, 1306, 252, 1304, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 1347, 1366, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 1276, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 1292, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 1382, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 1371, 1412, 420, - 467, 239, 596, 490, 199, 1286, 1291, 1284, 0, 253, - 254, 1353, 567, 1287, 1285, 1342, 1343, 1288, 1403, 1404, - 1405, 1390, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 1375, 1280, 0, 1289, 1290, 1384, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 1346, 196, 220, 364, 1408, - 449, 287, 637, 606, 601, 205, 222, 1283, 261, 1295, - 1303, 0, 1309, 1317, 1318, 1330, 1333, 1334, 1335, 1336, - 1354, 1355, 1357, 1365, 1367, 1370, 1372, 1379, 1391, 1411, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 1345, 1351, - 377, 280, 303, 318, 1360, 605, 496, 226, 461, 289, - 250, 1378, 1380, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 1341, 1369, 372, - 568, 569, 314, 392, 0, 0, 0, 1397, 1383, 520, - 0, 1325, 1400, 1294, 1313, 1410, 1316, 1319, 1362, 1272, - 1340, 411, 1310, 1265, 1298, 1267, 1305, 1268, 1296, 1327, - 269, 1293, 1385, 1344, 1399, 362, 266, 1274, 1299, 425, - 1315, 203, 1364, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 1406, 366, 1350, - 0, 491, 396, 0, 0, 0, 1329, 1389, 1338, 1376, - 1324, 1363, 1282, 1349, 1401, 1311, 1359, 1402, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, - 941, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 1307, 1356, 1396, - 1308, 1358, 264, 319, 271, 263, 572, 1407, 1388, 1271, - 1337, 1395, 1332, 0, 0, 228, 1398, 1331, 0, 1361, - 0, 1413, 1266, 1352, 0, 1269, 1273, 1409, 1393, 1302, - 274, 0, 0, 0, 0, 0, 0, 0, 1328, 1339, - 1373, 1377, 1322, 0, 0, 0, 0, 0, 0, 0, - 0, 1300, 0, 1348, 0, 0, 0, 1278, 1270, 0, + 0, 3974, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1263, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1326, 0, 0, 0, 0, 1281, 0, 1301, 1374, - 0, 1264, 296, 1275, 397, 256, 0, 448, 1381, 1392, - 1323, 616, 1394, 1321, 1320, 1368, 1279, 1387, 1314, 361, - 1277, 328, 197, 224, 0, 1312, 407, 456, 468, 1386, - 1297, 1306, 252, 1304, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 1347, 1366, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 1276, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 1292, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 1382, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 1371, 1412, 420, 467, 239, - 596, 490, 199, 1286, 1291, 1284, 0, 253, 254, 1353, - 567, 1287, 1285, 1342, 1343, 1288, 1403, 1404, 1405, 1390, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 1375, 1280, - 0, 1289, 1290, 1384, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 1346, 196, 220, 364, 1408, 449, 287, - 637, 606, 601, 205, 222, 1283, 261, 1295, 1303, 0, - 1309, 1317, 1318, 1330, 1333, 1334, 1335, 1336, 1354, 1355, - 1357, 1365, 1367, 1370, 1372, 1379, 1391, 1411, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 1345, 1351, 377, 280, - 303, 318, 1360, 605, 496, 226, 461, 289, 250, 1378, - 1380, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 1341, 1369, 372, 568, 569, - 314, 392, 0, 0, 0, 0, 0, 520, 0, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, - 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, - 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, - 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, - 264, 319, 271, 263, 572, 0, 0, 2176, 2177, 2178, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, - 0, 901, 0, 745, 0, 0, 753, 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, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, - 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, - 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, - 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, - 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, - 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, - 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, - 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, - 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, - 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, - 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, - 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, - 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, - 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, - 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, - 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, - 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, - 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, - 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, - 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, - 0, 0, 0, 0, 0, 0, 2382, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, - 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, - 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, - 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, - 963, 2383, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, - 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 755, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, - 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, - 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, - 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, - 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, - 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, - 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, - 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, - 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, - 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, - 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, - 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, - 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, - 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, - 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, - 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, - 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, - 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 0, 392, 372, 568, 569, - 314, 86, 520, 0, 761, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, - 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 0, 0, 0, 0, 0, 0, 3974, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2338, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 392, 3410, 0, 4028, + 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, + 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, + 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, 362, 266, + 1275, 1300, 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, - 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, - 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, - 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, - 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, - 0, 753, 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, 755, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 1407, 366, 1351, 0, 491, 396, 0, 0, 0, 1330, + 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, + 1403, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 4002, 941, 0, 0, 0, 0, 4003, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 1308, 1357, 1397, 1309, 1359, 264, 319, 271, 263, 572, + 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, 228, 1399, + 1332, 0, 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, + 1410, 1394, 1303, 274, 0, 0, 0, 0, 0, 0, + 0, 1329, 1340, 1374, 1378, 1323, 0, 0, 0, 0, + 0, 0, 0, 0, 1301, 0, 1349, 0, 0, 0, + 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1327, 0, 0, 0, 0, 1282, + 0, 1302, 1375, 0, 1265, 296, 1276, 397, 256, 0, + 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, + 1388, 1315, 361, 1278, 328, 197, 224, 0, 1313, 407, + 456, 468, 1387, 1298, 1307, 252, 1305, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 1348, 1367, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 1277, 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 805, 806, 279, 305, 882, 881, 880, 304, 306, - 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 1293, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 1383, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 888, 910, 899, 765, 766, - 889, 890, 914, 891, 768, 769, 911, 912, 762, 763, - 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, + 628, 631, 629, 402, 309, 489, 331, 369, 1372, 1413, + 420, 467, 239, 596, 490, 199, 1287, 1292, 1285, 0, + 253, 254, 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, + 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 902, 752, 751, 0, 758, 0, 787, 788, 790, - 794, 795, 796, 807, 854, 855, 863, 865, 866, 864, - 867, 868, 869, 872, 873, 874, 875, 870, 871, 876, - 770, 774, 771, 772, 773, 785, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 786, 925, 926, 927, - 928, 929, 930, 800, 804, 803, 801, 802, 798, 799, - 826, 825, 827, 828, 829, 830, 831, 832, 834, 833, - 835, 836, 837, 838, 839, 840, 808, 809, 812, 813, - 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, - 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, - 850, 851, 849, 848, 853, 852, 750, 196, 220, 364, - 94, 449, 287, 637, 606, 601, 205, 222, 916, 261, - 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, - 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 507, 1376, 1281, 0, 1290, 1291, 1385, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 1347, 196, 220, 364, + 1409, 449, 287, 637, 606, 601, 205, 222, 1284, 261, + 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, + 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, + 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 931, 932, 933, 934, 935, 936, 937, - 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 1346, + 1352, 377, 280, 303, 318, 1361, 605, 496, 226, 461, + 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 479, 511, 512, 513, 515, 391, 265, 428, 1342, 1370, + 372, 568, 569, 314, 392, 0, 0, 0, 1398, 1384, + 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, + 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, + 1328, 269, 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, + 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 1407, 366, + 1351, 0, 491, 396, 0, 0, 0, 1330, 1390, 1339, + 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 1308, 1357, + 1397, 1309, 1359, 264, 319, 271, 263, 572, 1408, 1389, + 1272, 1338, 1396, 1333, 0, 0, 228, 1399, 1332, 0, + 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, + 1303, 274, 0, 0, 0, 0, 0, 0, 0, 1329, + 1340, 1374, 1378, 1323, 0, 0, 0, 0, 0, 0, + 3174, 0, 1301, 0, 1349, 0, 0, 0, 1279, 1271, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1327, 0, 0, 0, 0, 1282, 0, 1302, + 1375, 0, 1265, 296, 1276, 397, 256, 0, 448, 1382, + 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, + 361, 1278, 328, 197, 224, 0, 1313, 407, 456, 468, + 1387, 1298, 1307, 252, 1305, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 1348, 1367, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 1277, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 1293, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 1383, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 1372, 1413, 420, 467, + 239, 596, 490, 199, 1287, 1292, 1285, 0, 253, 254, + 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, + 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 1376, + 1281, 0, 1290, 1291, 1385, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 1347, 196, 220, 364, 1409, 449, + 287, 637, 606, 601, 205, 222, 1284, 261, 1296, 1304, + 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, + 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 1346, 1352, 377, + 280, 303, 318, 1361, 605, 496, 226, 461, 289, 250, + 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 1342, 1370, 372, 568, + 569, 314, 392, 0, 0, 0, 1398, 1384, 520, 0, + 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, + 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, + 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, 425, 1316, + 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 1407, 366, 1351, 0, + 491, 396, 0, 0, 0, 1330, 1390, 1339, 1377, 1325, + 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 1308, 1357, 1397, 1309, + 1359, 264, 319, 271, 263, 572, 1408, 1389, 1272, 1338, + 1396, 1333, 0, 0, 228, 1399, 1332, 0, 1362, 0, + 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, + 0, 0, 0, 0, 0, 0, 0, 1329, 1340, 1374, + 1378, 1323, 0, 0, 0, 0, 0, 0, 3135, 0, + 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1327, 0, 0, 0, 0, 1282, 0, 1302, 1375, 0, + 1265, 296, 1276, 397, 256, 0, 448, 1382, 1393, 1324, + 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, + 328, 197, 224, 0, 1313, 407, 456, 468, 1387, 1298, + 1307, 252, 1305, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 1348, 1367, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 1277, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 1293, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 1383, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 1372, 1413, 420, 467, 239, 596, + 490, 199, 1287, 1292, 1285, 0, 253, 254, 1354, 567, + 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 1376, 1281, 0, + 1290, 1291, 1385, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 1347, 196, 220, 364, 1409, 449, 287, 637, + 606, 601, 205, 222, 1284, 261, 1296, 1304, 0, 1310, + 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, + 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 1346, 1352, 377, 280, 303, + 318, 1361, 605, 496, 226, 461, 289, 250, 1379, 1381, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 1342, 1370, 372, 568, 569, 314, + 392, 0, 0, 0, 1398, 1384, 520, 0, 1326, 1401, + 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, 411, 1311, + 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, 1294, 1386, + 1345, 1400, 362, 266, 1275, 1300, 425, 1316, 203, 1365, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 1407, 366, 1351, 0, 491, 396, + 0, 0, 0, 1330, 1390, 1339, 1377, 1325, 1364, 1283, + 1350, 1402, 1312, 1360, 1403, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 941, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 1308, 1357, 1397, 1309, 1359, 264, + 319, 271, 263, 572, 1408, 1389, 1272, 1338, 1396, 1333, + 0, 0, 228, 1399, 1332, 0, 1362, 0, 1414, 1267, + 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, 0, 0, + 0, 0, 0, 0, 0, 1329, 1340, 1374, 1378, 1323, + 0, 0, 0, 0, 0, 0, 2354, 0, 1301, 0, + 1349, 0, 0, 0, 1279, 1271, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1327, 0, + 0, 0, 0, 1282, 0, 1302, 1375, 0, 1265, 296, + 1276, 397, 256, 0, 448, 1382, 1393, 1324, 616, 1395, + 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, 328, 197, + 224, 0, 1313, 407, 456, 468, 1387, 1298, 1307, 252, + 1305, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 1348, 1367, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 1277, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 1293, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 1383, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 1372, 1413, 420, 467, 239, 596, 490, 199, + 1287, 1292, 1285, 0, 253, 254, 1354, 567, 1288, 1286, + 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 1376, 1281, 0, 1290, 1291, + 1385, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 1347, 196, 220, 364, 1409, 449, 287, 637, 606, 601, + 205, 222, 1284, 261, 1296, 1304, 0, 1310, 1318, 1319, + 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, 1366, 1368, + 1371, 1373, 1380, 1392, 1412, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 1346, 1352, 377, 280, 303, 318, 1361, + 605, 496, 226, 461, 289, 250, 1379, 1381, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 1342, 1370, 372, 568, 569, 314, 392, 0, + 0, 0, 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, + 1411, 1317, 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, + 1268, 1306, 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, + 362, 266, 1275, 1300, 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, - 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, - 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, - 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, - 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, - 745, 0, 0, 753, 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, 755, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 3987, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 510, 417, 1407, 366, 1351, 0, 491, 396, 0, 0, + 0, 1330, 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, + 1312, 1360, 1403, 321, 247, 323, 202, 408, 492, 285, + 0, 95, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 1308, 1357, 1397, 1309, 1359, 264, 319, 271, + 263, 572, 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, + 228, 1399, 1332, 0, 1362, 0, 1414, 1267, 1353, 0, + 1270, 1274, 1410, 1394, 1303, 274, 0, 0, 0, 0, + 0, 0, 0, 1329, 1340, 1374, 1378, 1323, 0, 0, + 0, 0, 0, 0, 0, 0, 1301, 0, 1349, 0, + 0, 0, 1279, 1271, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1327, 0, 0, 0, + 0, 1282, 0, 1302, 1375, 0, 1265, 296, 1276, 397, + 256, 0, 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, + 1369, 1280, 1388, 1315, 361, 1278, 328, 197, 224, 0, + 1313, 407, 456, 468, 1387, 1298, 1307, 252, 1305, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 1348, + 1367, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 805, 806, 279, 305, 882, 881, 880, - 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 1277, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 1293, 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 446, 1383, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 888, 910, 899, - 765, 766, 889, 890, 914, 891, 768, 769, 911, 912, - 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, + 1372, 1413, 420, 467, 239, 596, 490, 199, 1287, 1292, + 1285, 0, 253, 254, 1354, 567, 1288, 1286, 1343, 1344, + 1289, 1404, 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 902, 752, 751, 0, 758, 0, 787, - 788, 790, 794, 795, 796, 807, 854, 855, 863, 865, - 866, 864, 867, 868, 869, 872, 873, 874, 875, 870, - 871, 876, 770, 774, 771, 772, 773, 785, 775, 776, - 777, 778, 779, 780, 781, 782, 783, 784, 786, 925, - 926, 927, 928, 929, 930, 800, 804, 803, 801, 802, - 798, 799, 826, 825, 827, 828, 829, 830, 831, 832, - 834, 833, 835, 836, 837, 838, 839, 840, 808, 809, - 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, - 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, - 847, 846, 850, 851, 849, 848, 853, 852, 750, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, - 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, - 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 505, 0, 507, 1376, 1281, 0, 1290, 1291, 1385, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 1347, 196, + 220, 364, 1409, 449, 287, 637, 606, 601, 205, 222, + 1284, 261, 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, + 1335, 1336, 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, + 1380, 1392, 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 931, 932, 933, 934, 935, - 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 1346, 1352, 377, 280, 303, 318, 1361, 605, 496, + 226, 461, 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 1716, 957, 941, 733, 907, - 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, - 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, - 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, + 1342, 1370, 372, 568, 569, 314, 392, 0, 0, 0, + 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, + 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, + 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, 362, 266, + 1275, 1300, 425, 1316, 203, 1365, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 1407, 366, 1351, 0, 491, 396, 0, 0, 0, 1330, + 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, + 1403, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 1308, 1357, 1397, 1309, 1359, 264, 319, 271, 263, 572, + 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, 228, 1399, + 1332, 0, 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, + 1410, 1394, 1303, 274, 0, 0, 0, 0, 0, 0, + 0, 1329, 1340, 1374, 1378, 1323, 0, 0, 0, 0, + 0, 0, 0, 0, 1301, 0, 1349, 0, 0, 0, + 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1327, 0, 0, 0, 0, 1282, + 0, 1302, 1375, 0, 1265, 296, 1276, 397, 256, 0, + 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, + 1388, 1315, 361, 1278, 328, 197, 224, 0, 1313, 407, + 456, 468, 1387, 1298, 1307, 252, 1305, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 1348, 1367, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 1277, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 1293, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 1383, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 1372, 1413, + 420, 467, 239, 596, 490, 199, 1287, 1292, 1285, 0, + 253, 254, 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, + 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 1376, 1281, 0, 1290, 1291, 1385, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 1347, 196, 220, 364, + 1409, 449, 287, 637, 606, 601, 205, 222, 1284, 261, + 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, + 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, + 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 1346, + 1352, 377, 280, 303, 318, 1361, 605, 496, 226, 461, + 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 1342, 1370, + 372, 568, 569, 314, 392, 0, 0, 0, 1398, 1384, + 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, + 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, + 1328, 269, 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, + 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 1407, 366, + 1351, 0, 491, 396, 0, 0, 0, 1330, 1390, 1339, + 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 1308, 1357, + 1397, 1309, 1359, 264, 319, 271, 263, 572, 1408, 1389, + 1272, 1338, 1396, 1333, 0, 0, 228, 1399, 1332, 0, + 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, + 1303, 274, 0, 0, 0, 0, 0, 0, 0, 1329, + 1340, 1374, 1378, 1323, 0, 0, 0, 0, 0, 0, + 0, 0, 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, - 901, 0, 745, 0, 0, 753, 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, 755, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, - 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, - 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, - 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, - 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, - 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, - 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, - 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, - 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, - 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, - 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, - 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, - 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, - 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, - 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, - 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, - 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, - 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, - 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, - 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, - 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, - 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, - 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 743, 744, 1049, 0, - 0, 0, 901, 0, 745, 0, 0, 753, 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, - 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, - 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1327, 0, 0, 0, 0, 1282, 0, 1302, + 1375, 0, 1265, 296, 1276, 397, 256, 0, 448, 1382, + 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, + 361, 1278, 328, 197, 224, 0, 1313, 407, 456, 468, + 1387, 1298, 1307, 252, 1305, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 1348, 1367, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 1277, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 1293, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 1383, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 1372, 1413, 420, 467, + 239, 596, 490, 199, 1287, 1292, 1285, 0, 253, 254, + 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, + 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 1376, + 1281, 0, 1290, 1291, 1385, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 1347, 196, 220, 364, 1409, 449, + 287, 637, 606, 601, 205, 222, 1284, 261, 1296, 1304, + 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, + 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 1346, 1352, 377, + 280, 303, 318, 1361, 605, 496, 226, 461, 289, 250, + 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 1342, 1370, 372, 568, + 569, 314, 392, 0, 0, 0, 1398, 1384, 520, 0, + 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, + 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, + 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, 425, 1316, + 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 1407, 366, 1351, 0, + 491, 396, 0, 0, 0, 1330, 1390, 1339, 1377, 1325, + 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 941, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 1308, 1357, 1397, 1309, + 1359, 264, 319, 271, 263, 572, 1408, 1389, 1272, 1338, + 1396, 1333, 0, 0, 228, 1399, 1332, 0, 1362, 0, + 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, + 0, 0, 0, 0, 0, 0, 0, 1329, 1340, 1374, + 1378, 1323, 0, 0, 0, 0, 0, 0, 0, 0, + 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1327, 0, 0, 0, 0, 1282, 0, 1302, 1375, 0, + 1265, 296, 1276, 397, 256, 0, 448, 1382, 1393, 1324, + 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, + 328, 197, 224, 0, 1313, 407, 456, 468, 1387, 1298, + 1307, 252, 1305, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 1348, 1367, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, - 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 805, 806, 279, - 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 1277, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 234, 236, 1293, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 1383, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 888, 910, 899, 765, 766, 889, 890, 914, 891, - 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, + 309, 489, 331, 369, 1372, 1413, 420, 467, 239, 596, + 490, 199, 1287, 1292, 1285, 0, 253, 254, 1354, 567, + 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 902, 752, 751, - 0, 758, 0, 787, 788, 790, 794, 795, 796, 807, - 854, 855, 863, 865, 866, 864, 867, 868, 869, 872, - 873, 874, 875, 870, 871, 876, 770, 774, 771, 772, - 773, 785, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 786, 925, 926, 927, 928, 929, 930, 800, - 804, 803, 801, 802, 798, 799, 826, 825, 827, 828, - 829, 830, 831, 832, 834, 833, 835, 836, 837, 838, - 839, 840, 808, 809, 812, 813, 811, 810, 814, 823, - 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, - 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, - 853, 852, 750, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, - 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, - 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, + 501, 502, 503, 504, 505, 0, 507, 1376, 1281, 0, + 1290, 1291, 1385, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 1347, 196, 220, 364, 1409, 449, 287, 637, + 606, 601, 205, 222, 1284, 261, 1296, 1304, 0, 1310, + 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, + 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 931, - 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 1346, 1352, 377, 280, 303, + 318, 1361, 605, 496, 226, 461, 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, - 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, - 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, - 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, - 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, - 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, - 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, - 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, - 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, 755, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, - 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, - 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, - 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, - 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, - 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, - 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, - 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, - 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, - 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, - 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, - 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, - 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, - 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, - 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, - 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, - 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, - 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, - 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, - 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, - 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, - 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, - 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, - 0, 753, 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, 3092, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 805, 806, 279, 305, 882, 881, 880, 304, 306, - 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 888, 910, 899, 765, 766, - 889, 890, 914, 891, 768, 769, 911, 912, 762, 763, - 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 902, 752, 751, 0, 758, 0, 787, 788, 790, - 794, 795, 796, 807, 854, 855, 863, 865, 866, 864, - 867, 868, 869, 872, 873, 874, 875, 870, 871, 876, - 770, 774, 771, 772, 773, 785, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 786, 925, 926, 927, - 928, 929, 930, 800, 804, 803, 801, 802, 798, 799, - 826, 825, 827, 828, 829, 830, 831, 832, 834, 833, - 835, 836, 837, 838, 839, 840, 808, 809, 812, 813, - 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, - 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, - 850, 851, 849, 848, 853, 852, 750, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 916, 261, - 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, - 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 931, 932, 933, 934, 935, 936, 937, - 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, - 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, - 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, - 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, - 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, - 745, 0, 0, 753, 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, 3088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 805, 806, 279, 305, 882, 881, 880, - 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 888, 910, 899, - 765, 766, 889, 890, 914, 891, 768, 769, 911, 912, - 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 902, 752, 751, 0, 758, 0, 787, - 788, 790, 794, 795, 796, 807, 854, 855, 863, 865, - 866, 864, 867, 868, 869, 872, 873, 874, 875, 870, - 871, 876, 770, 774, 771, 772, 773, 785, 775, 776, - 777, 778, 779, 780, 781, 782, 783, 784, 786, 925, - 926, 927, 928, 929, 930, 800, 804, 803, 801, 802, - 798, 799, 826, 825, 827, 828, 829, 830, 831, 832, - 834, 833, 835, 836, 837, 838, 839, 840, 808, 809, - 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, - 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, - 847, 846, 850, 851, 849, 848, 853, 852, 750, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, - 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, - 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 931, 932, 933, 934, 935, - 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, + 515, 391, 265, 428, 1342, 1370, 372, 568, 569, 314, + 392, 0, 0, 0, 0, 0, 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, @@ -3985,13 +3387,13 @@ var yyAct = [...]int{ 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 0, 957, 941, 1070, 907, + 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 319, 271, 263, 572, 0, 0, 2177, 2178, 2179, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 746, 0, 759, 0, 0, 0, 274, 0, 0, + 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, 964, 965, 966, 967, @@ -4056,14 +3458,14 @@ var yyAct = [...]int{ 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 0, 0, 0, 0, 0, 2383, 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, - 1070, 907, 945, 958, 959, 960, 961, 946, 0, 237, + 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 2384, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 746, 0, 759, 0, 0, 0, 274, + 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, 964, 965, @@ -4071,7 +3473,7 @@ var yyAct = [...]int{ 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, - 2070, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, @@ -4121,521 +3523,882 @@ var yyAct = [...]int{ 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, - 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, - 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, - 957, 941, 1070, 907, 945, 958, 959, 960, 961, 946, - 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, - 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, - 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 746, 0, 759, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, - 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, - 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, 2068, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, - 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, - 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, - 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, - 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, - 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, - 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, - 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, - 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, - 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, - 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, - 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, - 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, - 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, - 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, - 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, - 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, - 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 1121, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 1120, 616, 0, 0, 0, 0, 0, - 1117, 1118, 361, 1078, 328, 197, 224, 1111, 1115, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 1678, 941, 0, 0, 1675, 0, - 0, 0, 0, 1673, 0, 237, 1674, 1672, 244, 1677, - 0, 906, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 391, 265, 428, 0, 392, 372, 568, 569, 314, + 86, 520, 0, 761, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, + 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, + 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, + 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, + 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, + 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, + 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, + 753, 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, 755, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 805, 806, 279, 305, 882, 881, 880, 304, 306, 878, + 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 888, 910, 899, 765, 766, 889, + 890, 914, 891, 768, 769, 911, 912, 762, 763, 767, + 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 902, 752, 751, 0, 758, 0, 787, 788, 790, 794, + 795, 796, 807, 854, 855, 863, 865, 866, 864, 867, + 868, 869, 872, 873, 874, 875, 870, 871, 876, 770, + 774, 771, 772, 773, 785, 775, 776, 777, 778, 779, + 780, 781, 782, 783, 784, 786, 925, 926, 927, 928, + 929, 930, 800, 804, 803, 801, 802, 798, 799, 826, + 825, 827, 828, 829, 830, 831, 832, 834, 833, 835, + 836, 837, 838, 839, 840, 808, 809, 812, 813, 811, + 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, + 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, + 851, 849, 848, 853, 852, 750, 196, 220, 364, 94, + 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, + 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, + 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 931, 932, 933, 934, 935, 936, 937, 938, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, + 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, + 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, + 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, + 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, + 0, 0, 753, 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, 755, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 3988, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, + 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, + 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, + 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, + 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, + 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, + 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, + 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, + 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, + 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, + 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, + 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, + 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, + 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, + 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, + 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, + 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 95, 0, 1717, 957, 941, 733, 907, 945, + 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, + 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, + 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, + 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, + 0, 745, 0, 0, 753, 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, 755, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, + 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 805, 806, 279, 305, 882, 881, + 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 888, 910, + 899, 765, 766, 889, 890, 914, 891, 768, 769, 911, + 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 902, 752, 751, 0, 758, 0, + 787, 788, 790, 794, 795, 796, 807, 854, 855, 863, + 865, 866, 864, 867, 868, 869, 872, 873, 874, 875, + 870, 871, 876, 770, 774, 771, 772, 773, 785, 775, + 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, + 925, 926, 927, 928, 929, 930, 800, 804, 803, 801, + 802, 798, 799, 826, 825, 827, 828, 829, 830, 831, + 832, 834, 833, 835, 836, 837, 838, 839, 840, 808, + 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, + 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, + 845, 847, 846, 850, 851, 849, 848, 853, 852, 750, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, + 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, + 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 931, 932, 933, 934, + 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 761, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, + 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, + 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, + 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 743, 744, 1049, 0, 0, + 0, 901, 0, 745, 0, 0, 753, 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, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 0, 392, 372, 568, 569, 314, 86, 520, 0, 0, + 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, + 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, + 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, + 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, + 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, + 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, + 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, + 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, + 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, + 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, + 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, + 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, + 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, + 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, + 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, + 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, + 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, + 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, + 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, + 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, + 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, + 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, + 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, + 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, + 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 755, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, + 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, + 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, + 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, + 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, + 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, + 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, + 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, + 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, + 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, + 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, + 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, + 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, + 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, + 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, + 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, + 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 761, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, + 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, + 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, + 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, + 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, + 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, + 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, + 753, 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, 3093, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 805, 806, 279, 305, 882, 881, 880, 304, 306, 878, + 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 888, 910, 899, 765, 766, 889, + 890, 914, 891, 768, 769, 911, 912, 762, 763, 767, + 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 902, 752, 751, 0, 758, 0, 787, 788, 790, 794, + 795, 796, 807, 854, 855, 863, 865, 866, 864, 867, + 868, 869, 872, 873, 874, 875, 870, 871, 876, 770, + 774, 771, 772, 773, 785, 775, 776, 777, 778, 779, + 780, 781, 782, 783, 784, 786, 925, 926, 927, 928, + 929, 930, 800, 804, 803, 801, 802, 798, 799, 826, + 825, 827, 828, 829, 830, 831, 832, 834, 833, 835, + 836, 837, 838, 839, 840, 808, 809, 812, 813, 811, + 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, + 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, + 851, 849, 848, 853, 852, 750, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, + 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, + 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 931, 932, 933, 934, 935, 936, 937, 938, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, + 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, + 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, + 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, + 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, + 0, 0, 753, 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, 3089, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, + 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, + 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, + 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, + 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, + 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, + 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, + 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, + 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, + 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, + 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, + 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, + 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, + 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, + 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, + 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, + 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 95, 0, 0, 957, 941, 1070, 907, 945, + 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, + 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, + 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, + 0, 745, 0, 0, 753, 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, 755, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, + 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 805, 806, 279, 305, 882, 881, + 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 888, 910, + 899, 765, 766, 889, 890, 914, 891, 768, 769, 911, + 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 902, 752, 751, 0, 758, 0, + 787, 788, 790, 794, 795, 796, 807, 854, 855, 863, + 865, 866, 864, 867, 868, 869, 872, 873, 874, 875, + 870, 871, 876, 770, 774, 771, 772, 773, 785, 775, + 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, + 925, 926, 927, 928, 929, 930, 800, 804, 803, 801, + 802, 798, 799, 826, 825, 827, 828, 829, 830, 831, + 832, 834, 833, 835, 836, 837, 838, 839, 840, 808, + 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, + 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, + 845, 847, 846, 850, 851, 849, 848, 853, 852, 750, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, + 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, + 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 931, 932, 933, 934, + 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 95, 0, 0, 0, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 408, 492, 285, 0, 95, 0, 0, 957, 941, 1070, + 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, + 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, + 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, + 0, 901, 0, 745, 0, 0, 753, 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, 2071, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, + 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, + 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, + 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, + 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 94, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, - 0, 2369, 0, 0, 2368, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, + 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, + 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, + 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, + 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, + 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, + 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, + 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, + 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, + 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, + 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, + 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, + 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, + 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, + 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 1735, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 1737, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, + 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 1739, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 1451, - 0, 1452, 1453, 0, 0, 0, 0, 0, 0, 0, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, + 941, 1070, 907, 945, 958, 959, 960, 961, 946, 0, + 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, + 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, + 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, + 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 2069, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, + 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, + 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, + 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, + 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, + 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, + 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, + 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, + 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, + 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, + 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, + 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, + 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, + 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, + 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, + 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, + 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 0, 392, 372, 568, 569, - 314, 86, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, - 0, 1716, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 1121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 94, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 0, 194, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 1120, 616, 0, 0, 0, 0, 0, 1117, + 1118, 361, 1078, 328, 197, 224, 1111, 1115, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 1679, 941, 0, 0, 1676, 0, 0, + 0, 0, 1674, 0, 237, 1675, 1673, 244, 1678, 0, + 906, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 2369, 0, - 0, 2368, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, + 392, 372, 568, 569, 314, 86, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 2319, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 1918, 194, 0, 0, + 492, 285, 0, 95, 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, @@ -4654,7 +4417,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 2317, 465, 368, 577, 445, 591, 617, 618, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, @@ -4684,9 +4447,9 @@ var yyAct = [...]int{ 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 0, 196, 220, 364, 94, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2370, 0, 0, 2369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, @@ -4699,22 +4462,22 @@ var yyAct = [...]int{ 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 265, 428, 1736, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 411, 0, 0, 0, 1738, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 202, 408, 492, 285, 0, 0, 0, 0, 1740, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 1072, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 1452, 0, + 1453, 1454, 0, 0, 0, 0, 0, 0, 0, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4723,8 +4486,8 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 1078, - 328, 197, 224, 1076, 0, 407, 456, 468, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, @@ -4771,888 +4534,1177 @@ var yyAct = [...]int{ 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 2319, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 1918, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 515, 391, 265, 428, 0, 392, 372, 568, 569, 314, + 86, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, + 1717, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 94, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 95, 0, 0, 0, 194, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 2370, 0, 0, + 2369, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 2320, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 1919, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 2318, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, + 0, 0, 0, 0, 0, 0, 0, 1072, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 1078, 328, + 197, 224, 1076, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 2320, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 1919, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 1717, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 1716, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 3898, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 3897, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 2080, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 2079, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 2081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 2814, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 2813, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, + 0, 0, 0, 0, 2815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 2799, 0, 0, 0, 0, 237, 0, + 0, 244, 2800, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 2798, 0, 0, 0, 0, 237, - 0, 0, 244, 2799, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 1759, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 1758, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 1758, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 1757, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 711, 712, 713, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 711, 712, 713, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 4021, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 4020, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 1919, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 1918, 194, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 3898, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 3897, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 2371, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 2370, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 1740, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 1739, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5660,71 +5712,71 @@ 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, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 194, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5732,71 +5784,72 @@ 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, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 2031, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 2032, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 2023, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 2022, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5804,72 +5857,71 @@ 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, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 1885, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 411, 0, 1886, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5877,71 +5929,71 @@ 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, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 1883, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 1884, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5949,1154 +6001,1154 @@ 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, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 1881, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 1882, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 1879, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 1880, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 1878, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 1877, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 1874, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 1873, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 1872, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 1871, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 1870, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 1869, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 1845, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 1844, 0, 0, 0, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 1744, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 194, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 1743, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, + 941, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, - 0, 941, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1431, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1430, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 1430, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 1429, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 194, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 194, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 662, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 662, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 4029, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 4028, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 941, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 194, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7104,80 +7156,80 @@ 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, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 0, 0, 372, 568, 569, 314, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, + 0, 372, 568, 569, 314, } var yyPact = [...]int{ - -1000, -1000, 1319, -1000, -532, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 1893, -1000, -532, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2401, 2519, -1000, -1000, -1000, -1000, 2569, -1000, 1002, - 2074, -1000, 2363, 4957, -1000, 54244, 500, -1000, 51356, -436, - 860, 234, 35472, -1000, 207, -1000, 193, 52800, 199, -1000, - -1000, -1000, -1000, -436, 21030, 2277, 56, 52, 54244, -1000, - -1000, -1000, -1000, -353, 2542, 2069, -1000, 408, -1000, -1000, - -1000, -1000, -1000, -1000, 50634, -1000, 1098, -1000, -1000, 2359, - 2349, 2577, 915, 2304, -1000, 2461, 2069, -1000, 21030, 2498, - 2432, 20308, 20308, 462, -1000, -1000, 268, -1000, -1000, 30418, - 54244, 38360, 890, -1000, 2363, -1000, -1000, -1000, 219, -1000, - 378, 1978, -1000, 1977, -1000, 469, 899, 392, 871, 868, - 391, 389, 388, 379, 377, 376, 375, 369, 398, -1000, - 938, 938, -218, -219, 361, 450, 448, 448, 1108, 479, - 2320, 2316, -1000, -1000, 938, 938, 938, 396, 938, 938, - 938, 938, 321, 320, 938, 938, 938, 938, 938, 938, - 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, - 938, 902, 2363, 300, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2352, 2406, -1000, -1000, -1000, -1000, 2560, -1000, 1002, + 2052, -1000, 2357, 4901, -1000, 54763, 481, -1000, 51875, -434, + 853, 234, 35991, -1000, 198, -1000, 182, 53319, 191, -1000, + -1000, -1000, -1000, -434, 21549, 2291, 57, 53, 54763, -1000, + -1000, -1000, -1000, -357, 2521, 2031, -1000, 409, -1000, -1000, + -1000, -1000, -1000, -1000, 51153, -1000, 1082, -1000, -1000, 2364, + 2338, 2563, 912, 2292, -1000, 2456, 2031, -1000, 21549, 2510, + 2450, 20827, 20827, 430, -1000, -1000, 238, -1000, -1000, 30937, + 54763, 38879, 293, -1000, 2357, -1000, -1000, -1000, 219, -1000, + 336, 1947, -1000, 1943, -1000, 845, 896, 380, 478, 456, + 379, 359, 358, 356, 354, 349, 346, 344, 374, -1000, + 936, 936, -217, -218, 361, 425, 413, 413, 968, 458, + 2321, 2320, -1000, -1000, 936, 936, 936, 369, 936, 936, + 936, 936, 296, 295, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 906, 2357, 274, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7224,66 +7276,66 @@ 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, - 54244, 210, 54244, -1000, 809, 499, -1000, -1000, -440, 1090, - 1090, 122, 1090, 1090, 1090, 1090, 184, 973, 49, -1000, - 182, 284, 197, 293, 1079, 183, -1000, -1000, 258, 1079, - 1806, -1000, 923, 281, 163, -1000, 1090, 1090, -1000, 13785, - 209, 13785, 13785, -1000, 2345, -1000, -1000, -1000, -1000, -1000, - 1333, -1000, -1000, -1000, -1000, -18, 478, -1000, -1000, -1000, - -1000, 52800, 49912, 290, -1000, -1000, 769, 1852, 1371, 21030, - 1291, 913, -1000, -1000, 1976, 876, -1000, -1000, -1000, -1000, - -1000, 800, -1000, 23196, 23196, 23196, 23196, -1000, -1000, 1983, - 49190, 1983, 1983, 23196, 1983, 23196, 1983, 1983, 1983, 21030, - 1983, 1983, 1983, 1983, -1000, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, -1000, -1000, -1000, -1000, 1983, 808, 1983, 1983, - 1983, 1983, 1983, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1983, 1983, 1983, 1983, 1983, 1983, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, -1000, + 54763, 181, 54763, -1000, 798, 480, -1000, -1000, -439, 1083, + 1083, 96, 1083, 1083, 1083, 1083, 186, 962, 50, -1000, + 176, 266, 171, 269, 1027, 319, -1000, -1000, 262, 1027, + 1736, -1000, 917, 264, 166, -1000, 1083, 1083, -1000, 14304, + 230, 14304, 14304, -1000, 2355, -1000, -1000, -1000, -1000, -1000, + 1361, -1000, -1000, -1000, -1000, -26, 454, -1000, -1000, -1000, + -1000, 53319, 50431, 233, -1000, -1000, 769, 1803, 1515, 21549, + 1254, 893, -1000, -1000, 1479, 858, -1000, -1000, -1000, -1000, + -1000, 508, -1000, 23715, 23715, 23715, 23715, -1000, -1000, 1788, + 49709, 1788, 1788, 23715, 1788, 23715, 1788, 1788, 1788, 21549, + 1788, 1788, 1788, 1788, -1000, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, -1000, -1000, -1000, -1000, 1788, 795, 1788, 1788, + 1788, 1788, 1788, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1788, 1788, 1788, 1788, 1788, 1788, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 26084, 1500, 1498, 1493, -1000, 18142, 1983, -1000, -1000, -1000, + 26603, 1518, 1512, 1506, -1000, 18661, 1788, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54244, -1000, 1983, - 218, 52800, 52800, 397, 1334, -1000, -1000, 2461, 2069, -1000, - 2542, 2477, 408, -1000, 3785, 1628, 1721, 1532, 2069, 1956, - 54244, -1000, 1992, -1000, -1000, -1000, -1000, 2207, 1524, 1804, - -1000, -1000, -1000, -1000, 1907, 21030, -1000, -1000, 2557, -1000, - 27529, 805, 2554, 48468, -1000, 462, 462, 1975, 430, 22, - -1000, -1000, -1000, -1000, 962, 34750, -1000, -1000, -1000, -1000, - -1000, 1902, 54244, -1000, -1000, 4793, 1173, -1000, 2071, -1000, - 1842, -1000, 2014, 21030, 2080, 498, 1173, 491, 490, 489, - -1000, -64, -1000, -1000, -1000, -1000, -1000, -1000, 938, 938, - 938, -1000, 343, 2495, 4957, 6237, -1000, -1000, -1000, 47746, - 2067, 1173, -1000, 2053, -1000, 1041, 859, 870, 870, 1173, - -1000, -1000, 53522, 1173, 1040, 1031, 1173, 1173, 52800, 52800, - -1000, 47024, -1000, 46302, 45580, 1331, 52800, 44858, 44136, 43414, - 42692, 41970, -1000, 2330, -1000, 2133, -1000, -1000, -1000, 53522, - 1173, 1173, 53522, 52800, 53522, 54244, 1173, -1000, -1000, 360, - -1000, -1000, 1330, 1328, 1327, 938, 938, 1326, 1800, 1798, - 1787, 938, 938, 1295, 1782, 36916, 1765, 286, 1293, 1292, - 1289, 1290, 1746, 229, 1719, 1281, 1230, 1288, 52800, 2036, - 54244, -1000, 254, 945, 994, 958, 2363, 2276, 1967, 476, - 494, 1173, 451, 451, 52800, -1000, 14513, 54244, 217, -1000, - 1707, 21030, -1000, 1080, 1079, 1079, -1000, -1000, -1000, -1000, - -1000, -1000, 1090, 54244, 1080, -1000, -1000, -1000, 1079, 1090, - 54244, 1090, 1090, 1090, 1090, 1079, 1079, 1079, 1090, 54244, - 54244, 54244, 54244, 54244, 54244, 54244, 54244, 54244, 13785, 923, - 1090, -441, -1000, 1672, -1000, -1000, 2171, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54763, -1000, 1788, + 216, 53319, 53319, 321, 1326, -1000, -1000, 2456, 2031, -1000, + 2521, 2488, 409, -1000, 3573, 1787, 1722, 1426, 2031, 1927, + 54763, -1000, 1966, -1000, -1000, -1000, -1000, 2204, 1507, 1734, + -1000, -1000, -1000, -1000, 1925, 21549, -1000, -1000, 2555, -1000, + 28048, 792, 2552, 48987, -1000, 430, 430, 1939, 421, 20, + -1000, -1000, -1000, -1000, 958, 35269, -1000, -1000, -1000, -1000, + -1000, 1870, 54763, -1000, -1000, 5319, 1353, -1000, 2044, -1000, + 1868, -1000, 1990, 21549, 2063, 477, 1353, 467, 465, 463, + -1000, -61, -1000, -1000, -1000, -1000, -1000, -1000, 936, 936, + 936, -1000, 343, 2505, 4901, 6077, -1000, -1000, -1000, 48265, + 2040, 1353, -1000, 2038, -1000, 1031, 859, 868, 868, 1353, + -1000, -1000, 54041, 1353, 1022, 1015, 1353, 1353, 53319, 53319, + -1000, 47543, -1000, 46821, 46099, 1319, 53319, 45377, 44655, 43933, + 43211, 42489, -1000, 2233, -1000, 2016, -1000, -1000, -1000, 54041, + 1353, 1353, 54041, 53319, 54041, 54763, 1353, -1000, -1000, 364, + -1000, -1000, 1308, 1307, 1306, 936, 936, 1292, 1731, 1728, + 1714, 936, 936, 1290, 1707, 37435, 1699, 270, 1289, 1270, + 1261, 1318, 1686, 229, 1674, 1281, 1264, 1252, 53319, 2032, + 54763, -1000, 254, 951, 435, 956, 2357, 2289, 1935, 453, + 474, 1353, 424, 424, 53319, -1000, 15032, 54763, 227, -1000, + 1670, 21549, -1000, 1043, 1027, 1027, -1000, -1000, -1000, -1000, + -1000, -1000, 1083, 54763, 1043, -1000, -1000, -1000, 1027, 1083, + 54763, 1083, 1083, 1083, 1083, 1027, 1027, 1027, 1083, 54763, + 54763, 54763, 54763, 54763, 54763, 54763, 54763, 54763, 14304, 917, + 1083, -440, -1000, 1659, -1000, -1000, -1000, 2157, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7299,327 +7351,327 @@ 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, 13785, 13785, -1000, -1000, -1000, -1000, - -1000, 1966, -1000, 189, 26, 196, -1000, 41248, 480, 957, - -1000, 480, -1000, -1000, -1000, 1964, 40526, -1000, -445, -446, - -447, -450, -1000, -1000, -1000, -451, -453, -1000, -1000, -1000, - 21030, 21030, 21030, 21030, -268, -1000, 1216, 23196, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 21030, 224, 997, 23196, 23196, - 23196, 23196, 23196, 23196, 23196, 24640, 23918, 23196, 23196, 23196, - 23196, 23196, 23196, -1000, -1000, 32584, 5973, 5973, 876, 876, - 876, 876, -1000, -175, 1963, 53522, -1000, -1000, -1000, 798, - 21030, 21030, 876, -1000, 1173, 2944, 18142, 20308, 20308, 21030, - 967, 1371, 53522, 21030, -1000, 1532, -1000, -1000, -1000, -1000, - 1207, -1000, -1000, 1093, 2354, 2354, 2354, 2354, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 2354, 21030, - 1270, 1270, 833, 21030, 21030, 21030, 21030, 21030, 21030, 16697, - 21030, 21030, 23196, 21030, 21030, 21030, 1532, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 1532, 21030, 1536, 21030, - 21030, 21030, 21030, 21030, 21030, 20308, 15969, 20308, 20308, 20308, - 20308, 20308, -1000, -1000, -1000, -1000, -1000, -1000, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 1532, 21030, 21030, 21030, - 21030, 21030, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1568, 1629, 1527, 21030, -1000, 1960, -1000, -184, - 29696, 21030, 1658, 2551, 2105, 52800, -1000, -1000, -1000, -1000, - 2461, -1000, 2461, 1568, 3572, 2218, 20308, -1000, -1000, 3572, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1667, -1000, - 54244, 1956, 2407, 52800, 2222, 1655, 357, -1000, 21030, 21030, - 1955, -1000, 1799, 54244, -1000, -268, -1000, 39804, -1000, -1000, - 13057, 54244, 346, 54244, -1000, 28974, 39082, 265, -1000, 22, - 1936, -1000, 25, 17, 17419, 864, -1000, -1000, -1000, 361, - 25362, 1737, 864, 103, -1000, -1000, -1000, 2014, -1000, 2014, - 2014, 2014, 2014, 357, 357, 357, 357, -1000, -1000, -1000, - -1000, -1000, 2034, 2032, -1000, 2014, 2014, 2014, 2014, -1000, + -1000, -1000, -1000, -1000, -1000, 14304, 14304, -1000, -1000, -1000, + -1000, -1000, 1934, -1000, 184, 26, 189, -1000, 41767, 517, + 955, -1000, 517, -1000, -1000, -1000, 1933, 41045, -1000, -441, + -445, -446, -447, -1000, -1000, -1000, -450, -460, -1000, -1000, + -1000, 21549, 21549, 21549, 21549, -251, -1000, 1019, 23715, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 21549, 251, 1038, 23715, + 23715, 23715, 23715, 23715, 23715, 23715, 25159, 24437, 23715, 23715, + 23715, 23715, 23715, 23715, -1000, -1000, 33103, 6798, 6798, 858, + 858, 858, 858, -1000, -173, 1932, 54041, -1000, -1000, -1000, + 790, 21549, 21549, 858, -1000, 1353, 2945, 18661, 20827, 20827, + 21549, 963, 1515, 54041, 21549, -1000, 1426, -1000, -1000, -1000, + -1000, 1257, -1000, -1000, 1093, 2335, 2335, 2335, 2335, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 2335, + 21549, 908, 908, 1136, 21549, 21549, 21549, 21549, 21549, 21549, + 17216, 21549, 21549, 23715, 21549, 21549, 21549, 1426, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 1426, 21549, 1665, + 21549, 21549, 21549, 21549, 21549, 21549, 20827, 16488, 20827, 20827, + 20827, 20827, 20827, -1000, -1000, -1000, -1000, -1000, -1000, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 1426, 21549, 21549, + 21549, 21549, 21549, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1769, 1532, 1481, 21549, -1000, 1928, -1000, + -184, 30215, 21549, 1656, 2547, 2092, 53319, -1000, -1000, -1000, + -1000, 2456, -1000, 2456, 1769, 2727, 2207, 20827, -1000, -1000, + 2727, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1777, + -1000, 54763, 1927, 2393, 53319, 2198, 1652, 351, -1000, 21549, + 21549, 1923, -1000, 1601, 54763, -1000, -251, -1000, 40323, -1000, + -1000, 13576, 54763, 334, 54763, -1000, 29493, 39601, 268, -1000, + 20, 1878, -1000, 31, 9, 17938, 857, -1000, -1000, -1000, + 361, 25881, 1705, 857, 109, -1000, -1000, -1000, 1990, -1000, + 1990, 1990, 1990, 1990, 351, 351, 351, 351, -1000, -1000, + -1000, -1000, -1000, 2025, 2021, -1000, 1990, 1990, 1990, 1990, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 2031, 2031, 2031, 2029, - 2029, 2015, 2015, 435, -1000, 21030, 416, 38360, 2419, 1282, - 1219, 254, 453, 2103, 1173, 1173, 1173, 453, -1000, 1425, - 1398, 1383, -1000, -518, 1950, -1000, -1000, 2493, -1000, -1000, - 960, 1057, 1056, 1117, 52800, 236, 334, -1000, 431, -1000, - 38360, 1173, 1028, 870, 1173, -1000, 1173, -1000, -1000, -1000, - -1000, -1000, 1173, -1000, -1000, 1949, -1000, 1845, 1168, 1055, - 1131, 1054, 1949, -1000, -1000, -182, 1949, -1000, 1949, -1000, - 1949, -1000, 1949, -1000, 1949, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 981, 304, -307, 52800, 236, 470, - -1000, 468, 32584, -1000, -1000, -1000, 32584, 32584, -1000, -1000, - -1000, -1000, 1637, 1625, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2020, 2020, 2020, + 2019, 2019, 1995, 1995, 417, -1000, 21549, 415, 38879, 2362, + 1247, 1474, 254, 428, 2079, 1353, 1353, 1353, 428, -1000, + 1383, 1377, 1366, -1000, -518, 1919, -1000, -1000, 2504, -1000, + -1000, 940, 1048, 1047, 903, 53319, 220, 327, -1000, 408, + -1000, 38879, 1353, 1003, 868, 1353, -1000, 1353, -1000, -1000, + -1000, -1000, -1000, 1353, -1000, -1000, 1918, -1000, 1801, 1091, + 1044, 1077, 1030, 1918, -1000, -1000, -178, 1918, -1000, 1918, + -1000, 1918, -1000, 1918, -1000, 1918, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 979, 281, -325, 53319, 220, + 441, -1000, 439, 33103, -1000, -1000, -1000, 33103, 33103, -1000, + -1000, -1000, -1000, 1633, 1619, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -502, 54244, -1000, 248, 956, 324, 335, - 353, 54244, 352, 2439, 2434, 2427, 2418, 2414, 305, 316, - 54244, 54244, 451, 2157, 54244, 2377, 54244, -1000, -1000, -1000, - -1000, -1000, 1622, 1620, -1000, 1371, 54244, -1000, -1000, 1090, - 1090, -1000, -1000, 54244, 1090, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1090, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54244, - -1000, -1000, -1000, -1000, -18, 187, -1000, -1000, 52800, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -104, -1000, - 801, 15, 409, -1000, -1000, -1000, -1000, -1000, 2457, -1000, - 1371, 1009, 1006, -1000, 1983, -1000, -1000, 1069, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 224, 23196, 23196, 23196, - 1598, 828, 1429, 1392, 1229, 1239, 1239, 929, 23196, 929, - 23196, 863, 863, 863, 863, 863, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1616, -1000, 1983, 53522, 1817, 15969, - 1952, 2163, 1532, 908, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -503, 54763, -1000, 240, 952, 283, + 306, 303, 54763, 420, 2419, 2408, 2405, 2400, 2397, 299, + 290, 54763, 54763, 424, 2130, 54763, 2376, 54763, -1000, -1000, + -1000, -1000, -1000, 1617, 1612, -1000, 1515, 54763, -1000, -1000, + 1083, 1083, -1000, -1000, 54763, 1083, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1083, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 4134, 1813, -1000, 1813, 1503, 971, - -1000, 21030, 1532, 4125, -1000, -1000, 1532, 1532, 21030, -1000, - -1000, 21030, 21030, 21030, 21030, 1219, 1219, 1219, 1219, 1219, - 1219, 1219, 1219, 1219, 1219, 21030, 1219, 1948, -1000, -1000, + 54763, -1000, -1000, -1000, -1000, -26, 178, -1000, -1000, 53319, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -105, + -1000, 847, 24, 384, -1000, -1000, -1000, -1000, -1000, 2445, + -1000, 1515, 988, 976, -1000, 1788, -1000, -1000, 1135, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 251, 23715, 23715, + 23715, 1565, 485, 1224, 1315, 1155, 1133, 1133, 1097, 23715, + 1097, 23715, 862, 862, 862, 862, 862, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1605, -1000, 1788, 54041, 1826, + 16488, 1974, 2164, 1426, 870, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1943, 2541, 1314, 1219, - 1219, 1219, 1219, 1219, 21030, 2187, -1000, -1000, -1000, 1534, - 4120, 1369, 4115, 1219, 1219, -1000, 1219, 4111, 4092, 1532, - 1852, 2876, 2871, 1219, 1219, 1219, 1219, 1219, 2863, 2802, - 1219, 1219, 2756, 1219, 3876, 1219, 2721, 2680, 2675, 2633, - 2619, 2614, 2603, 2597, 2555, 2540, 2533, 2528, 2510, 2506, - 2491, 2469, 2435, 2428, 1219, 1219, 1219, 3844, 1219, 3819, - 1219, 3812, 1219, 1219, 3807, 2412, 2403, 1532, 1942, -1000, - 3803, 1219, 3525, 3514, 3476, 2399, 3448, 3439, 3434, 1219, - 1219, 1219, 2329, 3426, 3420, 3416, 3406, 3402, 3377, 3369, - 3360, 3346, 1219, 1527, 1527, 1527, 1527, 1527, 3335, -271, - 1219, 1532, -1000, -1000, -1000, -1000, -1000, 3331, 2324, 3320, - 3316, 3289, 3275, 1532, 1938, 1983, 795, -1000, -1000, 1813, - 1532, 1532, 1813, 1813, 3206, 3190, 3017, 2996, 2959, 2939, - 1219, 1219, -1000, 1219, 2908, 2902, 2312, 2303, 1532, -1000, - 1527, 54244, -1000, -431, -1000, -7, 936, 1983, -1000, 36916, - 1532, -1000, 5074, -1000, 1233, -1000, -1000, -1000, -1000, -1000, - 34028, 1951, 3572, -1000, -1000, 1983, 1776, -1000, -1000, 357, - 90, 33306, 857, 857, 128, 1371, 1371, 21030, -1000, -1000, - -1000, -1000, -1000, -1000, 792, 2512, 400, 1983, -1000, 1979, - 3285, -1000, -1000, -1000, 2402, 26807, -1000, -1000, 1983, 1983, - 54244, 1937, 1931, -1000, 790, -1000, 1255, 1936, 22, 8, - -1000, -1000, -1000, -1000, 1371, -1000, 1348, 356, 341, -1000, - 438, -1000, -1000, -1000, -1000, 2290, 92, -1000, -1000, -1000, - 365, 357, -1000, -1000, -1000, -1000, -1000, -1000, 1611, 1611, - -1000, -1000, -1000, -1000, -1000, 1280, -1000, -1000, -1000, -1000, - 1278, -1000, -1000, 1271, -1000, -1000, 2641, 2129, 416, -1000, - -1000, 938, 1609, -1000, -1000, 2305, 938, 938, 52800, -1000, - -1000, 1722, 2419, 248, 54244, 986, 2156, -1000, 2103, 2103, - 2103, 54244, -1000, -1000, -1000, -1000, -1000, -1000, -504, 165, - 618, -1000, -1000, -1000, 2008, 52800, 1758, -1000, 232, -1000, - 1718, -1000, 52800, -1000, 1742, 2028, 1173, 1173, -1000, -1000, - -1000, 52800, 1983, -1000, -1000, -1000, -1000, 493, 2358, 297, - -1000, -1000, -290, -1000, -1000, 236, 232, 53522, 1173, 864, - -1000, -1000, -1000, -1000, -1000, -505, 1734, 481, 239, 329, - 54244, 54244, 54244, 54244, 54244, 54244, 512, -1000, -1000, 35, - -1000, -1000, 215, -1000, -1000, -1000, -1000, 215, -1000, -1000, - -1000, -1000, 307, 466, -1000, 54244, 54244, 914, -1000, -1000, - -1000, -1000, -1000, 1079, -1000, -1000, 1079, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2343, - 54244, 10, -471, -1000, -468, 21030, -1000, -1000, -1000, -1000, - 1312, 496, 1429, 23196, 23196, 2944, 2944, 23196, -1000, -1000, - -1000, 350, 350, 32584, -1000, 23196, 21030, 20308, -1000, -1000, - 21030, 21030, 961, -1000, 21030, 1167, -1000, 21030, -1000, -1000, - 1527, 1219, 1219, 1219, 1219, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1896, -1000, 21030, 21030, 21030, - 1532, 312, -1000, -1000, -1000, -1000, -1000, 2538, -1000, 21030, - -1000, 32584, 21030, 21030, 21030, -1000, -1000, -1000, 21030, 21030, - -1000, -1000, 21030, -1000, 21030, -1000, -1000, -1000, -1000, -1000, - -1000, 21030, -1000, 21030, -1000, -1000, -1000, 21030, -1000, 21030, - -1000, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, -1000, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, -1000, 21030, -1000, 21030, - -1000, 21030, -1000, 21030, 21030, -1000, 21030, 21030, 21030, -1000, - 21030, 21030, 21030, 21030, -1000, -1000, -1000, -1000, 21030, 21030, - 21030, 21030, 21030, 21030, 21030, 21030, 21030, 21030, -1000, -1000, - -1000, -1000, -1000, -1000, 21030, -1000, 38360, 23, -271, 1536, - 23, 1536, 22474, 813, 811, 21752, -1000, 20308, 15241, -1000, - -1000, -1000, -1000, -1000, 21030, 21030, 21030, 21030, 21030, 21030, - -1000, -1000, -1000, 21030, 21030, -1000, 21030, -1000, 21030, -1000, - -1000, -1000, -1000, -1000, 936, -1000, 870, 870, 870, 52800, - -1000, -1000, -1000, -1000, 1932, -1000, 2438, -1000, 2238, 2235, - 2536, 2512, -1000, 28974, 3572, -1000, -1000, 52800, -423, -1000, - 2270, 2357, 857, 857, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 12329, 2461, 21030, 2153, 53522, 247, -1000, 28252, 52800, - 53522, 28974, 28974, 28974, 28974, 28974, -1000, 2196, 2195, -1000, - 2225, 2215, 2318, 54244, -1000, 1568, 1732, -1000, 21030, 31140, - 1922, 28974, -1000, -1000, 28974, 54244, 11601, -1000, -1000, 2, - -13, -1000, -1000, -1000, -1000, 361, -1000, -1000, 1550, 2400, - 2282, -1000, -1000, -1000, -1000, -1000, 1728, -1000, 1717, 1926, - 1711, 1704, 304, -1000, 2047, 2326, 938, 938, -1000, 1254, - -1000, 1173, 1599, 1593, -1000, -1000, -1000, 472, -1000, 2375, - 54244, 2151, 2150, 2149, -1000, -515, 1251, 2026, 1982, 21030, - 2024, 2492, 1882, 52800, -1000, -1000, 53522, -1000, 294, -1000, - 416, 52800, -1000, -1000, -1000, 334, 54244, -1000, 8486, -1000, - -1000, -1000, 232, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 54244, 271, -1000, 2020, 1274, -1000, -1000, 2088, -1000, -1000, - -1000, -1000, -1000, 216, 190, 1566, 213, 1560, 213, -1000, - 54244, 911, 2129, 54244, -1000, -1000, -1000, 1090, 1090, -1000, - -1000, 2325, -1000, 1173, 1219, 23196, 23196, -1000, 876, -1000, - -1000, 384, -248, 2014, 2014, -1000, 2014, 2015, -1000, 2014, - 174, 2014, 172, 2014, -1000, -1000, 1532, 1532, -1000, 1527, - -1000, 2287, 1181, -1000, 1371, 21030, 2889, -1000, -1000, -1000, - -1000, -1000, -71, 2842, 2833, 1219, -1000, 2013, 2012, 21030, - 1219, 1532, 2279, 1219, 1219, 1219, 1219, 1219, 1219, 1219, - 1219, 1219, 1219, 1219, 1219, 2231, 2221, 2211, 2206, 2201, - 2192, 2183, 2172, 2124, 2110, 2104, 2064, 2037, 2017, 1946, - 1940, 1219, 1219, 1934, 1219, 1919, 1859, -1000, 1371, 1527, - 2516, 1527, 1219, 1219, 2445, 313, 1219, 1702, 1702, 1702, - 1702, 1702, 1527, 1527, 1527, 1527, 1219, 52800, -1000, -271, - -1000, -1000, -310, -311, -1000, 1532, -271, 1918, 23196, 1219, - 23196, 23196, 23196, 1219, 1532, -1000, 1846, 1825, 2081, 1815, - 1219, 2042, 1219, 1219, 1219, 1811, -1000, 2447, 2447, 2447, - 1696, 1233, 54244, -1000, -1000, -1000, -1000, 2512, 2505, 1899, - -1000, -1000, 90, 573, -1000, 2294, 2357, -1000, 2488, 2261, - 2486, -1000, -1000, -1000, -1000, -1000, 1371, -1000, 2350, 1916, - -1000, 955, 1857, -1000, -1000, 19586, 1698, 2226, 531, 1696, - 1894, 3285, 2111, 2143, 3000, -1000, -1000, -1000, -1000, 2178, - -1000, 2134, -1000, -1000, 1992, -1000, 1519, 346, 28974, 1778, - 1778, -1000, 525, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1076, 8486, 2571, -1000, 1558, -1000, 1346, 205, 1247, -1000, - -1000, 938, 938, -1000, 1025, 1023, -1000, 54244, 2011, -1000, - 357, 1554, 357, 1245, -1000, -1000, 1210, -1000, -1000, -1000, - -1000, 1973, 2092, -1000, -1000, -1000, -1000, 54244, -1000, -1000, - 54244, 54244, 54244, 2010, 2485, -1000, 21030, 2009, 944, 2334, - 52800, 52800, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 471, 938, -485, 311, 310, 938, 938, - 938, -526, -1000, -1000, 1691, 1687, -1000, -207, -1000, 21030, - -1000, -1000, -1000, -1000, -1000, 1273, 1273, 1500, 1498, 1493, - -1000, 1992, -1000, -1000, -1000, 1712, -1000, -1000, -193, 52800, - 52800, 52800, 52800, -1000, -1000, -1000, 1107, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 876, - 1532, 412, -195, 1532, -1000, -1000, 357, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21030, -1000, 21030, - -1000, 1371, 21030, 2461, 1461, 21030, 21030, -1000, 1198, 1172, - 1219, -1000, -1000, -1000, 21030, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - -1000, 21030, -1000, -1000, -1000, 21030, -1000, 21030, -1000, 21030, - -1000, -1000, -1000, 21030, 303, 350, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1532, 344, -1000, - -1000, -1000, -1000, 2514, -1000, 1532, 21030, 2944, -1000, 2944, - 2944, 2944, -1000, -1000, -1000, 21030, -1000, 21030, 21030, -1000, - 21030, -1000, 21030, -1000, -1000, -1000, -1000, 21030, 1983, 2237, - 1983, 1983, 31140, -1000, -1000, 2505, 2471, 2483, 2247, 2249, - 2249, 2294, -1000, 2482, 2474, -1000, 1440, 2473, 1435, 999, - -1000, 53522, 21030, 247, -1000, 419, 52800, 247, 52800, -1000, - 2478, -1000, -1000, 21030, 2004, -1000, 21030, -1000, -1000, -1000, - -1000, 5973, 2512, 1778, -1000, -1000, 887, -1000, 21030, -1000, - 9314, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1422, - 1419, -1000, -1000, 1994, 21030, -1000, -1000, -1000, 1692, 1630, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1992, -1000, - -1000, -1000, -1000, 334, -510, 2089, 52800, 1171, -1000, 1671, - 1882, 330, 247, 1416, 938, 938, 938, 1161, 1155, 36916, - 1654, -1000, 52800, 413, -1000, 334, -1000, -229, -244, 1219, - -1000, -1000, 2394, -1000, -1000, 15241, -1000, -1000, 1988, 2096, - -1000, -1000, -1000, -1000, 2210, -178, -208, -1000, -1000, 1219, - 1219, 1250, 1532, -1000, 1219, 1219, 1577, 1542, -1000, 1219, - 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, - 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1527, - 1785, -1000, 303, 1532, 2131, -1000, -1000, 5973, -1000, -1000, - 2478, 2470, 23, -1000, -1000, 230, 23, 1371, 985, 1532, - 1532, 985, 1779, 1219, 1749, 1736, 1219, 1219, 31862, -1000, - 2464, 2448, 37638, 37638, 936, 2471, -280, 21030, 21030, 2243, - 1123, -1000, -1000, -1000, -1000, 1409, 1385, -1000, 1380, -1000, - 2563, -1000, 1371, -1000, 247, -1000, 523, 1857, -1000, 2461, - 1371, 52800, 1371, 76, 2478, -1000, 1219, -1000, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, - 1983, 1983, 1983, 1983, 1983, 1983, 1983, -1000, -1000, 52800, - 1837, -1000, -1000, 2389, 1634, 164, -1000, 1535, 1882, -1000, - -1000, 206, -1000, 21030, -1000, 36916, 1375, 1344, -1000, -1000, - -1000, -1000, -526, -1000, -1000, -1000, -1000, -1000, -1000, 408, - 1876, -1000, 934, 52800, 54244, -1000, 2202, -1000, -1000, -1000, - 21030, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 4151, 1824, -1000, 1824, 1425, + 964, -1000, 21549, 1426, 4143, -1000, -1000, 1426, 1426, 21549, + -1000, -1000, 21549, 21549, 21549, 21549, 1474, 1474, 1474, 1474, + 1474, 1474, 1474, 1474, 1474, 1474, 21549, 1474, 1906, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21030, -1000, - 1532, 2126, -1000, -358, -1000, -486, 21030, -271, -1000, -1000, - -271, -1000, -1000, -1000, -1000, -1000, 21030, -1000, -1000, 21030, - -1000, 21030, -1000, -1000, 1576, -1000, -1000, -1000, -1000, -1000, - 1576, 1576, -1000, -280, -1000, 1861, -1000, 52800, 1371, 1852, - -1000, 1122, -1000, -1000, -1000, -1000, -1000, 53522, 1857, 52800, - -1000, 1541, 1532, 1983, 2461, -1000, 1537, -1000, 408, -1000, - 1986, 1982, -1000, -1000, -1000, 18864, -1000, -1000, -1000, -1000, - -1000, 267, -188, 15241, 10873, 1531, -1000, -187, 1219, 1527, - -1000, -461, -1000, -1000, -1000, -1000, 291, -1000, -1000, 1852, - -1000, -1000, 1607, 1565, 1379, 36194, -1000, -1000, -1000, -1000, - -280, -1000, -1000, 2382, -1000, -1000, 1751, -1000, -1000, 31140, - 52078, -1000, -172, 338, -188, 21030, 1985, 1532, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -37, -1000, -1000, 519, - -1000, -1000, -1000, 2088, -199, -1000, -1000, -1000, 318, -475, - -298, -299, 23196, -1000, 21030, -1000, 21030, -1000, 21030, -1000, - -1000, -1000, 52800, 1983, -1000, 1489, -1000, 3989, -327, 2120, - -1000, -132, -1000, -1000, -1000, 1072, 1341, -1000, -1000, -1000, - -1000, -1000, -1000, 1431, 52800, -1000, 421, -1000, -1000, 14513, - -193, -215, 992, -1000, -1000, -1000, -1000, -1000, 2944, 1329, - 1129, 1219, -1000, 52800, -1000, 52078, -322, 864, 5973, -1000, - 2117, 2113, 2522, -1000, -1000, -1000, -1000, -1000, -1000, -529, - 1465, 250, -1000, -1000, -1000, 318, -301, -1000, 21030, -1000, - 21030, -1000, 1532, -1000, -1000, 2372, 76, -1000, 2560, -1000, - 2534, 1060, 1060, -1000, 1106, -529, -1000, -1000, -1000, -1000, - 1219, 1219, -1000, -329, -1000, -1000, -1000, -1000, -1000, 420, - 1302, -1000, -1000, -1000, -1000, -1000, 5973, -1000, -1000, -1000, - 263, 263, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1900, 2544, 1352, + 1474, 1474, 1474, 1474, 1474, 21549, 1432, -1000, -1000, -1000, + 1434, 4139, 1116, 4135, 1474, 1474, -1000, 1474, 4126, 4116, + 1426, 1803, 2877, 2872, 1474, 1474, 1474, 1474, 1474, 2864, + 2803, 1474, 1474, 2722, 1474, 4112, 1474, 2681, 2658, 2645, + 2621, 2615, 2598, 2556, 2540, 2535, 2529, 2524, 2511, 2495, + 2491, 2468, 2453, 2449, 2429, 1474, 1474, 1474, 4093, 1474, + 3877, 1474, 3845, 1474, 1474, 3820, 2409, 2361, 1426, 1897, + -1000, 3813, 1474, 3808, 3804, 3526, 2351, 3515, 3477, 3449, + 1474, 1474, 1474, 2322, 3440, 3435, 3427, 3421, 3417, 3407, + 3403, 3378, 3370, 1474, 1481, 1481, 1481, 1481, 1481, 3361, + -267, 1474, 1426, -1000, -1000, -1000, -1000, -1000, 3347, 2316, + 3336, 3332, 3321, 3317, 1426, 1891, 1788, 761, -1000, -1000, + 1824, 1426, 1426, 1824, 1824, 3290, 3276, 3207, 3191, 3018, + 2997, 1474, 1474, -1000, 1474, 2960, 2940, 2312, 2304, 1426, + -1000, 1481, 54763, -1000, -431, -1000, 0, 933, 1788, -1000, + 37435, 1426, -1000, 4158, -1000, 1335, -1000, -1000, -1000, -1000, + -1000, 34547, 1752, 2727, -1000, -1000, 1788, 1791, -1000, -1000, + 351, 81, 33825, 852, 852, 127, 1515, 1515, 21549, -1000, + -1000, -1000, -1000, -1000, -1000, 542, 2527, 423, 1788, -1000, + 1883, 3286, -1000, -1000, -1000, 2386, 27326, -1000, -1000, 1788, + 1788, 54763, 1863, 1854, -1000, 537, -1000, 1359, 1878, 20, + 19, -1000, -1000, -1000, -1000, 1515, -1000, 1358, 337, 341, + -1000, 416, -1000, -1000, -1000, -1000, 2306, 102, -1000, -1000, + -1000, 365, 351, -1000, -1000, -1000, -1000, -1000, -1000, 1580, + 1580, -1000, -1000, -1000, -1000, -1000, 1241, -1000, -1000, -1000, + -1000, 1223, -1000, -1000, 1222, -1000, -1000, 2327, 2135, 415, + -1000, -1000, 936, 1566, -1000, -1000, 2293, 936, 936, 53319, + -1000, -1000, 1611, 2362, 240, 54763, 959, 2126, -1000, 2079, + 2079, 2079, 54763, -1000, -1000, -1000, -1000, -1000, -1000, -505, + 175, 583, -1000, -1000, -1000, 2009, 53319, 1785, -1000, 222, + -1000, 1549, -1000, 53319, -1000, 1768, 2015, 1353, 1353, -1000, + -1000, -1000, 53319, 1788, -1000, -1000, -1000, -1000, 473, 2347, + 353, -1000, -1000, -293, -1000, -1000, 220, 222, 54041, 1353, + 857, -1000, -1000, -1000, -1000, -1000, -506, 1759, 457, 217, + 563, 54763, 54763, 54763, 54763, 54763, 54763, 782, -1000, -1000, + 41, -1000, -1000, 207, -1000, -1000, -1000, -1000, 207, -1000, + -1000, -1000, -1000, 278, 432, -1000, 54763, 54763, 914, -1000, + -1000, -1000, -1000, -1000, 1027, -1000, -1000, 1027, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 2344, 54763, 15, -472, -1000, -469, 21549, -1000, -1000, -1000, + -1000, 1547, 484, 1224, 23715, 23715, 2945, 2945, 23715, -1000, + -1000, -1000, 1176, 1176, 33103, -1000, 23715, 21549, 20827, -1000, + -1000, 21549, 21549, 934, -1000, 21549, 1198, -1000, 21549, -1000, + -1000, 1481, 1474, 1474, 1474, 1474, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1858, -1000, 21549, 21549, + 21549, 1426, 304, -1000, -1000, -1000, -1000, -1000, 2543, -1000, + 21549, -1000, 33103, 21549, 21549, 21549, -1000, -1000, -1000, 21549, + 21549, -1000, -1000, 21549, -1000, 21549, -1000, -1000, -1000, -1000, + -1000, -1000, 21549, -1000, 21549, -1000, -1000, -1000, 21549, -1000, + 21549, -1000, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, -1000, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, -1000, 21549, -1000, + 21549, -1000, 21549, -1000, 21549, 21549, -1000, 21549, 21549, 21549, + -1000, 21549, 21549, 21549, 21549, -1000, -1000, -1000, -1000, 21549, + 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, -1000, + -1000, -1000, -1000, -1000, -1000, 21549, -1000, 38879, 58, -267, + 1665, 58, 1665, 22993, 805, 803, 22271, -1000, 20827, 15760, + -1000, -1000, -1000, -1000, -1000, 21549, 21549, 21549, 21549, 21549, + 21549, -1000, -1000, -1000, 21549, 21549, -1000, 21549, -1000, 21549, + -1000, -1000, -1000, -1000, -1000, 933, -1000, 868, 868, 868, + 53319, -1000, -1000, -1000, -1000, 1877, -1000, 2458, -1000, 2223, + 2219, 2539, 2527, -1000, 29493, 2727, -1000, -1000, 53319, -412, + -1000, 2258, 2253, 852, 852, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 12848, 2456, 21549, 2115, 54041, 249, -1000, 28771, + 53319, 54041, 29493, 29493, 29493, 29493, 29493, -1000, 2173, 2163, + -1000, 2190, 2154, 2216, 54763, -1000, 1769, 1741, -1000, 21549, + 31659, 1724, 29493, -1000, -1000, 29493, 54763, 12120, -1000, -1000, + 8, -11, -1000, -1000, -1000, -1000, 361, -1000, -1000, 1173, + 2383, 2297, -1000, -1000, -1000, -1000, -1000, 1721, -1000, 1712, + 1865, 1704, 1697, 281, -1000, 2060, 2339, 936, 936, -1000, + 1218, -1000, 1353, 1545, 1538, -1000, -1000, -1000, 436, -1000, + 2375, 54763, 2110, 2109, 2107, -1000, -515, 1213, 2011, 2014, + 21549, 2005, 2503, 1846, 53319, -1000, -1000, 54041, -1000, 294, + -1000, 415, 53319, -1000, -1000, -1000, 327, 54763, -1000, 8692, + -1000, -1000, -1000, 222, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 54763, 237, -1000, 2003, 1340, -1000, -1000, 2069, -1000, + -1000, -1000, -1000, -1000, 215, 213, 1536, 205, 1534, 205, + -1000, 54763, 907, 2135, 54763, -1000, -1000, -1000, 1083, 1083, + -1000, -1000, 2318, -1000, 1353, 1474, 23715, 23715, -1000, 858, + -1000, -1000, 520, -228, 1990, 1990, -1000, 1990, 1995, -1000, + 1990, 161, 1990, 159, 1990, -1000, -1000, 1426, 1426, -1000, + 1481, -1000, 2288, 1329, -1000, 1515, 21549, 2909, -1000, -1000, + -1000, -1000, -1000, -69, 2903, 2890, 1474, -1000, 1988, 1987, + 21549, 1474, 1426, 2280, 1474, 1474, 1474, 1474, 1474, 1474, + 1474, 1474, 1474, 1474, 1474, 1474, 2275, 2211, 2206, 2202, + 2185, 2175, 2111, 2105, 2093, 2089, 2085, 2076, 2062, 2055, + 2006, 1998, 1474, 1474, 1941, 1474, 1936, 1920, -1000, 1515, + 1481, 2843, 1481, 1474, 1474, 2834, 310, 1474, 1692, 1692, + 1692, 1692, 1692, 1481, 1481, 1481, 1481, 1474, 53319, -1000, + -267, -1000, -1000, -315, -316, -1000, 1426, -267, 1860, 23715, + 1474, 23715, 23715, 23715, 1474, 1426, -1000, 1894, 1861, 2689, + 1847, 1474, 2517, 1474, 1474, 1474, 1812, -1000, 2425, 2425, + 2425, 1640, 1335, 54763, -1000, -1000, -1000, -1000, 2527, 2519, + 1855, -1000, -1000, 81, 625, -1000, 2255, 2253, -1000, 2499, + 2272, 2496, -1000, -1000, -1000, -1000, -1000, 1515, -1000, 2353, + 1904, -1000, 950, 1819, -1000, -1000, 20105, 1683, 2210, 524, + 1640, 1881, 3286, 2084, 2106, 3001, -1000, -1000, -1000, -1000, + 2155, -1000, 2153, -1000, -1000, 1966, -1000, 2346, 334, 29493, + 1879, 1879, -1000, 518, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1057, 8692, 2542, -1000, 1525, -1000, 1334, 209, 1199, + -1000, -1000, 936, 936, -1000, 997, 995, -1000, 54763, 1986, + -1000, 351, 1523, 351, 1181, -1000, -1000, 1180, -1000, -1000, + -1000, -1000, 1973, 2217, -1000, -1000, -1000, -1000, 54763, -1000, + -1000, 54763, 54763, 54763, 1984, 2494, -1000, 21549, 1982, 938, + 2181, 53319, 53319, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 429, 936, -486, 285, 284, 936, + 936, 936, -526, -1000, -1000, 1638, 1610, -1000, -182, -1000, + 21549, -1000, -1000, -1000, -1000, -1000, 1238, 1238, 1518, 1512, + 1506, -1000, 1966, -1000, -1000, -1000, 1544, -1000, -1000, -187, + 53319, 53319, 53319, 53319, -1000, -1000, -1000, 1148, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 858, 1426, 345, -195, 1426, -1000, -1000, 351, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, -1000, + 21549, -1000, 1515, 21549, 2456, 1470, 21549, 21549, -1000, 1162, + 1144, 1474, -1000, -1000, -1000, 21549, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, -1000, 21549, -1000, -1000, -1000, 21549, -1000, 21549, -1000, + 21549, -1000, -1000, -1000, 21549, 204, 1176, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1426, 333, + -1000, -1000, -1000, -1000, 2538, -1000, 1426, 21549, 2945, -1000, + 2945, 2945, 2945, -1000, -1000, -1000, 21549, -1000, 21549, 21549, + -1000, 21549, -1000, 21549, -1000, -1000, -1000, -1000, 21549, 1788, + 2313, 1788, 1788, 31659, -1000, -1000, 2519, 2516, 2493, 2234, + 2240, 2240, 2255, -1000, 2486, 2482, -1000, 1458, 2472, 1456, + 991, -1000, 54041, 21549, 249, -1000, 419, 53319, 249, 53319, + -1000, 2459, -1000, -1000, 21549, 1977, -1000, 21549, -1000, -1000, + -1000, -1000, 6798, 2527, 1879, -1000, -1000, 869, -1000, 21549, + -1000, 10160, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1453, 1445, -1000, -1000, 1968, 21549, -1000, -1000, -1000, 1533, + 1511, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1966, + -1000, -1000, -1000, -1000, 327, -510, 2048, 53319, 1129, -1000, + 1578, 1846, 307, 249, 1406, 936, 936, 936, 1128, 1120, + 37435, 1576, -1000, 53319, 399, -1000, 327, -1000, -219, -220, + 1474, -1000, -1000, 2382, -1000, -1000, 15760, -1000, -1000, 1964, + 2074, -1000, -1000, -1000, -1000, 2183, -176, -208, -1000, -1000, + 1474, 1474, 1623, 1426, -1000, 1474, 1474, 1482, 1475, -1000, + 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, + 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, + 1481, 1750, -1000, 204, 1426, 2103, -1000, -1000, 6798, -1000, + -1000, 2459, 2470, 58, -1000, -1000, 236, 58, 1515, 987, + 1426, 1426, 987, 1685, 1474, 1680, 1608, 1474, 1474, 32381, + -1000, 2465, 2463, 38157, 38157, 933, 2516, -281, 21549, 21549, + 2227, 1142, -1000, -1000, -1000, -1000, 1403, 1401, -1000, 1387, + -1000, 2537, -1000, 1515, -1000, 249, -1000, 516, 1819, -1000, + 2456, 1515, 53319, 1515, 77, 2459, -1000, 1474, -1000, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, + 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, -1000, -1000, + 53319, 1907, -1000, -1000, 2381, 1574, 165, -1000, 1469, 1846, + -1000, -1000, 247, -1000, 21549, -1000, 37435, 1385, 1380, -1000, + -1000, -1000, -1000, -526, -1000, -1000, -1000, -1000, -1000, -1000, + 409, 1837, -1000, 931, 53319, 54763, -1000, 2161, -1000, -1000, + -1000, 21549, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, + -1000, 1426, 2099, -1000, -358, -1000, -490, 21549, -267, -1000, + -1000, -267, -1000, -1000, -1000, -1000, -1000, 21549, -1000, -1000, + 21549, -1000, 21549, -1000, -1000, 1571, -1000, -1000, -1000, -1000, + -1000, 1571, 1571, -1000, -281, -1000, 1832, -1000, 53319, 1515, + 1803, -1000, 1140, -1000, -1000, -1000, -1000, -1000, 54041, 1819, + 53319, -1000, 1548, 1426, 1788, 2456, -1000, 1543, -1000, 409, + -1000, 1952, 2014, -1000, -1000, -1000, 19383, -1000, -1000, -1000, + -1000, -1000, 267, -186, 15760, 11392, 1510, -1000, -180, 1474, + 1481, -1000, -462, -1000, -1000, -1000, -1000, 291, -1000, -1000, + 1803, -1000, -1000, 1461, 1419, 1357, 36713, -1000, -1000, -1000, + -1000, -281, -1000, -1000, 2380, -1000, -1000, 1766, -1000, -1000, + 31659, 52597, -1000, -171, 338, -186, 21549, 1951, 1426, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -34, -1000, -1000, + 501, -1000, -1000, -1000, 2069, -199, -1000, -1000, -1000, 318, + -475, -287, -292, 23715, -1000, 21549, -1000, 21549, -1000, 21549, + -1000, -1000, -1000, 53319, 1788, -1000, 1468, -1000, 4863, -326, + 2098, -1000, -92, -1000, -1000, -1000, 1051, 1336, -1000, -1000, + -1000, -1000, -1000, -1000, 1902, 53319, -1000, 366, -1000, -1000, + 15032, -187, -209, 972, -1000, -1000, -1000, -1000, -1000, 2945, + 1312, 1295, 1474, -1000, 53319, -1000, 52597, -321, 857, 6798, + -1000, 2086, 2026, 2532, -1000, -1000, -1000, -1000, -1000, -1000, + -529, 1442, 239, -1000, -1000, -1000, 318, -298, -1000, 21549, + -1000, 21549, -1000, 1426, -1000, -1000, 2369, 77, -1000, 2534, + -1000, 2497, 1021, 1021, -1000, 1089, -529, -1000, -1000, -1000, + -1000, 1474, 1474, -1000, -327, -1000, -1000, -1000, -1000, -1000, + 405, 1175, -1000, -1000, -1000, -1000, -1000, 6798, -1000, -1000, + -1000, 263, 263, -1000, -1000, } var yyPgo = [...]int{ - 0, 3158, 3156, 28, 6, 41, 35, 3155, 3154, 3153, - 177, 3151, 3137, 3135, 3134, 3130, 3129, 2624, 2610, 2600, - 3127, 3126, 3125, 3122, 3120, 3108, 3107, 3104, 3103, 39, - 106, 68, 99, 211, 213, 3100, 176, 166, 198, 3097, - 3096, 3095, 116, 192, 83, 82, 195, 3092, 3091, 74, - 3090, 3088, 3087, 185, 184, 183, 1040, 3086, 182, 112, - 48, 3083, 3080, 3076, 3075, 3072, 3065, 3063, 3061, 3060, - 3054, 3053, 3052, 3046, 3043, 3041, 3040, 3039, 3036, 296, - 3035, 3033, 21, 3030, 76, 3028, 3026, 3025, 3024, 3023, - 11, 3022, 3017, 26, 44, 3012, 3009, 47, 3008, 3007, - 3004, 2998, 2997, 69, 2994, 22, 2983, 40, 2979, 2978, - 121, 2974, 2971, 2966, 43, 2962, 2961, 2957, 29, 167, - 2956, 2955, 139, 2954, 2953, 2950, 165, 206, 2949, 2239, - 205, 108, 111, 2948, 2947, 103, 188, 2946, 123, 2927, - 2924, 2915, 150, 2914, 3191, 2913, 2909, 64, 70, 199, - 2907, 2895, 163, 66, 8, 16, 17, 2894, 2892, 63, - 73, 2889, 101, 2885, 2884, 104, 84, 2883, 90, 98, - 2882, 2881, 5, 7, 2879, 1, 4, 2, 80, 2878, - 2877, 115, 2876, 2873, 2871, 95, 2868, 2865, 4363, 2862, - 85, 128, 102, 62, 2860, 171, 131, 2858, 2857, 2856, - 2854, 2850, 49, 2849, 2848, 2847, 138, 251, 162, 2831, - 144, 337, 52, 143, 2830, 189, 77, 197, 190, 2828, - 2825, 135, 133, 2824, 2821, 55, 164, 191, 2812, 94, - 127, 117, 168, 91, 130, 2808, 2805, 56, 60, 2803, - 2802, 2801, 2800, 174, 2799, 2797, 59, 2795, 54, 2794, - 186, 2792, 136, 79, 2791, 170, 169, 2790, 61, 2789, - 2788, 65, 96, 100, 38, 2787, 158, 161, 125, 172, - 2786, 2782, 53, 2780, 2779, 2778, 196, 292, 2774, 2772, - 294, 178, 141, 147, 89, 2771, 299, 2770, 2767, 13, - 4391, 6814, 2766, 37, 160, 2765, 2758, 6537, 20, 45, - 24, 2755, 204, 2753, 2752, 2750, 2749, 217, 202, 110, - 159, 57, 2744, 2741, 2736, 36, 2735, 2734, 2733, 2732, - 2731, 2723, 72, 34, 33, 32, 212, 58, 19, 97, - 153, 152, 67, 2709, 2706, 2705, 124, 87, 2704, 157, - 155, 120, 129, 2701, 180, 142, 119, 2700, 93, 31, - 2696, 2693, 2688, 2681, 92, 2678, 2677, 2674, 2669, 151, - 146, 118, 78, 2666, 81, 114, 149, 145, 51, 2665, - 46, 2664, 2663, 30, 193, 23, 2662, 15, 105, 109, - 2661, 5648, 181, 2660, 9, 298, 148, 2657, 2655, 10, - 12, 18, 2654, 2639, 2638, 2636, 132, 2635, 2632, 2630, - 2625, 27, 50, 25, 14, 113, 75, 2620, 2615, 140, - 2614, 2593, 2592, 0, 1005, 126, 2591, 207, + 0, 3155, 3154, 28, 6, 41, 35, 3152, 3138, 3136, + 177, 3135, 3131, 3130, 3128, 3127, 3126, 2601, 2585, 2578, + 3123, 3121, 3109, 3108, 3105, 3104, 3101, 3098, 3097, 39, + 106, 68, 99, 204, 213, 3096, 176, 166, 198, 3093, + 3092, 3091, 116, 192, 83, 82, 195, 3089, 3088, 74, + 3087, 3084, 3081, 185, 184, 183, 1030, 3077, 182, 112, + 48, 3076, 3073, 3066, 3064, 3062, 3061, 3055, 3054, 3053, + 3047, 3044, 3042, 3041, 3040, 3037, 3036, 3034, 3031, 296, + 3029, 3027, 21, 3026, 76, 3025, 3024, 3023, 3018, 3013, + 11, 3010, 3009, 26, 44, 3008, 3005, 47, 2999, 2998, + 2995, 2984, 2980, 69, 2979, 22, 2975, 40, 2972, 2967, + 121, 2963, 2962, 2958, 43, 2957, 2956, 2955, 29, 167, + 2954, 2951, 139, 2950, 2949, 2948, 165, 206, 2947, 2255, + 215, 108, 111, 2928, 2925, 103, 188, 2916, 123, 2915, + 2914, 2910, 150, 2908, 3192, 2900, 2899, 64, 70, 199, + 2897, 2896, 163, 66, 8, 16, 17, 2895, 2893, 63, + 73, 2890, 101, 2886, 2885, 104, 84, 2884, 90, 98, + 2883, 2882, 5, 7, 2880, 1, 4, 2, 80, 2879, + 2878, 115, 2877, 2874, 2872, 95, 2869, 2866, 4205, 2863, + 85, 128, 102, 62, 2861, 171, 131, 2859, 2858, 2857, + 2855, 2851, 49, 2850, 2849, 2848, 138, 251, 162, 2846, + 144, 337, 52, 143, 2845, 189, 77, 197, 190, 2826, + 2825, 135, 133, 2822, 2819, 55, 164, 191, 2818, 94, + 127, 117, 168, 91, 130, 2816, 2813, 56, 60, 2809, + 2806, 2804, 2803, 174, 2802, 2796, 59, 2790, 54, 2789, + 186, 2784, 136, 79, 2783, 170, 169, 2782, 61, 2781, + 2780, 65, 96, 100, 38, 2779, 158, 161, 125, 172, + 2776, 2775, 53, 2774, 2773, 2772, 196, 292, 2771, 2768, + 294, 178, 141, 147, 89, 2767, 299, 2765, 2762, 13, + 4392, 7332, 2760, 37, 160, 2759, 2756, 7030, 20, 45, + 24, 2754, 205, 2749, 2745, 2744, 2742, 238, 202, 110, + 159, 57, 2737, 2736, 2735, 36, 2732, 2731, 2724, 2723, + 2722, 2708, 72, 34, 33, 32, 212, 58, 19, 97, + 153, 152, 67, 2707, 2706, 2705, 124, 87, 2702, 157, + 155, 120, 129, 2701, 180, 142, 119, 2697, 93, 31, + 2694, 2692, 2689, 2684, 92, 2681, 2679, 2676, 2674, 151, + 146, 118, 78, 2670, 81, 114, 149, 145, 51, 2665, + 46, 2663, 2661, 30, 193, 23, 2658, 15, 105, 109, + 2656, 6221, 181, 2655, 9, 298, 148, 2650, 2647, 10, + 12, 18, 2646, 2640, 2639, 2636, 132, 2632, 2630, 2626, + 2622, 27, 50, 25, 14, 113, 75, 2621, 2616, 140, + 2615, 2614, 2594, 0, 1005, 126, 2586, 207, } -//line sql.y:8575 +//line sql.y:8579 type yySymType struct { union any empty struct{} @@ -8381,44 +8433,44 @@ var yyR1 = [...]int{ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 278, 278, 287, 287, 277, 277, - 302, 302, 302, 280, 280, 280, 281, 281, 398, 398, - 398, 274, 274, 66, 66, 66, 303, 303, 303, 303, - 69, 69, 407, 407, 408, 408, 409, 409, 409, 70, - 71, 71, 305, 305, 306, 306, 72, 73, 85, 85, - 85, 85, 85, 85, 85, 86, 86, 86, 86, 109, - 109, 109, 10, 10, 10, 10, 81, 81, 81, 9, - 9, 11, 68, 68, 75, 395, 395, 396, 397, 397, - 397, 397, 76, 78, 27, 27, 27, 27, 27, 27, - 134, 134, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 129, 129, 129, 123, 123, 416, - 79, 80, 80, 127, 127, 127, 120, 120, 120, 126, - 126, 126, 12, 12, 13, 260, 260, 14, 14, 131, - 131, 133, 133, 133, 133, 133, 135, 135, 135, 135, - 135, 135, 135, 130, 130, 132, 132, 132, 132, 295, - 295, 295, 294, 294, 165, 165, 167, 166, 166, 168, - 168, 169, 169, 169, 169, 214, 214, 191, 191, 253, - 253, 254, 254, 252, 252, 259, 259, 255, 255, 255, - 255, 262, 262, 170, 170, 170, 170, 178, 178, 179, - 179, 180, 180, 304, 304, 300, 300, 300, 299, 299, - 184, 184, 184, 186, 185, 185, 185, 185, 187, 187, - 189, 189, 188, 188, 190, 195, 195, 194, 194, 192, - 192, 192, 192, 193, 193, 193, 193, 196, 196, 144, - 144, 144, 144, 144, 144, 144, 144, 157, 157, 157, - 157, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 243, 243, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 152, + 65, 65, 65, 65, 65, 278, 278, 287, 287, 277, + 277, 302, 302, 302, 280, 280, 280, 281, 281, 398, + 398, 398, 274, 274, 66, 66, 66, 303, 303, 303, + 303, 69, 69, 407, 407, 408, 408, 409, 409, 409, + 70, 71, 71, 305, 305, 306, 306, 72, 73, 85, + 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, + 109, 109, 109, 10, 10, 10, 10, 81, 81, 81, + 9, 9, 11, 68, 68, 75, 395, 395, 396, 397, + 397, 397, 397, 76, 78, 27, 27, 27, 27, 27, + 27, 134, 134, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 129, 129, 129, 123, 123, + 416, 79, 80, 80, 127, 127, 127, 120, 120, 120, + 126, 126, 126, 12, 12, 13, 260, 260, 14, 14, + 131, 131, 133, 133, 133, 133, 133, 135, 135, 135, + 135, 135, 135, 135, 130, 130, 132, 132, 132, 132, + 295, 295, 295, 294, 294, 165, 165, 167, 166, 166, + 168, 168, 169, 169, 169, 169, 214, 214, 191, 191, + 253, 253, 254, 254, 252, 252, 259, 259, 255, 255, + 255, 255, 262, 262, 170, 170, 170, 170, 178, 178, + 179, 179, 180, 180, 304, 304, 300, 300, 300, 299, + 299, 184, 184, 184, 186, 185, 185, 185, 185, 187, + 187, 189, 189, 188, 188, 190, 195, 195, 194, 194, + 192, 192, 192, 192, 193, 193, 193, 193, 196, 196, + 144, 144, 144, 144, 144, 144, 144, 144, 157, 157, + 157, 157, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 243, 243, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 219, 219, 218, 218, 87, 87, - 87, 88, 88, 89, 89, 89, 89, 89, 90, 90, - 90, 90, 90, 90, 90, 92, 92, 91, 91, 209, - 209, 292, 292, 93, 94, 94, 97, 97, 96, 95, - 95, 101, 101, 98, 98, 100, 100, 99, 102, 102, - 103, 104, 104, 275, 275, 197, 197, 205, 205, 205, - 205, 198, 198, 198, 198, 198, 198, 198, 206, 206, - 206, 213, 207, 207, 203, 203, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 202, 202, 202, 202, + 152, 152, 152, 152, 152, 219, 219, 218, 218, 87, + 87, 87, 88, 88, 89, 89, 89, 89, 89, 90, + 90, 90, 90, 90, 90, 90, 92, 92, 91, 91, + 209, 209, 292, 292, 93, 94, 94, 97, 97, 96, + 95, 95, 101, 101, 98, 98, 100, 100, 99, 102, + 102, 103, 104, 104, 275, 275, 197, 197, 205, 205, + 205, 205, 198, 198, 198, 198, 198, 198, 198, 206, + 206, 206, 213, 207, 207, 203, 203, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, @@ -8437,35 +8489,35 @@ var yyR1 = [...]int{ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 162, 162, 162, - 162, 224, 224, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 151, 151, - 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, - 164, 312, 312, 118, 118, 118, 118, 118, 118, 118, + 202, 202, 202, 202, 202, 202, 202, 202, 162, 162, + 162, 162, 224, 224, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, + 151, 163, 163, 163, 163, 164, 164, 164, 164, 164, + 164, 164, 312, 312, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, + 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 417, 417, 326, 326, 326, 204, 204, 204, 204, - 204, 125, 125, 125, 125, 125, 309, 309, 309, 313, - 313, 313, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 314, 314, 222, - 222, 121, 121, 220, 220, 221, 223, 223, 215, 215, - 215, 215, 217, 217, 200, 200, 200, 225, 225, 226, - 226, 105, 106, 106, 107, 107, 227, 227, 229, 228, - 228, 230, 231, 231, 231, 232, 232, 233, 233, 233, - 49, 49, 49, 49, 49, 44, 44, 44, 44, 45, - 45, 45, 45, 136, 136, 136, 136, 138, 138, 137, - 137, 82, 82, 83, 83, 83, 142, 142, 143, 143, - 143, 140, 140, 141, 141, 250, 250, 234, 234, 234, - 241, 241, 241, 237, 237, 239, 239, 239, 240, 240, - 240, 238, 247, 247, 249, 249, 248, 248, 244, 244, - 245, 245, 246, 246, 246, 242, 242, 199, 199, 199, - 199, 199, 251, 251, 251, 251, 263, 263, 210, 210, - 212, 212, 211, 211, 161, 264, 264, 272, 269, 269, - 270, 270, 296, 296, 296, 273, 273, 286, 286, 282, - 282, 283, 283, 276, 276, 288, 288, 288, 77, 208, - 208, 365, 365, 362, 291, 291, 293, 293, 297, 297, - 301, 301, 298, 298, 8, 410, 410, 410, 289, 289, + 119, 119, 417, 417, 326, 326, 326, 204, 204, 204, + 204, 204, 125, 125, 125, 125, 125, 309, 309, 309, + 313, 313, 313, 311, 311, 311, 311, 311, 311, 311, + 311, 311, 311, 311, 311, 311, 311, 311, 314, 314, + 222, 222, 121, 121, 220, 220, 221, 223, 223, 215, + 215, 215, 215, 217, 217, 200, 200, 200, 225, 225, + 226, 226, 105, 106, 106, 107, 107, 227, 227, 229, + 228, 228, 230, 231, 231, 231, 232, 232, 233, 233, + 233, 49, 49, 49, 49, 49, 44, 44, 44, 44, + 45, 45, 45, 45, 136, 136, 136, 136, 138, 138, + 137, 137, 82, 82, 83, 83, 83, 142, 142, 143, + 143, 143, 140, 140, 141, 141, 250, 250, 234, 234, + 234, 241, 241, 241, 237, 237, 239, 239, 239, 240, + 240, 240, 238, 247, 247, 249, 249, 248, 248, 244, + 244, 245, 245, 246, 246, 246, 242, 242, 199, 199, + 199, 199, 199, 251, 251, 251, 251, 263, 263, 210, + 210, 212, 212, 211, 211, 161, 264, 264, 272, 269, + 269, 270, 270, 296, 296, 296, 273, 273, 286, 286, + 282, 282, 283, 283, 276, 276, 288, 288, 288, 77, + 208, 208, 365, 365, 362, 291, 291, 293, 293, 297, + 297, 301, 301, 298, 298, 8, 410, 410, 410, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, @@ -8480,7 +8532,7 @@ var yyR1 = [...]int{ 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 289, 289, 289, 289, 289, 290, 290, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, @@ -8527,7 +8579,7 @@ var yyR1 = [...]int{ 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 413, 414, 307, 308, 308, 308, + 290, 290, 290, 413, 414, 307, 308, 308, 308, } var yyR2 = [...]int{ @@ -8607,92 +8659,92 @@ var yyR2 = [...]int{ 7, 5, 2, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, 3, 3, 3, 3, - 5, 2, 3, 3, 2, 3, 4, 4, 4, 3, - 4, 4, 5, 3, 0, 1, 0, 1, 1, 1, - 0, 2, 2, 0, 2, 2, 0, 2, 0, 1, - 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, - 1, 3, 0, 1, 1, 3, 3, 2, 2, 1, - 1, 5, 0, 1, 0, 1, 2, 3, 0, 3, - 3, 3, 3, 3, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 1, 4, - 4, 4, 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, 5, 5, 4, 0, 2, 4, 4, 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, 1, 2, 1, 3, 1, - 1, 1, 4, 3, 1, 1, 2, 3, 7, 0, - 3, 0, 1, 1, 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, 1, 1, 2, 6, - 5, 6, 6, 0, 2, 3, 3, 0, 2, 3, - 3, 3, 2, 3, 1, 3, 6, 3, 4, 3, - 1, 3, 4, 5, 6, 3, 4, 5, 6, 3, - 4, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 5, 5, 3, 3, 3, 3, 3, 3, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 2, 2, 2, - 2, 1, 1, 2, 7, 7, 6, 6, 2, 2, - 5, 6, 3, 3, 1, 3, 1, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 4, 2, 4, 0, 1, 2, 5, 0, - 3, 0, 1, 4, 4, 2, 0, 1, 1, 2, - 2, 1, 1, 2, 2, 0, 1, 1, 1, 1, - 5, 1, 3, 0, 3, 1, 1, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 6, 4, 4, 8, 6, - 8, 6, 5, 4, 10, 2, 2, 1, 2, 2, - 2, 2, 2, 4, 5, 5, 5, 5, 5, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, - 4, 8, 8, 6, 5, 4, 4, 4, 4, 4, - 7, 4, 4, 6, 6, 6, 8, 6, 6, 4, - 4, 3, 4, 6, 6, 4, 4, 6, 4, 6, - 4, 4, 4, 4, 4, 4, 6, 4, 6, 4, - 4, 4, 6, 4, 6, 4, 4, 6, 4, 6, + 3, 5, 2, 3, 3, 2, 3, 4, 4, 4, + 3, 4, 4, 5, 3, 0, 1, 0, 1, 1, + 1, 0, 2, 2, 0, 2, 2, 0, 2, 0, + 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, + 1, 1, 3, 0, 1, 1, 3, 3, 2, 2, + 1, 1, 5, 0, 1, 0, 1, 2, 3, 0, + 3, 3, 3, 3, 3, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, + 4, 4, 4, 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, 5, 5, 4, 0, 2, 4, 4, + 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, 1, 2, 1, 3, + 1, 1, 1, 4, 3, 1, 1, 2, 3, 7, + 0, 3, 0, 1, 1, 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, 1, 1, 2, + 6, 5, 6, 6, 0, 2, 3, 3, 0, 2, + 3, 3, 3, 2, 3, 1, 3, 6, 3, 4, + 3, 1, 3, 4, 5, 6, 3, 4, 5, 6, + 3, 4, 1, 1, 1, 3, 3, 3, 3, 3, + 3, 5, 5, 3, 3, 3, 3, 3, 3, 1, + 1, 1, 1, 1, 3, 1, 1, 1, 2, 2, + 2, 2, 1, 1, 2, 7, 7, 6, 6, 2, + 2, 5, 6, 3, 3, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 4, 2, 4, 0, 1, 2, 5, + 0, 3, 0, 1, 4, 4, 2, 0, 1, 1, + 2, 2, 1, 1, 2, 2, 0, 1, 1, 1, + 1, 5, 1, 3, 0, 3, 1, 1, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 4, 6, 4, 4, 8, + 6, 8, 6, 5, 4, 10, 2, 2, 1, 2, + 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 4, 8, 8, 6, 5, 4, 4, 4, 4, + 4, 7, 4, 4, 6, 6, 6, 8, 6, 6, + 4, 4, 3, 4, 6, 6, 4, 4, 6, 4, + 6, 4, 4, 4, 4, 4, 4, 6, 4, 6, + 4, 4, 4, 6, 4, 6, 4, 4, 6, 4, + 6, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, - 6, 8, 4, 6, 8, 4, 6, 8, 4, 4, - 4, 6, 4, 6, 4, 8, 6, 4, 4, 6, - 4, 6, 8, 4, 6, 8, 4, 4, 6, 8, - 6, 4, 6, 6, 8, 10, 7, 8, 8, 9, - 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, - 6, 4, 6, 5, 9, 6, 9, 8, 6, 8, - 8, 8, 6, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 2, 6, 8, 10, 12, 14, 6, 8, - 8, 10, 12, 14, 6, 8, 10, 12, 6, 8, - 4, 4, 3, 4, 6, 6, 4, 6, 4, 6, - 8, 0, 2, 1, 1, 1, 1, 1, 1, 1, + 4, 4, 6, 4, 6, 4, 8, 6, 4, 4, + 6, 4, 6, 8, 4, 6, 8, 4, 4, 6, + 8, 6, 4, 6, 6, 8, 10, 7, 8, 8, + 9, 4, 4, 4, 4, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, + 4, 6, 4, 6, 5, 9, 6, 9, 8, 6, + 8, 8, 8, 6, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 2, 6, 8, 10, 12, 14, 6, + 8, 8, 10, 12, 14, 6, 8, 10, 12, 6, + 8, 4, 4, 3, 4, 6, 6, 4, 6, 4, + 6, 8, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 2, 0, 2, 3, 4, 4, 4, 4, - 4, 0, 3, 4, 7, 3, 1, 1, 1, 0, - 5, 5, 2, 3, 1, 2, 2, 1, 2, 1, - 2, 2, 1, 2, 2, 1, 1, 0, 1, 0, - 1, 0, 2, 1, 2, 4, 0, 2, 1, 1, - 3, 5, 1, 1, 1, 2, 2, 0, 3, 0, - 2, 2, 1, 3, 0, 1, 0, 1, 3, 1, - 3, 2, 0, 1, 1, 0, 1, 2, 4, 4, - 0, 2, 2, 1, 1, 3, 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, 1, 0, 1, 2, 4, 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, 4, 1, 1, 3, 3, 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, 3, 0, 1, 1, 1, 1, + 1, 1, 0, 2, 0, 2, 3, 4, 4, 4, + 4, 4, 0, 3, 4, 7, 3, 1, 1, 1, + 0, 5, 5, 2, 3, 1, 2, 2, 1, 2, + 1, 2, 2, 1, 2, 2, 1, 1, 0, 1, + 0, 1, 0, 2, 1, 2, 4, 0, 2, 1, + 1, 3, 5, 1, 1, 1, 2, 2, 0, 3, + 0, 2, 2, 1, 3, 0, 1, 0, 1, 3, + 1, 3, 2, 0, 1, 1, 0, 1, 2, 4, + 4, 0, 2, 2, 1, 1, 3, 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, 1, 0, 1, 2, 4, 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, 4, 1, 1, 3, 3, 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, 3, 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, @@ -8754,7 +8806,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{ @@ -8883,34 +8935,34 @@ var yyChk = [...]int{ -280, -280, 287, 381, -343, 241, 36, 252, 398, 287, 381, 287, 288, 287, 288, 391, 401, 287, -302, 15, 163, 425, 386, 390, 280, 240, 281, 242, 400, 288, - -302, 90, -281, 160, 287, 398, 283, -280, -280, -308, - -413, -293, -291, -289, 232, 24, 143, 26, 28, 146, - 179, 130, 20, 147, 38, 234, 347, 251, 178, 247, - 470, 227, 73, 586, 426, 433, 424, 432, 436, 472, - 473, 425, 384, 32, 14, 588, 29, 261, 25, 39, - 172, 229, 150, 589, 264, 27, 262, 118, 121, 591, - 23, 76, 256, 15, 249, 41, 17, 592, 593, 18, - 245, 244, 163, 241, 71, 12, 222, 30, 159, 67, - 594, 138, 133, 595, 596, 597, 598, 131, 69, 160, - 21, 726, 434, 435, 34, 687, 574, 275, 174, 74, - 60, 688, 144, 430, 599, 600, 119, 601, 122, 77, - 693, 140, 19, 72, 43, 602, 276, 603, 246, 727, - 604, 416, 605, 161, 230, 469, 70, 162, 700, 606, - 701, 239, 397, 9, 474, 33, 260, 248, 129, 68, - 440, 607, 240, 149, 243, 132, 120, 8, 137, 35, - 13, 75, 78, 437, 438, 439, 58, 128, 578, 148, - 16, 608, 417, 142, -381, 689, -308, -308, 33, 92, - -407, -408, -409, 578, 416, 243, -291, -188, -85, 679, - 231, -86, 685, 24, 238, -134, 398, -122, 179, 707, - 690, 691, 692, 689, 395, 697, 695, 693, 287, 694, - 88, 140, 142, 143, 4, -144, 159, -198, 152, 153, - 154, 155, 156, 157, 158, 164, 163, 144, 146, 160, - -243, 141, 165, 166, 167, 168, 169, 170, 171, 173, - 172, 174, 175, 161, 162, 178, 225, 226, -152, -152, - -152, -152, -213, -219, -218, -413, -215, -381, -290, -297, - -413, -413, -152, -275, -413, -149, -413, -413, -413, -413, - -222, -144, -413, -413, -417, -413, -417, -417, -417, -326, - -413, -326, -326, -413, -413, -413, -413, -413, -413, -413, + -302, 90, -281, 160, 287, 398, 392, 283, -280, -280, + -308, -413, -293, -291, -289, 232, 24, 143, 26, 28, + 146, 179, 130, 20, 147, 38, 234, 347, 251, 178, + 247, 470, 227, 73, 586, 426, 433, 424, 432, 436, + 472, 473, 425, 384, 32, 14, 588, 29, 261, 25, + 39, 172, 229, 150, 589, 264, 27, 262, 118, 121, + 591, 23, 76, 256, 15, 249, 41, 17, 592, 593, + 18, 245, 244, 163, 241, 71, 12, 222, 30, 159, + 67, 594, 138, 133, 595, 596, 597, 598, 131, 69, + 160, 21, 726, 434, 435, 34, 687, 574, 275, 174, + 74, 60, 688, 144, 430, 599, 600, 119, 601, 122, + 77, 693, 140, 19, 72, 43, 602, 276, 603, 246, + 727, 604, 416, 605, 161, 230, 469, 70, 162, 700, + 606, 701, 239, 397, 9, 474, 33, 260, 248, 129, + 68, 440, 607, 240, 149, 243, 132, 120, 8, 137, + 35, 13, 75, 78, 437, 438, 439, 58, 128, 578, + 148, 16, 608, 417, 142, -381, 689, -308, -308, 33, + 92, -407, -408, -409, 578, 416, 243, -291, -188, -85, + 679, 231, -86, 685, 24, 238, -134, 398, -122, 179, + 707, 690, 691, 692, 689, 395, 697, 695, 693, 287, + 694, 88, 140, 142, 143, 4, -144, 159, -198, 152, + 153, 154, 155, 156, 157, 158, 164, 163, 144, 146, + 160, -243, 141, 165, 166, 167, 168, 169, 170, 171, + 173, 172, 174, 175, 161, 162, 178, 225, 226, -152, + -152, -152, -152, -213, -219, -218, -413, -215, -381, -290, + -297, -413, -413, -152, -275, -413, -149, -413, -413, -413, + -413, -222, -144, -413, -413, -417, -413, -417, -417, -417, + -326, -413, -326, -326, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, @@ -8922,386 +8974,386 @@ var yyChk = [...]int{ -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, - -413, -413, -413, -413, -413, -413, 223, -413, -413, -413, - -413, -413, -326, -326, -326, -326, -326, -326, -413, -413, + -413, -413, -413, -413, -413, -413, -413, 223, -413, -413, + -413, -413, -413, -326, -326, -326, -326, -326, -326, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, - -413, -413, 103, 99, 102, 94, -217, 105, 90, 90, - 90, 90, -31, -32, -207, -413, -307, -395, -396, -191, - -188, -413, 304, -291, -291, 273, 96, -232, -34, -31, - -227, -233, -229, -31, -79, -120, -133, 64, 65, -135, - 25, 39, 68, 66, 24, -414, 89, -414, -250, -414, - 88, -38, -253, 87, 62, 44, 90, 90, 88, 22, - -228, -230, -144, 15, -295, 4, -294, 26, -291, 90, - 223, 15, -189, 30, -188, -276, -276, 88, 91, 317, - -266, -268, 414, 416, 152, -296, -291, 90, 32, 89, - 88, -188, -315, -318, -320, -319, -321, -316, -317, 344, - 345, 179, 348, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 361, 33, 263, 340, 341, 342, 343, 362, - 363, 364, 365, 367, 368, 369, 370, 325, 346, 576, - 326, 327, 328, 329, 330, 331, 333, 334, 337, 335, - 336, 338, 339, -382, -381, 87, 89, 88, -322, 87, - -144, -136, 240, -381, 241, 241, 241, -79, 469, -348, - -348, -348, 271, 20, -46, -43, -374, 19, -42, -43, - 232, 123, 124, 229, 87, -337, 87, -346, -382, -381, - 87, 138, 246, 137, -345, -342, -345, -346, -381, -215, - -381, 138, 138, -381, -381, -262, -291, -262, -262, 24, - -262, 24, -262, 24, 96, -291, -262, 24, -262, 24, - -262, 24, -262, 24, -262, 24, 32, 79, 80, 81, - 32, 83, 84, 85, -215, -381, -381, -215, -337, -215, - -188, -381, -269, 96, 96, 96, -348, -348, 96, 90, - 90, 90, -348, -348, 96, 90, -299, -297, 90, 90, - -387, 257, 301, 303, 96, 96, 96, 96, 32, 90, - -388, 32, 714, 713, 715, 716, 717, 90, 96, 32, - 96, 32, 96, -291, 87, -188, -142, 291, 227, 229, - 232, 77, 90, 307, 308, 305, 310, 311, 152, 45, - 88, 243, 240, -381, -282, 245, -282, -291, -298, -297, - -289, -188, 243, 380, 90, -144, -344, 15, 163, -302, - -302, -280, -188, -344, -302, -280, -188, -280, -280, -280, - -280, -302, -302, -302, -280, -297, -297, -188, -188, -188, - -188, -188, -188, -188, -308, -281, -280, 689, 90, -274, - 15, 77, -308, -308, 88, 323, 417, 418, -306, 320, - -81, -291, 90, -10, -29, -18, -17, -19, 152, -10, - 88, 578, -181, -188, 689, 689, 689, 689, 689, 689, - -144, -144, -144, -144, 601, -205, 119, 144, 120, 121, - -160, -144, -206, -211, -213, 106, 163, 146, 160, -243, - -149, -152, -149, -149, -149, -149, -149, -149, 222, -149, - 222, -149, -149, -149, -149, -149, -149, -309, -291, 90, - 179, -156, -155, 105, -404, -156, 575, 88, -218, 223, - -144, -144, -381, -118, 442, 443, 444, 445, 447, 448, - 449, 452, 453, 457, 458, 441, 459, 446, 451, 454, - 455, 456, 450, 343, -144, -130, -132, -130, -144, -220, - -221, 148, -215, -144, -414, -414, 96, 170, -126, 25, - 39, -126, -126, -126, -126, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -126, -144, -119, 441, 459, - 446, 451, 454, 455, 456, 450, 343, 460, 461, 462, - 463, 464, 465, 466, 467, 468, -119, -118, -144, -144, - -144, -144, -144, -144, -87, -144, 130, 131, 132, -207, - -144, -149, -144, -144, -144, -414, -144, -144, -144, -208, - -207, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -413, -413, -413, 103, 99, 102, 94, -217, 105, 90, + 90, 90, 90, -31, -32, -207, -413, -307, -395, -396, + -191, -188, -413, 304, -291, -291, 273, 96, -232, -34, + -31, -227, -233, -229, -31, -79, -120, -133, 64, 65, + -135, 25, 39, 68, 66, 24, -414, 89, -414, -250, + -414, 88, -38, -253, 87, 62, 44, 90, 90, 88, + 22, -228, -230, -144, 15, -295, 4, -294, 26, -291, + 90, 223, 15, -189, 30, -188, -276, -276, 88, 91, + 317, -266, -268, 414, 416, 152, -296, -291, 90, 32, + 89, 88, -188, -315, -318, -320, -319, -321, -316, -317, + 344, 345, 179, 348, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 361, 33, 263, 340, 341, 342, 343, + 362, 363, 364, 365, 367, 368, 369, 370, 325, 346, + 576, 326, 327, 328, 329, 330, 331, 333, 334, 337, + 335, 336, 338, 339, -382, -381, 87, 89, 88, -322, + 87, -144, -136, 240, -381, 241, 241, 241, -79, 469, + -348, -348, -348, 271, 20, -46, -43, -374, 19, -42, + -43, 232, 123, 124, 229, 87, -337, 87, -346, -382, + -381, 87, 138, 246, 137, -345, -342, -345, -346, -381, + -215, -381, 138, 138, -381, -381, -262, -291, -262, -262, + 24, -262, 24, -262, 24, 96, -291, -262, 24, -262, + 24, -262, 24, -262, 24, -262, 24, 32, 79, 80, + 81, 32, 83, 84, 85, -215, -381, -381, -215, -337, + -215, -188, -381, -269, 96, 96, 96, -348, -348, 96, + 90, 90, 90, -348, -348, 96, 90, -299, -297, 90, + 90, -387, 257, 301, 303, 96, 96, 96, 96, 32, + 90, -388, 32, 714, 713, 715, 716, 717, 90, 96, + 32, 96, 32, 96, -291, 87, -188, -142, 291, 227, + 229, 232, 77, 90, 307, 308, 305, 310, 311, 152, + 45, 88, 243, 240, -381, -282, 245, -282, -291, -298, + -297, -289, -188, 243, 380, 90, -144, -344, 15, 163, + -302, -302, -280, -188, -344, -302, -280, -188, -280, -280, + -280, -280, -302, -302, -302, -280, -297, -297, -188, -188, + -188, -188, -188, -188, -188, -308, -281, -280, 689, 90, + -274, 15, 77, -308, -308, 88, 323, 417, 418, -306, + 320, -81, -291, 90, -10, -29, -18, -17, -19, 152, + -10, 88, 578, -181, -188, 689, 689, 689, 689, 689, + 689, -144, -144, -144, -144, 601, -205, 119, 144, 120, + 121, -160, -144, -206, -211, -213, 106, 163, 146, 160, + -243, -149, -152, -149, -149, -149, -149, -149, -149, 222, + -149, 222, -149, -149, -149, -149, -149, -149, -309, -291, + 90, 179, -156, -155, 105, -404, -156, 575, 88, -218, + 223, -144, -144, -381, -118, 442, 443, 444, 445, 447, + 448, 449, 452, 453, 457, 458, 441, 459, 446, 451, + 454, 455, 456, 450, 343, -144, -130, -132, -130, -144, + -220, -221, 148, -215, -144, -414, -414, 96, 170, -126, + 25, 39, -126, -126, -126, -126, -144, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -126, -144, -119, 441, + 459, 446, 451, 454, 455, 456, 450, 343, 460, 461, + 462, 463, 464, 465, 466, 467, 468, -119, -118, -144, + -144, -144, -144, -144, -144, -87, -144, 130, 131, 132, + -207, -144, -149, -144, -144, -144, -414, -144, -144, -144, + -208, -207, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -380, -379, -378, + -144, -144, -144, -144, -144, -144, -144, -144, -380, -379, + -378, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -144, -207, -207, -207, -207, -207, -144, + -414, -144, -162, -147, 96, -258, 105, 92, -144, -144, + -144, -144, -144, -144, -131, -130, -293, -298, -289, -290, + -130, -131, -131, -130, -130, -144, -144, -144, -144, -144, + -144, -144, -144, -414, -144, -144, -144, -144, -144, -250, + -414, -207, 88, -397, 416, 417, 687, -300, 276, -299, + 26, -208, 90, 15, -260, 78, -291, -232, -232, 64, + 65, 60, -130, -135, -414, -37, 26, -252, -291, 63, + 90, -327, -269, 371, 372, 179, -144, -144, 88, -231, + 28, 29, -188, -294, 170, -298, -188, -261, 276, -188, + -166, -168, -169, -170, -191, -214, -413, -171, -31, 597, + 594, 15, -181, -182, -190, -297, -267, -310, -266, 88, + 415, 417, 418, 77, 122, -144, -328, 178, -356, -355, + -354, -337, -339, -340, -341, 89, -328, -333, 377, 376, + -322, -322, -322, -322, -322, -327, -327, -327, -327, 87, + 87, -322, -322, -322, -322, -330, 87, -330, -330, -331, + -330, 87, -331, -332, 87, -332, -367, -144, -364, -363, + -361, -362, 250, 101, 669, 625, 578, 618, 659, 78, + -359, -231, 96, -414, -142, -283, 245, -365, -362, -381, + -381, -381, -283, 91, 90, 91, 90, 91, 90, -111, + -60, -1, 726, 727, 728, 88, 20, -338, -337, -59, + 301, -370, -371, 276, -366, -360, -346, 138, -345, -346, + -346, -381, 88, 30, 127, 127, 127, 127, 578, 229, + 33, -284, 617, 144, 669, 625, -337, -59, 243, 243, + -309, -309, -309, 90, 90, -279, 722, -181, -138, 293, + 152, 282, 282, 240, 295, 240, 295, -188, 306, 309, + 307, 308, 305, 310, 311, 24, 24, 24, 24, 24, + 294, 296, 298, 284, -188, -188, -282, 77, -183, -188, + 27, -297, 90, 90, -188, -280, -280, -188, -280, -280, + -188, -409, 324, -291, 358, 680, 681, 683, 682, -122, + 416, 88, 578, 23, -123, 23, -413, 119, 120, 121, + -206, -149, -152, -149, 143, 264, -149, -149, -413, -215, + -414, -293, 26, 88, 78, -414, 168, 88, 88, -414, + -414, 88, 15, -223, -221, 150, -144, -414, 88, -414, + -414, -207, -144, -144, -144, -144, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -207, -414, 88, 88, + 15, -313, 26, -414, -414, -414, -414, -414, -222, -414, + 15, -414, 78, 88, 163, 88, -414, -414, -414, 88, + 88, -414, -414, 88, -414, 88, -414, -414, -414, -414, + -414, -414, 88, -414, 88, -414, -414, -414, 88, -414, + 88, -414, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, -414, + -414, 88, -414, 88, -414, 88, -414, -414, 88, -414, + 88, -414, 88, -414, 88, 88, -414, 88, 88, 88, + -414, 88, 88, 88, 88, -414, -414, -414, -414, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, -414, + -414, -414, -414, -414, -414, 88, -94, 602, -414, -414, + 88, -414, 88, 88, 88, 88, 88, -414, -413, 223, + -414, -414, -414, -414, -414, 88, 88, 88, 88, 88, + 88, -414, -414, -414, 88, 88, -414, 88, -414, 88, + -414, -396, 686, 417, -195, -194, -192, 75, 244, 76, + -413, -299, -414, -156, -258, -259, -258, -200, -291, 96, + 105, -234, -165, -167, 15, -135, -213, 89, 88, -327, + -238, -244, -277, -291, 90, 179, -329, 179, -329, 371, + 372, -230, 223, -196, 16, -199, 33, 58, -29, -413, + -413, 33, 88, -184, -186, -185, -187, 67, 71, 73, + 68, 69, 70, 74, -304, 26, -31, -166, -31, -413, + -188, -181, -415, 15, 78, -415, 88, 223, -268, -271, + 419, 416, 422, -381, 90, -110, 88, -354, -341, -235, + -139, 41, -334, 378, -327, 585, -327, -336, 90, -336, + 96, 96, 96, 89, -49, -44, -45, 34, 82, -361, + -348, 90, 40, -348, -348, -291, 89, -231, -138, -188, + 144, 77, -365, -365, -365, -297, -2, 725, 731, 138, + 87, 383, 19, -252, 88, 89, -216, 302, 89, -112, + -291, 89, 87, -346, -346, -291, -413, 240, 32, 32, + 669, 625, 617, -59, -216, -215, -381, -328, 724, 723, + 89, 242, 300, -143, 436, -140, 90, 91, -188, -188, + -188, -188, -188, -188, 232, 229, 406, -405, 312, -405, + 285, 243, -181, -188, 88, -84, 259, 254, -302, -302, + 34, -188, 416, 698, 696, -144, 143, 264, -160, -152, + -118, -118, -149, -311, 179, 344, 263, 342, 338, 358, + 349, 376, 340, 377, 335, 334, 333, -311, -309, -149, + -207, -132, -144, -144, 151, -144, 149, -144, -414, -414, + -414, -414, -414, -227, -144, -144, -144, -414, 179, 344, + 15, -144, -309, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -207, -207, -207, -207, -207, -144, -414, - -144, -162, -147, 96, -258, 105, 92, -144, -144, -144, - -144, -144, -144, -131, -130, -293, -298, -289, -290, -130, - -131, -131, -130, -130, -144, -144, -144, -144, -144, -144, - -144, -144, -414, -144, -144, -144, -144, -144, -250, -414, - -207, 88, -397, 416, 417, 687, -300, 276, -299, 26, - -208, 90, 15, -260, 78, -291, -232, -232, 64, 65, - 60, -130, -135, -414, -37, 26, -252, -291, 63, 90, - -327, -269, 371, 372, 179, -144, -144, 88, -231, 28, - 29, -188, -294, 170, -298, -188, -261, 276, -188, -166, - -168, -169, -170, -191, -214, -413, -171, -31, 597, 594, - 15, -181, -182, -190, -297, -267, -310, -266, 88, 415, - 417, 418, 77, 122, -144, -328, 178, -356, -355, -354, - -337, -339, -340, -341, 89, -328, -333, 377, 376, -322, - -322, -322, -322, -322, -327, -327, -327, -327, 87, 87, - -322, -322, -322, -322, -330, 87, -330, -330, -331, -330, - 87, -331, -332, 87, -332, -367, -144, -364, -363, -361, - -362, 250, 101, 669, 625, 578, 618, 659, 78, -359, - -231, 96, -414, -142, -283, 245, -365, -362, -381, -381, - -381, -283, 91, 90, 91, 90, 91, 90, -111, -60, - -1, 726, 727, 728, 88, 20, -338, -337, -59, 301, - -370, -371, 276, -366, -360, -346, 138, -345, -346, -346, - -381, 88, 30, 127, 127, 127, 127, 578, 229, 33, - -284, 617, 144, 669, 625, -337, -59, 243, 243, -309, - -309, -309, 90, 90, -279, 722, -181, -138, 293, 152, - 282, 282, 240, 295, 240, 295, -188, 306, 309, 307, - 308, 305, 310, 311, 24, 24, 24, 24, 24, 294, - 296, 298, 284, -188, -188, -282, 77, -183, -188, 27, - -297, 90, 90, -188, -280, -280, -188, -280, -280, -188, - -409, 324, -291, 358, 680, 681, 683, 682, -122, 416, - 88, 578, 23, -123, 23, -413, 119, 120, 121, -206, - -149, -152, -149, 143, 264, -149, -149, -413, -215, -414, - -293, 26, 88, 78, -414, 168, 88, 88, -414, -414, - 88, 15, -223, -221, 150, -144, -414, 88, -414, -414, - -207, -144, -144, -144, -144, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -207, -414, 88, 88, 15, - -313, 26, -414, -414, -414, -414, -414, -222, -414, 15, - -414, 78, 88, 163, 88, -414, -414, -414, 88, 88, - -414, -414, 88, -414, 88, -414, -414, -414, -414, -414, - -414, 88, -414, 88, -414, -414, -414, 88, -414, 88, - -414, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, -414, -414, - 88, -414, 88, -414, 88, -414, -414, 88, -414, 88, - -414, 88, -414, 88, 88, -414, 88, 88, 88, -414, - 88, 88, 88, 88, -414, -414, -414, -414, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, -414, -414, - -414, -414, -414, -414, 88, -94, 602, -414, -414, 88, - -414, 88, 88, 88, 88, 88, -414, -413, 223, -414, - -414, -414, -414, -414, 88, 88, 88, 88, 88, 88, - -414, -414, -414, 88, 88, -414, 88, -414, 88, -414, - -396, 686, 417, -195, -194, -192, 75, 244, 76, -413, - -299, -414, -156, -258, -259, -258, -200, -291, 96, 105, - -234, -165, -167, 15, -135, -213, 89, 88, -327, -238, - -244, -277, -291, 90, 179, -329, 179, -329, 371, 372, - -230, 223, -196, 16, -199, 33, 58, -29, -413, -413, - 33, 88, -184, -186, -185, -187, 67, 71, 73, 68, - 69, 70, 74, -304, 26, -31, -166, -31, -413, -188, - -181, -415, 15, 78, -415, 88, 223, -268, -271, 419, - 416, 422, -381, 90, -110, 88, -354, -341, -235, -139, - 41, -334, 378, -327, 585, -327, -336, 90, -336, 96, - 96, 96, 89, -49, -44, -45, 34, 82, -361, -348, - 90, 40, -348, -348, -291, 89, -231, -138, -188, 144, - 77, -365, -365, -365, -297, -2, 725, 731, 138, 87, - 383, 19, -252, 88, 89, -216, 302, 89, -112, -291, - 89, 87, -346, -346, -291, -413, 240, 32, 32, 669, - 625, 617, -59, -216, -215, -381, -328, 724, 723, 89, - 242, 300, -143, 436, -140, 90, 91, -188, -188, -188, - -188, -188, -188, 232, 229, 406, -405, 312, -405, 285, - 243, -181, -188, 88, -84, 259, 254, -302, -302, 34, - -188, 416, 698, 696, -144, 143, 264, -160, -152, -118, - -118, -149, -311, 179, 344, 263, 342, 338, 358, 349, - 376, 340, 377, 335, 334, 333, -311, -309, -149, -207, - -132, -144, -144, 151, -144, 149, -144, -414, -414, -414, - -414, -414, -227, -144, -144, -144, -414, 179, 344, 15, - -144, -309, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -144, -378, -144, + -207, -144, -207, -144, -144, -144, -144, -144, -379, -379, + -379, -379, -379, -207, -207, -207, -207, -144, -413, -291, + -97, -96, -95, 652, 244, -94, -162, -97, -162, 222, + -144, 222, 222, 222, -144, -131, -293, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -192, -342, -342, + -342, -262, 88, -273, 23, 15, 58, 58, -165, -196, + -166, -135, -291, -241, 679, -247, 47, -245, -246, 48, + -242, 49, 57, -329, -329, 170, -232, -144, -263, 77, + -264, -272, -215, -210, -212, -211, -413, -251, -414, -291, + -262, -264, -168, -169, -169, -168, -169, 67, 67, 67, + 72, 67, 72, 67, -185, -297, -414, -144, -300, 78, + -166, -166, -190, -297, 170, 416, 420, 421, -354, -403, + 119, 144, 32, 77, 374, 101, -401, 178, 614, 664, + 669, 625, 618, 659, -402, 246, 137, 138, 258, 26, + 42, 89, 88, 89, 88, 89, 89, 88, -285, -284, + -45, -44, -348, -348, 96, -381, 90, 90, 242, 27, + -188, 77, 77, 77, -113, 729, 96, 87, -3, 82, + -144, 87, 20, -337, -215, -372, -323, -373, -324, -325, + -5, -6, -349, -116, 58, 101, -63, 45, 241, 709, + 710, 127, -413, 722, -364, -252, -368, -370, -188, -148, + -413, -159, -146, -145, -147, -153, 168, 169, 263, 340, + 341, -216, -188, -137, 291, 299, 87, -141, 92, -384, + 78, 282, 374, 282, 374, 90, -406, 313, 90, -406, + -188, -84, -49, -188, -280, -280, 34, -381, -414, -160, + -152, -125, 163, 578, -314, 584, -322, -322, -322, -332, + -322, 330, -322, 330, -322, -414, -414, -414, 88, -414, + 23, -414, -144, 88, -121, 474, 88, 88, -414, 87, + 87, -144, -414, -414, -414, 88, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, -414, 88, -414, -414, -414, 88, -414, 88, -414, + 88, -414, -414, -414, 88, -312, 670, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -93, -292, + -291, -94, 634, 634, -414, -94, -224, 88, -149, -414, + -149, -149, -149, -414, -414, -414, 88, -414, 88, 88, + -414, 88, -414, 88, -414, -414, -414, -414, 88, -193, + 23, -193, -193, -414, -258, -188, -196, -225, 17, -238, + 52, 350, -249, -248, 56, 48, -246, 20, 50, 20, + 31, -263, 88, 152, 88, -414, -414, 88, 58, 223, + -414, -196, -179, -178, 77, 78, -180, 77, -178, 67, + 67, -253, 88, -261, -166, -196, -196, 223, 119, -413, + -148, 13, 90, 90, -381, -400, 713, 714, 32, 96, + -348, -348, 138, 138, -188, 87, -327, 90, -327, 96, + 96, 32, 83, 84, 85, 32, 79, 80, 81, -188, + -188, -188, -188, -369, 87, 20, -144, 87, 152, 89, + -252, -252, 278, 163, -348, 707, 284, 284, -348, -348, + -348, -115, -114, 729, 89, -414, 88, -335, 578, 581, + -144, -154, -154, -253, 89, -377, 578, -383, -291, -291, + -291, -291, 96, 98, -414, 576, 74, 579, -414, -327, + -144, -144, -144, -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -378, -144, -207, - -144, -207, -144, -144, -144, -144, -144, -379, -379, -379, - -379, -379, -207, -207, -207, -207, -144, -413, -291, -97, - -96, -95, 652, 244, -94, -162, -97, -162, 222, -144, - 222, 222, 222, -144, -131, -293, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -192, -342, -342, -342, - -262, 88, -273, 23, 15, 58, 58, -165, -196, -166, - -135, -291, -241, 679, -247, 47, -245, -246, 48, -242, - 49, 57, -329, -329, 170, -232, -144, -263, 77, -264, - -272, -215, -210, -212, -211, -413, -251, -414, -291, -262, - -264, -168, -169, -169, -168, -169, 67, 67, 67, 72, - 67, 72, 67, -185, -297, -414, -144, -300, 78, -166, - -166, -190, -297, 170, 416, 420, 421, -354, -403, 119, - 144, 32, 77, 374, 101, -401, 178, 614, 664, 669, - 625, 618, 659, -402, 246, 137, 138, 258, 26, 42, - 89, 88, 89, 88, 89, 89, 88, -285, -284, -45, - -44, -348, -348, 96, -381, 90, 90, 242, 27, -188, - 77, 77, 77, -113, 729, 96, 87, -3, 82, -144, - 87, 20, -337, -215, -372, -323, -373, -324, -325, -5, - -6, -349, -116, 58, 101, -63, 45, 241, 709, 710, - 127, -413, 722, -364, -252, -368, -370, -188, -148, -413, - -159, -146, -145, -147, -153, 168, 169, 263, 340, 341, - -216, -188, -137, 291, 299, 87, -141, 92, -384, 78, - 282, 374, 282, 374, 90, -406, 313, 90, -406, -188, - -84, -49, -188, -280, -280, 34, -381, -414, -160, -152, - -125, 163, 578, -314, 584, -322, -322, -322, -332, -322, - 330, -322, 330, -322, -414, -414, -414, 88, -414, 23, - -414, -144, 88, -121, 474, 88, 88, -414, 87, 87, - -144, -414, -414, -414, 88, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - -414, 88, -414, -414, -414, 88, -414, 88, -414, 88, - -414, -414, -414, 88, -312, 670, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -93, -292, -291, - -94, 634, 634, -414, -94, -224, 88, -149, -414, -149, - -149, -149, -414, -414, -414, 88, -414, 88, 88, -414, - 88, -414, 88, -414, -414, -414, -414, 88, -193, 23, - -193, -193, -414, -258, -188, -196, -225, 17, -238, 52, - 350, -249, -248, 56, 48, -246, 20, 50, 20, 31, - -263, 88, 152, 88, -414, -414, 88, 58, 223, -414, - -196, -179, -178, 77, 78, -180, 77, -178, 67, 67, - -253, 88, -261, -166, -196, -196, 223, 119, -413, -148, - 13, 90, 90, -381, -400, 713, 714, 32, 96, -348, - -348, 138, 138, -188, 87, -327, 90, -327, 96, 96, - 32, 83, 84, 85, 32, 79, 80, 81, -188, -188, - -188, -188, -369, 87, 20, -144, 87, 152, 89, -252, - -252, 278, 163, -348, 707, 284, 284, -348, -348, -348, - -115, -114, 729, 89, -414, 88, -335, 578, 581, -144, - -154, -154, -253, 89, -377, 578, -383, -291, -291, -291, - -291, 96, 98, -414, 576, 74, 579, -414, -327, -144, - -144, -144, -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -144, -144, -207, - -144, -414, -176, -175, -177, 690, 119, 32, -311, -414, - -209, 276, -100, -99, -98, 15, -414, -144, -118, -118, - -118, -118, -144, -144, -144, -144, -144, -144, -413, 67, - 19, 17, -413, -413, -300, -225, -226, 18, 20, -239, - 54, -237, 53, -237, -248, 20, 20, 90, 20, 90, - 138, -272, -144, -212, 58, -29, -291, -210, -291, -227, - -144, 87, -144, -156, -196, -196, -144, -202, 498, 500, - 501, 502, 499, 504, 505, 506, 507, 508, 509, 510, - 511, 512, 513, 503, 514, 475, 476, 477, 108, 110, - 109, 478, 479, 480, 344, 526, 527, 521, 524, 525, - 523, 522, 359, 360, 481, 544, 545, 549, 548, 546, - 547, 550, 553, 554, 555, 556, 557, 558, 560, 559, - 551, 552, 529, 528, 530, 531, 532, 533, 534, 535, - 537, 536, 538, 539, 540, 541, 542, 543, 561, 562, - 563, 564, 565, 567, 566, 571, 570, 568, 569, 573, - 572, 482, 483, 111, 112, 113, 114, 115, 116, 117, - 484, 487, 485, 488, 489, 490, 495, 496, 491, 492, - 493, 494, 497, 370, 368, 369, 365, 364, 363, 423, - 428, 429, 431, 515, 516, 517, 518, 519, 520, 671, - 672, 673, 674, 675, 676, 677, 678, 90, 90, 87, - -144, 89, 89, -253, -368, -60, 89, -254, -252, 96, - 89, 279, -211, -413, 90, -348, -348, -348, 96, 96, - -299, -414, 88, -291, -402, -370, 582, 582, -414, 26, - -376, -375, -293, 87, 78, 63, 577, 580, -414, -414, - 88, -414, -414, -414, 89, 89, -414, -414, -414, -414, + -207, -144, -414, -176, -175, -177, 690, 119, 32, -311, + -414, -209, 276, -100, -99, -98, 15, -414, -144, -118, + -118, -118, -118, -144, -144, -144, -144, -144, -144, -413, + 67, 19, 17, -413, -413, -300, -225, -226, 18, 20, + -239, 54, -237, 53, -237, -248, 20, 20, 90, 20, + 90, 138, -272, -144, -212, 58, -29, -291, -210, -291, + -227, -144, 87, -144, -156, -196, -196, -144, -202, 498, + 500, 501, 502, 499, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 503, 514, 475, 476, 477, 108, + 110, 109, 478, 479, 480, 344, 526, 527, 521, 524, + 525, 523, 522, 359, 360, 481, 544, 545, 549, 548, + 546, 547, 550, 553, 554, 555, 556, 557, 558, 560, + 559, 551, 552, 529, 528, 530, 531, 532, 533, 534, + 535, 537, 536, 538, 539, 540, 541, 542, 543, 561, + 562, 563, 564, 565, 567, 566, 571, 570, 568, 569, + 573, 572, 482, 483, 111, 112, 113, 114, 115, 116, + 117, 484, 487, 485, 488, 489, 490, 495, 496, 491, + 492, 493, 494, 497, 370, 368, 369, 365, 364, 363, + 423, 428, 429, 431, 515, 516, 517, 518, 519, 520, + 671, 672, 673, 674, 675, 676, 677, 678, 90, 90, + 87, -144, 89, 89, -253, -368, -60, 89, -254, -252, + 96, 89, 279, -211, -413, 90, -348, -348, -348, 96, + 96, -299, -414, 88, -291, -402, -370, 582, 582, -414, + 26, -376, -375, -293, 87, 78, 63, 577, 580, -414, + -414, 88, -414, -414, -414, 89, 89, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -414, 88, -414, - -175, -177, -414, 77, -156, -227, 20, -97, 301, 303, - -97, -414, -414, -414, -414, -414, 88, -414, -414, 88, - -414, 88, -414, -414, -255, -414, -291, 246, 20, 20, - -255, -255, -195, -226, -107, -106, -105, 608, -144, -207, - -240, 55, 77, 122, 90, 90, 90, 13, -210, 223, - -232, -252, -173, 383, -227, -414, -252, 89, 26, 89, - 731, 138, 89, -211, -124, -413, 275, -299, 90, 90, - -114, -117, -29, 88, 152, -252, -188, 63, -144, -207, - -414, 77, 589, 690, -92, -91, -88, 701, 727, -207, - -94, -94, -144, -144, -144, 88, -414, -414, -414, -107, - 88, -104, -103, -291, 77, 122, -264, -291, 89, -414, - -413, -232, 89, -236, -29, 87, -3, 275, -323, -373, - -324, -325, -5, -6, -349, -82, 578, -375, -353, -297, - -293, 90, 96, 89, 578, -414, -414, -90, 146, 699, - 667, -154, 222, -414, 88, -414, 88, -414, 88, -291, - 246, -105, 88, 26, -300, -174, -172, -291, 631, -393, - -392, 574, -403, -399, 119, 144, 101, -401, 669, 625, - 128, 129, -82, -144, 87, -414, -83, 290, 686, 223, - -384, 579, -90, 700, 645, 620, 645, 620, -149, -144, - -144, -144, -103, -413, -414, 88, 23, -315, -62, 642, - -390, -391, 77, -394, 389, 641, 662, 119, 90, 89, - -252, 251, -298, -377, 580, 143, -118, -414, 88, -414, - 88, -414, -93, -172, 638, -328, -156, -391, 77, -390, - 77, 14, 13, -4, 730, 89, 292, -90, 645, 620, - -144, -144, -414, -61, 27, -173, -389, 259, 254, 257, - 33, -389, 96, -4, -414, -414, 642, 253, 32, 119, - -156, -176, -175, -175, + -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, + -414, -175, -177, -414, 77, -156, -227, 20, -97, 301, + 303, -97, -414, -414, -414, -414, -414, 88, -414, -414, + 88, -414, 88, -414, -414, -255, -414, -291, 246, 20, + 20, -255, -255, -195, -226, -107, -106, -105, 608, -144, + -207, -240, 55, 77, 122, 90, 90, 90, 13, -210, + 223, -232, -252, -173, 383, -227, -414, -252, 89, 26, + 89, 731, 138, 89, -211, -124, -413, 275, -299, 90, + 90, -114, -117, -29, 88, 152, -252, -188, 63, -144, + -207, -414, 77, 589, 690, -92, -91, -88, 701, 727, + -207, -94, -94, -144, -144, -144, 88, -414, -414, -414, + -107, 88, -104, -103, -291, 77, 122, -264, -291, 89, + -414, -413, -232, 89, -236, -29, 87, -3, 275, -323, + -373, -324, -325, -5, -6, -349, -82, 578, -375, -353, + -297, -293, 90, 96, 89, 578, -414, -414, -90, 146, + 699, 667, -154, 222, -414, 88, -414, 88, -414, 88, + -291, 246, -105, 88, 26, -300, -174, -172, -291, 631, + -393, -392, 574, -403, -399, 119, 144, 101, -401, 669, + 625, 128, 129, -82, -144, 87, -414, -83, 290, 686, + 223, -384, 579, -90, 700, 645, 620, 645, 620, -149, + -144, -144, -144, -103, -413, -414, 88, 23, -315, -62, + 642, -390, -391, 77, -394, 389, 641, 662, 119, 90, + 89, -252, 251, -298, -377, 580, 143, -118, -414, 88, + -414, 88, -414, -93, -172, 638, -328, -156, -391, 77, + -390, 77, 14, 13, -4, 730, 89, 292, -90, 645, + 620, -144, -144, -414, -61, 27, -173, -389, 259, 254, + 257, 33, -389, 96, -4, -414, -414, 642, 253, 32, + 119, -156, -176, -175, -175, } var yyDef = [...]int{ - 879, -2, -2, 881, 2, 4, 5, 6, 7, 8, + 880, -2, -2, 882, 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, 34, 35, 36, 37, 38, - 39, 72, 74, 75, 879, 879, 879, 0, 879, 0, - 0, 879, -2, -2, 879, 1610, 0, 879, 0, 874, - 0, -2, 794, 800, 0, 809, -2, 0, 0, 879, - 879, 2234, 2234, 874, 0, 0, 0, 0, 0, 879, - 879, 879, 879, 1615, 1476, 52, 879, 0, 87, 88, - 829, 830, 831, 67, 0, 2232, 880, 1, 3, 73, - 77, 0, 0, 0, 60, 1485, 0, 80, 0, 0, - 883, 0, 0, 1593, 879, 879, 0, 128, 129, 0, + 39, 72, 74, 75, 880, 880, 880, 0, 880, 0, + 0, 880, -2, -2, 880, 1611, 0, 880, 0, 875, + 0, -2, 795, 801, 0, 810, -2, 0, 0, 880, + 880, 2235, 2235, 875, 0, 0, 0, 0, 0, 880, + 880, 880, 880, 1616, 1477, 52, 880, 0, 87, 88, + 830, 831, 832, 67, 0, 2233, 881, 1, 3, 73, + 77, 0, 0, 0, 60, 1486, 0, 80, 0, 0, + 884, 0, 0, 1594, 880, 880, 0, 128, 129, 0, 0, 0, -2, 132, -2, 161, 162, 163, 0, 168, 605, 526, 578, 524, 563, -2, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, - 401, 401, 0, 0, -2, 512, 512, 512, 1595, 0, + 401, 401, 0, 0, -2, 512, 512, 512, 1596, 0, 0, 0, 560, 463, 401, 401, 401, 0, 401, 401, 401, 401, 0, 0, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 1503, 167, 1611, 1608, 1609, 1768, 1769, 1770, 1771, - 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, - 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, - 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, - 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, - 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, - 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, - 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, - 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, - 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, - 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, - 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, - 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, - 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, - 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, - 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, - 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, - 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, - 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, - 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, - 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, - 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, - 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, - 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, - 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, - 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, - 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, - 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, - 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, - 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, - 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, - 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, - 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, - 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, - 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, - 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, - 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, - 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, - 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, - 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, - 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, - 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, - 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, - 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, - 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, - 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, - 0, 1587, 0, 718, 982, 0, 875, 876, 0, 783, - 783, 0, 783, 783, 783, 783, 0, 0, 0, 732, - 0, 0, 0, 0, 780, 0, 748, 749, 0, 780, - 0, 755, 786, 0, 0, 761, 783, 783, 764, 2235, - 0, 2235, 2235, 1578, 0, 777, 775, 789, 790, 42, - 793, 796, 797, 798, 799, 802, 0, 813, 816, 1604, - 1605, 0, 818, 825, 842, 843, 0, 47, 1132, 0, - 1004, 0, 1010, -2, 1021, 1038, 1039, 1040, 1041, 1042, - 1044, 1045, 1046, 0, 0, 0, 0, 1051, 1052, 0, - 0, 0, 0, 0, 1113, 0, 0, 0, 0, 1449, - 0, 0, 1411, 1411, 1147, 1411, 1411, 1413, 1413, 1413, - 1820, 1958, 1966, 2142, 1781, 1787, 1788, 1789, 2088, 2089, - 2090, 2091, 2179, 2180, 2184, 1882, 1776, 2155, 2156, 0, - 2231, 1919, 1927, 1928, 1952, 2052, 2165, 1799, 1947, 2016, - 1879, 1901, 1902, 2034, 2035, 1923, 1924, 1905, 2094, 2096, - 2112, 2113, 2098, 2100, 2109, 2115, 2120, 2099, 2111, 2116, - 2129, 2133, 2136, 2137, 2138, 2106, 2104, 2117, 2121, 2123, - 2125, 2131, 2134, 2107, 2105, 2118, 2122, 2124, 2126, 2132, - 2135, 2093, 2097, 2101, 2110, 2128, 2108, 2127, 2102, 2114, - 2119, 2130, 2103, 2095, 1917, 1920, 1908, 1909, 1911, 1913, - 1918, 1925, 1931, 1910, 1930, 1929, 0, 1906, 1907, 1912, - 1922, 1926, 1914, 1915, 1916, 1921, 1932, 1972, 1971, 1970, - 2015, 1943, 2014, 0, 0, 0, 0, 0, 1771, 1825, - 1826, 2139, 1333, 1334, 1335, 1336, 0, 0, 0, 0, - 0, 0, 0, 293, 294, 1462, 1463, 46, 1131, 1574, - 1413, 1413, 1413, 1413, 1413, 1413, 1073, 1074, 1075, 1076, - 1077, 1101, 1102, 1108, 1109, 2029, 2030, 2031, 2032, 1863, - 2174, 1871, 1872, 2011, 2012, 1884, 1885, 2205, 2206, -2, + 401, 1504, 167, 1612, 1609, 1610, 1769, 1770, 1771, 1772, + 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, + 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, + 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, + 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, + 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, + 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, + 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, + 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, + 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, + 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, + 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, + 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, + 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, + 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, + 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, + 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, + 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, + 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, + 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, + 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, + 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, + 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, + 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, + 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, + 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, + 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, + 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, + 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, + 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, + 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, + 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, + 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, + 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, + 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, + 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, + 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, + 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, + 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, + 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, + 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, + 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, + 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, + 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, + 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, + 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, + 0, 1588, 0, 718, 983, 0, 876, 877, 0, 784, + 784, 0, 784, 784, 784, 784, 0, 0, 0, 732, + 0, 0, 0, 0, 781, 0, 748, 749, 0, 781, + 0, 755, 787, 0, 0, 762, 784, 784, 765, 2236, + 0, 2236, 2236, 1579, 0, 778, 776, 790, 791, 42, + 794, 797, 798, 799, 800, 803, 0, 814, 817, 1605, + 1606, 0, 819, 826, 843, 844, 0, 47, 1133, 0, + 1005, 0, 1011, -2, 1022, 1039, 1040, 1041, 1042, 1043, + 1045, 1046, 1047, 0, 0, 0, 0, 1052, 1053, 0, + 0, 0, 0, 0, 1114, 0, 0, 0, 0, 1450, + 0, 0, 1412, 1412, 1148, 1412, 1412, 1414, 1414, 1414, + 1821, 1959, 1967, 2143, 1782, 1788, 1789, 1790, 2089, 2090, + 2091, 2092, 2180, 2181, 2185, 1883, 1777, 2156, 2157, 0, + 2232, 1920, 1928, 1929, 1953, 2053, 2166, 1800, 1948, 2017, + 1880, 1902, 1903, 2035, 2036, 1924, 1925, 1906, 2095, 2097, + 2113, 2114, 2099, 2101, 2110, 2116, 2121, 2100, 2112, 2117, + 2130, 2134, 2137, 2138, 2139, 2107, 2105, 2118, 2122, 2124, + 2126, 2132, 2135, 2108, 2106, 2119, 2123, 2125, 2127, 2133, + 2136, 2094, 2098, 2102, 2111, 2129, 2109, 2128, 2103, 2115, + 2120, 2131, 2104, 2096, 1918, 1921, 1909, 1910, 1912, 1914, + 1919, 1926, 1932, 1911, 1931, 1930, 0, 1907, 1908, 1913, + 1923, 1927, 1915, 1916, 1917, 1922, 1933, 1973, 1972, 1971, + 2016, 1944, 2015, 0, 0, 0, 0, 0, 1772, 1826, + 1827, 2140, 1334, 1335, 1336, 1337, 0, 0, 0, 0, + 0, 0, 0, 293, 294, 1463, 1464, 46, 1132, 1575, + 1414, 1414, 1414, 1414, 1414, 1414, 1074, 1075, 1076, 1077, + 1078, 1102, 1103, 1109, 1110, 2030, 2031, 2032, 2033, 1864, + 2175, 1872, 1873, 2012, 2013, 1885, 1886, 2206, 2207, -2, -2, -2, 234, 235, 236, 237, 238, 239, 240, 241, - 0, 1824, 2153, 2154, 230, 0, 0, 298, 299, 295, - 296, 297, 1115, 1116, 251, 252, 253, 254, 255, 256, + 0, 1825, 2154, 2155, 230, 0, 0, 298, 299, 295, + 296, 297, 1116, 1117, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 2234, 0, 852, 0, - 0, 0, 0, 0, 0, 1616, 1617, 1485, 0, 1477, - 1476, 65, 0, 879, -2, 0, 0, 0, 0, 49, - 0, 54, 939, 882, 79, 78, 1525, 0, 0, 0, - 61, 1486, 69, 71, 1487, 0, 884, 885, 0, 915, - 919, 0, 0, 0, 1594, 1593, 1593, 104, 0, 0, - 105, 125, 126, 127, 0, 0, 111, 112, 1580, 1581, + 287, 288, 289, 290, 291, 292, 2235, 0, 853, 0, + 0, 0, 0, 0, 0, 1617, 1618, 1486, 0, 1478, + 1477, 65, 0, 880, -2, 0, 0, 0, 0, 49, + 0, 54, 940, 883, 79, 78, 1526, 0, 0, 0, + 61, 1487, 69, 71, 1488, 0, 885, 886, 0, 916, + 920, 0, 0, 0, 1595, 1594, 1594, 104, 0, 0, + 105, 125, 126, 127, 0, 0, 111, 112, 1581, 1582, 45, 0, 0, 179, 180, 0, 43, 428, 0, 175, - 0, 421, 360, 0, 1503, 0, 0, 0, 0, 0, - 879, 0, 1588, 156, 157, 164, 165, 166, 401, 401, + 0, 421, 360, 0, 1504, 0, 0, 0, 0, 0, + 880, 0, 1589, 156, 157, 164, 165, 166, 401, 401, 401, 575, 0, 0, 167, 167, 533, 534, 535, 0, 0, -2, 426, 0, 513, 0, 0, 415, 415, 419, 417, 418, 0, 0, 0, 0, 0, 0, 0, 0, 552, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 666, 0, 402, 0, 573, 574, 464, 0, - 0, 0, 0, 0, 0, 0, 0, 1596, 1597, 0, + 0, 0, 0, 0, 0, 0, 0, 1597, 1598, 0, 550, 551, 0, 0, 0, 401, 401, 0, 0, 0, 0, 401, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 155, 1516, 0, 0, 0, -2, 0, 710, 0, - 0, 0, 1589, 1589, 0, 717, 0, 0, 0, 722, - 0, 0, 723, 0, 780, 780, 778, 779, 725, 726, - 727, 728, 783, 0, 0, 410, 411, 412, 780, 783, - 0, 783, 783, 783, 783, 780, 780, 780, 783, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2235, 786, - 783, 0, 756, 0, 757, 758, 759, 762, 763, 765, - 2236, 2237, 1606, 1607, 1618, 1619, 1620, 1621, 1622, 1623, + 0, 155, 1517, 0, 0, 0, -2, 0, 710, 0, + 0, 0, 1590, 1590, 0, 717, 0, 0, 0, 722, + 0, 0, 723, 0, 781, 781, 779, 780, 725, 726, + 727, 728, 784, 0, 0, 410, 411, 412, 781, 784, + 0, 784, 784, 784, 784, 781, 781, 781, 784, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2236, 787, + 784, 0, 756, 0, 757, 758, 759, 760, 763, 764, + 766, 2237, 2238, 1607, 1608, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, @@ -9316,279 +9368,279 @@ var yyDef = [...]int{ 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, - 1764, 1765, 1766, 1767, 2235, 2235, 769, 773, 1579, 795, - 801, 803, 804, 0, 0, 814, 817, 836, 51, 1870, - 824, 51, 826, 827, 828, 854, 855, 860, 0, 0, - 0, 0, 866, 867, 868, 0, 0, 871, 872, 873, - 0, 0, 0, 0, 0, 1002, 0, 0, 1121, 1122, - 1123, 1124, 1125, 1126, 1127, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1022, 1023, 0, 0, 0, 1047, 1048, - 1049, 1050, 1053, 0, 1064, 0, 1066, 1458, -2, 0, - 0, 0, 1058, 1059, 0, 0, 0, 0, 0, 0, - 0, 1450, 0, 0, 1145, 0, 1146, 1148, 1149, 1150, - 0, 1151, 1152, 889, 889, 889, 889, 889, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 889, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 899, 0, 0, 899, 899, - 0, 0, 222, 223, 224, 225, 226, 227, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 242, 243, 244, 245, 246, 247, 300, 248, - 249, 250, 1131, 0, 0, 0, 48, 844, 845, 0, - 965, 1599, 0, 0, 895, 0, 1614, 59, 68, 70, - 1485, 63, 1485, 0, 901, 0, 0, -2, -2, 902, - 908, 909, 910, 911, 912, 56, 2233, 57, 0, 76, - 0, 50, 0, 0, 0, 0, 374, 1528, 0, 0, - 1478, 1479, 1482, 0, 916, 1964, 920, 0, 922, 923, - 0, 0, 102, 0, 981, 0, 0, 0, 113, 0, - 115, 116, 0, 0, 0, 385, 1582, 1583, 1584, -2, - 408, 0, 385, 369, 308, 309, 310, 360, 312, 360, - 360, 360, 360, 374, 374, 374, 374, 343, 344, 345, - 346, 347, 0, 0, 329, 360, 360, 360, 360, 350, - 351, 352, 353, 354, 355, 356, 357, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 362, 362, 362, 362, - 362, 366, 366, 0, 44, 0, 389, 0, 1482, 0, - 0, 1516, 1591, 1601, 0, 0, 0, 1591, 134, 0, - 0, 0, 576, 616, 527, 564, 577, 0, 530, 531, - -2, 0, 0, 512, 0, 514, 0, 409, 0, -2, - 0, 419, 0, 415, 419, 416, 419, 407, 420, 554, - 555, 556, 0, 558, 559, 646, 951, 0, 0, 0, - 0, 0, 652, 653, 654, 0, 656, 657, 658, 659, - 660, 661, 662, 663, 664, 665, 565, 566, 567, 568, - 569, 570, 571, 572, 0, 0, 0, 0, 514, 0, - 561, 0, 0, 465, 466, 467, 0, 0, 470, 471, - 472, 473, 0, 0, 476, 477, 478, 968, 969, 479, - 480, 505, 506, 507, 481, 482, 483, 484, 485, 486, - 487, 499, 500, 501, 502, 503, 504, 488, 489, 490, - 491, 492, 493, 496, 0, 149, 1507, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1589, 0, 0, 0, 0, 898, 983, 1612, - 1613, 719, 0, 0, 784, 785, 0, 413, 414, 783, - 783, 729, 770, 0, 783, 733, 771, 734, 736, 735, - 737, 750, 751, 783, 740, 781, 782, 741, 742, 743, - 744, 745, 746, 747, 766, 752, 753, 754, 787, 0, - 791, 792, 767, 768, 0, 0, 807, 808, 0, 815, - 839, 837, 838, 840, 832, 833, 834, 835, 0, 841, - 0, 0, 857, 98, 862, 863, 864, 865, 877, 870, - 1133, 999, 1000, 1001, 0, 1003, 1007, 0, 1117, 1119, - 1009, 1005, 1011, 1128, 1129, 1130, 0, 0, 0, 0, - 0, 1015, 1019, 1024, 1025, 1026, 1027, 1028, 0, 1029, - 0, 1032, 1033, 1034, 1035, 1036, 1037, 1043, 1426, 1427, - 1428, 1062, 301, 302, 0, 1063, 0, 0, 0, 0, - 0, 0, 0, 0, 1373, 1374, 1375, 1376, 1377, 1378, + 1764, 1765, 1766, 1767, 1768, 2236, 2236, 770, 774, 1580, + 796, 802, 804, 805, 0, 0, 815, 818, 837, 51, + 1871, 825, 51, 827, 828, 829, 855, 856, 861, 0, + 0, 0, 0, 867, 868, 869, 0, 0, 872, 873, + 874, 0, 0, 0, 0, 0, 1003, 0, 0, 1122, + 1123, 1124, 1125, 1126, 1127, 1128, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1023, 1024, 0, 0, 0, 1048, + 1049, 1050, 1051, 1054, 0, 1065, 0, 1067, 1459, -2, + 0, 0, 0, 1059, 1060, 0, 0, 0, 0, 0, + 0, 0, 1451, 0, 0, 1146, 0, 1147, 1149, 1150, + 1151, 0, 1152, 1153, 890, 890, 890, 890, 890, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 890, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1600, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 900, 0, 0, 900, + 900, 0, 0, 222, 223, 224, 225, 226, 227, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 242, 243, 244, 245, 246, 247, 300, + 248, 249, 250, 1132, 0, 0, 0, 48, 845, 846, + 0, 966, 1600, 0, 0, 896, 0, 1615, 59, 68, + 70, 1486, 63, 1486, 0, 902, 0, 0, -2, -2, + 903, 909, 910, 911, 912, 913, 56, 2234, 57, 0, + 76, 0, 50, 0, 0, 0, 0, 374, 1529, 0, + 0, 1479, 1480, 1483, 0, 917, 1965, 921, 0, 923, + 924, 0, 0, 102, 0, 982, 0, 0, 0, 113, + 0, 115, 116, 0, 0, 0, 385, 1583, 1584, 1585, + -2, 408, 0, 385, 369, 308, 309, 310, 360, 312, + 360, 360, 360, 360, 374, 374, 374, 374, 343, 344, + 345, 346, 347, 0, 0, 329, 360, 360, 360, 360, + 350, 351, 352, 353, 354, 355, 356, 357, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 362, 362, 362, + 362, 362, 366, 366, 0, 44, 0, 389, 0, 1483, + 0, 0, 1517, 1592, 1602, 0, 0, 0, 1592, 134, + 0, 0, 0, 576, 616, 527, 564, 577, 0, 530, + 531, -2, 0, 0, 512, 0, 514, 0, 409, 0, + -2, 0, 419, 0, 415, 419, 416, 419, 407, 420, + 554, 555, 556, 0, 558, 559, 646, 952, 0, 0, + 0, 0, 0, 652, 653, 654, 0, 656, 657, 658, + 659, 660, 661, 662, 663, 664, 665, 565, 566, 567, + 568, 569, 570, 571, 572, 0, 0, 0, 0, 514, + 0, 561, 0, 0, 465, 466, 467, 0, 0, 470, + 471, 472, 473, 0, 0, 476, 477, 478, 969, 970, + 479, 480, 505, 506, 507, 481, 482, 483, 484, 485, + 486, 487, 499, 500, 501, 502, 503, 504, 488, 489, + 490, 491, 492, 493, 496, 0, 149, 1508, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1590, 0, 0, 0, 0, 899, 984, + 1613, 1614, 719, 0, 0, 785, 786, 0, 413, 414, + 784, 784, 729, 771, 0, 784, 733, 772, 734, 736, + 735, 737, 750, 751, 784, 740, 782, 783, 741, 742, + 743, 744, 745, 746, 747, 767, 752, 753, 754, 788, + 0, 792, 793, 768, 769, 0, 0, 808, 809, 0, + 816, 840, 838, 839, 841, 833, 834, 835, 836, 0, + 842, 0, 0, 858, 98, 863, 864, 865, 866, 878, + 871, 1134, 1000, 1001, 1002, 0, 1004, 1008, 0, 1118, + 1120, 1010, 1006, 1012, 1129, 1130, 1131, 0, 0, 0, + 0, 0, 1016, 1020, 1025, 1026, 1027, 1028, 1029, 0, + 1030, 0, 1033, 1034, 1035, 1036, 1037, 1038, 1044, 1427, + 1428, 1429, 1063, 301, 302, 0, 1064, 0, 0, 0, + 0, 0, 0, 0, 0, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, - 1389, 1390, 1391, 1392, 1132, 0, 913, 0, 0, 1456, - 1453, 0, 0, 0, 1412, 1414, 0, 0, 0, 890, - 891, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1393, 1394, + 1389, 1390, 1391, 1392, 1393, 1133, 0, 914, 0, 0, + 1457, 1454, 0, 0, 0, 1413, 1415, 0, 0, 0, + 891, 892, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, - 1405, 1406, 1407, 1408, 1409, 1410, 0, 0, 1429, 0, - 0, 0, 0, 0, 1449, 0, 1068, 1069, 1070, 0, - 0, 0, 0, 0, 0, 1191, 0, 0, 0, 0, - 1600, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 144, 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, - 0, 0, 1337, 1338, 1339, 1340, 41, 0, 0, 0, - 0, 0, 0, 0, 900, 1460, 0, -2, -2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1362, 0, 0, 0, 0, 0, 0, 1572, - 0, 0, 847, 848, 850, 0, 985, 0, 966, 0, - 0, 853, 0, 894, 0, 897, 62, 64, 906, 907, - 0, 924, 903, 58, 53, 0, 0, 943, 1526, 374, - 1548, 0, 383, 383, 380, 1488, 1489, 0, 1481, 1483, - 1484, 81, 921, 917, 0, 997, 0, 0, 980, 0, - 927, 929, 930, 931, 963, 0, 934, 935, 0, 0, - 0, 0, 0, 100, 982, 106, 0, 114, 0, 0, - 119, 120, 107, 108, 109, 110, 0, 605, -2, 460, - 181, 183, 184, 185, 176, -2, 372, 370, 371, 311, - 374, 374, 337, 338, 339, 340, 341, 342, 0, 0, - 330, 331, 332, 333, 322, 0, 323, 324, 325, 364, - 0, 326, 327, 0, 328, 427, 0, 1490, 390, 391, - 393, 401, 0, 396, 397, 0, 401, 401, 0, 422, - 423, 0, 1482, 1507, 0, 0, 0, 1602, 1601, 1601, - 1601, 0, 169, 170, 171, 172, 173, 174, 641, 0, - 0, 617, 639, 640, 167, 0, 0, 177, 516, 515, - 0, 673, 0, 425, 0, 0, 419, 419, 404, 405, - 557, 0, 0, 648, 649, 650, 651, 0, 0, 0, - 543, 454, 0, 544, 545, 514, 516, 0, 0, 385, - 468, 469, 474, 475, 494, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 592, 593, 594, - 597, 599, 518, 603, 596, 598, 600, 518, 604, 1504, - 1505, 1506, 0, 0, 711, 0, 0, 451, 96, 1590, - 716, 720, 721, 780, 739, 772, 780, 731, 738, 760, - 805, 806, 811, 819, 820, 821, 822, 823, 861, 0, - 0, 0, 0, 869, 0, 0, 1008, 1118, 1120, 1012, - 0, 1016, 1020, 0, 0, 0, 0, 0, 1067, 1065, - 1460, 0, 0, 0, 1114, 0, 0, 0, 1136, 1137, - 0, 0, 0, 1454, 0, 0, 1143, 0, 1415, 1153, - 0, 0, 0, 0, 0, 1159, 1160, 1161, 1162, 1163, - 1164, 1165, 1166, 1167, 1168, 1476, 1170, 0, 0, 0, - 0, 0, 1175, 1176, 1177, 1178, 1179, 0, 1181, 0, - 1182, 0, 0, 0, 0, 1189, 1190, 1192, 0, 0, - 1195, 1196, 0, 1198, 0, 1200, 1201, 1202, 1203, 1204, - 1205, 0, 1207, 0, 1209, 1210, 1211, 0, 1213, 0, - 1215, 1216, 0, 1218, 0, 1220, 0, 1223, 0, 1226, - 0, 1229, 0, 1232, 0, 1235, 0, 1238, 0, 1241, - 0, 1244, 0, 1247, 0, 1250, 0, 1253, 0, 1256, - 0, 1259, 0, 1262, 0, 1265, 0, 1268, 1269, 1270, - 0, 1272, 0, 1274, 0, 1277, 1278, 0, 1280, 0, - 1283, 0, 1286, 0, 0, 1287, 0, 0, 0, 1291, - 0, 0, 0, 0, 1300, 1301, 1302, 1303, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1314, 1315, - 1316, 1317, 1318, 1319, 0, 1321, 0, 1096, 0, 0, - 1096, 0, 0, 0, 0, 0, 1134, 899, 0, 1416, - 1417, 1418, 1419, 1420, 0, 0, 0, 0, 0, 0, - 1360, 1361, 1363, 0, 0, 1366, 0, 1368, 0, 1573, - 846, 849, 851, 937, 986, 987, 0, 0, 0, 0, - 967, 1598, 892, 893, 896, 945, 0, 1464, 0, 0, - 924, 997, 925, 0, 904, 55, 940, 0, 1530, 1529, - 1542, 1555, 383, 383, 377, 378, 384, 379, 381, 382, - 1480, 0, 1485, 0, 1566, 0, 0, 1558, 0, 0, - 0, 0, 0, 0, 0, 0, 970, 0, 0, 973, - 0, 0, 0, 0, 964, 935, 0, 936, 0, -2, - 0, 0, 94, 95, 0, 0, 0, 117, 118, 0, - 0, 124, 386, 387, 158, 167, 462, 182, 435, 0, - 0, 307, 373, 334, 335, 336, 0, 358, 0, 0, - 0, 0, 456, 130, 1494, 1493, 401, 401, 392, 0, - 395, 0, 0, 0, 1603, 361, 424, 0, 148, 0, - 0, 0, 0, 0, 154, 611, 0, 0, 618, 0, - 0, 0, 525, 0, 536, 537, 0, 645, -2, 707, - 389, 0, 403, 406, 952, 0, 0, 538, 0, 541, - 542, 455, 516, 547, 548, 562, 549, 497, 498, 495, - 0, 0, 1517, 1518, 1523, 1521, 1522, 135, 583, 585, - 589, 584, 588, 0, 0, 0, 520, 0, 520, 581, - 0, 451, 1490, 0, 715, 452, 453, 783, 783, 856, - 99, 0, 859, 0, 0, 0, 0, 1013, 1017, 1030, - 1031, 1421, 1447, 360, 360, 1434, 360, 366, 1437, 360, - 1439, 360, 1442, 360, 1445, 1446, 0, 0, 1060, 0, - 914, 0, 0, 1142, 1457, 0, 0, 1154, 1155, 1156, - 1157, 1158, 1451, 0, 0, 0, 1174, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 146, 147, 0, - 0, 0, 0, 0, 0, 1371, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1091, 1095, 0, - 1097, 1098, 0, 0, 1323, 0, 0, 1341, 0, 0, - 0, 0, 0, 0, 0, 1461, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 988, 993, 993, 993, - 0, 0, 0, 1585, 1586, 1465, 1466, 997, 1467, 926, - 905, 944, 1548, 0, 1541, 0, -2, 1550, 0, 0, - 0, 1556, 375, 376, 918, 82, 998, 85, 0, 1566, - 1575, 0, 1557, 1568, 1570, 0, 0, 0, 1562, 0, - 997, 928, 959, 961, 0, 956, 971, 972, 974, 0, - 976, 0, 978, 979, 939, 933, 0, 102, 0, 997, - 997, 101, 0, 984, 121, 122, 123, 461, 186, 191, - 0, 0, 0, 196, 0, 198, 0, 0, 0, 203, - 204, 401, 401, 436, 0, 304, 306, 0, 0, 189, - 374, 0, 374, 0, 365, 367, 0, 437, 457, 1491, - 1492, 0, 0, 394, 398, 399, 400, 0, 1592, 150, - 0, 0, 0, 614, 0, 642, 0, 0, 0, 0, - 0, 0, 178, 517, 674, 675, 676, 677, 678, 679, - 680, 681, 682, 0, 401, 0, 0, 0, 401, 401, - 401, 0, 699, 388, 0, 0, 670, 667, 539, 0, - 220, 221, 228, 229, 231, 0, 0, 0, 0, 0, - 546, 939, 1508, 1509, 1510, 0, 1520, 1524, 138, 0, - 0, 0, 0, 591, 595, 601, 0, 519, 602, 712, - 713, 714, 97, 724, 730, 858, 878, 1006, 1014, 1018, - 0, 0, 0, 0, 1448, 1432, 374, 1435, 1436, 1438, - 1440, 1441, 1443, 1444, 1056, 1057, 1061, 0, 1139, 0, - 1141, 1455, 0, 1485, 0, 0, 0, 1173, 0, 0, - 0, 1184, 1183, 1185, 0, 1187, 1188, 1193, 1194, 1197, - 1199, 1206, 1208, 1212, 1214, 1217, 1219, 1221, 0, 1224, - 0, 1227, 0, 1230, 0, 1233, 0, 1236, 0, 1239, - 0, 1242, 0, 1245, 0, 1248, 0, 1251, 0, 1254, - 0, 1257, 0, 1260, 0, 1263, 0, 1266, 0, 1271, - 1273, 0, 1276, 1279, 1281, 0, 1284, 0, 1288, 0, - 1290, 1292, 1293, 0, 0, 0, 1304, 1305, 1306, 1307, - 1308, 1309, 1310, 1311, 1312, 1313, 1320, 0, 1089, 1092, - 1322, 1099, 1100, 1105, 1325, 0, 0, 0, 1328, 0, - 0, 0, 1332, 1135, 1343, 0, 1348, 0, 0, 1354, - 0, 1358, 0, 1364, 1365, 1367, 1369, 0, 0, 0, - 0, 0, 965, 946, 66, 1467, 1469, 0, 1535, 1533, - 1533, 1543, 1544, 0, 0, 1551, 0, 0, 0, 0, - 86, 0, 0, 0, 1571, 0, 0, 0, 0, 103, - 1476, 953, 960, 0, 0, 954, 0, 955, 975, 977, - 932, 0, 997, 997, 92, 93, 0, 192, 0, 194, - 0, 197, 199, 200, 201, 207, 208, 209, 202, 0, - 0, 303, 305, 0, 0, 348, 359, 349, 0, 0, - 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 939, 151, - 152, 153, 606, 0, 616, 0, 941, 0, 609, 0, - 528, 0, 0, 0, 401, 401, 401, 0, 0, 0, - 0, 684, 0, 0, 647, 0, 655, 0, 0, 0, - 232, 233, 0, 1519, 582, 0, 136, 137, 0, 0, - 587, 521, 522, 1054, 0, 0, 0, 1055, 1433, 0, - 0, 0, 0, 1452, 0, 0, 0, 0, 1180, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1296, 0, 0, 0, 636, 637, 0, 1372, 1094, - 1476, 0, 1096, 1106, 1107, 0, 1096, 1342, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, - 0, 0, 0, 0, 985, 1469, 1474, 0, 0, 1538, - 0, 1531, 1534, 1532, 1545, 0, 0, 1552, 0, 1554, - 0, 1576, 1577, 1569, 0, 1561, 1564, 1560, 1563, 1485, - 957, 0, 962, 0, 1476, 91, 0, 195, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 205, 206, 0, - 0, 363, 368, 0, 0, 0, 607, 0, 942, 619, - 610, 0, 697, 0, 701, 0, 0, 0, 704, 705, - 706, 683, 0, 687, 429, 671, 668, 669, 540, 0, - 139, 140, 0, 0, 0, 1422, 0, 1425, 1138, 1140, - 0, 1169, 1171, 1172, 1430, 1431, 1186, 1222, 1225, 1228, - 1231, 1234, 1237, 1240, 1243, 1246, 1249, 1252, 1255, 1258, - 1261, 1264, 1267, 1275, 1282, 1285, 1289, 1294, 0, 1297, - 0, 0, 1298, 0, 638, 1085, 0, 0, 1103, 1104, - 0, 1327, 1329, 1330, 1331, 1344, 0, 1349, 1350, 0, - 1355, 0, 1359, 1370, 0, 990, 947, 948, 995, 996, - 0, 0, 938, 1474, 84, 1475, 1472, 0, 1470, 1468, - 1527, 0, 1536, 1537, 1546, 1547, 1553, 0, 1559, 0, - 89, 0, 0, 0, 1485, 193, 0, 212, 0, 615, - 0, 618, 608, 695, 696, 0, 708, 700, 702, 703, - 685, -2, 1511, 0, 0, 0, 590, 1423, 0, 0, - 1299, 0, 634, 635, 1093, 1086, 0, 1071, 1072, 1090, - 1324, 1326, 0, 0, 0, 0, 989, 991, 992, 83, - 0, 1471, 1111, 0, 1539, 1540, 1567, 1565, 958, 965, - 0, 90, 442, 435, 1511, 0, 0, 0, 688, 689, - 690, 691, 692, 693, 694, 579, 1513, 141, 142, 0, - 509, 510, 511, 135, 0, 1144, 1295, 1087, 0, 0, - 0, 0, 0, 1345, 0, 1351, 0, 1356, 0, 949, - 950, 1473, 0, 0, 620, 0, 622, 0, -2, 430, - 443, 0, 187, 213, 214, 0, 0, 217, 218, 219, - 210, 211, 131, 0, 0, 709, 0, 1514, 1515, 0, - 138, 0, 0, 1078, 1079, 1080, 1081, 1083, 0, 0, - 0, 0, 1112, 1091, 621, 0, 0, 385, 0, 631, - 431, 432, 0, 438, 439, 440, 441, 215, 216, 643, - 0, 0, 508, 586, 1424, 0, 0, 1346, 0, 1352, - 0, 1357, 0, 623, 624, 632, 0, 433, 0, 434, - 0, 0, 0, 612, 0, 643, 1512, 1088, 1082, 1084, - 0, 0, 1110, 0, 633, 629, 444, 446, 447, 0, - 0, 445, 644, 613, 1347, 1353, 0, 448, 449, 450, - 625, 626, 627, 628, + 1405, 1406, 1407, 1408, 1409, 1410, 1411, 0, 0, 1430, + 0, 0, 0, 0, 0, 1450, 0, 1069, 1070, 1071, + 0, 0, 0, 0, 0, 0, 1192, 0, 0, 0, + 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, + 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, 0, 0, 1338, 1339, 1340, 1341, 41, 0, 0, + 0, 0, 0, 0, 0, 901, 1461, 0, -2, -2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1363, 0, 0, 0, 0, 0, 0, + 1573, 0, 0, 848, 849, 851, 0, 986, 0, 967, + 0, 0, 854, 0, 895, 0, 898, 62, 64, 907, + 908, 0, 925, 904, 58, 53, 0, 0, 944, 1527, + 374, 1549, 0, 383, 383, 380, 1489, 1490, 0, 1482, + 1484, 1485, 81, 922, 918, 0, 998, 0, 0, 981, + 0, 928, 930, 931, 932, 964, 0, 935, 936, 0, + 0, 0, 0, 0, 100, 983, 106, 0, 114, 0, + 0, 119, 120, 107, 108, 109, 110, 0, 605, -2, + 460, 181, 183, 184, 185, 176, -2, 372, 370, 371, + 311, 374, 374, 337, 338, 339, 340, 341, 342, 0, + 0, 330, 331, 332, 333, 322, 0, 323, 324, 325, + 364, 0, 326, 327, 0, 328, 427, 0, 1491, 390, + 391, 393, 401, 0, 396, 397, 0, 401, 401, 0, + 422, 423, 0, 1483, 1508, 0, 0, 0, 1603, 1602, + 1602, 1602, 0, 169, 170, 171, 172, 173, 174, 641, + 0, 0, 617, 639, 640, 167, 0, 0, 177, 516, + 515, 0, 673, 0, 425, 0, 0, 419, 419, 404, + 405, 557, 0, 0, 648, 649, 650, 651, 0, 0, + 0, 543, 454, 0, 544, 545, 514, 516, 0, 0, + 385, 468, 469, 474, 475, 494, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 592, 593, + 594, 597, 599, 518, 603, 596, 598, 600, 518, 604, + 1505, 1506, 1507, 0, 0, 711, 0, 0, 451, 96, + 1591, 716, 720, 721, 781, 739, 773, 781, 731, 738, + 761, 806, 807, 812, 820, 821, 822, 823, 824, 862, + 0, 0, 0, 0, 870, 0, 0, 1009, 1119, 1121, + 1013, 0, 1017, 1021, 0, 0, 0, 0, 0, 1068, + 1066, 1461, 0, 0, 0, 1115, 0, 0, 0, 1137, + 1138, 0, 0, 0, 1455, 0, 0, 1144, 0, 1416, + 1154, 0, 0, 0, 0, 0, 1160, 1161, 1162, 1163, + 1164, 1165, 1166, 1167, 1168, 1169, 1477, 1171, 0, 0, + 0, 0, 0, 1176, 1177, 1178, 1179, 1180, 0, 1182, + 0, 1183, 0, 0, 0, 0, 1190, 1191, 1193, 0, + 0, 1196, 1197, 0, 1199, 0, 1201, 1202, 1203, 1204, + 1205, 1206, 0, 1208, 0, 1210, 1211, 1212, 0, 1214, + 0, 1216, 1217, 0, 1219, 0, 1221, 0, 1224, 0, + 1227, 0, 1230, 0, 1233, 0, 1236, 0, 1239, 0, + 1242, 0, 1245, 0, 1248, 0, 1251, 0, 1254, 0, + 1257, 0, 1260, 0, 1263, 0, 1266, 0, 1269, 1270, + 1271, 0, 1273, 0, 1275, 0, 1278, 1279, 0, 1281, + 0, 1284, 0, 1287, 0, 0, 1288, 0, 0, 0, + 1292, 0, 0, 0, 0, 1301, 1302, 1303, 1304, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1315, + 1316, 1317, 1318, 1319, 1320, 0, 1322, 0, 1097, 0, + 0, 1097, 0, 0, 0, 0, 0, 1135, 900, 0, + 1417, 1418, 1419, 1420, 1421, 0, 0, 0, 0, 0, + 0, 1361, 1362, 1364, 0, 0, 1367, 0, 1369, 0, + 1574, 847, 850, 852, 938, 987, 988, 0, 0, 0, + 0, 968, 1599, 893, 894, 897, 946, 0, 1465, 0, + 0, 925, 998, 926, 0, 905, 55, 941, 0, 1531, + 1530, 1543, 1556, 383, 383, 377, 378, 384, 379, 381, + 382, 1481, 0, 1486, 0, 1567, 0, 0, 1559, 0, + 0, 0, 0, 0, 0, 0, 0, 971, 0, 0, + 974, 0, 0, 0, 0, 965, 936, 0, 937, 0, + -2, 0, 0, 94, 95, 0, 0, 0, 117, 118, + 0, 0, 124, 386, 387, 158, 167, 462, 182, 435, + 0, 0, 307, 373, 334, 335, 336, 0, 358, 0, + 0, 0, 0, 456, 130, 1495, 1494, 401, 401, 392, + 0, 395, 0, 0, 0, 1604, 361, 424, 0, 148, + 0, 0, 0, 0, 0, 154, 611, 0, 0, 618, + 0, 0, 0, 525, 0, 536, 537, 0, 645, -2, + 707, 389, 0, 403, 406, 953, 0, 0, 538, 0, + 541, 542, 455, 516, 547, 548, 562, 549, 497, 498, + 495, 0, 0, 1518, 1519, 1524, 1522, 1523, 135, 583, + 585, 589, 584, 588, 0, 0, 0, 520, 0, 520, + 581, 0, 451, 1491, 0, 715, 452, 453, 784, 784, + 857, 99, 0, 860, 0, 0, 0, 0, 1014, 1018, + 1031, 1032, 1422, 1448, 360, 360, 1435, 360, 366, 1438, + 360, 1440, 360, 1443, 360, 1446, 1447, 0, 0, 1061, + 0, 915, 0, 0, 1143, 1458, 0, 0, 1155, 1156, + 1157, 1158, 1159, 1452, 0, 0, 0, 1175, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 146, 147, + 0, 0, 0, 0, 0, 0, 1372, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1092, 1096, + 0, 1098, 1099, 0, 0, 1324, 0, 0, 1342, 0, + 0, 0, 0, 0, 0, 0, 1462, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 989, 994, 994, + 994, 0, 0, 0, 1586, 1587, 1466, 1467, 998, 1468, + 927, 906, 945, 1549, 0, 1542, 0, -2, 1551, 0, + 0, 0, 1557, 375, 376, 919, 82, 999, 85, 0, + 1567, 1576, 0, 1558, 1569, 1571, 0, 0, 0, 1563, + 0, 998, 929, 960, 962, 0, 957, 972, 973, 975, + 0, 977, 0, 979, 980, 940, 934, 0, 102, 0, + 998, 998, 101, 0, 985, 121, 122, 123, 461, 186, + 191, 0, 0, 0, 196, 0, 198, 0, 0, 0, + 203, 204, 401, 401, 436, 0, 304, 306, 0, 0, + 189, 374, 0, 374, 0, 365, 367, 0, 437, 457, + 1492, 1493, 0, 0, 394, 398, 399, 400, 0, 1593, + 150, 0, 0, 0, 614, 0, 642, 0, 0, 0, + 0, 0, 0, 178, 517, 674, 675, 676, 677, 678, + 679, 680, 681, 682, 0, 401, 0, 0, 0, 401, + 401, 401, 0, 699, 388, 0, 0, 670, 667, 539, + 0, 220, 221, 228, 229, 231, 0, 0, 0, 0, + 0, 546, 940, 1509, 1510, 1511, 0, 1521, 1525, 138, + 0, 0, 0, 0, 591, 595, 601, 0, 519, 602, + 712, 713, 714, 97, 724, 730, 859, 879, 1007, 1015, + 1019, 0, 0, 0, 0, 1449, 1433, 374, 1436, 1437, + 1439, 1441, 1442, 1444, 1445, 1057, 1058, 1062, 0, 1140, + 0, 1142, 1456, 0, 1486, 0, 0, 0, 1174, 0, + 0, 0, 1185, 1184, 1186, 0, 1188, 1189, 1194, 1195, + 1198, 1200, 1207, 1209, 1213, 1215, 1218, 1220, 1222, 0, + 1225, 0, 1228, 0, 1231, 0, 1234, 0, 1237, 0, + 1240, 0, 1243, 0, 1246, 0, 1249, 0, 1252, 0, + 1255, 0, 1258, 0, 1261, 0, 1264, 0, 1267, 0, + 1272, 1274, 0, 1277, 1280, 1282, 0, 1285, 0, 1289, + 0, 1291, 1293, 1294, 0, 0, 0, 1305, 1306, 1307, + 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1321, 0, 1090, + 1093, 1323, 1100, 1101, 1106, 1326, 0, 0, 0, 1329, + 0, 0, 0, 1333, 1136, 1344, 0, 1349, 0, 0, + 1355, 0, 1359, 0, 1365, 1366, 1368, 1370, 0, 0, + 0, 0, 0, 966, 947, 66, 1468, 1470, 0, 1536, + 1534, 1534, 1544, 1545, 0, 0, 1552, 0, 0, 0, + 0, 86, 0, 0, 0, 1572, 0, 0, 0, 0, + 103, 1477, 954, 961, 0, 0, 955, 0, 956, 976, + 978, 933, 0, 998, 998, 92, 93, 0, 192, 0, + 194, 0, 197, 199, 200, 201, 207, 208, 209, 202, + 0, 0, 303, 305, 0, 0, 348, 359, 349, 0, + 0, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 940, + 151, 152, 153, 606, 0, 616, 0, 942, 0, 609, + 0, 528, 0, 0, 0, 401, 401, 401, 0, 0, + 0, 0, 684, 0, 0, 647, 0, 655, 0, 0, + 0, 232, 233, 0, 1520, 582, 0, 136, 137, 0, + 0, 587, 521, 522, 1055, 0, 0, 0, 1056, 1434, + 0, 0, 0, 0, 1453, 0, 0, 0, 0, 1181, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1297, 0, 0, 0, 636, 637, 0, 1373, + 1095, 1477, 0, 1097, 1107, 1108, 0, 1097, 1343, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 995, 0, 0, 0, 0, 986, 1470, 1475, 0, 0, + 1539, 0, 1532, 1535, 1533, 1546, 0, 0, 1553, 0, + 1555, 0, 1577, 1578, 1570, 0, 1562, 1565, 1561, 1564, + 1486, 958, 0, 963, 0, 1477, 91, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 205, 206, + 0, 0, 363, 368, 0, 0, 0, 607, 0, 943, + 619, 610, 0, 697, 0, 701, 0, 0, 0, 704, + 705, 706, 683, 0, 687, 429, 671, 668, 669, 540, + 0, 139, 140, 0, 0, 0, 1423, 0, 1426, 1139, + 1141, 0, 1170, 1172, 1173, 1431, 1432, 1187, 1223, 1226, + 1229, 1232, 1235, 1238, 1241, 1244, 1247, 1250, 1253, 1256, + 1259, 1262, 1265, 1268, 1276, 1283, 1286, 1290, 1295, 0, + 1298, 0, 0, 1299, 0, 638, 1086, 0, 0, 1104, + 1105, 0, 1328, 1330, 1331, 1332, 1345, 0, 1350, 1351, + 0, 1356, 0, 1360, 1371, 0, 991, 948, 949, 996, + 997, 0, 0, 939, 1475, 84, 1476, 1473, 0, 1471, + 1469, 1528, 0, 1537, 1538, 1547, 1548, 1554, 0, 1560, + 0, 89, 0, 0, 0, 1486, 193, 0, 212, 0, + 615, 0, 618, 608, 695, 696, 0, 708, 700, 702, + 703, 685, -2, 1512, 0, 0, 0, 590, 1424, 0, + 0, 1300, 0, 634, 635, 1094, 1087, 0, 1072, 1073, + 1091, 1325, 1327, 0, 0, 0, 0, 990, 992, 993, + 83, 0, 1472, 1112, 0, 1540, 1541, 1568, 1566, 959, + 966, 0, 90, 442, 435, 1512, 0, 0, 0, 688, + 689, 690, 691, 692, 693, 694, 579, 1514, 141, 142, + 0, 509, 510, 511, 135, 0, 1145, 1296, 1088, 0, + 0, 0, 0, 0, 1346, 0, 1352, 0, 1357, 0, + 950, 951, 1474, 0, 0, 620, 0, 622, 0, -2, + 430, 443, 0, 187, 213, 214, 0, 0, 217, 218, + 219, 210, 211, 131, 0, 0, 709, 0, 1515, 1516, + 0, 138, 0, 0, 1079, 1080, 1081, 1082, 1084, 0, + 0, 0, 0, 1113, 1092, 621, 0, 0, 385, 0, + 631, 431, 432, 0, 438, 439, 440, 441, 215, 216, + 643, 0, 0, 508, 586, 1425, 0, 0, 1347, 0, + 1353, 0, 1358, 0, 623, 624, 632, 0, 433, 0, + 434, 0, 0, 0, 612, 0, 643, 1513, 1089, 1083, + 1085, 0, 0, 1111, 0, 633, 629, 444, 446, 447, + 0, 0, 445, 644, 613, 1348, 1354, 0, 448, 449, + 450, 625, 626, 627, 628, } var yyTok1 = [...]int{ @@ -15622,31 +15674,31 @@ yydefault: var yyLOCAL Statement //line sql.y:4132 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} } yyVAL.union = yyLOCAL case 760: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4136 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} } yyVAL.union = yyLOCAL case 761: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4140 { - yyLOCAL = &Show{&ShowBasic{Command: Warnings}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} } yyVAL.union = yyLOCAL case 762: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4144 { - yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } yyVAL.union = yyLOCAL case 763: @@ -15654,31 +15706,31 @@ yydefault: var yyLOCAL Statement //line sql.y:4148 { - yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 764: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4152 { - yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} + yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 765: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4159 +//line sql.y:4156 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} + yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} } yyVAL.union = yyLOCAL case 766: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4163 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} } yyVAL.union = yyLOCAL case 767: @@ -15686,7 +15738,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4167 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL case 768: @@ -15694,23 +15746,23 @@ yydefault: var yyLOCAL Statement //line sql.y:4171 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} } yyVAL.union = yyLOCAL case 769: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4175 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL case 770: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4179 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL case 771: @@ -15722,55 +15774,57 @@ yydefault: } yyVAL.union = yyLOCAL case 772: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4187 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL case 773: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4191 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL case 774: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL Statement +//line sql.y:4195 + { + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} + } + yyVAL.union = yyLOCAL + case 775: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4197 +//line sql.y:4201 { yyVAL.str = "" } - case 775: + case 776: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4201 +//line sql.y:4205 { yyVAL.str = "extended " } - case 776: + case 777: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4207 +//line sql.y:4211 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 777: + case 778: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4211 +//line sql.y:4215 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 778: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4217 - { - yyVAL.str = string(yyDollar[1].str) - } case 779: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4221 @@ -15778,16 +15832,16 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 780: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4227 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4225 { - yyVAL.identifierCS = NewIdentifierCS("") + yyVAL.str = string(yyDollar[1].str) } case 781: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4231 { - yyVAL.identifierCS = yyDollar[2].identifierCS + yyVAL.identifierCS = NewIdentifierCS("") } case 782: yyDollar = yyS[yypt-2 : yypt+1] @@ -15796,53 +15850,53 @@ yydefault: yyVAL.identifierCS = yyDollar[2].identifierCS } case 783: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:4239 + { + yyVAL.identifierCS = yyDollar[2].identifierCS + } + case 784: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4241 +//line sql.y:4245 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 784: + case 785: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4245 +//line sql.y:4249 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 785: + case 786: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4249 +//line sql.y:4253 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 786: + case 787: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4255 +//line sql.y:4259 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 787: + case 788: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4259 +//line sql.y:4263 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 788: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4265 - { - yyVAL.empty = struct{}{} - } case 789: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4269 { yyVAL.empty = struct{}{} @@ -15855,9 +15909,9 @@ yydefault: } case 791: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4279 +//line sql.y:4277 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.empty = struct{}{} } case 792: yyDollar = yyS[yypt-1 : yypt+1] @@ -15866,202 +15920,200 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 793: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4287 + { + yyVAL.str = string(yyDollar[1].str) + } + case 794: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4289 +//line sql.y:4293 { yyLOCAL = &Use{DBName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 794: + case 795: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4293 +//line sql.y:4297 { yyLOCAL = &Use{DBName: IdentifierCS{v: ""}} } yyVAL.union = yyLOCAL - case 795: + case 796: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4297 +//line sql.y:4301 { yyLOCAL = &Use{DBName: NewIdentifierCS(yyDollar[2].identifierCS.String() + "@" + string(yyDollar[3].str))} } yyVAL.union = yyLOCAL - case 796: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4304 - { - yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) - } case 797: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4308 { - yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) + yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 798: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4312 { - yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) + yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) } case 799: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4316 { - yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) + yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) } case 800: yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4320 + { + yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) + } + case 801: + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4323 +//line sql.y:4327 { yyLOCAL = &Begin{} } yyVAL.union = yyLOCAL - case 801: + case 802: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4327 +//line sql.y:4331 { yyLOCAL = &Begin{TxAccessModes: yyDollar[3].txAccessModesUnion()} } yyVAL.union = yyLOCAL - case 802: + case 803: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4332 +//line sql.y:4336 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 803: + case 804: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4336 +//line sql.y:4340 { yyLOCAL = yyDollar[1].txAccessModesUnion() } yyVAL.union = yyLOCAL - case 804: + case 805: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4342 +//line sql.y:4346 { yyLOCAL = []TxAccessMode{yyDollar[1].txAccessModeUnion()} } yyVAL.union = yyLOCAL - case 805: + case 806: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4346 +//line sql.y:4350 { yySLICE := (*[]TxAccessMode)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].txAccessModeUnion()) } - case 806: + case 807: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4352 +//line sql.y:4356 { yyLOCAL = WithConsistentSnapshot } yyVAL.union = yyLOCAL - case 807: + case 808: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4356 +//line sql.y:4360 { yyLOCAL = ReadWrite } yyVAL.union = yyLOCAL - case 808: + case 809: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4360 +//line sql.y:4364 { yyLOCAL = ReadOnly } yyVAL.union = yyLOCAL - case 809: + case 810: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4367 +//line sql.y:4371 { yyLOCAL = &Commit{} } yyVAL.union = yyLOCAL - case 810: + case 811: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4373 +//line sql.y:4377 { yyLOCAL = &Rollback{} } yyVAL.union = yyLOCAL - case 811: + case 812: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4377 +//line sql.y:4381 { yyLOCAL = &SRollback{Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 812: + case 813: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4382 +//line sql.y:4386 { yyVAL.empty = struct{}{} } - case 813: + case 814: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4384 +//line sql.y:4388 { yyVAL.empty = struct{}{} } - case 814: + case 815: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4387 +//line sql.y:4391 { yyVAL.empty = struct{}{} } - case 815: + case 816: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4389 +//line sql.y:4393 { yyVAL.empty = struct{}{} } - case 816: + case 817: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4393 +//line sql.y:4397 { yyLOCAL = &Savepoint{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 817: + case 818: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4399 +//line sql.y:4403 { yyLOCAL = &Release{Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 818: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL ExplainType -//line sql.y:4404 - { - yyLOCAL = EmptyType - } - yyVAL.union = yyLOCAL case 819: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType //line sql.y:4408 { - yyLOCAL = JSONType + yyLOCAL = EmptyType } yyVAL.union = yyLOCAL case 820: @@ -16069,7 +16121,7 @@ yydefault: var yyLOCAL ExplainType //line sql.y:4412 { - yyLOCAL = TreeType + yyLOCAL = JSONType } yyVAL.union = yyLOCAL case 821: @@ -16077,7 +16129,7 @@ yydefault: var yyLOCAL ExplainType //line sql.y:4416 { - yyLOCAL = VitessType + yyLOCAL = TreeType } yyVAL.union = yyLOCAL case 822: @@ -16085,7 +16137,7 @@ yydefault: var yyLOCAL ExplainType //line sql.y:4420 { - yyLOCAL = VTExplainType + yyLOCAL = VitessType } yyVAL.union = yyLOCAL case 823: @@ -16093,27 +16145,27 @@ yydefault: var yyLOCAL ExplainType //line sql.y:4424 { - yyLOCAL = TraditionalType + yyLOCAL = VTExplainType } yyVAL.union = yyLOCAL case 824: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType //line sql.y:4428 { - yyLOCAL = AnalyzeType + yyLOCAL = TraditionalType } yyVAL.union = yyLOCAL case 825: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL VExplainType -//line sql.y:4433 + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ExplainType +//line sql.y:4432 { - yyLOCAL = PlanVExplainType + yyLOCAL = AnalyzeType } yyVAL.union = yyLOCAL case 826: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL VExplainType //line sql.y:4437 { @@ -16125,7 +16177,7 @@ yydefault: var yyLOCAL VExplainType //line sql.y:4441 { - yyLOCAL = AllVExplainType + yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL case 828: @@ -16133,15 +16185,17 @@ yydefault: var yyLOCAL VExplainType //line sql.y:4445 { - yyLOCAL = QueriesVExplainType + yyLOCAL = AllVExplainType } yyVAL.union = yyLOCAL case 829: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4451 + var yyLOCAL VExplainType +//line sql.y:4449 { - yyVAL.str = yyDollar[1].str + yyLOCAL = QueriesVExplainType } + yyVAL.union = yyLOCAL case 830: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4455 @@ -16156,18 +16210,16 @@ yydefault: } case 832: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Statement -//line sql.y:4465 +//line sql.y:4463 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyVAL.str = yyDollar[1].str } - yyVAL.union = yyLOCAL case 833: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement //line sql.y:4469 { - yyLOCAL = yyDollar[1].statementUnion() + yyLOCAL = yyDollar[1].selStmtUnion() } yyVAL.union = yyLOCAL case 834: @@ -16187,208 +16239,210 @@ yydefault: } yyVAL.union = yyLOCAL case 836: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4482 + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Statement +//line sql.y:4481 { - yyVAL.str = "" + yyLOCAL = yyDollar[1].statementUnion() } + yyVAL.union = yyLOCAL case 837: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4486 { - yyVAL.str = yyDollar[1].identifierCI.val + yyVAL.str = "" } case 838: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4490 { - yyVAL.str = encodeSQLString(yyDollar[1].str) + yyVAL.str = yyDollar[1].identifierCI.val } case 839: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4494 + { + yyVAL.str = encodeSQLString(yyDollar[1].str) + } + case 840: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4496 +//line sql.y:4500 { yyLOCAL = &ExplainTab{Table: yyDollar[3].tableName, Wild: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 840: + case 841: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4500 +//line sql.y:4504 { yyLOCAL = &ExplainStmt{Type: yyDollar[3].explainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 841: + case 842: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4506 +//line sql.y:4510 { yyLOCAL = &VExplainStmt{Type: yyDollar[3].vexplainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 842: + case 843: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4512 +//line sql.y:4516 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 843: + case 844: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4516 +//line sql.y:4520 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 844: + case 845: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4522 +//line sql.y:4526 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } yyVAL.union = yyLOCAL - case 845: + case 846: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:4528 +//line sql.y:4532 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL - case 846: + case 847: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4532 +//line sql.y:4536 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) } - case 847: + case 848: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:4538 +//line sql.y:4542 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } yyVAL.union = yyLOCAL - case 848: + case 849: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4544 +//line sql.y:4548 { yyLOCAL = Read } yyVAL.union = yyLOCAL - case 849: + case 850: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4548 +//line sql.y:4552 { yyLOCAL = ReadLocal } yyVAL.union = yyLOCAL - case 850: + case 851: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4552 +//line sql.y:4556 { yyLOCAL = Write } yyVAL.union = yyLOCAL - case 851: + case 852: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4556 +//line sql.y:4560 { yyLOCAL = LowPriorityWrite } yyVAL.union = yyLOCAL - case 852: + case 853: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4562 +//line sql.y:4566 { yyLOCAL = &UnlockTables{} } yyVAL.union = yyLOCAL - case 853: + case 854: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4568 +//line sql.y:4572 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs).Parsed(), UUID: string(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 854: + case 855: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4574 +//line sql.y:4578 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } yyVAL.union = yyLOCAL - case 855: + case 856: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4578 +//line sql.y:4582 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } yyVAL.union = yyLOCAL - case 856: + case 857: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4582 +//line sql.y:4586 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 857: + case 858: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4586 +//line sql.y:4590 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 858: + case 859: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4590 +//line sql.y:4594 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 859: + case 860: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4594 +//line sql.y:4598 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL - case 860: + case 861: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4600 +//line sql.y:4604 { yyVAL.strs = []string{yyDollar[1].str} } - case 861: + case 862: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4604 +//line sql.y:4608 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } - case 862: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4610 - { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) - } case 863: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:4614 @@ -16408,10 +16462,10 @@ yydefault: yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 866: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:4626 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 867: yyDollar = yyS[yypt-1 : yypt+1] @@ -16426,22 +16480,22 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 869: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4638 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str + yyVAL.str = string(yyDollar[1].str) } case 870: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4642 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } case 871: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:4646 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 872: yyDollar = yyS[yypt-1 : yypt+1] @@ -16456,144 +16510,150 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 874: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4658 + { + yyVAL.str = string(yyDollar[1].str) + } + case 875: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4659 +//line sql.y:4663 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 875: + case 876: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4663 +//line sql.y:4667 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 876: + case 877: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4667 +//line sql.y:4671 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 877: + case 878: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4672 +//line sql.y:4676 { yyVAL.str = "" } - case 878: + case 879: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4676 +//line sql.y:4680 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String() } - case 879: + case 880: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4681 +//line sql.y:4685 { setAllowComments(yylex, true) } - case 880: + case 881: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4685 +//line sql.y:4689 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } - case 881: + case 882: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4691 +//line sql.y:4695 { yyVAL.strs = nil } - case 882: + case 883: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4695 +//line sql.y:4699 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 883: + case 884: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4701 +//line sql.y:4705 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 884: + case 885: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4705 +//line sql.y:4709 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 885: + case 886: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4709 +//line sql.y:4713 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 886: + case 887: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4714 +//line sql.y:4718 { yyVAL.str = "" } - case 887: + case 888: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4718 +//line sql.y:4722 { yyVAL.str = SQLNoCacheStr } - case 888: + case 889: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4722 +//line sql.y:4726 { yyVAL.str = SQLCacheStr } - case 889: + case 890: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4727 +//line sql.y:4731 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 890: + case 891: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4731 +//line sql.y:4735 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 891: + case 892: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4735 +//line sql.y:4739 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 892: + case 893: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4741 +//line sql.y:4745 { yyLOCAL = &PrepareStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Statement: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 893: + case 894: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4745 +//line sql.y:4749 { yyLOCAL = &PrepareStmt{ Name: yyDollar[3].identifierCI, @@ -16602,109 +16662,103 @@ yydefault: } } yyVAL.union = yyLOCAL - case 894: + case 895: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4755 +//line sql.y:4759 { yyLOCAL = &ExecuteStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Arguments: yyDollar[4].variablesUnion()} } yyVAL.union = yyLOCAL - case 895: + case 896: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4760 +//line sql.y:4764 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 896: + case 897: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4764 +//line sql.y:4768 { yyLOCAL = yyDollar[2].variablesUnion() } yyVAL.union = yyLOCAL - case 897: + case 898: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4770 +//line sql.y:4774 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 898: + case 899: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4774 +//line sql.y:4778 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 899: + case 900: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4779 +//line sql.y:4783 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 900: + case 901: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4783 +//line sql.y:4787 { yyLOCAL = yyDollar[1].selectExprsUnion() } yyVAL.union = yyLOCAL - case 901: + case 902: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4788 +//line sql.y:4792 { yyVAL.strs = nil } - case 902: + case 903: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4792 +//line sql.y:4796 { yyVAL.strs = []string{yyDollar[1].str} } - case 903: + case 904: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4796 +//line sql.y:4800 { // 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 904: + case 905: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4800 +//line sql.y:4804 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str} } - case 905: + case 906: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4804 +//line sql.y:4808 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str, yyDollar[4].str} } - case 906: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4810 - { - yyVAL.str = SQLNoCacheStr - } case 907: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4814 { - yyVAL.str = SQLCacheStr + yyVAL.str = SQLNoCacheStr } case 908: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4818 { - yyVAL.str = DistinctStr + yyVAL.str = SQLCacheStr } case 909: yyDollar = yyS[yypt-1 : yypt+1] @@ -16716,481 +16770,487 @@ yydefault: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4826 { - yyVAL.str = StraightJoinHint + yyVAL.str = DistinctStr } case 911: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4830 { - yyVAL.str = SQLCalcFoundRowsStr + yyVAL.str = StraightJoinHint } case 912: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4834 { - 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 + yyVAL.str = SQLCalcFoundRowsStr } case 913: yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4838 + { + 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 914: + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4840 +//line sql.y:4844 { yyLOCAL = SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL - case 914: + case 915: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4844 +//line sql.y:4848 { yySLICE := (*SelectExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].selectExprUnion()) } - case 915: + case 916: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4850 +//line sql.y:4854 { yyLOCAL = &StarExpr{} } yyVAL.union = yyLOCAL - case 916: + case 917: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4854 +//line sql.y:4858 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 917: + case 918: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4858 +//line sql.y:4862 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } yyVAL.union = yyLOCAL - case 918: + case 919: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4862 +//line sql.y:4866 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 919: + case 920: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4867 +//line sql.y:4871 { yyVAL.identifierCI = IdentifierCI{} } - case 920: + case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4871 +//line sql.y:4875 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 921: + case 922: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4875 +//line sql.y:4879 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 923: + case 924: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4882 +//line sql.y:4886 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 924: + case 925: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4887 +//line sql.y:4891 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } yyVAL.union = yyLOCAL - case 925: + case 926: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4891 +//line sql.y:4895 { yyLOCAL = yyDollar[1].tableExprsUnion() } yyVAL.union = yyLOCAL - case 926: + case 927: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4897 +//line sql.y:4901 { yyLOCAL = yyDollar[2].tableExprsUnion() } yyVAL.union = yyLOCAL - case 927: + case 928: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4903 +//line sql.y:4907 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL - case 928: + case 929: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4907 +//line sql.y:4911 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) } - case 931: + case 932: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4917 +//line sql.y:4921 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } yyVAL.union = yyLOCAL - case 932: + case 933: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4921 +//line sql.y:4925 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 933: + case 934: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4925 +//line sql.y:4929 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } yyVAL.union = yyLOCAL - case 934: + case 935: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4929 +//line sql.y:4933 { yyLOCAL = yyDollar[1].tableExprUnion() } yyVAL.union = yyLOCAL - case 935: + case 936: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4935 +//line sql.y:4939 { yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 936: + case 937: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4939 +//line sql.y:4943 { yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].selStmtUnion()} } yyVAL.union = yyLOCAL - case 937: + case 938: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4945 +//line sql.y:4949 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 938: + case 939: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4949 +//line sql.y:4953 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 939: + case 940: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4954 +//line sql.y:4958 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 940: + case 941: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:4958 +//line sql.y:4962 { yyLOCAL = yyDollar[2].columnsUnion() } yyVAL.union = yyLOCAL - case 941: + case 942: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4963 +//line sql.y:4967 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 942: + case 943: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4967 +//line sql.y:4971 { yyLOCAL = yyDollar[1].columnsUnion() } yyVAL.union = yyLOCAL - case 943: + case 944: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4973 +//line sql.y:4977 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 944: + case 945: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4977 +//line sql.y:4981 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 945: + case 946: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4983 +//line sql.y:4987 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL - case 946: + case 947: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4987 +//line sql.y:4991 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) } - case 947: + case 948: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4993 +//line sql.y:4997 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 948: + case 949: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4997 +//line sql.y:5001 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 949: + case 950: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5001 +//line sql.y:5005 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 950: + case 951: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5005 +//line sql.y:5009 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) } - case 951: + case 952: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5011 +//line sql.y:5015 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 952: + case 953: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5015 +//line sql.y:5019 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 953: + case 954: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5028 +//line sql.y:5032 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 954: + case 955: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5032 +//line sql.y:5036 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 955: + case 956: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5036 +//line sql.y:5040 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 956: + case 957: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5040 +//line sql.y:5044 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 957: + case 958: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5046 +//line sql.y:5050 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 958: + case 959: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5048 +//line sql.y:5052 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 959: + case 960: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5052 +//line sql.y:5056 { yyVAL.joinCondition = &JoinCondition{} } - case 960: + case 961: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5054 +//line sql.y:5058 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 961: + case 962: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5058 +//line sql.y:5062 { yyVAL.joinCondition = &JoinCondition{} } - case 962: + case 963: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5060 +//line sql.y:5064 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 963: + case 964: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5063 +//line sql.y:5067 { yyVAL.empty = struct{}{} } - case 964: + case 965: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5065 +//line sql.y:5069 { yyVAL.empty = struct{}{} } - case 965: + case 966: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5068 +//line sql.y:5072 { yyVAL.identifierCS = NewIdentifierCS("") } - case 966: + case 967: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5072 +//line sql.y:5076 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 967: + case 968: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5076 +//line sql.y:5080 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 969: + case 970: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5083 +//line sql.y:5087 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 970: + case 971: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5089 +//line sql.y:5093 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 971: + case 972: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5093 +//line sql.y:5097 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 972: + case 973: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5097 +//line sql.y:5101 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 973: + case 974: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5103 +//line sql.y:5107 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 974: + case 975: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5109 +//line sql.y:5113 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 975: + case 976: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5113 +//line sql.y:5117 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 976: + case 977: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5117 +//line sql.y:5121 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 977: + case 978: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5121 +//line sql.y:5125 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 978: + case 979: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5127 +//line sql.y:5131 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 979: + case 980: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5131 +//line sql.y:5135 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -17199,161 +17259,153 @@ yydefault: } } yyVAL.union = yyLOCAL - case 980: + case 981: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5141 +//line sql.y:5145 { yyVAL.tableName = yyDollar[2].tableName } - case 981: + case 982: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5145 +//line sql.y:5149 { yyVAL.tableName = yyDollar[1].tableName } - case 982: + case 983: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5151 +//line sql.y:5155 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 983: + case 984: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5155 +//line sql.y:5159 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } - case 984: + case 985: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5161 +//line sql.y:5165 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 985: + case 986: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5166 +//line sql.y:5170 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 986: + case 987: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5170 +//line sql.y:5174 { yyLOCAL = yyDollar[1].indexHintsUnion() } yyVAL.union = yyLOCAL - case 987: + case 988: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5176 +//line sql.y:5180 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL - case 988: + case 989: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5180 +//line sql.y:5184 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) } - case 989: + case 990: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5186 +//line sql.y:5190 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 990: + case 991: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5190 +//line sql.y:5194 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } yyVAL.union = yyLOCAL - case 991: + case 992: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5194 +//line sql.y:5198 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 992: + case 993: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5198 +//line sql.y:5202 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 993: + case 994: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5203 +//line sql.y:5207 { yyLOCAL = NoForType } yyVAL.union = yyLOCAL - case 994: + case 995: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5207 +//line sql.y:5211 { yyLOCAL = JoinForType } yyVAL.union = yyLOCAL - case 995: + case 996: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5211 +//line sql.y:5215 { yyLOCAL = OrderByForType } yyVAL.union = yyLOCAL - case 996: + case 997: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5215 +//line sql.y:5219 { yyLOCAL = GroupByForType } yyVAL.union = yyLOCAL - case 997: + case 998: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5221 +//line sql.y:5225 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 998: + case 999: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5225 +//line sql.y:5229 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 999: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL Expr -//line sql.y:5232 - { - yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} - } - yyVAL.union = yyLOCAL case 1000: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5236 { - yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} + yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1001: @@ -17361,193 +17413,193 @@ yydefault: var yyLOCAL Expr //line sql.y:5240 { - yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} + yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1002: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5244 { - yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} + yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1003: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:5248 { - yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} + yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 1004: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5252 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } yyVAL.union = yyLOCAL case 1005: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:5256 { - yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1006: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5260 { - yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} + yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1007: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5266 +//line sql.y:5264 { - yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} + yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1008: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5270 { - yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} + yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } yyVAL.union = yyLOCAL case 1009: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5274 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} + yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } yyVAL.union = yyLOCAL case 1010: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5278 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1011: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5284 +//line sql.y:5282 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1012: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5288 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL case 1013: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5292 { - yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL case 1014: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:5296 { - yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} + yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1015: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:5300 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL case 1016: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5304 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1017: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5308 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1018: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:5312 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1019: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:5316 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL case 1020: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5320 { - yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1021: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5324 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1022: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5330 + var yyLOCAL Expr +//line sql.y:5328 { + yyLOCAL = yyDollar[1].exprUnion() } + yyVAL.union = yyLOCAL case 1023: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5333 +//line sql.y:5334 { } case 1024: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL Expr -//line sql.y:5339 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:5337 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } - yyVAL.union = yyLOCAL case 1025: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5343 { - 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 1026: @@ -17555,7 +17607,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5347 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1027: @@ -17563,7 +17615,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5351 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1028: @@ -17571,7 +17623,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5355 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1029: @@ -17579,15 +17631,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5359 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1030: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5363 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1031: @@ -17595,15 +17647,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5367 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1032: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:5371 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1033: @@ -17611,7 +17663,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5375 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1034: @@ -17619,7 +17671,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5379 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1035: @@ -17627,7 +17679,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5383 { - 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 1036: @@ -17635,7 +17687,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5387 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1037: @@ -17643,21 +17695,21 @@ yydefault: var yyLOCAL Expr //line sql.y:5391 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1038: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5395 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1039: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5401 +//line sql.y:5399 { yyLOCAL = yyDollar[1].exprUnion() } @@ -17687,19 +17739,19 @@ yydefault: } yyVAL.union = yyLOCAL case 1043: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:5417 { - yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1044: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:5421 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } yyVAL.union = yyLOCAL case 1045: @@ -17715,15 +17767,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5429 { - yyLOCAL = yyDollar[1].variableUnion() + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1047: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:5433 { - yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? + yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL case 1048: @@ -17731,7 +17783,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5437 { - yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} + yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } yyVAL.union = yyLOCAL case 1049: @@ -17739,7 +17791,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5441 { - yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 1050: @@ -17747,15 +17799,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5445 { - yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 1051: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:5449 { - yyLOCAL = yyDollar[1].subqueryUnion() + yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 1052: @@ -17763,23 +17815,23 @@ yydefault: var yyLOCAL Expr //line sql.y:5453 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL case 1053: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:5457 { - yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1054: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:5461 { - yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} + yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL case 1055: @@ -17787,15 +17839,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5465 { - yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} + yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } yyVAL.union = yyLOCAL case 1056: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr //line sql.y:5469 { - yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} + yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } yyVAL.union = yyLOCAL case 1057: @@ -17803,13 +17855,21 @@ yydefault: var yyLOCAL Expr //line sql.y:5473 { - yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} + yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL case 1058: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:5477 + { + yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} + } + yyVAL.union = yyLOCAL + case 1059: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL Expr +//line sql.y:5481 { // From: https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#operator_binary // To convert a string expression to a binary string, these constructs are equivalent: @@ -17818,91 +17878,83 @@ yydefault: yyLOCAL = &ConvertExpr{Expr: yyDollar[2].exprUnion(), Type: &ConvertType{Type: yyDollar[1].str}} } yyVAL.union = yyLOCAL - case 1059: + case 1060: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5485 +//line sql.y:5489 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1060: + case 1061: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5489 +//line sql.y:5493 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1061: + case 1062: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5493 +//line sql.y:5497 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1062: + case 1063: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5497 +//line sql.y:5501 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1063: + case 1064: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5501 +//line sql.y:5505 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1064: + case 1065: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5507 +//line sql.y:5511 { yyLOCAL = yyDollar[1].colNamesUnion() } yyVAL.union = yyLOCAL - case 1065: + case 1066: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5511 +//line sql.y:5515 { yyLOCAL = yyDollar[2].colNamesUnion() } yyVAL.union = yyLOCAL - case 1066: + case 1067: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5517 +//line sql.y:5521 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL - case 1067: + case 1068: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5521 +//line sql.y:5525 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) } - case 1068: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL TrimType -//line sql.y:5527 - { - yyLOCAL = BothTrimType - } - yyVAL.union = yyLOCAL case 1069: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType //line sql.y:5531 { - yyLOCAL = LeadingTrimType + yyLOCAL = BothTrimType } yyVAL.union = yyLOCAL case 1070: @@ -17910,15 +17962,15 @@ yydefault: var yyLOCAL TrimType //line sql.y:5535 { - yyLOCAL = TrailingTrimType + yyLOCAL = LeadingTrimType } yyVAL.union = yyLOCAL case 1071: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL FrameUnitType -//line sql.y:5541 + var yyLOCAL TrimType +//line sql.y:5539 { - yyLOCAL = FrameRowsType + yyLOCAL = TrailingTrimType } yyVAL.union = yyLOCAL case 1072: @@ -17926,15 +17978,15 @@ yydefault: var yyLOCAL FrameUnitType //line sql.y:5545 { - yyLOCAL = FrameRangeType + yyLOCAL = FrameRowsType } yyVAL.union = yyLOCAL case 1073: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5552 + var yyLOCAL FrameUnitType +//line sql.y:5549 { - yyLOCAL = CumeDistExprType + yyLOCAL = FrameRangeType } yyVAL.union = yyLOCAL case 1074: @@ -17942,7 +17994,7 @@ yydefault: var yyLOCAL ArgumentLessWindowExprType //line sql.y:5556 { - yyLOCAL = DenseRankExprType + yyLOCAL = CumeDistExprType } yyVAL.union = yyLOCAL case 1075: @@ -17950,7 +18002,7 @@ yydefault: var yyLOCAL ArgumentLessWindowExprType //line sql.y:5560 { - yyLOCAL = PercentRankExprType + yyLOCAL = DenseRankExprType } yyVAL.union = yyLOCAL case 1076: @@ -17958,7 +18010,7 @@ yydefault: var yyLOCAL ArgumentLessWindowExprType //line sql.y:5564 { - yyLOCAL = RankExprType + yyLOCAL = PercentRankExprType } yyVAL.union = yyLOCAL case 1077: @@ -17966,15 +18018,15 @@ yydefault: var yyLOCAL ArgumentLessWindowExprType //line sql.y:5568 { - yyLOCAL = RowNumberExprType + yyLOCAL = RankExprType } yyVAL.union = yyLOCAL case 1078: - yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL *FramePoint -//line sql.y:5574 + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ArgumentLessWindowExprType +//line sql.y:5572 { - yyLOCAL = &FramePoint{Type: CurrentRowType} + yyLOCAL = RowNumberExprType } yyVAL.union = yyLOCAL case 1079: @@ -17982,7 +18034,7 @@ yydefault: var yyLOCAL *FramePoint //line sql.y:5578 { - yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} + yyLOCAL = &FramePoint{Type: CurrentRowType} } yyVAL.union = yyLOCAL case 1080: @@ -17990,7 +18042,7 @@ yydefault: var yyLOCAL *FramePoint //line sql.y:5582 { - yyLOCAL = &FramePoint{Type: UnboundedFollowingType} + yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } yyVAL.union = yyLOCAL case 1081: @@ -17998,309 +18050,309 @@ yydefault: var yyLOCAL *FramePoint //line sql.y:5586 { - yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} + yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } yyVAL.union = yyLOCAL case 1082: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint //line sql.y:5590 { - yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} + yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL case 1083: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint //line sql.y:5594 { - yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} + yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL case 1084: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint //line sql.y:5598 { - yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} + yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL case 1085: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL *FramePoint +//line sql.y:5602 + { + yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} + } + yyVAL.union = yyLOCAL + case 1086: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5603 +//line sql.y:5607 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1086: + case 1087: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5607 +//line sql.y:5611 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1087: + case 1088: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5613 +//line sql.y:5617 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } yyVAL.union = yyLOCAL - case 1088: + case 1089: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5617 +//line sql.y:5621 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } yyVAL.union = yyLOCAL - case 1089: + case 1090: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:5622 +//line sql.y:5626 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1090: + case 1091: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:5626 +//line sql.y:5630 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1091: + case 1092: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5631 +//line sql.y:5635 { } - case 1092: + case 1093: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5634 +//line sql.y:5638 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1093: + case 1094: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:5640 +//line sql.y:5644 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } yyVAL.union = yyLOCAL - case 1094: + case 1095: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5646 +//line sql.y:5650 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1095: + case 1096: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5650 +//line sql.y:5654 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 1096: + case 1097: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5655 +//line sql.y:5659 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1098: + case 1099: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5662 +//line sql.y:5666 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } yyVAL.union = yyLOCAL - case 1099: + case 1100: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5668 +//line sql.y:5672 { yyLOCAL = RespectNullsType } yyVAL.union = yyLOCAL - case 1100: + case 1101: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5672 +//line sql.y:5676 { yyLOCAL = IgnoreNullsType } yyVAL.union = yyLOCAL - case 1101: + case 1102: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5678 +//line sql.y:5682 { yyLOCAL = FirstValueExprType } yyVAL.union = yyLOCAL - case 1102: + case 1103: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5682 +//line sql.y:5686 { yyLOCAL = LastValueExprType } yyVAL.union = yyLOCAL - case 1103: + case 1104: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5688 +//line sql.y:5692 { yyLOCAL = FromFirstType } yyVAL.union = yyLOCAL - case 1104: + case 1105: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5692 +//line sql.y:5696 { yyLOCAL = FromLastType } yyVAL.union = yyLOCAL - case 1105: + case 1106: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5697 +//line sql.y:5701 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1107: + case 1108: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5704 +//line sql.y:5708 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } yyVAL.union = yyLOCAL - case 1108: + case 1109: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5710 +//line sql.y:5714 { yyLOCAL = LagExprType } yyVAL.union = yyLOCAL - case 1109: + case 1110: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5714 +//line sql.y:5718 { yyLOCAL = LeadExprType } yyVAL.union = yyLOCAL - case 1110: + case 1111: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:5720 +//line sql.y:5724 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1111: + case 1112: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:5726 +//line sql.y:5730 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL - case 1112: + case 1113: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5730 +//line sql.y:5734 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } - case 1113: + case 1114: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5736 +//line sql.y:5740 { yyVAL.str = "" } - case 1114: + case 1115: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5740 +//line sql.y:5744 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 1115: + case 1116: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5746 +//line sql.y:5750 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 1116: + case 1117: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5750 +//line sql.y:5754 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 1117: + case 1118: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5757 +//line sql.y:5761 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 1118: + case 1119: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5761 +//line sql.y:5765 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 1119: + case 1120: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5765 +//line sql.y:5769 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 1120: + case 1121: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5769 +//line sql.y:5773 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 1121: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL ComparisonExprOperator -//line sql.y:5775 - { - yyLOCAL = EqualOp - } - yyVAL.union = yyLOCAL case 1122: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator //line sql.y:5779 { - yyLOCAL = LessThanOp + yyLOCAL = EqualOp } yyVAL.union = yyLOCAL case 1123: @@ -18308,7 +18360,7 @@ yydefault: var yyLOCAL ComparisonExprOperator //line sql.y:5783 { - yyLOCAL = GreaterThanOp + yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL case 1124: @@ -18316,7 +18368,7 @@ yydefault: var yyLOCAL ComparisonExprOperator //line sql.y:5787 { - yyLOCAL = LessEqualOp + yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL case 1125: @@ -18324,7 +18376,7 @@ yydefault: var yyLOCAL ComparisonExprOperator //line sql.y:5791 { - yyLOCAL = GreaterEqualOp + yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL case 1126: @@ -18332,7 +18384,7 @@ yydefault: var yyLOCAL ComparisonExprOperator //line sql.y:5795 { - yyLOCAL = NotEqualOp + yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL case 1127: @@ -18340,15 +18392,15 @@ yydefault: var yyLOCAL ComparisonExprOperator //line sql.y:5799 { - yyLOCAL = NullSafeEqualOp + yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL case 1128: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL ColTuple -//line sql.y:5805 + var yyLOCAL ComparisonExprOperator +//line sql.y:5803 { - yyLOCAL = yyDollar[1].valTupleUnion() + yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL case 1129: @@ -18356,159 +18408,159 @@ yydefault: var yyLOCAL ColTuple //line sql.y:5809 { - yyLOCAL = yyDollar[1].subqueryUnion() + yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple //line sql.y:5813 + { + yyLOCAL = yyDollar[1].subqueryUnion() + } + yyVAL.union = yyLOCAL + case 1131: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ColTuple +//line sql.y:5817 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 1131: + case 1132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:5820 +//line sql.y:5824 { yyLOCAL = &Subquery{yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1132: + case 1133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:5826 +//line sql.y:5830 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1133: + case 1134: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5830 +//line sql.y:5834 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 1134: + case 1135: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5840 +//line sql.y:5844 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1135: + case 1136: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5844 +//line sql.y:5848 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1136: - yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL Expr -//line sql.y:5854 - { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].selectExprsUnion()} - } - yyVAL.union = yyLOCAL case 1137: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5858 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1138: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5862 { - yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1139: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:5866 { - yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} + yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1140: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:5870 { - yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} + yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1141: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:5874 { - yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} + yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1142: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:5878 { - yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} + yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1143: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:5882 { - yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} + yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1144: - yyDollar = yyS[yypt-10 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5886 { - yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} + yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL case 1145: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr //line sql.y:5890 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} + yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL case 1146: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5901 +//line sql.y:5894 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 1147: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:5905 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } yyVAL.union = yyLOCAL case 1148: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5911 +//line sql.y:5909 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1149: @@ -18516,7 +18568,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5915 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } yyVAL.union = yyLOCAL case 1150: @@ -18524,39 +18576,39 @@ yydefault: var yyLOCAL Expr //line sql.y:5919 { - yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } yyVAL.union = yyLOCAL case 1151: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5924 +//line sql.y:5923 { - yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL case 1152: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5929 +//line sql.y:5928 { - yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL case 1153: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:5933 { - yyLOCAL = &CountStar{} + yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL case 1154: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5937 { - yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion()} + yyLOCAL = &CountStar{} } yyVAL.union = yyLOCAL case 1155: @@ -18564,7 +18616,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5941 { - yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} + yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL case 1156: @@ -18572,7 +18624,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5945 { - yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} + yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1157: @@ -18580,7 +18632,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5949 { - yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} + yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1158: @@ -18588,15 +18640,15 @@ yydefault: var yyLOCAL Expr //line sql.y:5953 { - yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} + yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1159: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:5957 { - yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 1160: @@ -18604,7 +18656,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5961 { - yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1161: @@ -18612,7 +18664,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5965 { - yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1162: @@ -18620,7 +18672,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5969 { - yyLOCAL = &Std{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1163: @@ -18628,7 +18680,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5973 { - yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &Std{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1164: @@ -18636,7 +18688,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5977 { - yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1165: @@ -18644,7 +18696,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5981 { - yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1166: @@ -18652,7 +18704,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5985 { - yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1167: @@ -18660,7 +18712,7 @@ yydefault: var yyLOCAL Expr //line sql.y:5989 { - yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1168: @@ -18668,31 +18720,31 @@ yydefault: var yyLOCAL Expr //line sql.y:5993 { - yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1169: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:5997 { - yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} + yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1170: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6001 { - yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} + yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL case 1171: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6005 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} + yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1172: @@ -18700,31 +18752,31 @@ yydefault: var yyLOCAL Expr //line sql.y:6009 { - yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL case 1173: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6013 { - yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} + yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1174: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6017 { - yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} + yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1175: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:6021 { - yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} + yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } yyVAL.union = yyLOCAL case 1176: @@ -18732,7 +18784,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6025 { - yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} + yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1177: @@ -18740,7 +18792,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6029 { - yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} + yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1178: @@ -18748,7 +18800,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6033 { - yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} + yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1179: @@ -18756,23 +18808,23 @@ yydefault: var yyLOCAL Expr //line sql.y:6037 { - yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} + yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1180: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6041 { - yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} + yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1181: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr //line sql.y:6045 { - yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} + yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL case 1182: @@ -18780,15 +18832,15 @@ yydefault: var yyLOCAL Expr //line sql.y:6049 { - yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} + yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1183: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6053 { - yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} + yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1184: @@ -18796,7 +18848,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6057 { - yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} + yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } yyVAL.union = yyLOCAL case 1185: @@ -18804,23 +18856,23 @@ yydefault: var yyLOCAL Expr //line sql.y:6061 { - yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} + yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1186: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6065 { - yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} + yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1187: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6069 { - yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} + yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1188: @@ -18828,15 +18880,15 @@ yydefault: var yyLOCAL Expr //line sql.y:6073 { - yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} + yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1189: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6077 { - yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} + yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1190: @@ -18844,31 +18896,31 @@ yydefault: var yyLOCAL Expr //line sql.y:6081 { - yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} + yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1191: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6085 { - yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} + yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1192: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:6089 { - yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} + yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } yyVAL.union = yyLOCAL case 1193: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6093 { - yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} + yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1194: @@ -18876,15 +18928,15 @@ yydefault: var yyLOCAL Expr //line sql.y:6097 { - yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} + yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1195: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6101 { - yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} + yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1196: @@ -18892,39 +18944,39 @@ yydefault: var yyLOCAL Expr //line sql.y:6105 { - yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1197: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6109 { - yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1198: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6113 { - yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1199: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6117 { - yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1200: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6121 { - yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1201: @@ -18932,7 +18984,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6125 { - yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1202: @@ -18940,7 +18992,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6129 { - yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1203: @@ -18948,7 +19000,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6133 { - yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1204: @@ -18956,7 +19008,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6137 { - yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1205: @@ -18964,39 +19016,39 @@ yydefault: var yyLOCAL Expr //line sql.y:6141 { - yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} + yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1206: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6145 { - yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1207: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6149 { - yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1208: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6153 { - yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1209: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6157 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1210: @@ -19004,7 +19056,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6161 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1211: @@ -19012,39 +19064,39 @@ yydefault: var yyLOCAL Expr //line sql.y:6165 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1212: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6169 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1213: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6173 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1214: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6177 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1215: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6181 { - yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1216: @@ -19052,423 +19104,423 @@ yydefault: var yyLOCAL Expr //line sql.y:6185 { - yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} + yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1217: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6189 { - yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1218: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6193 { - yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1219: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6197 { - yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1220: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6201 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1221: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6205 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1222: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6209 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1223: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6213 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1224: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6217 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1225: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6221 { - yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1226: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6225 { - yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1227: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6229 { - yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1228: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6233 { - yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1229: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6237 { - yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1230: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6241 { - yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1231: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6245 { - yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1232: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6249 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1233: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6253 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1234: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6257 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1235: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6261 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1236: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6265 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1237: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6269 { - yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1238: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6273 { - yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1239: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6277 { - yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1240: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6281 { - yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1241: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6285 { - yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1242: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6289 { - yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1243: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6293 { - yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1244: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6297 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1245: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6301 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1246: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6305 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1247: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6309 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1248: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6313 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1249: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6317 { - yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1250: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6321 { - yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1251: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6325 { - yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1252: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6329 { - yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1253: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6333 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1254: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6337 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1255: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6341 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1256: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6345 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1257: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6349 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1258: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6353 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1259: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6357 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1260: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6361 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1261: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6365 { - yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1262: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6369 { - yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1263: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6373 { - yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1264: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6377 { - yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1265: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6381 { - yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1266: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6385 { - yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1267: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6389 { - yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1268: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6393 { - yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1269: @@ -19476,7 +19528,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6397 { - yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} + yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1270: @@ -19484,63 +19536,63 @@ yydefault: var yyLOCAL Expr //line sql.y:6401 { - yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} + yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1271: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6405 { - yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} + yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1272: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6409 { - yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} + yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1273: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6413 { - yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} + yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1274: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6417 { - yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} + yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1275: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6421 { - yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} + yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1276: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6425 { - yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} + yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1277: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6429 { - yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} + yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1278: @@ -19548,71 +19600,71 @@ yydefault: var yyLOCAL Expr //line sql.y:6433 { - yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1279: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6437 { - yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1280: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6441 { - yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1281: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6445 { - yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} + yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1282: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6449 { - yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} + yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1283: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6453 { - yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} + yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1284: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6457 { - yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} + yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1285: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6461 { - yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} + yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1286: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6465 { - yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} + yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1287: @@ -19620,47 +19672,47 @@ yydefault: var yyLOCAL Expr //line sql.y:6469 { - yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} + yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1288: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6473 { - yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} + yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1289: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6477 { - yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} + yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } yyVAL.union = yyLOCAL case 1290: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6481 { - yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} + yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } yyVAL.union = yyLOCAL case 1291: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6485 { - yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} + yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL case 1292: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6489 { - yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} + yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1293: @@ -19668,39 +19720,39 @@ yydefault: var yyLOCAL Expr //line sql.y:6493 { - yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} + yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1294: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6497 { - yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} + yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1295: - yyDollar = yyS[yypt-10 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6501 { - yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} + yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 1296: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr //line sql.y:6505 { - yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} + yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} } yyVAL.union = yyLOCAL case 1297: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr //line sql.y:6509 { - yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} + yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } yyVAL.union = yyLOCAL case 1298: @@ -19708,23 +19760,23 @@ yydefault: var yyLOCAL Expr //line sql.y:6513 { - yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} + yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL case 1299: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6517 { - yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} + yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL case 1300: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr //line sql.y:6521 { - yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} + yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} } yyVAL.union = yyLOCAL case 1301: @@ -19732,7 +19784,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6525 { - yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} + yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1302: @@ -19740,7 +19792,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6529 { - yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} + yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1303: @@ -19748,15 +19800,15 @@ yydefault: var yyLOCAL Expr //line sql.y:6533 { - yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} + yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1304: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6537 { - yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} + yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1305: @@ -19764,7 +19816,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6541 { - yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} + yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1306: @@ -19772,7 +19824,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6545 { - yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} + yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1307: @@ -19780,7 +19832,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6549 { - yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} + yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1308: @@ -19788,7 +19840,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6553 { - yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} + yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1309: @@ -19796,7 +19848,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6557 { - yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} + yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1310: @@ -19804,7 +19856,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6561 { - yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} + yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL case 1311: @@ -19812,7 +19864,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6565 { - yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} + yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL case 1312: @@ -19820,7 +19872,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6569 { - yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} + yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL case 1313: @@ -19828,15 +19880,15 @@ yydefault: var yyLOCAL Expr //line sql.y:6573 { - yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} + yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL case 1314: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6577 { - yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} + yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL case 1315: @@ -19844,7 +19896,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6581 { - yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} + yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1316: @@ -19852,7 +19904,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6585 { - yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} + yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1317: @@ -19860,7 +19912,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6589 { - yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} + yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1318: @@ -19868,7 +19920,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6593 { - yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} + yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1319: @@ -19876,87 +19928,87 @@ yydefault: var yyLOCAL Expr //line sql.y:6597 { - yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} + yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1320: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6601 { - yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} + yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL case 1321: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6605 { - yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} + yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1322: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:6609 { - yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} + yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } yyVAL.union = yyLOCAL case 1323: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6613 { - yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} + yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL case 1324: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:6617 { - yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} + yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL case 1325: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr //line sql.y:6621 { - yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} + yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL case 1326: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6625 { - yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} + yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL case 1327: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr //line sql.y:6629 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} + yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL case 1328: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6633 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL case 1329: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:6637 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL case 1330: @@ -19964,7 +20016,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6641 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL case 1331: @@ -19972,23 +20024,23 @@ yydefault: var yyLOCAL Expr //line sql.y:6645 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL case 1332: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:6649 { - yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1337: - yyDollar = yyS[yypt-1 : yypt+1] + case 1333: + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6659 +//line sql.y:6653 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL case 1338: @@ -19996,7 +20048,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6663 { - yyLOCAL = NewIntLiteral(yyDollar[1].str) + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1339: @@ -20004,7 +20056,7 @@ yydefault: var yyLOCAL Expr //line sql.y:6667 { - yyLOCAL = yyDollar[1].variableUnion() + yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 1340: @@ -20012,282 +20064,282 @@ yydefault: var yyLOCAL Expr //line sql.y:6671 { - yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) + yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL case 1341: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Expr +//line sql.y:6675 + { + yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) + } + yyVAL.union = yyLOCAL + case 1342: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:6676 +//line sql.y:6680 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1342: + case 1343: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6680 +//line sql.y:6684 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1343: + case 1344: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6686 +//line sql.y:6690 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1344: + case 1345: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6690 +//line sql.y:6694 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1345: + case 1346: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6694 +//line sql.y:6698 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1346: + case 1347: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6698 +//line sql.y:6702 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1347: + case 1348: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6702 +//line sql.y:6706 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1348: + case 1349: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6707 +//line sql.y:6711 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1349: + case 1350: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6711 +//line sql.y:6715 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1350: + case 1351: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6715 +//line sql.y:6719 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1351: + case 1352: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6719 +//line sql.y:6723 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1352: + case 1353: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6723 +//line sql.y:6727 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1353: + case 1354: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6727 +//line sql.y:6731 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1354: + case 1355: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6732 +//line sql.y:6736 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1355: + case 1356: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6736 +//line sql.y:6740 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1356: + case 1357: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6740 +//line sql.y:6744 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1357: + case 1358: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6744 +//line sql.y:6748 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), MatchType: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1358: + case 1359: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6751 +//line sql.y:6755 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1359: + case 1360: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6755 +//line sql.y:6759 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1360: + case 1361: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6761 +//line sql.y:6765 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1361: + case 1362: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6765 +//line sql.y:6769 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1362: + case 1363: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6769 +//line sql.y:6773 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } yyVAL.union = yyLOCAL - case 1363: + case 1364: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6773 +//line sql.y:6777 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1364: + case 1365: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6779 +//line sql.y:6783 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1365: + case 1366: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6783 +//line sql.y:6787 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1366: + case 1367: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6787 +//line sql.y:6791 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1367: + case 1368: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6791 +//line sql.y:6795 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1368: + case 1369: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6795 +//line sql.y:6799 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1369: + case 1370: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6799 +//line sql.y:6803 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1370: + case 1371: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6803 +//line sql.y:6807 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1371: + case 1372: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6808 +//line sql.y:6812 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1372: + case 1373: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6812 +//line sql.y:6816 { yyLOCAL = yyDollar[2].convertTypeUnion() } yyVAL.union = yyLOCAL - case 1373: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL IntervalType -//line sql.y:6818 - { - yyLOCAL = IntervalDayHour - } - yyVAL.union = yyLOCAL case 1374: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType //line sql.y:6822 { - yyLOCAL = IntervalDayMicrosecond + yyLOCAL = IntervalDayHour } yyVAL.union = yyLOCAL case 1375: @@ -20295,7 +20347,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6826 { - yyLOCAL = IntervalDayMinute + yyLOCAL = IntervalDayMicrosecond } yyVAL.union = yyLOCAL case 1376: @@ -20303,7 +20355,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6830 { - yyLOCAL = IntervalDaySecond + yyLOCAL = IntervalDayMinute } yyVAL.union = yyLOCAL case 1377: @@ -20311,7 +20363,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6834 { - yyLOCAL = IntervalHourMicrosecond + yyLOCAL = IntervalDaySecond } yyVAL.union = yyLOCAL case 1378: @@ -20319,7 +20371,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6838 { - yyLOCAL = IntervalHourMinute + yyLOCAL = IntervalHourMicrosecond } yyVAL.union = yyLOCAL case 1379: @@ -20327,7 +20379,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6842 { - yyLOCAL = IntervalHourSecond + yyLOCAL = IntervalHourMinute } yyVAL.union = yyLOCAL case 1380: @@ -20335,7 +20387,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6846 { - yyLOCAL = IntervalMinuteMicrosecond + yyLOCAL = IntervalHourSecond } yyVAL.union = yyLOCAL case 1381: @@ -20343,7 +20395,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6850 { - yyLOCAL = IntervalMinuteSecond + yyLOCAL = IntervalMinuteMicrosecond } yyVAL.union = yyLOCAL case 1382: @@ -20351,7 +20403,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6854 { - yyLOCAL = IntervalSecondMicrosecond + yyLOCAL = IntervalMinuteSecond } yyVAL.union = yyLOCAL case 1383: @@ -20359,7 +20411,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6858 { - yyLOCAL = IntervalYearMonth + yyLOCAL = IntervalSecondMicrosecond } yyVAL.union = yyLOCAL case 1384: @@ -20367,7 +20419,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6862 { - yyLOCAL = IntervalDay + yyLOCAL = IntervalYearMonth } yyVAL.union = yyLOCAL case 1385: @@ -20375,7 +20427,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6866 { - yyLOCAL = IntervalWeek + yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL case 1386: @@ -20383,7 +20435,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6870 { - yyLOCAL = IntervalHour + yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL case 1387: @@ -20391,7 +20443,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6874 { - yyLOCAL = IntervalMinute + yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL case 1388: @@ -20399,7 +20451,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6878 { - yyLOCAL = IntervalMonth + yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL case 1389: @@ -20407,7 +20459,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6882 { - yyLOCAL = IntervalQuarter + yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL case 1390: @@ -20415,7 +20467,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6886 { - yyLOCAL = IntervalSecond + yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL case 1391: @@ -20423,7 +20475,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6890 { - yyLOCAL = IntervalMicrosecond + yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL case 1392: @@ -20431,15 +20483,15 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6894 { - yyLOCAL = IntervalYear + yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL case 1393: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6900 +//line sql.y:6898 { - yyLOCAL = IntervalDay + yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL case 1394: @@ -20447,7 +20499,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6904 { - yyLOCAL = IntervalWeek + yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL case 1395: @@ -20455,7 +20507,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6908 { - yyLOCAL = IntervalHour + yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL case 1396: @@ -20463,7 +20515,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6912 { - yyLOCAL = IntervalMinute + yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL case 1397: @@ -20471,7 +20523,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6916 { - yyLOCAL = IntervalMonth + yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL case 1398: @@ -20479,7 +20531,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6920 { - yyLOCAL = IntervalQuarter + yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL case 1399: @@ -20487,7 +20539,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6924 { - yyLOCAL = IntervalSecond + yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL case 1400: @@ -20495,7 +20547,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6928 { - yyLOCAL = IntervalMicrosecond + yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL case 1401: @@ -20503,7 +20555,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6932 { - yyLOCAL = IntervalYear + yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL case 1402: @@ -20511,7 +20563,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6936 { - yyLOCAL = IntervalDay + yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL case 1403: @@ -20519,7 +20571,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6940 { - yyLOCAL = IntervalWeek + yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL case 1404: @@ -20527,7 +20579,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6944 { - yyLOCAL = IntervalHour + yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL case 1405: @@ -20535,7 +20587,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6948 { - yyLOCAL = IntervalMinute + yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL case 1406: @@ -20543,7 +20595,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6952 { - yyLOCAL = IntervalMonth + yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL case 1407: @@ -20551,7 +20603,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6956 { - yyLOCAL = IntervalQuarter + yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL case 1408: @@ -20559,7 +20611,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6960 { - yyLOCAL = IntervalSecond + yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL case 1409: @@ -20567,7 +20619,7 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6964 { - yyLOCAL = IntervalMicrosecond + yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL case 1410: @@ -20575,19 +20627,19 @@ yydefault: var yyLOCAL IntervalType //line sql.y:6968 { - yyLOCAL = IntervalYear + yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1413: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL int -//line sql.y:6978 + case 1411: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL IntervalType +//line sql.y:6972 { - yyLOCAL = 0 + yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL case 1414: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int //line sql.y:6982 { @@ -20595,19 +20647,19 @@ yydefault: } yyVAL.union = yyLOCAL case 1415: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int //line sql.y:6986 { - yyLOCAL = convertStringToInt(yyDollar[2].str) + yyLOCAL = 0 } yyVAL.union = yyLOCAL case 1416: - yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL Expr -//line sql.y:6996 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL int +//line sql.y:6990 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL case 1417: @@ -20615,7 +20667,7 @@ yydefault: var yyLOCAL Expr //line sql.y:7000 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1418: @@ -20623,7 +20675,7 @@ yydefault: var yyLOCAL Expr //line sql.y:7004 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1419: @@ -20631,7 +20683,7 @@ yydefault: var yyLOCAL Expr //line sql.y:7008 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1420: @@ -20639,60 +20691,62 @@ yydefault: var yyLOCAL Expr //line sql.y:7012 { - yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1421: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL MatchExprOption -//line sql.y:7018 + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Expr +//line sql.y:7016 { - yyLOCAL = NoOption + yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 1422: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption //line sql.y:7022 { - yyLOCAL = BooleanModeOpt + yyLOCAL = NoOption } yyVAL.union = yyLOCAL case 1423: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption //line sql.y:7026 { - yyLOCAL = NaturalLanguageModeOpt + yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL case 1424: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption //line sql.y:7030 { - yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt + yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL case 1425: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption //line sql.y:7034 { - yyLOCAL = QueryExpansionOpt + yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL case 1426: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7040 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL MatchExprOption +//line sql.y:7038 { - yyVAL.str = string(yyDollar[1].identifierCI.String()) + yyLOCAL = QueryExpansionOpt } + yyVAL.union = yyLOCAL case 1427: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:7044 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].identifierCI.String()) } case 1428: yyDollar = yyS[yypt-1 : yypt+1] @@ -20701,19 +20755,17 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 1429: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL *ConvertType -//line sql.y:7054 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:7052 { - yyLOCAL = nil + yyVAL.str = string(yyDollar[1].str) } - yyVAL.union = yyLOCAL case 1430: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7058 { - yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: NewIntLiteral(yyDollar[4].str)} + yyLOCAL = nil } yyVAL.union = yyLOCAL case 1431: @@ -20725,73 +20777,73 @@ yydefault: } yyVAL.union = yyLOCAL case 1432: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7068 +//line sql.y:7066 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} + yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: NewIntLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL case 1433: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7072 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: yyDollar[3].columnCharset} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL case 1434: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7076 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: yyDollar[3].columnCharset} } yyVAL.union = yyLOCAL case 1435: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7080 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 1436: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7084 - { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} - yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length - yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale + { + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL case 1437: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7090 +//line sql.y:7088 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length + yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL case 1438: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7094 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 1439: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7098 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL case 1440: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7102 { @@ -20803,19 +20855,19 @@ yydefault: var yyLOCAL *ConvertType //line sql.y:7106 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 1442: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7110 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL case 1443: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7114 { @@ -20827,15 +20879,15 @@ yydefault: var yyLOCAL *ConvertType //line sql.y:7118 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 1445: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType //line sql.y:7122 { - yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL case 1446: @@ -20847,140 +20899,148 @@ yydefault: } yyVAL.union = yyLOCAL case 1447: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL *ConvertType +//line sql.y:7130 + { + yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} + } + yyVAL.union = yyLOCAL + case 1448: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7132 +//line sql.y:7136 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1448: + case 1449: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7136 +//line sql.y:7140 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1449: + case 1450: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7141 +//line sql.y:7145 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1450: + case 1451: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7145 +//line sql.y:7149 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1451: + case 1452: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7150 +//line sql.y:7154 { yyVAL.str = string("") } - case 1452: + case 1453: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7154 +//line sql.y:7158 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 1453: + case 1454: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7160 +//line sql.y:7164 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 1454: + case 1455: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7164 +//line sql.y:7168 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 1455: + case 1456: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7170 +//line sql.y:7174 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1456: + case 1457: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7175 +//line sql.y:7179 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1457: + case 1458: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7179 +//line sql.y:7183 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1458: + case 1459: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7185 +//line sql.y:7189 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1459: + case 1460: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7189 +//line sql.y:7193 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1460: + case 1461: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7193 +//line sql.y:7197 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1461: + case 1462: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7197 +//line sql.y:7201 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 1462: + case 1463: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7203 +//line sql.y:7207 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 1463: + case 1464: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7207 +//line sql.y:7211 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1464: + case 1465: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7213 +//line sql.y:7217 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -20990,218 +21050,210 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 1465: + case 1466: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7222 +//line sql.y:7226 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1466: + case 1467: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7226 +//line sql.y:7230 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1467: + case 1468: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7231 +//line sql.y:7235 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1468: + case 1469: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:7235 +//line sql.y:7239 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1469: + case 1470: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7240 +//line sql.y:7244 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1470: + case 1471: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7244 +//line sql.y:7248 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1471: + case 1472: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7250 +//line sql.y:7254 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 1472: + case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7256 +//line sql.y:7260 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL - case 1473: + case 1474: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7260 +//line sql.y:7264 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) } - case 1474: + case 1475: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7265 +//line sql.y:7269 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1475: + case 1476: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7269 +//line sql.y:7273 { yyLOCAL = yyDollar[1].namedWindowsUnion() } yyVAL.union = yyLOCAL - case 1476: + case 1477: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7274 +//line sql.y:7278 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1477: + case 1478: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7278 +//line sql.y:7282 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 1478: + case 1479: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7284 +//line sql.y:7288 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 1479: + case 1480: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7290 +//line sql.y:7294 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 1480: + case 1481: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7294 +//line sql.y:7298 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 1481: + case 1482: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7300 +//line sql.y:7304 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 1482: + case 1483: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7305 +//line sql.y:7309 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1483: + case 1484: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7309 +//line sql.y:7313 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1484: + case 1485: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7313 +//line sql.y:7317 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 1485: + case 1486: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7318 +//line sql.y:7322 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1486: + case 1487: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7322 +//line sql.y:7326 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 1487: + case 1488: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7328 +//line sql.y:7332 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1488: + case 1489: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7332 +//line sql.y:7336 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1489: + case 1490: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7336 +//line sql.y:7340 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1490: - yyDollar = yyS[yypt-0 : yypt+1] - var yyLOCAL []AlterOption -//line sql.y:7341 - { - yyLOCAL = nil - } - yyVAL.union = yyLOCAL case 1491: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption //line sql.y:7345 { - yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} + yyLOCAL = nil } yyVAL.union = yyLOCAL case 1492: @@ -21213,11 +21265,11 @@ yydefault: } yyVAL.union = yyLOCAL case 1493: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption //line sql.y:7353 { - yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} + yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL case 1494: @@ -21229,11 +21281,11 @@ yydefault: } yyVAL.union = yyLOCAL case 1495: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:7364 + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL []AlterOption +//line sql.y:7361 { - yyLOCAL = &LockOption{Type: DefaultType} + yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL case 1496: @@ -21241,7 +21293,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:7368 { - yyLOCAL = &LockOption{Type: NoneType} + yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL case 1497: @@ -21249,7 +21301,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:7372 { - yyLOCAL = &LockOption{Type: SharedType} + yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL case 1498: @@ -21257,15 +21309,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:7376 { - yyLOCAL = &LockOption{Type: ExclusiveType} + yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL case 1499: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7382 +//line sql.y:7380 { - yyLOCAL = AlgorithmValue(yyDollar[3].str) + yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL case 1500: @@ -21293,16 +21345,18 @@ yydefault: } yyVAL.union = yyLOCAL case 1503: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7399 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:7398 { - yyVAL.str = "" + yyLOCAL = AlgorithmValue(yyDollar[3].str) } + yyVAL.union = yyLOCAL case 1504: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:7403 { - yyVAL.str = string(yyDollar[3].str) + yyVAL.str = "" } case 1505: yyDollar = yyS[yypt-3 : yypt+1] @@ -21317,22 +21371,22 @@ yydefault: yyVAL.str = string(yyDollar[3].str) } case 1507: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7416 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:7415 { - yyVAL.str = "" + yyVAL.str = string(yyDollar[3].str) } case 1508: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:7420 { - yyVAL.str = yyDollar[3].str + yyVAL.str = "" } case 1509: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7426 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:7424 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = yyDollar[3].str } case 1510: yyDollar = yyS[yypt-1 : yypt+1] @@ -21341,28 +21395,28 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 1511: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7435 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:7434 { - yyVAL.str = "" + yyVAL.str = string(yyDollar[1].str) } case 1512: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:7439 { - yyVAL.str = yyDollar[2].str + yyVAL.str = "" } case 1513: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7444 + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:7443 { - yyVAL.str = "cascaded" + yyVAL.str = yyDollar[2].str } case 1514: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:7448 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = "cascaded" } case 1515: yyDollar = yyS[yypt-1 : yypt+1] @@ -21371,45 +21425,51 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 1516: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:7456 + { + yyVAL.str = string(yyDollar[1].str) + } + case 1517: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:7457 +//line sql.y:7461 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1517: + case 1518: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7461 +//line sql.y:7465 { yyLOCAL = yyDollar[3].definerUnion() } yyVAL.union = yyLOCAL - case 1518: + case 1519: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:7467 +//line sql.y:7471 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1519: + case 1520: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7473 +//line sql.y:7477 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1520: + case 1521: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:7479 +//line sql.y:7483 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -21417,369 +21477,369 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1521: + case 1522: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7488 +//line sql.y:7492 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 1522: + case 1523: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7492 +//line sql.y:7496 { yyVAL.str = formatIdentifier(yyDollar[1].str) } - case 1523: + case 1524: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7497 +//line sql.y:7501 { yyVAL.str = "" } - case 1524: + case 1525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7501 +//line sql.y:7505 { yyVAL.str = formatAddress(yyDollar[1].str) } - case 1525: + case 1526: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7507 +//line sql.y:7511 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 1526: + case 1527: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7511 +//line sql.y:7515 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 1527: + case 1528: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7517 +//line sql.y:7521 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 1528: + case 1529: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7521 +//line sql.y:7525 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1529: + case 1530: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7525 +//line sql.y:7529 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1530: + case 1531: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7530 +//line sql.y:7534 { yyVAL.str = "" } - case 1531: + case 1532: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7534 +//line sql.y:7538 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1532: + case 1533: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7538 +//line sql.y:7542 { yyVAL.str = " format text" + yyDollar[3].str } - case 1533: + case 1534: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7543 +//line sql.y:7547 { yyVAL.str = "" } - case 1534: + case 1535: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7547 +//line sql.y:7551 { yyVAL.str = " header" } - case 1535: + case 1536: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7552 +//line sql.y:7556 { yyVAL.str = "" } - case 1536: + case 1537: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7556 +//line sql.y:7560 { yyVAL.str = " manifest on" } - case 1537: + case 1538: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7560 +//line sql.y:7564 { yyVAL.str = " manifest off" } - case 1538: + case 1539: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7565 +//line sql.y:7569 { yyVAL.str = "" } - case 1539: + case 1540: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7569 +//line sql.y:7573 { yyVAL.str = " overwrite on" } - case 1540: + case 1541: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7573 +//line sql.y:7577 { yyVAL.str = " overwrite off" } - case 1541: + case 1542: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7579 +//line sql.y:7583 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1542: + case 1543: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7584 +//line sql.y:7588 { yyVAL.str = "" } - case 1543: + case 1544: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7588 +//line sql.y:7592 { yyVAL.str = " lines" + yyDollar[2].str } - case 1544: + case 1545: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7594 +//line sql.y:7598 { yyVAL.str = yyDollar[1].str } - case 1545: + case 1546: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7598 +//line sql.y:7602 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1546: + case 1547: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7604 +//line sql.y:7608 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1547: + case 1548: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7608 +//line sql.y:7612 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1548: + case 1549: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7613 +//line sql.y:7617 { yyVAL.str = "" } - case 1549: + case 1550: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7617 +//line sql.y:7621 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1550: + case 1551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7623 +//line sql.y:7627 { yyVAL.str = yyDollar[1].str } - case 1551: + case 1552: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7627 +//line sql.y:7631 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1552: + case 1553: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7633 +//line sql.y:7637 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1553: + case 1554: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7637 +//line sql.y:7641 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1554: + case 1555: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7641 +//line sql.y:7645 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1555: + case 1556: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7646 +//line sql.y:7650 { yyVAL.str = "" } - case 1556: + case 1557: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7650 +//line sql.y:7654 { yyVAL.str = " optionally" } - case 1557: + case 1558: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Insert -//line sql.y:7663 +//line sql.y:7667 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion()} } yyVAL.union = yyLOCAL - case 1558: + case 1559: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:7667 +//line sql.y:7671 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1559: + case 1560: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:7671 +//line sql.y:7675 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion()} } yyVAL.union = yyLOCAL - case 1560: + case 1561: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7675 +//line sql.y:7679 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion()} } yyVAL.union = yyLOCAL - case 1561: + case 1562: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7679 +//line sql.y:7683 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1562: + case 1563: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:7685 +//line sql.y:7689 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1563: + case 1564: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:7689 +//line sql.y:7693 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1564: + case 1565: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7693 +//line sql.y:7697 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1565: + case 1566: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:7697 +//line sql.y:7701 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1566: + case 1567: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7702 +//line sql.y:7706 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1567: + case 1568: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7706 +//line sql.y:7710 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1568: + case 1569: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:7712 +//line sql.y:7716 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1569: + case 1570: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7716 +//line sql.y:7720 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1570: + case 1571: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7722 +//line sql.y:7726 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1571: + case 1572: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7726 +//line sql.y:7730 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1572: + case 1573: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7732 +//line sql.y:7736 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1573: + case 1574: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7736 +//line sql.y:7740 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1574: + case 1575: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7741 +//line sql.y:7745 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -21788,212 +21848,206 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1575: + case 1576: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7751 +//line sql.y:7755 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1576: + case 1577: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7755 +//line sql.y:7759 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1577: + case 1578: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:7761 +//line sql.y:7765 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1579: + case 1580: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7768 +//line sql.y:7772 { yyVAL.str = "charset" } - case 1582: + case 1583: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7778 +//line sql.y:7782 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1583: + case 1584: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7782 +//line sql.y:7786 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1584: + case 1585: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7786 +//line sql.y:7790 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1587: + case 1588: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7795 +//line sql.y:7799 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1588: + case 1589: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7797 +//line sql.y:7801 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1589: + case 1590: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7800 +//line sql.y:7804 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1590: + case 1591: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7802 +//line sql.y:7806 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1591: + case 1592: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7805 +//line sql.y:7809 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1592: + case 1593: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:7807 +//line sql.y:7811 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1593: + case 1594: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:7810 +//line sql.y:7814 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1594: + case 1595: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:7812 +//line sql.y:7816 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1595: + case 1596: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7815 +//line sql.y:7819 { yyVAL.empty = struct{}{} } - case 1596: + case 1597: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7817 +//line sql.y:7821 { yyVAL.empty = struct{}{} } - case 1597: + case 1598: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7819 +//line sql.y:7823 { yyVAL.empty = struct{}{} } - case 1598: + case 1599: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:7823 +//line sql.y:7827 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1599: + case 1600: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7828 +//line sql.y:7832 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1600: + case 1601: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:7832 +//line sql.y:7836 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1601: + case 1602: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7837 +//line sql.y:7841 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1602: + case 1603: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7839 +//line sql.y:7843 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1603: + case 1604: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:7843 +//line sql.y:7847 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1604: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7849 - { - yyVAL.identifierCI = yyDollar[1].identifierCI - } case 1605: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:7853 { - yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) + yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1607: + case 1606: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7860 +//line sql.y:7857 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 1608: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7866 +//line sql.y:7864 { - yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) + yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 1609: yyDollar = yyS[yypt-1 : yypt+1] @@ -22002,79 +22056,79 @@ yydefault: yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 1610: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:7874 + { + yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) + } + case 1611: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7876 +//line sql.y:7880 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1611: + case 1612: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7880 +//line sql.y:7884 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1613: + case 1614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7887 +//line sql.y:7891 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1614: + case 1615: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:7893 +//line sql.y:7897 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1615: + case 1616: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:7899 +//line sql.y:7903 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1616: + case 1617: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7903 +//line sql.y:7907 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1617: + case 1618: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7907 +//line sql.y:7911 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2232: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8550 - { - } case 2233: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8555 +//line sql.y:8554 { } case 2234: - yyDollar = yyS[yypt-0 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:8559 { - skipToEnd(yylex) } case 2235: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8564 +//line sql.y:8563 { skipToEnd(yylex) } case 2236: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:8568 { skipToEnd(yylex) @@ -22085,6 +22139,12 @@ yydefault: { skipToEnd(yylex) } + case 2238: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:8576 + { + skipToEnd(yylex) + } } goto yystack /* stack new state and value */ } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index fcb481725e9..4ed613718fd 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -4128,6 +4128,10 @@ show_statement: { $$ = &Show{&ShowBasic{Command: VschemaTables}} } +| SHOW VSCHEMA KEYSPACES + { + $$ = &Show{&ShowBasic{Command: VschemaKeyspaces}} + } | SHOW VSCHEMA VINDEXES { $$ = &Show{&ShowBasic{Command: VschemaVindexes}} diff --git a/go/vt/vtgate/planbuilder/show.go b/go/vt/vtgate/planbuilder/show.go index 6e5fad4023a..2a8b11fb70e 100644 --- a/go/vt/vtgate/planbuilder/show.go +++ b/go/vt/vtgate/planbuilder/show.go @@ -20,6 +20,7 @@ import ( "fmt" "regexp" "sort" + "strconv" "strings" "sync" @@ -116,6 +117,8 @@ func buildShowBasicPlan(show *sqlparser.ShowBasic, vschema plancontext.VSchema) return buildShowTargetPlan(vschema) case sqlparser.VschemaTables: return buildVschemaTablesPlan(vschema) + case sqlparser.VschemaKeyspaces: + return buildVschemaKeyspacesPlan(vschema) case sqlparser.VschemaVindexes: return buildVschemaVindexesPlan(show, vschema) } @@ -641,6 +644,26 @@ func buildEnginesPlan() (engine.Primitive, error) { buildVarCharFields("Engine", "Support", "Comment", "Transactions", "XA", "Savepoints")), nil } +func buildVschemaKeyspacesPlan(vschema plancontext.VSchema) (engine.Primitive, error) { + vs := vschema.GetVSchema() + var rows [][]sqltypes.Value + for ksName, ks := range vs.Keyspaces { + var row []sqltypes.Value + row = append(row, sqltypes.NewVarChar(ksName)) + row = append(row, sqltypes.NewVarChar(strconv.FormatBool(ks.Keyspace.Sharded))) + fkMode, _ := vschema.ForeignKeyMode(ksName) + row = append(row, sqltypes.NewVarChar(fkMode.String())) + ksError := "" + if ks.Error != nil { + ksError = ks.Error.Error() + } + row = append(row, sqltypes.NewVarChar(ksError)) + rows = append(rows, row) + } + + return engine.NewRowsPrimitive(rows, buildVarCharFields("Keyspace", "Sharded", "Foreign Key", "Comment")), nil +} + func buildVschemaTablesPlan(vschema plancontext.VSchema) (engine.Primitive, error) { vs := vschema.GetVSchema() ks, err := vschema.DefaultKeyspace() diff --git a/go/vt/vtgate/planbuilder/testdata/show_cases.json b/go/vt/vtgate/planbuilder/testdata/show_cases.json index c20a1c79f5a..896f762819e 100644 --- a/go/vt/vtgate/planbuilder/testdata/show_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/show_cases.json @@ -720,6 +720,24 @@ } } }, + { + "comment": "show vschema keyspaces", + "query": "show vschema keyspaces", + "plan": { + "QueryType": "SHOW", + "Original": "show vschema keyspaces", + "Instructions": { + "OperatorType": "Rows", + "Fields": { + "Comment": "VARCHAR", + "Foreign Key": "VARCHAR", + "Keyspace": "VARCHAR", + "Sharded": "VARCHAR" + }, + "RowCount": 7 + } + } + }, { "comment": "show vschema vindexes", "query": "show vschema vindexes", From cb98acd896b2f9b4a32c418b714fbd472298f23d Mon Sep 17 00:00:00 2001 From: lixin18 <68135097+lixin963@users.noreply.github.com> Date: Tue, 14 Nov 2023 02:59:45 +0800 Subject: [PATCH 011/119] Update create_release.sh (#14492) --- tools/create_release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/create_release.sh b/tools/create_release.sh index 68e051f884e..17c8139dce2 100755 --- a/tools/create_release.sh +++ b/tools/create_release.sh @@ -52,7 +52,7 @@ function createRelease () { rm -f ./.github/workflows/code_freeze.yml.bak # Wait for release notes to be injected in the code base - echo -n Pausing so relase notes can be added. Press enter to continue + echo -n Pausing so release notes can be added. Press enter to continue read line git add --all From 22f1b22759350c6eb786dd1c1a5223c7956f314c Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Mon, 13 Nov 2023 21:48:33 -0800 Subject: [PATCH 012/119] release notes: add FK import to summary (#14518) Signed-off-by: deepthi --- changelog/18.0/18.0.0/summary.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog/18.0/18.0.0/summary.md b/changelog/18.0/18.0.0/summary.md index eb2b6692201..35ad018b7bc 100644 --- a/changelog/18.0/18.0.0/summary.md +++ b/changelog/18.0/18.0.0/summary.md @@ -95,6 +95,8 @@ There are 3 foreign key modes now supported in Vitess - 3. `disallow` - In this mode Vitess explicitly disallows any DDL statements that try to create a foreign key constraint. This mode is equivalent to running VTGate with the flag `--foreign_key_mode=disallow`. +In addition to query support, there is a new flag to `MoveTables` called `--atomic-copy` which should be used to import data into Vitess from databases which have foreign keys defined in the schema. + #### Upgrade process After upgrading from v17 to v18, users should specify the correct foreign key mode for all their keyspaces in the VSchema using the new property. From 71bd1e089e0fd58c4215ace9a55324999a19702d Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 14 Nov 2023 22:06:03 +0200 Subject: [PATCH 013/119] Support `fast_analyze_table` variable, introduced in public MySQL fork (#14494) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/schema.go | 3 +++ go/vt/vttablet/onlineddl/vrepl.go | 35 ++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 1cef44e08d3..c072da2dc7b 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -528,6 +528,9 @@ const ( sqlShowVariablesLikePreserveForeignKey = "show global variables like 'rename_table_preserve_foreign_key'" sqlEnablePreserveForeignKey = "set @@rename_table_preserve_foreign_key = 1" sqlDisablePreserveForeignKey = "set @@rename_table_preserve_foreign_key = 0" + sqlShowVariablesLikeFastAnalyzeTable = "show global variables like 'fast_analyze_table'" + sqlEnableFastAnalyzeTable = "set @@fast_analyze_table = 1" + sqlDisableFastAnalyzeTable = "set @@fast_analyze_table = 0" sqlGetAutoIncrement = ` SELECT AUTO_INCREMENT diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 8432f79b506..b1dd0ff8629 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -37,6 +37,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/textutil" "vitess.io/vitess/go/vt/dbconnpool" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" @@ -247,11 +248,41 @@ func (v *VRepl) readTableUniqueKeys(ctx context.Context, conn *dbconnpool.DBConn return uniqueKeys, nil } +// isFastAnalyzeTableSupported checks if the underlying MySQL server supports 'fast_analyze_table', +// introduced by a fork of MySQL: https://github.com/planetscale/mysql-server/commit/c8a9d93686358dabfba8f3dc5cc0621e3149fe78 +// When `fast_analyze_table=1`, an `ANALYZE TABLE` command only analyzes the clustering index (normally the `PRIMARY KEY`). +// This is useful when you want to get a better estimate of the number of table rows, as fast as possible. +func (v *VRepl) isFastAnalyzeTableSupported(ctx context.Context, conn *dbconnpool.DBConnection) (isSupported bool, err error) { + rs, err := conn.ExecuteFetch(sqlShowVariablesLikeFastAnalyzeTable, math.MaxInt64, true) + if err != nil { + return false, err + } + return len(rs.Rows) > 0, nil +} + // executeAnalyzeTable runs an ANALYZE TABLE command func (v *VRepl) executeAnalyzeTable(ctx context.Context, conn *dbconnpool.DBConnection, tableName string) error { + fastAnalyzeTableSupported, err := v.isFastAnalyzeTableSupported(ctx, conn) + if err != nil { + return err + } + if fastAnalyzeTableSupported { + // This code is only applicable when MySQL supports the 'fast_analyze_table' variable. This variable + // does not exist in vanilla MySQL. + // See https://github.com/planetscale/mysql-server/commit/c8a9d93686358dabfba8f3dc5cc0621e3149fe78 + // as part of https://github.com/planetscale/mysql-server/releases/tag/8.0.34-ps1. + if _, err := conn.ExecuteFetch(sqlEnableFastAnalyzeTable, 1, false); err != nil { + return err + } + log.Infof("@@fast_analyze_table enabled") + defer conn.ExecuteFetch(sqlDisableFastAnalyzeTable, 1, false) + } + parsed := sqlparser.BuildParsedQuery(sqlAnalyzeTable, tableName) - _, err := conn.ExecuteFetch(parsed.Query, 1, false) - return err + if _, err := conn.ExecuteFetch(parsed.Query, 1, false); err != nil { + return err + } + return nil } // readTableStatus reads table status information From 45777324260fcc72e62f209e529cf50188f5b6a4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 15 Nov 2023 06:38:32 +0200 Subject: [PATCH 014/119] Online DDL: edit CONSTRAINT names in CREATE TABLE (#14517) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/flavor.go | 1 + go/mysql/flavor_mysql.go | 2 ++ go/mysql/flavor_test.go | 10 +++++++++ .../onlineddl/revert/onlineddl_revert_test.go | 18 ++++++++++++++-- .../scheduler/onlineddl_scheduler_test.go | 21 ++++++++++++++++++- go/vt/vttablet/onlineddl/executor.go | 11 ++++++++++ 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/go/mysql/flavor.go b/go/mysql/flavor.go index edb64913c31..a8c2de2e114 100644 --- a/go/mysql/flavor.go +++ b/go/mysql/flavor.go @@ -55,6 +55,7 @@ const ( MySQLUpgradeInServerFlavorCapability DynamicRedoLogCapacityFlavorCapability // supported in MySQL 8.0.30 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-30.html DisableRedoLogFlavorCapability // supported in MySQL 8.0.21 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html + CheckConstraintsCapability // supported in MySQL 8.0.16 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html ) const ( diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index bc5f31006e5..3cc2e08e489 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -397,6 +397,8 @@ func (mysqlFlavor80) supportsCapability(serverVersion string, capability FlavorC return ServerVersionAtLeast(serverVersion, 8, 0, 30) case DisableRedoLogFlavorCapability: return ServerVersionAtLeast(serverVersion, 8, 0, 21) + case CheckConstraintsCapability: + return ServerVersionAtLeast(serverVersion, 8, 0, 16) default: return false, nil } diff --git a/go/mysql/flavor_test.go b/go/mysql/flavor_test.go index 891725b5afc..925504722b7 100644 --- a/go/mysql/flavor_test.go +++ b/go/mysql/flavor_test.go @@ -160,6 +160,16 @@ func TestGetFlavor(t *testing.T) { capability: DisableRedoLogFlavorCapability, isCapable: false, }, + { + version: "8.0.15", + capability: CheckConstraintsCapability, + isCapable: false, + }, + { + version: "8.0.20", + capability: CheckConstraintsCapability, + isCapable: true, + }, } for _, tc := range testcases { name := fmt.Sprintf("%s %v", tc.version, tc.capability) diff --git a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go index 41cd5b5a1be..3220465269e 100644 --- a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go +++ b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go @@ -428,7 +428,20 @@ func testRevertible(t *testing.T) { droppedNoDefaultColumnNames := row.AsString("dropped_no_default_column_names", "") expandedColumnNames := row.AsString("expanded_column_names", "") - assert.Equal(t, testcase.removedForeignKeyNames, removeBackticks(removedForeignKeyNames)) + // Online DDL renames constraint names, and keeps the original name as a prefix. + // The name of e.g. "some_fk_2_" might turn into "some_fk_2_518ubnm034rel35l1m0u1dc7m" + expectRemovedForeignKeyNames := strings.Split(testcase.removedForeignKeyNames, ",") + actualRemovedForeignKeyNames := strings.Split(removeBackticks(removedForeignKeyNames), ",") + assert.Equal(t, len(expectRemovedForeignKeyNames), len(actualRemovedForeignKeyNames)) + for _, actualRemovedForeignKeyName := range actualRemovedForeignKeyNames { + found := false + for _, expectRemovedForeignKeyName := range expectRemovedForeignKeyNames { + if strings.HasPrefix(actualRemovedForeignKeyName, expectRemovedForeignKeyName) { + found = true + } + } + assert.Truef(t, found, "unexpected FK name", "%s", actualRemovedForeignKeyName) + } assert.Equal(t, testcase.removedUniqueKeyNames, removeBackticks(removedUniqueKeyNames)) assert.Equal(t, testcase.droppedNoDefaultColumnNames, removeBackticks(droppedNoDefaultColumnNames)) assert.Equal(t, testcase.expandedColumnNames, removeBackticks(expandedColumnNames)) @@ -466,7 +479,8 @@ func testRevertible(t *testing.T) { droppedNoDefaultColumnNames := row.AsString("dropped_no_default_column_names", "") expandedColumnNames := row.AsString("expanded_column_names", "") - assert.Equal(t, "some_fk_2", removeBackticks(removedForeignKeyNames)) + // Online DDL renames constraint names, and keeps the original name as a prefix. The name will be e.g. some_fk_2_518ubnm034rel35l1m0u1dc7m + assert.Contains(t, removeBackticks(removedForeignKeyNames), "some_fk_2") assert.Equal(t, "", removeBackticks(removedUniqueKeyNames)) assert.Equal(t, "", removeBackticks(droppedNoDefaultColumnNames)) assert.Equal(t, "", removeBackticks(expandedColumnNames)) diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index fbe6377c1fe..627567441b1 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -941,6 +941,25 @@ func testScheduler(t *testing.T) { }) }) + checkConstraintCapable, err := capableOf(mysql.CheckConstraintsCapability) // 8.0.16 and above + require.NoError(t, err) + if checkConstraintCapable { + // Constraints + t.Run("CREATE TABLE with CHECK constraint", func(t *testing.T) { + query := `create table with_constraint (id int primary key, check ((id >= 0)))` + uuid := testOnlineDDLStatement(t, createParams(query, ddlStrategy, "vtgate", "chk_", "", false)) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) + t.Run("ensure constraint name is rewritten", func(t *testing.T) { + // Since we did not provide a name for the CHECK constraint, MySQL will + // name it `with_constraint_chk_1`. But we expect Online DDL to explicitly + // modify the constraint name, specifically to get rid of the prefix, + // so that we don't get into https://bugs.mysql.com/bug.php?id=107772 situation. + createStatement := getCreateTableStatement(t, shards[0].Vttablets[0], "with_constraint") + assert.NotContains(t, createStatement, "with_constraint_chk") + }) + }) + } + // INSTANT DDL instantDDLCapable, err := capableOf(mysql.InstantAddLastColumnFlavorCapability) require.NoError(t, err) @@ -2328,7 +2347,7 @@ func testRevertMigration(t *testing.T, params *testRevertMigrationParams) (uuid return uuid } -// checkTable checks the number of tables in the first two shards. +// checkTable checks the number of tables in all shards func checkTable(t *testing.T, showTableName string, expectExists bool) bool { expectCount := 0 if expectExists { diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 8a3cf61348b..771a9000435 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -2863,6 +2863,17 @@ func (e *Executor) executeCreateDDLActionMigration(ctx context.Context, onlineDD } } } + if originalCreateTable, ok := ddlStmt.(*sqlparser.CreateTable); ok { + newCreateTable := sqlparser.CloneRefOfCreateTable(originalCreateTable) + // Rewrite this CREATE TABLE statement such that CONSTRAINT names are edited, + // specifically removing any prefix. + if _, err := e.validateAndEditCreateTableStatement(ctx, onlineDDL, newCreateTable); err != nil { + return failMigration(err) + } + ddlStmt = newCreateTable + onlineDDL.SQL = sqlparser.String(newCreateTable) + } + // from now on, whether a VIEW or a TABLE, they get the same treatment sentryArtifactTableName, err := schema.GenerateGCTableName(schema.HoldTableGCState, newGCTableRetainTime()) From 43d72a8c9fd3aea3cb36528e3bbf8bc7226608f8 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:30:19 +0200 Subject: [PATCH 015/119] Online DDL: fix endtoend test dropping foreign key (#14522) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../scheduler/onlineddl_scheduler_test.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index 627567441b1..575ecb91091 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -2147,7 +2147,7 @@ func testForeignKeys(t *testing.T) { }, { name: "drop foreign key from a child", - sql: "alter table child_table DROP FOREIGN KEY child_parent_fk", + sql: "alter table child_table DROP FOREIGN KEY ", // See "getting child_table constraint name" test step below. allowForeignKeys: true, expectHint: "child_hint", onlyIfFKOnlineDDLPossible: true, @@ -2212,6 +2212,19 @@ func testForeignKeys(t *testing.T) { }) } }) + t.Run("getting child_table constraint name", func(t *testing.T) { + // Due to how OnlineDDL works, the name of the foreign key constraint will not be the one we used in the CREATE TABLE statement. + // There's a specific test where we drop said constraint. So speficially for that test (or any similar future tests), we need to dynamically + // evaluate the constraint name. + rs := onlineddl.VtgateExecQuery(t, &vtParams, "select CONSTRAINT_NAME from information_schema.REFERENTIAL_CONSTRAINTS where TABLE_NAME='child_table'", "") + assert.Equal(t, 1, len(rs.Rows)) + row := rs.Named().Row() + assert.NotNil(t, row) + childTableConstraintName := row.AsString("CONSTRAINT_NAME", "") + assert.NotEmpty(t, childTableConstraintName) + testcase.sql = strings.ReplaceAll(testcase.sql, "", childTableConstraintName) + }) + var uuid string t.Run("run migration", func(t *testing.T) { if testcase.allowForeignKeys { From 1cad33349a0006f4aa85bed919e58958abf08f4f Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:22:39 +0200 Subject: [PATCH 016/119] MysqlCtl: implement missing `ReadBinlogFilesTimestamps` function (#14525) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/test/endtoend/mysqlctld/mysqlctld_test.go | 8 ++++++++ go/vt/mysqlctl/grpcmysqlctlserver/server.go | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/go/test/endtoend/mysqlctld/mysqlctld_test.go b/go/test/endtoend/mysqlctld/mysqlctld_test.go index 908a870d6f0..e1577acfc52 100644 --- a/go/test/endtoend/mysqlctld/mysqlctld_test.go +++ b/go/test/endtoend/mysqlctld/mysqlctld_test.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/vt/mysqlctl/mysqlctlclient" + "vitess.io/vitess/go/vt/proto/mysqlctl" "vitess.io/vitess/go/test/endtoend/cluster" ) @@ -169,3 +170,10 @@ func TestVersionString(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, version) } + +func TestReadBinlogFilesTimestamps(t *testing.T) { + client, err := mysqlctlclient.New("unix", primaryTablet.MysqlctldProcess.SocketFile) + require.NoError(t, err) + _, err = client.ReadBinlogFilesTimestamps(context.Background(), &mysqlctl.ReadBinlogFilesTimestampsRequest{}) + require.ErrorContains(t, err, "empty binlog list in ReadBinlogFilesTimestampsRequest") +} diff --git a/go/vt/mysqlctl/grpcmysqlctlserver/server.go b/go/vt/mysqlctl/grpcmysqlctlserver/server.go index 84953020534..ac3b5092f19 100644 --- a/go/vt/mysqlctl/grpcmysqlctlserver/server.go +++ b/go/vt/mysqlctl/grpcmysqlctlserver/server.go @@ -56,6 +56,11 @@ func (s *server) ApplyBinlogFile(ctx context.Context, request *mysqlctlpb.ApplyB return &mysqlctlpb.ApplyBinlogFileResponse{}, s.mysqld.ApplyBinlogFile(ctx, request) } +// ReadBinlogFilesTimestamps implements the server side of the MysqlctlClient interface. +func (s *server) ReadBinlogFilesTimestamps(ctx context.Context, request *mysqlctlpb.ReadBinlogFilesTimestampsRequest) (*mysqlctlpb.ReadBinlogFilesTimestampsResponse, error) { + return s.mysqld.ReadBinlogFilesTimestamps(ctx, request) +} + // ReinitConfig implements the server side of the MysqlctlClient interface. func (s *server) ReinitConfig(ctx context.Context, request *mysqlctlpb.ReinitConfigRequest) (*mysqlctlpb.ReinitConfigResponse, error) { return &mysqlctlpb.ReinitConfigResponse{}, s.mysqld.ReinitConfig(ctx, s.cnf) From f2b9ef869cdd29d12d937221c758340f56676c49 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 15 Nov 2023 23:45:43 +0530 Subject: [PATCH 017/119] `Replace into` statement plan with foreign keys : unsharded (#14396) Signed-off-by: Harshit Gangal Co-authored-by: Manan Gupta --- go/mysql/sqlerror/sql_error.go | 1 + .../vtgate/foreignkey/fk_fuzz_test.go | 164 +++--- go/test/endtoend/vtgate/foreignkey/fk_test.go | 161 ++++++ .../endtoend/vtgate/foreignkey/main_test.go | 12 +- .../{sharded_schema.sql => schema.sql} | 44 +- .../vtgate/foreignkey/unsharded_schema.sql | 472 ------------------ go/vt/proto/vschema/vschema.pb.go | 79 +-- go/vt/proto/vschema/vschema_vtproto.pb.go | 44 ++ go/vt/vterrors/code.go | 6 +- go/vt/vterrors/state.go | 1 + go/vt/vtgate/engine/cached_size.go | 21 +- go/vt/vtgate/engine/delete.go | 1 + go/vt/vtgate/engine/dml.go | 4 +- go/vt/vtgate/engine/insert.go | 5 +- go/vt/vtgate/engine/sequential.go | 90 ++++ go/vt/vtgate/engine/update.go | 1 + go/vt/vtgate/planbuilder/insert.go | 15 +- .../planbuilder/operator_transformers.go | 19 + go/vt/vtgate/planbuilder/operators/insert.go | 235 ++++++++- .../planbuilder/operators/sequential.go | 54 ++ go/vt/vtgate/planbuilder/plan_test.go | 18 +- go/vt/vtgate/planbuilder/sequential.go | 36 ++ .../testdata/foreignkey_cases.json | 182 ++++++- .../planbuilder/testdata/vschemas/schema.json | 7 +- go/vt/vtgate/schema/tracker.go | 16 +- go/vt/vtgate/schema/tracker_test.go | 89 +++- go/vt/vtgate/vindexes/foreign_keys.go | 30 ++ go/vt/vtgate/vindexes/vschema.go | 36 +- go/vt/vtgate/vindexes/vschema_test.go | 26 +- go/vt/vtgate/vschema_manager.go | 30 +- go/vt/vtgate/vschema_manager_test.go | 123 +++-- proto/vschema.proto | 1 + web/vtadmin/src/proto/vtadmin.d.ts | 6 + web/vtadmin/src/proto/vtadmin.js | 23 + 34 files changed, 1375 insertions(+), 677 deletions(-) rename go/test/endtoend/vtgate/foreignkey/{sharded_schema.sql => schema.sql} (95%) delete mode 100644 go/test/endtoend/vtgate/foreignkey/unsharded_schema.sql create mode 100644 go/vt/vtgate/engine/sequential.go create mode 100644 go/vt/vtgate/planbuilder/operators/sequential.go create mode 100644 go/vt/vtgate/planbuilder/sequential.go diff --git a/go/mysql/sqlerror/sql_error.go b/go/mysql/sqlerror/sql_error.go index 9b1f65c82e3..30ce99d681a 100644 --- a/go/mysql/sqlerror/sql_error.go +++ b/go/mysql/sqlerror/sql_error.go @@ -243,6 +243,7 @@ var stateToMysqlCode = map[vterrors.State]mysqlCode{ vterrors.CharacterSetMismatch: {num: ERCharacterSetMismatch, state: SSUnknownSQLState}, vterrors.WrongParametersToNativeFct: {num: ERWrongParametersToNativeFct, state: SSUnknownSQLState}, vterrors.KillDeniedError: {num: ERKillDenied, state: SSUnknownSQLState}, + vterrors.BadNullError: {num: ERBadNullError, state: SSConstraintViolation}, } func getStateToMySQLState(state vterrors.State) mysqlCode { diff --git a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go index f7d7340d6a4..4c84eae2f42 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go @@ -95,9 +95,9 @@ func (fz *fuzzer) generateQuery() []string { if val < fz.insertShare { switch fz.queryFormat { case OlapSQLQueries, SQLQueries: - return []string{fz.generateInsertDMLQuery()} + return []string{fz.generateInsertDMLQuery(getInsertType())} case PreparedStatmentQueries: - return fz.getPreparedInsertQueries() + return fz.getPreparedInsertQueries(getInsertType()) default: panic("Unknown query type") } @@ -122,22 +122,26 @@ func (fz *fuzzer) generateQuery() []string { } } +func getInsertType() string { + return "insert" +} + // generateInsertDMLQuery generates an INSERT query from the parameters for the fuzzer. -func (fz *fuzzer) generateInsertDMLQuery() string { +func (fz *fuzzer) generateInsertDMLQuery(insertType string) string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col, col2) values (%v, %v, %v)", tableName, idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)) + return fmt.Sprintf("%s into %v (id, col, col2) values (%v, %v, %v)", insertType, tableName, idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)) } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, cola, colb) values (%v, %v, %v)", tableName, idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)) + return fmt.Sprintf("%s into %v (id, cola, colb) values (%v, %v, %v)", insertType, tableName, idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)) } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col) values (%v, %v)", tableName, idValue, convertIntValueToString(colValue)) + return fmt.Sprintf("%s into %v (id, col) values (%v, %v)", insertType, tableName, idValue, convertIntValueToString(colValue)) } } @@ -332,7 +336,7 @@ func (fz *fuzzer) getPreparedDeleteQueries() []string { } // getPreparedInsertQueries gets the list of queries to run for executing an INSERT using prepared statements. -func (fz *fuzzer) getPreparedInsertQueries() []string { +func (fz *fuzzer) getPreparedInsertQueries(insertType string) []string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] @@ -340,7 +344,7 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) return []string{ - "prepare stmt_insert from 'insert into fk_t20 (id, col, col2) values (?, ?, ?)'", + fmt.Sprintf("prepare stmt_insert from '%s into fk_t20 (id, col, col2) values (?, ?, ?)'", insertType), fmt.Sprintf("SET @id = %v", idValue), fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), fmt.Sprintf("SET @col2 = %v", convertIntValueToString(col2Value)), @@ -350,7 +354,7 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) return []string{ - fmt.Sprintf("prepare stmt_insert from 'insert into %v (id, cola, colb) values (?, ?, ?)'", tableName), + fmt.Sprintf("prepare stmt_insert from '%s into %v (id, cola, colb) values (?, ?, ?)'", insertType, tableName), fmt.Sprintf("SET @id = %v", idValue), fmt.Sprintf("SET @cola = %v", convertIntValueToString(colaValue)), fmt.Sprintf("SET @colb = %v", convertIntValueToString(colbValue)), @@ -359,7 +363,7 @@ func (fz *fuzzer) getPreparedInsertQueries() []string { } else { colValue := rand.Intn(1 + fz.maxValForCol) return []string{ - fmt.Sprintf("prepare stmt_insert from 'insert into %v (id, col) values (?, ?)'", tableName), + fmt.Sprintf("prepare stmt_insert from '%s into %v (id, col) values (?, ?)'", insertType, tableName), fmt.Sprintf("SET @id = %v", idValue), fmt.Sprintf("SET @col = %v", convertIntValueToString(colValue)), "execute stmt_insert using @id, @col", @@ -407,7 +411,7 @@ func (fz *fuzzer) getPreparedUpdateQueries() []string { func (fz *fuzzer) generateParameterizedQuery() (query string, params []any) { val := rand.Intn(fz.insertShare + fz.updateShare + fz.deleteShare) if val < fz.insertShare { - return fz.generateParameterizedInsertQuery() + return fz.generateParameterizedInsertQuery(getInsertType()) } if val < fz.insertShare+fz.updateShare { return fz.generateParameterizedUpdateQuery() @@ -416,21 +420,21 @@ func (fz *fuzzer) generateParameterizedQuery() (query string, params []any) { } // generateParameterizedInsertQuery generates a parameterized INSERT query for the query format PreparedStatementPacket. -func (fz *fuzzer) generateParameterizedInsertQuery() (query string, params []any) { +func (fz *fuzzer) generateParameterizedInsertQuery(insertType string) (query string, params []any) { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col, col2) values (?, ?, ?)", tableName), []any{idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)} + return fmt.Sprintf("%s into %v (id, col, col2) values (?, ?, ?)", insertType, tableName), []any{idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)} } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, cola, colb) values (?, ?, ?)", tableName), []any{idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)} + return fmt.Sprintf("%s into %v (id, cola, colb) values (?, ?, ?)", insertType, tableName), []any{idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)} } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("insert into %v (id, col) values (?, ?)", tableName), []any{idValue, convertIntValueToString(colValue)} + return fmt.Sprintf("%s into %v (id, col) values (?, ?)", insertType, tableName), []any{idValue, convertIntValueToString(colValue)} } } @@ -555,58 +559,61 @@ func TestFkFuzzTest(t *testing.T) { insertShare int deleteShare int updateShare int - }{ - { - name: "Single Thread - Only Inserts", - concurrency: 1, - timeForTesting: 5 * time.Second, - maxValForCol: 5, - maxValForId: 10, - insertShare: 100, - deleteShare: 0, - updateShare: 0, - }, - { - name: "Single Thread - Balanced Inserts and Deletes", - concurrency: 1, - timeForTesting: 5 * time.Second, - maxValForCol: 5, - maxValForId: 10, - insertShare: 50, - deleteShare: 50, - updateShare: 0, - }, - { - name: "Single Thread - Balanced Inserts and Updates", - concurrency: 1, - timeForTesting: 5 * time.Second, - maxValForCol: 5, - maxValForId: 10, - insertShare: 50, - deleteShare: 0, - updateShare: 50, - }, - { - name: "Single Thread - Balanced Inserts, Updates and Deletes", - concurrency: 1, - timeForTesting: 5 * time.Second, - maxValForCol: 5, - maxValForId: 10, - insertShare: 50, - deleteShare: 50, - updateShare: 50, - }, - { - name: "Multi Thread - Balanced Inserts, Updates and Deletes", - concurrency: 30, - timeForTesting: 5 * time.Second, - maxValForCol: 5, - maxValForId: 30, - insertShare: 50, - deleteShare: 50, - updateShare: 50, - }, - } + }{{ + name: "Single Thread - Only Inserts", + concurrency: 1, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 10, + insertShare: 100, + deleteShare: 0, + updateShare: 0, + }, { + name: "Single Thread - Balanced Inserts and Deletes", + concurrency: 1, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 10, + insertShare: 50, + deleteShare: 50, + updateShare: 0, + }, { + name: "Single Thread - Balanced Inserts and Updates", + concurrency: 1, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 10, + insertShare: 50, + deleteShare: 0, + updateShare: 50, + }, { + name: "Single Thread - Balanced Inserts, Updates and Deletes", + concurrency: 1, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 10, + insertShare: 50, + deleteShare: 50, + updateShare: 50, + }, { + name: "Multi Thread - Only Inserts", + concurrency: 30, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 30, + insertShare: 100, + deleteShare: 0, + updateShare: 0, + }, { + name: "Multi Thread - Balanced Inserts, Updates and Deletes", + concurrency: 30, + timeForTesting: 5 * time.Second, + maxValForCol: 5, + maxValForId: 30, + insertShare: 50, + deleteShare: 50, + updateShare: 50, + }} for _, tt := range testcases { for _, testSharded := range []bool{false, true} { @@ -632,7 +639,16 @@ func TestFkFuzzTest(t *testing.T) { fz.start(t, testSharded) // Wait for the timeForTesting so that the threads continue to run. - time.Sleep(tt.timeForTesting) + totalTime := time.After(tt.timeForTesting) + done := false + for !done { + select { + case <-totalTime: + done = true + case <-time.After(10 * time.Millisecond): + validateReplication(t) + } + } fz.stop() @@ -654,3 +670,15 @@ func TestFkFuzzTest(t *testing.T) { } } } + +func validateReplication(t *testing.T) { + for _, keyspace := range clusterInstance.Keyspaces { + for _, shard := range keyspace.Shards { + for _, vttablet := range shard.Vttablets { + if vttablet.Type != "primary" { + checkReplicationHealthy(t, vttablet) + } + } + } + } +} diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index afd04679066..a05f0de7ac1 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -986,3 +986,164 @@ func TestCyclicFks(t *testing.T) { _, err := utils.ExecAllowError(t, mcmp.VtConn, "insert into fk_t10(id, col) values (1, 1)") require.ErrorContains(t, err, "VT09019: uks has cyclic foreign keys") } + +func TestReplace(t *testing.T) { + t.Skip("replace engine marked for failure, hence skipping this.") + // Wait for schema-tracking to be complete. + waitForSchemaTrackingForFkTables(t) + // Remove all the foreign key constraints for all the replicas. + // We can then verify that the replica, and the primary have the same data, to ensure + // that none of the queries ever lead to cascades/updates on MySQL level. + for _, ks := range []string{shardedKs, unshardedKs} { + replicas := getReplicaTablets(ks) + for _, replica := range replicas { + removeAllForeignKeyConstraints(t, replica, ks) + } + } + + mcmp1, _ := start(t) + // defer closer1() + _ = utils.Exec(t, mcmp1.VtConn, "use `uks`") + + mcmp2, _ := start(t) + // defer closer2() + _ = utils.Exec(t, mcmp2.VtConn, "use `uks`") + + _ = utils.Exec(t, mcmp1.VtConn, "insert into fk_t2 values(1,5), (2,5)") + + done := false + go func() { + number := 1 + for !done { + query := fmt.Sprintf("replace /* g1q1 - %d */ into fk_t2 values(5,5)", number) + _, _ = utils.ExecAllowError(t, mcmp1.VtConn, query) + number++ + } + }() + + go func() { + number := 1 + for !done { + query := fmt.Sprintf("replace /* q1 - %d */ into fk_t3 values(3,5)", number) + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, query) + + query = fmt.Sprintf("replace /* q2 - %d */ into fk_t3 values(4,5)", number) + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, query) + number++ + } + }() + + totalTime := time.After(1 * time.Minute) + for !done { + select { + case <-totalTime: + done = true + case <-time.After(10 * time.Millisecond): + validateReplication(t) + } + } +} + +func TestReplaceExplicit(t *testing.T) { + t.Skip("explicit delete-insert in transaction fails, hence skipping") + // Wait for schema-tracking to be complete. + waitForSchemaTrackingForFkTables(t) + // Remove all the foreign key constraints for all the replicas. + // We can then verify that the replica, and the primary have the same data, to ensure + // that none of the queries ever lead to cascades/updates on MySQL level. + for _, ks := range []string{shardedKs, unshardedKs} { + replicas := getReplicaTablets(ks) + for _, replica := range replicas { + removeAllForeignKeyConstraints(t, replica, ks) + } + } + + mcmp1, _ := start(t) + // defer closer1() + _ = utils.Exec(t, mcmp1.VtConn, "use `uks`") + + mcmp2, _ := start(t) + // defer closer2() + _ = utils.Exec(t, mcmp2.VtConn, "use `uks`") + + _ = utils.Exec(t, mcmp1.VtConn, "insert into fk_t2 values(1,5), (2,5)") + + done := false + go func() { + number := 0 + for !done { + number++ + _, _ = utils.ExecAllowError(t, mcmp1.VtConn, "begin") + query := fmt.Sprintf("delete /* g1q1 - %d */ from fk_t2 where id = 5", number) + _, err := utils.ExecAllowError(t, mcmp1.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp1.VtConn, "rollback") + continue + } + query = fmt.Sprintf("insert /* g1q1 - %d */ into fk_t2 values(5,5)", number) + _, err = utils.ExecAllowError(t, mcmp1.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp1.VtConn, "rollback") + continue + } + _, _ = utils.ExecAllowError(t, mcmp1.VtConn, "commit") + } + }() + + go func() { + number := 0 + for !done { + number++ + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "begin") + query := fmt.Sprintf("delete /* g1q1 - %d */ from fk_t3 where id = 3 or col = 5", number) + _, err := utils.ExecAllowError(t, mcmp2.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "rollback") + } else { + query = fmt.Sprintf("insert /* g1q1 - %d */ into fk_t3 values(3,5)", number) + _, err = utils.ExecAllowError(t, mcmp2.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "rollback") + } else { + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "commit") + } + } + + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "begin") + query = fmt.Sprintf("delete /* g1q1 - %d */ from fk_t3 where id = 4 or col = 5", number) + _, err = utils.ExecAllowError(t, mcmp2.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "rollback") + continue + } + query = fmt.Sprintf("insert /* g1q1 - %d */ into fk_t3 values(4,5)", number) + _, err = utils.ExecAllowError(t, mcmp2.VtConn, query) + if err != nil { + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "rollback") + continue + } + _, _ = utils.ExecAllowError(t, mcmp2.VtConn, "commit") + } + }() + + totalTime := time.After(1 * time.Minute) + for !done { + select { + case <-totalTime: + done = true + case <-time.After(10 * time.Millisecond): + validateReplication(t) + } + } +} + +// TestReplaceWithFK tests that replace into work as expected when foreign key management is enabled in Vitess. +func TestReplaceWithFK(t *testing.T) { + mcmp, closer := start(t) + conn := mcmp.VtConn + defer closer() + + // replace some data. + _, err := utils.ExecAllowError(t, conn, `replace into t1(id, col) values (1, 1)`) + require.ErrorContains(t, err, "VT12001: unsupported: REPLACE INTO with sharded keyspace (errno 1235) (sqlstate 42000)") +} diff --git a/go/test/endtoend/vtgate/foreignkey/main_test.go b/go/test/endtoend/vtgate/foreignkey/main_test.go index dae78ae93a1..3ce449f893f 100644 --- a/go/test/endtoend/vtgate/foreignkey/main_test.go +++ b/go/test/endtoend/vtgate/foreignkey/main_test.go @@ -38,11 +38,9 @@ var ( shardedKs = "ks" unshardedKs = "uks" Cell = "test" - //go:embed sharded_schema.sql - shardedSchemaSQL string - //go:embed unsharded_schema.sql - unshardedSchemaSQL string + //go:embed schema.sql + schemaSQL string //go:embed sharded_vschema.json shardedVSchema string @@ -107,7 +105,7 @@ func TestMain(m *testing.M) { // Start keyspace sKs := &cluster.Keyspace{ Name: shardedKs, - SchemaSQL: shardedSchemaSQL, + SchemaSQL: schemaSQL, VSchema: shardedVSchema, } @@ -118,7 +116,7 @@ func TestMain(m *testing.M) { uKs := &cluster.Keyspace{ Name: unshardedKs, - SchemaSQL: unshardedSchemaSQL, + SchemaSQL: schemaSQL, VSchema: unshardedVSchema, } err = clusterInstance.StartUnshardedKeyspace(*uKs, 1, false) @@ -142,7 +140,7 @@ func TestMain(m *testing.M) { } vtgateGrpcAddress = fmt.Sprintf("%s:%d", clusterInstance.Hostname, clusterInstance.VtgateGrpcPort) - connParams, closer, err := utils.NewMySQL(clusterInstance, shardedKs, shardedSchemaSQL) + connParams, closer, err := utils.NewMySQL(clusterInstance, shardedKs, schemaSQL) if err != nil { fmt.Println(err) return 1 diff --git a/go/test/endtoend/vtgate/foreignkey/sharded_schema.sql b/go/test/endtoend/vtgate/foreignkey/schema.sql similarity index 95% rename from go/test/endtoend/vtgate/foreignkey/sharded_schema.sql rename to go/test/endtoend/vtgate/foreignkey/schema.sql index c1f511350f2..fd8bec5dc4a 100644 --- a/go/test/endtoend/vtgate/foreignkey/sharded_schema.sql +++ b/go/test/endtoend/vtgate/foreignkey/schema.sql @@ -73,6 +73,31 @@ create table t6 foreign key (sk, col1) references t5 (sk, col1) on delete restrict on update restrict ) Engine = InnoDB; +create table u_t1 +( + id bigint, + col1 bigint, + index(col1), + primary key (id) +) Engine = InnoDB; + +create table u_t2 +( + id bigint, + col2 bigint, + primary key (id), + foreign key (col2) references u_t1 (col1) on delete set null on update set null +) Engine = InnoDB; + +create table u_t3 +( + id bigint, + col3 bigint, + primary key (id), + foreign key (col3) references u_t1 (col1) on delete cascade on update cascade +) Engine = InnoDB; + + /* * fk_t1 * │ @@ -122,7 +147,7 @@ create table fk_t3 id bigint, col varchar(10), primary key (id), - index(col), + unique index(col), foreign key (col) references fk_t2(col) on delete set null on update set null ) Engine = InnoDB; @@ -184,7 +209,7 @@ create table fk_t10 id bigint, col varchar(10), primary key (id), - index(col) + unique index(col) ) Engine = InnoDB; create table fk_t11 @@ -243,7 +268,7 @@ create table fk_t15 id bigint, col varchar(10), primary key (id), - index(col) + unique index(col) ) Engine = InnoDB; create table fk_t16 @@ -251,7 +276,7 @@ create table fk_t16 id bigint, col varchar(10), primary key (id), - index(col), + unique index(col), foreign key (col) references fk_t15(col) on delete cascade on update cascade ) Engine = InnoDB; @@ -296,6 +321,7 @@ create table fk_t20 foreign key (col2) references fk_t20(col) on delete restrict on update restrict ) Engine = InnoDB; + /* * fk_multicol_t1 * │ @@ -328,16 +354,17 @@ create table fk_multicol_t1 colb varchar(10), cola varchar(10), primary key (id), - index(cola, colb) + index(cola, colb), + unique index(colb) ) Engine = InnoDB; create table fk_multicol_t2 ( id bigint, - colb varchar(10), + colb varchar(10) default 'xyz', cola varchar(10), primary key (id), - index(cola, colb), + unique index(cola, colb), foreign key (cola, colb) references fk_multicol_t1(cola, colb) on delete restrict on update restrict ) Engine = InnoDB; @@ -355,9 +382,10 @@ create table fk_multicol_t4 ( id bigint, colb varchar(10), - cola varchar(10), + cola varchar(10) default 'abcd', primary key (id), index(cola, colb), + unique index(cola), foreign key (cola, colb) references fk_multicol_t3(cola, colb) on delete set null on update set null ) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/foreignkey/unsharded_schema.sql b/go/test/endtoend/vtgate/foreignkey/unsharded_schema.sql deleted file mode 100644 index 3b4496d47fb..00000000000 --- a/go/test/endtoend/vtgate/foreignkey/unsharded_schema.sql +++ /dev/null @@ -1,472 +0,0 @@ -create table u_t1 -( - id bigint, - col1 bigint, - index(col1), - primary key (id) -) Engine = InnoDB; - -create table u_t2 -( - id bigint, - col2 bigint, - primary key (id), - foreign key (col2) references u_t1 (col1) on delete set null on update set null -) Engine = InnoDB; - -create table u_t3 -( - id bigint, - col3 bigint, - primary key (id), - foreign key (col3) references u_t1 (col1) on delete cascade on update cascade -) Engine = InnoDB; - - -/* - * fk_t1 - * │ - * │ On Delete Restrict - * │ On Update Restrict - * ▼ - * ┌────────────────fk_t2────────────────┐ - * │ │ - * │On Delete Set Null │ On Delete Set Null - * │On Update Set Null │ On Update Set Null - * ▼ ▼ - * fk_t7 fk_t3───────────────────┐ - * │ │ - * │ │ On Delete Set Null - * On Delete Set Null │ │ On Update Set Null - * On Update Set Null │ │ - * ▼ ▼ - * fk_t4 fk_t6 - * │ - * │ - * On Delete Restrict │ - * On Update Restrict │ - * │ - * ▼ - * fk_t5 - */ - -create table fk_t1 -( - id bigint, - col varchar(10), - primary key (id), - index(col) -) Engine = InnoDB; - -create table fk_t2 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t1(col) on delete restrict on update restrict -) Engine = InnoDB; - -create table fk_t3 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t2(col) on delete set null on update set null -) Engine = InnoDB; - -create table fk_t4 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t3(col) on delete set null on update set null -) Engine = InnoDB; - -create table fk_t5 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t4(col) on delete restrict on update restrict -) Engine = InnoDB; - -create table fk_t6 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t3(col) on delete set null on update set null -) Engine = InnoDB; - -create table fk_t7 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t2(col) on delete set null on update set null -) Engine = InnoDB; - -/* - * fk_t10 - * │ - * On Delete Cascade │ - * On Update Cascade │ - * │ - * ▼ - * fk_t11──────────────────┐ - * │ │ - * │ │ On Delete Restrict - * On Delete Cascade │ │ On Update Restrict - * On Update Cascade │ │ - * │ │ - * ▼ ▼ - * fk_t12 fk_t13 - */ - -create table fk_t10 -( - id bigint, - col varchar(10), - primary key (id), - index(col) -) Engine = InnoDB; - -create table fk_t11 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t10(col) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_t12 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t11(col) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_t13 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t11(col) on delete restrict on update restrict -) Engine = InnoDB; - -/* - * fk_t15 - * │ - * │ - * On Delete Cascade │ - * On Update Cascade │ - * │ - * ▼ - * fk_t16 - * │ - * On Delete Set Null │ - * On Update Set Null │ - * │ - * ▼ - * fk_t17──────────────────┐ - * │ │ - * │ │ On Delete Set Null - * On Delete Cascade │ │ On Update Set Null - * On Update Cascade │ │ - * │ │ - * ▼ ▼ - * fk_t18 fk_t19 - */ - -create table fk_t15 -( - id bigint, - col varchar(10), - primary key (id), - index(col) -) Engine = InnoDB; - -create table fk_t16 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t15(col) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_t17 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t16(col) on delete set null on update set null -) Engine = InnoDB; - -create table fk_t18 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t17(col) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_t19 -( - id bigint, - col varchar(10), - primary key (id), - index(col), - foreign key (col) references fk_t17(col) on delete set null on update set null -) Engine = InnoDB; - -/* - Self referenced foreign key from col2 to col in fk_t20 -*/ - -create table fk_t20 -( - id bigint, - col varchar(10), - col2 varchar(10), - primary key (id), - index(col), - foreign key (col2) references fk_t20(col) on delete restrict on update restrict -) Engine = InnoDB; - - -/* - * fk_multicol_t1 - * │ - * │ On Delete Restrict - * │ On Update Restrict - * ▼ - * ┌────────fk_multicol_t2───────────────┐ - * │ │ - * │On Delete Set Null │ On Delete Set Null - * │On Update Set Null │ On Update Set Null - * ▼ ▼ - * fk_multicol_t7 fk_multicol_t3───────────────────┐ - * │ │ - * │ │ On Delete Set Null - * On Delete Set Null │ │ On Update Set Null - * On Update Set Null │ │ - * ▼ ▼ - * fk_multicol_t4 fk_multicol_t6 - * │ - * │ - * On Delete Restrict │ - * On Update Restrict │ - * │ - * ▼ - * fk_multicol_t5 - */ -create table fk_multicol_t1 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb) -) Engine = InnoDB; - -create table fk_multicol_t2 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t1(cola, colb) on delete restrict on update restrict -) Engine = InnoDB; - -create table fk_multicol_t3 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t2(cola, colb) on delete set null on update set null -) Engine = InnoDB; - -create table fk_multicol_t4 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t3(cola, colb) on delete set null on update set null -) Engine = InnoDB; - -create table fk_multicol_t5 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t4(cola, colb) on delete restrict on update restrict -) Engine = InnoDB; - -create table fk_multicol_t6 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t3(cola, colb) on delete set null on update set null -) Engine = InnoDB; - -create table fk_multicol_t7 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t2(cola, colb) on delete set null on update set null -) Engine = InnoDB; - -/* - * fk_multicol_t10 - * │ - * On Delete Cascade │ - * On Update Cascade │ - * │ - * ▼ - * fk_multicol_t11──────────────────┐ - * │ │ - * │ │ On Delete Restrict - * On Delete Cascade │ │ On Update Restrict - * On Update Cascade │ │ - * │ │ - * ▼ ▼ - * fk_multicol_t12 fk_multicol_t13 - */ - -create table fk_multicol_t10 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb) -) Engine = InnoDB; - -create table fk_multicol_t11 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t10(cola, colb) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_multicol_t12 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t11(cola, colb) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_multicol_t13 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t11(cola, colb) on delete restrict on update restrict -) Engine = InnoDB; - -/* - * fk_multicol_t15 - * │ - * │ - * On Delete Cascade │ - * On Update Cascade │ - * │ - * ▼ - * fk_multicol_t16 - * │ - * On Delete Set Null │ - * On Update Set Null │ - * │ - * ▼ - * fk_multicol_t17──────────────────┐ - * │ │ - * │ │ On Delete Set Null - * On Delete Cascade │ │ On Update Set Null - * On Update Cascade │ │ - * │ │ - * ▼ ▼ - * fk_multicol_t18 fk_multicol_t19 - */ - -create table fk_multicol_t15 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb) -) Engine = InnoDB; - -create table fk_multicol_t16 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t15(cola, colb) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_multicol_t17 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t16(cola, colb) on delete set null on update set null -) Engine = InnoDB; - -create table fk_multicol_t18 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t17(cola, colb) on delete cascade on update cascade -) Engine = InnoDB; - -create table fk_multicol_t19 -( - id bigint, - colb varchar(10), - cola varchar(10), - primary key (id), - index(cola, colb), - foreign key (cola, colb) references fk_multicol_t17(cola, colb) on delete set null on update set null -) Engine = InnoDB; diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index b45f7010c56..fe185d63fcd 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -603,6 +603,7 @@ type Column struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Type query.Type `protobuf:"varint,2,opt,name=type,proto3,enum=query.Type" json:"type,omitempty"` Invisible bool `protobuf:"varint,3,opt,name=invisible,proto3" json:"invisible,omitempty"` + Default string `protobuf:"bytes,4,opt,name=default,proto3" json:"default,omitempty"` } func (x *Column) Reset() { @@ -658,6 +659,13 @@ func (x *Column) GetInvisible() bool { return false } +func (x *Column) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + // SrvVSchema is the roll-up of all the Keyspace schema for a cell. type SrvVSchema struct { state protoimpl.MessageState @@ -920,46 +928,47 @@ var file_vschema_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x5b, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x75, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x73, - 0x69, 0x62, 0x6c, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x12, 0x40, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 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, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x4f, 0x0a, - 0x0e, 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, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, - 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, - 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x42, 0x26, 0x5a, 0x24, 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, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0xa7, + 0x02, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x40, 0x0a, + 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, + 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x18, 0x02, 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, 0x4a, 0x0a, 0x13, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x4f, 0x0a, 0x0e, 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, 0x27, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, + 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6e, + 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x42, 0x26, + 0x5a, 0x24, 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, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/vt/proto/vschema/vschema_vtproto.pb.go b/go/vt/proto/vschema/vschema_vtproto.pb.go index 94527ef14ae..2235bfea496 100644 --- a/go/vt/proto/vschema/vschema_vtproto.pb.go +++ b/go/vt/proto/vschema/vschema_vtproto.pb.go @@ -213,6 +213,7 @@ func (m *Column) CloneVT() *Column { Name: m.Name, Type: m.Type, Invisible: m.Invisible, + Default: m.Default, } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -787,6 +788,13 @@ func (m *Column) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Default) > 0 { + i -= len(m.Default) + copy(dAtA[i:], m.Default) + i = encodeVarint(dAtA, i, uint64(len(m.Default))) + i-- + dAtA[i] = 0x22 + } if m.Invisible { i-- if m.Invisible { @@ -1203,6 +1211,10 @@ func (m *Column) SizeVT() (n int) { if m.Invisible { n += 2 } + l = len(m.Default) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } n += len(m.unknownFields) return n } @@ -2725,6 +2737,38 @@ func (m *Column) UnmarshalVT(dAtA []byte) error { } } m.Invisible = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Default", 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.Default = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vterrors/code.go b/go/vt/vterrors/code.go index 6bc317db4ed..80e1b0edd34 100644 --- a/go/vt/vterrors/code.go +++ b/go/vt/vterrors/code.go @@ -36,7 +36,7 @@ var ( VT03011 = errorWithoutState("VT03011", vtrpcpb.Code_INVALID_ARGUMENT, "invalid value type: %v", "The given value type is not accepted.") VT03012 = errorWithoutState("VT03012", vtrpcpb.Code_INVALID_ARGUMENT, "invalid syntax: %s", "The syntax is invalid. Please refer to the MySQL documentation for the proper syntax.") VT03013 = errorWithState("VT03013", vtrpcpb.Code_INVALID_ARGUMENT, NonUniqTable, "not unique table/alias: '%s'", "This table or alias name is already use. Please use another one that is unique.") - VT03014 = errorWithState("VT03014", vtrpcpb.Code_INVALID_ARGUMENT, BadFieldError, "unknown column '%d' in '%s'", "The given column is unknown.") + VT03014 = errorWithState("VT03014", vtrpcpb.Code_INVALID_ARGUMENT, BadFieldError, "unknown column '%s' in '%s'", "The given column is unknown.") VT03015 = errorWithoutState("VT03015", vtrpcpb.Code_INVALID_ARGUMENT, "column has duplicate set values: '%v'", "Cannot assign multiple values to a column in an update statement.") VT03016 = errorWithoutState("VT03016", vtrpcpb.Code_INVALID_ARGUMENT, "unknown vindex column: '%s'", "The given column is unknown in the vindex table.") VT03017 = errorWithState("VT03017", vtrpcpb.Code_INVALID_ARGUMENT, SyntaxError, "where clause can only be of the type 'pos > '", "This vstream where clause can only be a greater than filter.") @@ -49,6 +49,7 @@ var ( VT03024 = errorWithoutState("VT03024", vtrpcpb.Code_INVALID_ARGUMENT, "'%s' user defined variable does not exists", "The query cannot be prepared using the user defined variable as it does not exists for this session.") VT03025 = errorWithState("VT03025", vtrpcpb.Code_INVALID_ARGUMENT, WrongArguments, "Incorrect arguments to %s", "The execute statement have wrong number of arguments") VT03026 = errorWithoutState("VT03024", vtrpcpb.Code_INVALID_ARGUMENT, "'%s' bind variable does not exists", "The query cannot be executed as missing the bind variable.") + VT03027 = errorWithState("VT03027", vtrpcpb.Code_INVALID_ARGUMENT, BadNullError, "Column '%s' cannot be null", "The column cannot have null value.") VT05001 = errorWithState("VT05001", vtrpcpb.Code_NOT_FOUND, DbDropExists, "cannot drop database '%s'; database does not exists", "The given database does not exist; Vitess cannot drop it.") VT05002 = errorWithState("VT05002", vtrpcpb.Code_NOT_FOUND, BadDb, "cannot alter database '%s'; unknown database", "The given database does not exist; Vitess cannot alter it.") @@ -83,6 +84,7 @@ var ( VT09019 = errorWithoutState("VT09019", vtrpcpb.Code_FAILED_PRECONDITION, "%s has cyclic foreign keys", "Vitess doesn't support cyclic foreign keys.") VT10001 = errorWithoutState("VT10001", vtrpcpb.Code_ABORTED, "foreign key constraints are not allowed", "Foreign key constraints are not allowed, see https://vitess.io/blog/2021-06-15-online-ddl-why-no-fk/.") + VT10002 = errorWithoutState("VT10002", vtrpcpb.Code_ABORTED, "'replace into' with foreign key constraints are not allowed", "Foreign key constraints sometimes are not written in binary logs and will cause issue with vreplication workflows like online-ddl.") VT12001 = errorWithoutState("VT12001", vtrpcpb.Code_UNIMPLEMENTED, "unsupported: %s", "This statement is unsupported by Vitess. Please rewrite your query to use supported syntax.") VT12002 = errorWithoutState("VT12002", vtrpcpb.Code_UNIMPLEMENTED, "unsupported: cross-shard foreign keys", "Vitess does not support cross shard foreign keys.") @@ -124,6 +126,7 @@ var ( VT03024, VT03025, VT03026, + VT03027, VT05001, VT05002, VT05003, @@ -152,6 +155,7 @@ var ( VT09017, VT09018, VT10001, + VT10002, VT12001, VT12002, VT13001, diff --git a/go/vt/vterrors/state.go b/go/vt/vterrors/state.go index 5e3dcf22dfb..5d286b0c991 100644 --- a/go/vt/vterrors/state.go +++ b/go/vt/vterrors/state.go @@ -47,6 +47,7 @@ const ( WrongValueCountOnRow WrongValue WrongArguments + BadNullError // failed precondition NoDB diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index d878650c63e..6121ad5f675 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -145,7 +145,7 @@ func (cached *DML) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(128) + size += int64(144) } // field Query string size += hack.RuntimeAllocSize(int64(len(cached.Query))) @@ -1007,6 +1007,25 @@ func (cached *Send) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Query))) return size } +func (cached *Sequential) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + // field Sources []vitess.io/vitess/go/vt/vtgate/engine.Primitive + { + size += hack.RuntimeAllocSize(int64(cap(cached.Sources)) * int64(16)) + for _, elem := range cached.Sources { + if cc, ok := elem.(cachedObject); ok { + size += cc.CachedSize(true) + } + } + } + return size +} func (cached *SessionPrimitive) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go index 5f0f2408993..adcc11174fd 100644 --- a/go/vt/vtgate/engine/delete.go +++ b/go/vt/vtgate/engine/delete.go @@ -130,6 +130,7 @@ func (del *Delete) description() PrimitiveDescription { "OwnedVindexQuery": del.OwnedVindexQuery, "MultiShardAutocommit": del.MultiShardAutocommit, "QueryTimeout": del.QueryTimeout, + "NoAutoCommit": del.PreventAutoCommit, } addFieldsIfNotEmpty(del.DML, other) diff --git a/go/vt/vtgate/engine/dml.go b/go/vt/vtgate/engine/dml.go index 51177f41e08..a7b1712bacd 100644 --- a/go/vt/vtgate/engine/dml.go +++ b/go/vt/vtgate/engine/dml.go @@ -61,6 +61,8 @@ type DML struct { // QueryTimeout contains the optional timeout (in milliseconds) to apply to this query QueryTimeout int + PreventAutoCommit bool + // RoutingParameters parameters required for query routing. *RoutingParameters @@ -73,7 +75,7 @@ func NewDML() *DML { } func (dml *DML) execUnsharded(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard) (*sqltypes.Result, error) { - return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, true /* canAutocommit */) + return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, !dml.PreventAutoCommit /* canAutocommit */) } func (dml *DML) execMultiDestination(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(context.Context, VCursor, map[string]*querypb.BindVariable, []*srvtopo.ResolvedShard) error) (*sqltypes.Result, error) { diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index fc65fbfbff9..e0c90d091a0 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -102,6 +102,8 @@ type ( // This will avoid locking by the select table. ForceNonStreaming bool + PreventAutoCommit bool + // Insert needs tx handling txNeeded } @@ -958,6 +960,7 @@ func (ins *Insert) description() PrimitiveDescription { "QueryTimeout": ins.QueryTimeout, "InsertIgnore": ins.Ignore, "InputAsNonStreaming": ins.ForceNonStreaming, + "NoAutoCommit": ins.PreventAutoCommit, } if len(ins.VindexValues) > 0 { @@ -1041,7 +1044,7 @@ func (ins *Insert) executeUnshardedTableQuery(ctx context.Context, vcursor VCurs if err != nil { return 0, nil, err } - qr, err := execShard(ctx, ins, vcursor, query, bindVars, rss[0], true, true /* canAutocommit */) + qr, err := execShard(ctx, ins, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */) if err != nil { return 0, nil, err } diff --git a/go/vt/vtgate/engine/sequential.go b/go/vt/vtgate/engine/sequential.go new file mode 100644 index 00000000000..d038df4afbf --- /dev/null +++ b/go/vt/vtgate/engine/sequential.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" +) + +// Sequential Primitive is used to execute DML statements in a fixed order. +// Any failure, stops the execution and returns. +type Sequential struct { + Sources []Primitive + + txNeeded +} + +var _ Primitive = (*Sequential)(nil) + +// NewSequential creates a Sequential primitive. +func NewSequential(Sources []Primitive) *Sequential { + return &Sequential{ + Sources: Sources, + } +} + +// RouteType returns a description of the query routing type used by the primitive +func (s *Sequential) RouteType() string { + return "Sequential" +} + +// GetKeyspaceName specifies the Keyspace that this primitive routes to +func (s *Sequential) GetKeyspaceName() string { + res := s.Sources[0].GetKeyspaceName() + for i := 1; i < len(s.Sources); i++ { + res = formatTwoOptionsNicely(res, s.Sources[i].GetKeyspaceName()) + } + return res +} + +// GetTableName specifies the table that this primitive routes to. +func (s *Sequential) GetTableName() string { + res := s.Sources[0].GetTableName() + for i := 1; i < len(s.Sources); i++ { + res = formatTwoOptionsNicely(res, s.Sources[i].GetTableName()) + } + return res +} + +// TryExecute performs a non-streaming exec. +func (s *Sequential) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantFields bool) (*sqltypes.Result, error) { + return nil, vterrors.VT10002() +} + +// TryStreamExecute performs a streaming exec. +func (s *Sequential) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantFields bool, callback func(*sqltypes.Result) error) error { + return vterrors.VT10002() +} + +// GetFields fetches the field info. +func (s *Sequential) GetFields(context.Context, VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unreachable code for Sequential engine") +} + +// Inputs returns the input primitives for this +func (s *Sequential) Inputs() ([]Primitive, []map[string]any) { + return s.Sources, nil +} + +func (s *Sequential) description() PrimitiveDescription { + return PrimitiveDescription{OperatorType: s.RouteType()} +} diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go index 3db7972fba5..913cacaaba8 100644 --- a/go/vt/vtgate/engine/update.go +++ b/go/vt/vtgate/engine/update.go @@ -204,6 +204,7 @@ func (upd *Update) description() PrimitiveDescription { "OwnedVindexQuery": upd.OwnedVindexQuery, "MultiShardAutocommit": upd.MultiShardAutocommit, "QueryTimeout": upd.QueryTimeout, + "NoAutoCommit": upd.PreventAutoCommit, } addFieldsIfNotEmpty(upd.DML, other) diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index c187cd7efdc..39144fc858d 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -19,7 +19,6 @@ package planbuilder import ( querypb "vitess.io/vitess/go/vt/proto/query" "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/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -62,7 +61,7 @@ func gen4InsertStmtPlanner(version querypb.ExecuteOptions_PlannerVersion, insStm return nil, err } - if err = errOutIfPlanCannotBeConstructed(ctx, tblInfo.GetVindexTable(), insStmt, ctx.SemTable.ForeignKeysPresent()); err != nil { + if err = errOutIfPlanCannotBeConstructed(ctx, tblInfo.GetVindexTable()); err != nil { return nil, err } @@ -84,17 +83,11 @@ func gen4InsertStmtPlanner(version querypb.ExecuteOptions_PlannerVersion, insStm return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil } -func errOutIfPlanCannotBeConstructed(ctx *plancontext.PlanningContext, vTbl *vindexes.Table, insStmt *sqlparser.Insert, fkPlanNeeded bool) error { - if vTbl.Keyspace.Sharded && ctx.SemTable.NotUnshardedErr != nil { - return ctx.SemTable.NotUnshardedErr - } - if insStmt.Action != sqlparser.ReplaceAct { +func errOutIfPlanCannotBeConstructed(ctx *plancontext.PlanningContext, vTbl *vindexes.Table) error { + if !vTbl.Keyspace.Sharded { return nil } - if fkPlanNeeded { - return vterrors.VT12001("REPLACE INTO with foreign keys") - } - return nil + return ctx.SemTable.NotUnshardedErr } func insertUnshardedShortcut(stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 59200e92e2a..5f59a96000a 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -68,11 +68,30 @@ func transformToLogicalPlan(ctx *plancontext.PlanningContext, op ops.Operator) ( return transformFkVerify(ctx, op) case *operators.InsertSelection: return transformInsertionSelection(ctx, op) + case *operators.Sequential: + return transformSequential(ctx, op) } return nil, vterrors.VT13001(fmt.Sprintf("unknown type encountered: %T (transformToLogicalPlan)", op)) } +func transformSequential(ctx *plancontext.PlanningContext, op *operators.Sequential) (logicalPlan, error) { + var lps []logicalPlan + for _, source := range op.Sources { + lp, err := transformToLogicalPlan(ctx, source) + if err != nil { + return nil, err + } + if ins, ok := lp.(*insert); ok { + ins.eInsert.PreventAutoCommit = true + } + lps = append(lps, lp) + } + return &sequential{ + sources: lps, + }, nil +} + func transformInsertionSelection(ctx *plancontext.PlanningContext, op *operators.InsertSelection) (logicalPlan, error) { rb, isRoute := op.Insert.(*operators.Route) if !isRoute { diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index a48e53c18b1..e3f0748b78b 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -111,12 +111,228 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I return nil, err } - vindexTable, routing, err := buildVindexTableForDML(ctx, tableInfo, qt, "insert") + vTbl, routing, err := buildVindexTableForDML(ctx, tableInfo, qt, "insert") if err != nil { return nil, err } - insOp, err := createInsertOperator(ctx, ins, vindexTable, routing) + deleteBeforeInsert := false + if ins.Action == sqlparser.ReplaceAct && + (ctx.SemTable.ForeignKeysPresent() || vTbl.Keyspace.Sharded) && + (len(vTbl.PrimaryKey) > 0 || len(vTbl.UniqueKeys) > 0) { + // this needs a delete before insert as there can be row clash which needs to be deleted first. + ins.Action = sqlparser.InsertAct + deleteBeforeInsert = true + } + + insOp, err := checkAndCreateInsertOperator(ctx, ins, vTbl, routing) + if err != nil { + return nil, err + } + + if !deleteBeforeInsert { + return insOp, nil + } + + rows, isRows := ins.Rows.(sqlparser.Values) + if !isRows { + return nil, vterrors.VT12001("REPLACE INTO using select statement") + } + + pkCompExpr := pkCompExpression(vTbl, ins, rows) + uniqKeyCompExprs, err := uniqKeyCompExpressions(vTbl, ins, rows) + if err != nil { + return nil, err + } + + whereExpr := getWhereCondExpr(append(uniqKeyCompExprs, pkCompExpr)) + + delStmt := &sqlparser.Delete{ + TableExprs: sqlparser.TableExprs{sqlparser.CloneRefOfAliasedTableExpr(ins.Table)}, + Where: sqlparser.NewWhere(sqlparser.WhereClause, whereExpr), + } + delOp, err := createOpFromStmt(ctx, delStmt, false, "") + if err != nil { + return nil, err + } + return &Sequential{Sources: []ops.Operator{delOp, insOp}}, nil +} + +func getWhereCondExpr(compExprs []*sqlparser.ComparisonExpr) sqlparser.Expr { + var outputExpr sqlparser.Expr + for _, expr := range compExprs { + if expr == nil { + continue + } + if outputExpr == nil { + outputExpr = expr + continue + } + outputExpr = &sqlparser.OrExpr{ + Left: outputExpr, + Right: expr, + } + } + return outputExpr +} + +func pkCompExpression(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparser.Values) *sqlparser.ComparisonExpr { + if len(vTbl.PrimaryKey) == 0 { + return nil + } + type pComp struct { + idx int + def sqlparser.Expr + } + var pIndexes []pComp + var pColTuple sqlparser.ValTuple + for _, pCol := range vTbl.PrimaryKey { + var def sqlparser.Expr + idx := ins.Columns.FindColumn(pCol) + if idx == -1 { + def = findDefault(vTbl, pCol) + if def == nil { + // If default value is empty, nothing to compare as it will always be false. + return nil + } + } + pIndexes = append(pIndexes, pComp{idx, def}) + pColTuple = append(pColTuple, sqlparser.NewColName(pCol.String())) + } + + var pValTuple sqlparser.ValTuple + for _, row := range rows { + var rowTuple sqlparser.ValTuple + for _, pIdx := range pIndexes { + if pIdx.idx == -1 { + rowTuple = append(rowTuple, pIdx.def) + } else { + rowTuple = append(rowTuple, row[pIdx.idx]) + } + } + pValTuple = append(pValTuple, rowTuple) + } + return sqlparser.NewComparisonExpr(sqlparser.InOp, pColTuple, pValTuple, nil) +} + +func findDefault(vTbl *vindexes.Table, pCol sqlparser.IdentifierCI) sqlparser.Expr { + for _, column := range vTbl.Columns { + if column.Name.Equal(pCol) { + return column.Default + } + } + panic(vterrors.VT03014(pCol.String(), vTbl.Name.String())) +} + +type uComp struct { + idx int + def sqlparser.Expr +} + +func uniqKeyCompExpressions(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparser.Values) (comps []*sqlparser.ComparisonExpr, err error) { + noOfUniqKeys := len(vTbl.UniqueKeys) + if noOfUniqKeys == 0 { + return nil, nil + } + + type uIdx struct { + Indexes [][]uComp + uniqKey sqlparser.Exprs + } + + allIndexes := make([]uIdx, 0, noOfUniqKeys) + allColTuples := make([]sqlparser.ValTuple, 0, noOfUniqKeys) + for _, uniqKey := range vTbl.UniqueKeys { + var uIndexes [][]uComp + var uColTuple sqlparser.ValTuple + skipKey := false + for _, expr := range uniqKey { + var offsets []uComp + offsets, skipKey, err = createUniqueKeyComp(ins, expr, vTbl) + if err != nil { + return nil, err + } + if skipKey { + break + } + uIndexes = append(uIndexes, offsets) + uColTuple = append(uColTuple, expr) + } + if skipKey { + continue + } + allIndexes = append(allIndexes, uIdx{uIndexes, uniqKey}) + allColTuples = append(allColTuples, uColTuple) + } + + allValTuples := make([]sqlparser.ValTuple, len(allColTuples)) + for _, row := range rows { + for i, uk := range allIndexes { + var rowTuple sqlparser.ValTuple + for j, offsets := range uk.Indexes { + colIdx := 0 + valExpr := sqlparser.CopyOnRewrite(uk.uniqKey[j], nil, func(cursor *sqlparser.CopyOnWriteCursor) { + _, isCol := cursor.Node().(*sqlparser.ColName) + if !isCol { + return + } + if offsets[colIdx].idx == -1 { + cursor.Replace(offsets[colIdx].def) + } else { + cursor.Replace(row[offsets[colIdx].idx]) + } + colIdx++ + }, nil).(sqlparser.Expr) + rowTuple = append(rowTuple, valExpr) + } + allValTuples[i] = append(allValTuples[i], rowTuple) + } + } + + compExprs := make([]*sqlparser.ComparisonExpr, 0, noOfUniqKeys) + for i, valTuple := range allValTuples { + compExprs = append(compExprs, sqlparser.NewComparisonExpr(sqlparser.InOp, allColTuples[i], valTuple, nil)) + } + return compExprs, nil +} + +func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vindexes.Table) ([]uComp, bool, error) { + col, isCol := expr.(*sqlparser.ColName) + if isCol { + var def sqlparser.Expr + idx := ins.Columns.FindColumn(col.Name) + if idx == -1 { + def = findDefault(vTbl, col.Name) + if def == nil { + // default value is empty, nothing to compare as it will always be false. + return nil, true, nil + } + } + return []uComp{{idx, def}}, false, nil + } + var offsets []uComp + err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + col, ok := node.(*sqlparser.ColName) + if !ok { + return true, nil + } + var def sqlparser.Expr + idx := ins.Columns.FindColumn(col.Name) + if idx == -1 { + def = findDefault(vTbl, col.Name) + // no default, replace it with null value. + if def == nil { + def = &sqlparser.NullVal{} + } + } + offsets = append(offsets, uComp{idx, def}) + return false, nil + }, expr) + return offsets, false, err +} + +func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) (ops.Operator, error) { + insOp, err := createInsertOperator(ctx, ins, vTbl, routing) if err != nil { return nil, err } @@ -129,7 +345,7 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I } // Find the foreign key mode and for unmanaged foreign-key-mode, we don't need to do anything. - ksMode, err := ctx.VSchema.ForeignKeyMode(vindexTable.Keyspace.Name) + ksMode, err := ctx.VSchema.ForeignKeyMode(vTbl.Keyspace.Name) if err != nil { return nil, err } @@ -139,13 +355,18 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I parentFKs := ctx.SemTable.GetParentForeignKeysList() childFks := ctx.SemTable.GetChildForeignKeysList() - if len(childFks) == 0 && len(parentFKs) == 0 { - return insOp, nil - } if len(parentFKs) > 0 { return nil, vterrors.VT12002() } - return nil, vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys") + if len(childFks) > 0 { + if ins.Action == sqlparser.ReplaceAct { + return nil, vterrors.VT12001("REPLACE INTO with foreign keys") + } + if len(ins.OnDup) > 0 { + return nil, vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys") + } + } + return insOp, nil } func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) (ops.Operator, error) { diff --git a/go/vt/vtgate/planbuilder/operators/sequential.go b/go/vt/vtgate/planbuilder/operators/sequential.go new file mode 100644 index 00000000000..2b333c6270a --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/sequential.go @@ -0,0 +1,54 @@ +/* +Copyright 2023 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 operators + +import ( + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" +) + +type Sequential struct { + Sources []ops.Operator + + noPredicates + noColumns +} + +// Clone implements the Operator interface +func (s *Sequential) Clone(inputs []ops.Operator) ops.Operator { + newOp := *s + newOp.Sources = inputs + return &newOp +} + +func (s *Sequential) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { + return nil +} + +// Inputs implements the Operator interface +func (s *Sequential) Inputs() []ops.Operator { + return s.Sources +} + +// SetInputs implements the Operator interface +func (s *Sequential) SetInputs(ops []ops.Operator) { + s.Sources = ops +} + +func (s *Sequential) ShortDescription() string { + return "" +} diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 472648828ef..9c1592fdf81 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -175,7 +175,23 @@ func setFks(t *testing.T, vschema *vindexes.VSchema) { _ = vschema.AddForeignKey("unsharded_fk_allow", "u_multicol_tbl2", createFkDefinition([]string{"cola", "colb"}, "u_multicol_tbl1", []string{"cola", "colb"}, sqlparser.SetNull, sqlparser.SetNull)) _ = vschema.AddForeignKey("unsharded_fk_allow", "u_multicol_tbl3", createFkDefinition([]string{"cola", "colb"}, "u_multicol_tbl2", []string{"cola", "colb"}, sqlparser.Cascade, sqlparser.Cascade)) - } + + _ = vschema.AddForeignKey("unsharded_fk_allow", "fk_t3", createFkDefinition([]string{"col"}, "fk_t2", []string{"col2"}, sqlparser.SetNull, sqlparser.SetNull)) + _ = vschema.AddForeignKey("unsharded_fk_allow", "fk_t4", createFkDefinition([]string{"col3"}, "fk_t3", []string{"col2"}, sqlparser.SetNull, sqlparser.SetNull)) + _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t2", []string{"id"}) + _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t3", []string{"id"}) + _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t4", []string{"id"}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "fk_t3", sqlparser.Exprs{sqlparser.NewColName("col")}) + } + + _ = vschema.AddPrimaryKey("unsharded_fk_allow", "u_tbl1", []string{"id"}) + _ = vschema.AddPrimaryKey("unsharded_fk_allow", "u_tbl9", []string{"id"}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{&sqlparser.BinaryExpr{Operator: sqlparser.MultOp, Left: sqlparser.NewColName("col9"), Right: sqlparser.NewColName("foo")}}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9"), sqlparser.NewColName("foo")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("foo"), sqlparser.NewColName("bar")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("bar"), sqlparser.NewColName("col9")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl8", sqlparser.Exprs{sqlparser.NewColName("col8")}) } func TestSystemTables57(t *testing.T) { diff --git a/go/vt/vtgate/planbuilder/sequential.go b/go/vt/vtgate/planbuilder/sequential.go new file mode 100644 index 00000000000..ff6abacb437 --- /dev/null +++ b/go/vt/vtgate/planbuilder/sequential.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package planbuilder + +import ( + "vitess.io/vitess/go/vt/vtgate/engine" +) + +type sequential struct { + sources []logicalPlan +} + +var _ logicalPlan = (*sequential)(nil) + +// Primitive implements the logicalPlan interface +func (s *sequential) Primitive() engine.Primitive { + var sources []engine.Primitive + for _, source := range s.sources { + sources = append(sources, source.Primitive()) + } + return engine.NewSequential(sources) +} diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index afe42a45720..0a57806cb1d 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -1690,9 +1690,113 @@ "plan": "VT12002: unsupported: cross-shard foreign keys" }, { - "comment": "replace with fk reference unsupported", + "comment": "replace into with table having primary key", "query": "replace into u_tbl1 (id, col1) values (1, 2)", - "plan": "VT12001: unsupported: REPLACE INTO with foreign keys" + "plan": { + "QueryType": "INSERT", + "Original": "replace into u_tbl1 (id, col1) values (1, 2)", + "Instructions": { + "OperatorType": "Sequential", + "Inputs": [ + { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where (id) in ((1)) for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from u_tbl2 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from u_tbl1 where (id) in ((1))", + "Table": "u_tbl1" + } + ] + }, + { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl1(id, col1) values (1, 2)", + "TableName": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } }, { "comment": "update on a multicol foreign key that set nulls and then cascades", @@ -2258,5 +2362,79 @@ "unsharded_fk_allow.u_multicol_tbl3" ] } + }, + { + "comment": "replace into with table having unique key and primary key", + "query": "replace into u_tbl9(id, col9) values (1, 10),(2, 20),(3, 30)", + "plan": { + "QueryType": "INSERT", + "Original": "replace into u_tbl9(id, col9) values (1, 10),(2, 20),(3, 30)", + "Instructions": { + "OperatorType": "Sequential", + "Inputs": [ + { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ((10), (20), (30)) or (col9 * foo) in ((10 * null), (20 * null), (30 * null)) or (bar, col9) in ((1, 10), (1, 20), (1, 30)) or (id) in ((1), (2), (3)) for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update u_tbl8 set col8 = null where (col8) in ::fkc_vals", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from u_tbl9 where (col9) in ((10), (20), (30)) or (col9 * foo) in ((10 * null), (20 * null), (30 * null)) or (bar, col9) in ((1, 10), (1, 20), (1, 30)) or (id) in ((1), (2), (3))", + "Table": "u_tbl9" + } + ] + }, + { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl9(id, col9) values (1, 10), (2, 20), (3, 30)", + "TableName": "u_tbl9" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json index a7824126c98..d5b9ece501b 100644 --- a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json @@ -760,7 +760,12 @@ "u_tbl6": {}, "u_tbl7": {}, "u_tbl8": {}, - "u_tbl9": {}, + "u_tbl9": { + "columns": [ + {"name": "foo"}, + {"name": "bar", "default": "1"} + ] + }, "u_tbl": {}, "u_multicol_tbl1": {}, "u_multicol_tbl2": {}, diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index 369ab178986..c4b48ce8156 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -216,6 +216,15 @@ func (t *Tracker) GetForeignKeys(ks string, tbl string) []*sqlparser.ForeignKeyD return tblInfo.ForeignKeys } +// GetIndexes returns the indexes for table in the given keyspace. +func (t *Tracker) GetIndexes(ks string, tbl string) []*sqlparser.IndexDefinition { + t.mu.Lock() + defer t.mu.Unlock() + + tblInfo := t.tables.get(ks, tbl) + return tblInfo.Indexes +} + // Tables returns a map with the columns for all known tables in the keyspace func (t *Tracker) Tables(ks string) map[string]*vindexes.TableInfo { t.mu.Lock() @@ -293,7 +302,7 @@ func (t *Tracker) updateTables(keyspace string, res map[string]string) { cols := getColumns(ddl.TableSpec) fks := getForeignKeys(ddl.TableSpec) - t.tables.set(keyspace, tableName, cols, fks) + t.tables.set(keyspace, tableName, cols, fks, ddl.TableSpec.Indexes) } } @@ -308,6 +317,7 @@ func getColumns(tblSpec *sqlparser.TableSpec) []vindexes.Column { Type: column.Type.SQLType(), CollationName: colCollation, Invisible: column.Type.Invisible(), + Default: column.Type.Options.Default, }) } return cols @@ -403,13 +413,13 @@ type tableMap struct { m map[keyspaceStr]map[tableNameStr]*vindexes.TableInfo } -func (tm *tableMap) set(ks, tbl string, cols []vindexes.Column, fks []*sqlparser.ForeignKeyDefinition) { +func (tm *tableMap) set(ks, tbl string, cols []vindexes.Column, fks []*sqlparser.ForeignKeyDefinition, indexes []*sqlparser.IndexDefinition) { m := tm.m[ks] if m == nil { m = make(map[tableNameStr]*vindexes.TableInfo) tm.m[ks] = m } - m[tbl] = &vindexes.TableInfo{Columns: cols, ForeignKeys: fks} + m[tbl] = &vindexes.TableInfo{Columns: cols, ForeignKeys: fks, Indexes: indexes} } func (tm *tableMap) get(ks, tbl string) *vindexes.TableInfo { diff --git a/go/vt/vtgate/schema/tracker_test.go b/go/vt/vtgate/schema/tracker_test.go index 4f514fec101..88b9dfa0d50 100644 --- a/go/vt/vtgate/schema/tracker_test.go +++ b/go/vt/vtgate/schema/tracker_test.go @@ -264,8 +264,8 @@ func TestViewsTracking(t *testing.T) { testTracker(t, schemaDefResult, testcases) } -// TestTableInfoRetrieval tests that the tracker is able to retrieve required information from ddl statement. -func TestTableInfoRetrieval(t *testing.T) { +// TestFKInfoRetrieval tests that the tracker is able to retrieve required foreign key information from ddl statement. +func TestFKInfoRetrieval(t *testing.T) { schemaDefResult := []map[string]string{{ "my_tbl": "CREATE TABLE `my_tbl` (" + "`id` bigint NOT NULL AUTO_INCREMENT," + @@ -293,8 +293,8 @@ func TestTableInfoRetrieval(t *testing.T) { expTbl: map[string][]vindexes.Column{ "my_tbl": { {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci"}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci"}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, }, }, }, { @@ -303,14 +303,14 @@ func TestTableInfoRetrieval(t *testing.T) { expTbl: map[string][]vindexes.Column{ "my_tbl": { {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci"}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci"}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, }, "my_child_tbl": { {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci"}, - {Name: sqlparser.NewIdentifierCI("code"), Type: querypb.Type_VARCHAR, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("my_id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("code"), Type: querypb.Type_VARCHAR, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("my_id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, }, }, expFk: map[string]string{ @@ -322,12 +322,73 @@ func TestTableInfoRetrieval(t *testing.T) { testTracker(t, schemaDefResult, testcases) } +// TestIndexInfoRetrieval tests that the tracker is able to retrieve required index information from ddl statement. +func TestIndexInfoRetrieval(t *testing.T) { + schemaDefResult := []map[string]string{{ + "my_tbl": "CREATE TABLE `my_tbl` (" + + "`id` bigint NOT NULL AUTO_INCREMENT," + + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + + "`email` varbinary(100) DEFAULT NULL," + + "PRIMARY KEY (`id`)," + + "KEY `id` (`id`,`name`)) " + + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + }, { + // initial load of view - kept empty + }, { + "my_tbl": "CREATE TABLE `my_tbl` (" + + "`id` bigint NOT NULL AUTO_INCREMENT," + + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + + "`email` varbinary(100) DEFAULT NULL," + + "PRIMARY KEY (`id`)," + + "KEY `id` (`id`,`name`), " + + "UNIQUE KEY `email` (`email`)) " + + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + }} + + testcases := []testCases{{ + testName: "initial table load", + expTbl: map[string][]vindexes.Column{ + "my_tbl": { + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + }, + }, + expIdx: map[string][]string{ + "my_tbl": { + "primary key (id)", + "key id (id, `name`)", + }, + }, + }, { + testName: "next load", + updTbl: []string{"my_tbl"}, + expTbl: map[string][]vindexes.Column{ + "my_tbl": { + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + }, + }, + expIdx: map[string][]string{ + "my_tbl": { + "primary key (id)", + "key id (id, `name`)", + "unique key email (email)", + }, + }, + }} + + testTracker(t, schemaDefResult, testcases) +} + type testCases struct { testName string updTbl []string expTbl map[string][]vindexes.Column expFk map[string]string + expIdx map[string][]string updView []string expView map[string]string @@ -376,6 +437,16 @@ func testTracker(t *testing.T, schemaDefResult []map[string]string, tcases []tes utils.MustMatch(t, tcase.expFk[k], sqlparser.String(fk), "mismatch foreign keys for table: ", k) } } + expIndexes := tcase.expIdx[k] + if len(expIndexes) > 0 { + idxs := tracker.GetIndexes(keyspace, k) + if len(expIndexes) != len(idxs) { + t.Fatalf("mismatch index for table: %s", k) + } + for i, idx := range idxs { + utils.MustMatch(t, expIndexes[i], sqlparser.String(idx), "mismatch index for table: ", k) + } + } } for k, v := range tcase.expView { diff --git a/go/vt/vtgate/vindexes/foreign_keys.go b/go/vt/vtgate/vindexes/foreign_keys.go index 74f9ce74844..275a0674998 100644 --- a/go/vt/vtgate/vindexes/foreign_keys.go +++ b/go/vt/vtgate/vindexes/foreign_keys.go @@ -144,3 +144,33 @@ func (vschema *VSchema) AddForeignKey(ksname, childTableName string, fkConstrain cTbl.ParentForeignKeys = append(cTbl.ParentForeignKeys, NewParentFkInfo(pTbl, fkConstraint)) return nil } + +// AddPrimaryKey is for testing only. +func (vschema *VSchema) AddPrimaryKey(ksname, tblName string, cols []string) error { + ks, ok := vschema.Keyspaces[ksname] + if !ok { + return fmt.Errorf("keyspace %s not found in vschema", ksname) + } + tbl, ok := ks.Tables[tblName] + if !ok { + return fmt.Errorf("table %s not found in keyspace %s", tblName, ksname) + } + for _, col := range cols { + tbl.PrimaryKey = append(tbl.PrimaryKey, sqlparser.NewIdentifierCI(col)) + } + return nil +} + +// AddUniqueKey is for testing only. +func (vschema *VSchema) AddUniqueKey(ksname, tblName string, exprs sqlparser.Exprs) error { + ks, ok := vschema.Keyspaces[ksname] + if !ok { + return fmt.Errorf("keyspace %s not found in vschema", ksname) + } + tbl, ok := ks.Tables[tblName] + if !ok { + return fmt.Errorf("table %s not found in keyspace %s", tblName, ksname) + } + tbl.UniqueKeys = append(tbl.UniqueKeys, exprs) + return nil +} diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 4e9f527eb83..66321b7a41c 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -118,6 +118,12 @@ type Table struct { ChildForeignKeys []ChildFKInfo `json:"child_foreign_keys,omitempty"` ParentForeignKeys []ParentFKInfo `json:"parent_foreign_keys,omitempty"` + + // index can be columns or expression. + // For Primary key, functional indexes are not allowed, therefore it will only be columns. + // MySQL error message: ERROR 3756 (HY000): The primary key cannot be a functional index + PrimaryKey sqlparser.Columns `json:"primary_key,omitempty"` + UniqueKeys []sqlparser.Exprs `json:"unique_keys,omitempty"` } // GetTableName gets the sqlparser.TableName for the vindex Table. @@ -148,6 +154,7 @@ type ColumnVindex struct { type TableInfo struct { Columns []Column ForeignKeys []*sqlparser.ForeignKeyDefinition + Indexes []*sqlparser.IndexDefinition } // IsUnique is used to tell whether the ColumnVindex @@ -178,6 +185,7 @@ type Column struct { Name sqlparser.IdentifierCI `json:"name"` Type querypb.Type `json:"type"` CollationName string `json:"collation_name"` + Default sqlparser.Expr `json:"default,omitempty"` // Invisible marks this as a column that will not be automatically included in `*` projections Invisible bool `json:"invisible"` @@ -185,13 +193,22 @@ type Column struct { // MarshalJSON returns a JSON representation of Column. func (col *Column) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - Name string `json:"name"` - Type string `json:"type,omitempty"` + cj := struct { + Name string `json:"name"` + Type string `json:"type,omitempty"` + Invisible bool `json:"invisible,omitempty"` + Default string `json:"default,omitempty"` }{ Name: col.Name.String(), Type: querypb.Type_name[int32(col.Type)], - }) + } + if col.Invisible { + cj.Invisible = true + } + if col.Default != nil { + cj.Default = sqlparser.String(col.Default) + } + return json.Marshal(cj) } // KeyspaceSchema contains the schema(table) for a keyspace. @@ -612,8 +629,17 @@ func buildTables(ks *vschemapb.Keyspace, vschema *VSchema, ksvschema *KeyspaceSc tname, ) } + var colDefault sqlparser.Expr + if col.Default != "" { + var err error + colDefault, err = sqlparser.ParseExpr(col.Default) + if err != nil { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, + "could not parse the '%s' column's default expression '%s' for table '%s'", col.Name, col.Default, tname) + } + } colNames[name.Lowered()] = true - t.Columns = append(t.Columns, Column{Name: name, Type: col.Type, Invisible: col.Invisible}) + t.Columns = append(t.Columns, Column{Name: name, Type: col.Type, Invisible: col.Invisible, Default: colDefault}) } // Initialize ColumnVindexes. diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index a59ec78139d..92c95d64674 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -315,10 +315,12 @@ func TestVSchemaColumns(t *testing.T) { "unsharded": { Tables: map[string]*vschemapb.Table{ "t1": { - Columns: []*vschemapb.Column{{ - Name: "c1"}, { - Name: "c2", - Type: sqltypes.VarChar}}}}}}} + Columns: []*vschemapb.Column{ + {Name: "c1"}, + {Name: "c2", Type: sqltypes.VarChar}, + {Name: "c3", Type: sqltypes.VarChar, Default: "''"}, + {Name: "c4", Type: sqltypes.TypeJSON, Default: "json_array()"}, + }}}}}} got := BuildVSchema(&good) require.NoError(t, got.Keyspaces["unsharded"].Error) @@ -327,6 +329,8 @@ func TestVSchemaColumns(t *testing.T) { require.NoError(t, err) assertColumn(t, t1.Columns[0], "c1", sqltypes.Null) assertColumn(t, t1.Columns[1], "c2", sqltypes.VarChar) + assertColumnWithDefault(t, t1.Columns[2], "c3", sqltypes.VarChar, sqlparser.NewStrLiteral("")) + assertColumnWithDefault(t, t1.Columns[3], "c4", sqltypes.TypeJSON, &sqlparser.JSONArrayExpr{}) } func TestVSchemaViews(t *testing.T) { @@ -2687,8 +2691,9 @@ func TestVSchemaJSON(t *testing.T) { Columns: []Column{{ Name: sqlparser.NewIdentifierCI("c1"), }, { - Name: sqlparser.NewIdentifierCI("c2"), - Type: sqltypes.VarChar, + Name: sqlparser.NewIdentifierCI("c2"), + Type: sqltypes.VarChar, + Invisible: true, }}, }, "t2": { @@ -2761,7 +2766,8 @@ func TestVSchemaJSON(t *testing.T) { }, { "name": "c2", - "type": "VARCHAR" + "type": "VARCHAR", + "invisible": true } ] }, @@ -3165,5 +3171,11 @@ func assertVindexMatches(t *testing.T, cv *ColumnVindex, v Vindex, name string, func assertColumn(t *testing.T, col Column, expectedName string, expectedType querypb.Type) { assert.True(t, col.Name.EqualString(expectedName), "column name does not match") assert.Equal(t, expectedType, col.Type, "column type does not match") +} +func assertColumnWithDefault(t *testing.T, col Column, expectedName string, expectedType querypb.Type, expDefault sqlparser.Expr) { + assertColumn(t, col, expectedName, expectedType) + if expDefault != nil { + assert.Equal(t, expDefault, col.Default, "column default does not match") + } } diff --git a/go/vt/vtgate/vschema_manager.go b/go/vt/vtgate/vschema_manager.go index 7f2b7267dc0..20c11634b54 100644 --- a/go/vt/vtgate/vschema_manager.go +++ b/go/vt/vtgate/vschema_manager.go @@ -210,19 +210,37 @@ func (vm *VSchemaManager) updateFromSchema(vschema *vindexes.VSchema) { // Now that we have ensured that all the tables are created, we can start populating the foreign keys // in the tables. for tblName, tblInfo := range m { + rTbl, err := vschema.FindRoutedTable(ksName, tblName, topodatapb.TabletType_PRIMARY) + if err != nil { + log.Errorf("error finding routed table %s: %v", tblName, err) + continue + } for _, fkDef := range tblInfo.ForeignKeys { parentTbl, err := vschema.FindRoutedTable(ksName, fkDef.ReferenceDefinition.ReferencedTable.Name.String(), topodatapb.TabletType_PRIMARY) if err != nil { log.Errorf("error finding parent table %s: %v", fkDef.ReferenceDefinition.ReferencedTable.Name.String(), err) continue } - childTbl, err := vschema.FindRoutedTable(ksName, tblName, topodatapb.TabletType_PRIMARY) - if err != nil { - log.Errorf("error finding child table %s: %v", tblName, err) - continue + rTbl.ParentForeignKeys = append(rTbl.ParentForeignKeys, vindexes.NewParentFkInfo(parentTbl, fkDef)) + parentTbl.ChildForeignKeys = append(parentTbl.ChildForeignKeys, vindexes.NewChildFkInfo(rTbl, fkDef)) + } + for _, idxDef := range tblInfo.Indexes { + switch idxDef.Info.Type { + case sqlparser.IndexTypePrimary: + for _, idxCol := range idxDef.Columns { + rTbl.PrimaryKey = append(rTbl.PrimaryKey, idxCol.Column) + } + case sqlparser.IndexTypeUnique: + var uniqueKey sqlparser.Exprs + for _, idxCol := range idxDef.Columns { + if idxCol.Expression == nil { + uniqueKey = append(uniqueKey, sqlparser.NewColName(idxCol.Column.String())) + } else { + uniqueKey = append(uniqueKey, idxCol.Expression) + } + } + rTbl.UniqueKeys = append(rTbl.UniqueKeys, uniqueKey) } - childTbl.ParentForeignKeys = append(childTbl.ParentForeignKeys, vindexes.NewParentFkInfo(parentTbl, fkDef)) - parentTbl.ChildForeignKeys = append(parentTbl.ChildForeignKeys, vindexes.NewChildFkInfo(childTbl, fkDef)) } } diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index 9c51266c26a..38e22fee0a2 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -82,6 +82,27 @@ func TestVSchemaUpdate(t *testing.T) { ParentColumns: sqlparserCols1, }) + idxTbl1 := &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("idxTbl1"), + Keyspace: ks, + ColumnListAuthoritative: true, + PrimaryKey: sqlparser.Columns{sqlparser.NewIdentifierCI("a")}, + UniqueKeys: []sqlparser.Exprs{ + {sqlparser.NewColName("b")}, + {sqlparser.NewColName("c"), sqlparser.NewColName("d")}, + }, + } + idxTbl2 := &vindexes.Table{ + Name: sqlparser.NewIdentifierCS("idxTbl2"), + Keyspace: ks, + ColumnListAuthoritative: true, + PrimaryKey: sqlparser.Columns{sqlparser.NewIdentifierCI("a")}, + UniqueKeys: []sqlparser.Exprs{ + {&sqlparser.BinaryExpr{Operator: sqlparser.DivOp, Left: sqlparser.NewColName("b"), Right: sqlparser.NewIntLiteral("2")}}, + {sqlparser.NewColName("c"), &sqlparser.BinaryExpr{Operator: sqlparser.PlusOp, Left: sqlparser.NewColName("d"), Right: sqlparser.NewColName("e")}}, + }, + } + tcases := []struct { name string srvVschema *vschemapb.SrvVSchema @@ -192,41 +213,18 @@ func TestVSchemaUpdate(t *testing.T) { Sharded: false, ForeignKeyMode: vschemapb.Keyspace_managed, Tables: map[string]*vschemapb.Table{ - "t1": { - Columns: []*vschemapb.Column{ - { - Name: "id", - Type: querypb.Type_INT64, - }, - }, - }, - "t2": { - Columns: []*vschemapb.Column{ - { - Name: "id", - Type: querypb.Type_INT64, - }, - }, - }, + "t1": {Columns: []*vschemapb.Column{{Name: "id", Type: querypb.Type_INT64}}}, + "t2": {Columns: []*vschemapb.Column{{Name: "id", Type: querypb.Type_INT64}}}, "multicol_t1": { Columns: []*vschemapb.Column{ - { - Name: "uid", - Type: querypb.Type_INT64, - }, { - Name: "name", - Type: querypb.Type_VARCHAR, - }, + {Name: "uid", Type: querypb.Type_INT64}, + {Name: "name", Type: querypb.Type_VARCHAR}, }, - }, "multicol_t2": { + }, + "multicol_t2": { Columns: []*vschemapb.Column{ - { - Name: "uid", - Type: querypb.Type_INT64, - }, { - Name: "name", - Type: querypb.Type_VARCHAR, - }, + {Name: "uid", Type: querypb.Type_INT64}, + {Name: "name", Type: querypb.Type_VARCHAR}, }, }, }, @@ -249,6 +247,69 @@ func TestVSchemaUpdate(t *testing.T) { }, }, }, + }, { + name: "indexes in schema using columns", + currentVSchema: &vindexes.VSchema{}, + schema: map[string]*vindexes.TableInfo{ + "idxTbl1": { + Indexes: []*sqlparser.IndexDefinition{{ + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypePrimary}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("a")}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeUnique}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("b")}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeDefault}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("x")}, + {Column: sqlparser.NewIdentifierCI("y")}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeUnique}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("c")}, + {Column: sqlparser.NewIdentifierCI("d")}, + }, + }}, + }, + }, + srvVschema: makeTestSrvVSchema("ks", false, nil), + expected: makeTestVSchema("ks", false, map[string]*vindexes.Table{"idxTbl1": idxTbl1}), + }, { + name: "indexes in schema using expressions", + currentVSchema: &vindexes.VSchema{}, + schema: map[string]*vindexes.TableInfo{ + "idxTbl2": { + Indexes: []*sqlparser.IndexDefinition{{ + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypePrimary}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("a")}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeUnique}, + Columns: []*sqlparser.IndexColumn{ + {Expression: &sqlparser.BinaryExpr{Operator: sqlparser.DivOp, Left: sqlparser.NewColName("b"), Right: sqlparser.NewIntLiteral("2")}}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeDefault}, + Columns: []*sqlparser.IndexColumn{ + {Expression: &sqlparser.BinaryExpr{Operator: sqlparser.PlusOp, Left: sqlparser.NewColName("x"), Right: sqlparser.NewColName("y")}}, + }, + }, { + Info: &sqlparser.IndexInfo{Type: sqlparser.IndexTypeUnique}, + Columns: []*sqlparser.IndexColumn{ + {Column: sqlparser.NewIdentifierCI("c")}, + {Expression: &sqlparser.BinaryExpr{Operator: sqlparser.PlusOp, Left: sqlparser.NewColName("d"), Right: sqlparser.NewColName("e")}}, + }, + }}, + }, + }, + srvVschema: makeTestSrvVSchema("ks", false, nil), + expected: makeTestVSchema("ks", false, map[string]*vindexes.Table{"idxTbl2": idxTbl2}), }} vm := &VSchemaManager{} diff --git a/proto/vschema.proto b/proto/vschema.proto index 067be686db5..c6665688c23 100644 --- a/proto/vschema.proto +++ b/proto/vschema.proto @@ -127,6 +127,7 @@ message Column { string name = 1; query.Type type = 2; bool invisible = 3; + string default = 4; } // SrvVSchema is the roll-up of all the Keyspace schema for a cell. diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 398d93080dc..bda230c6570 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -41592,6 +41592,9 @@ export namespace vschema { /** Column invisible */ invisible?: (boolean|null); + + /** Column default */ + "default"?: (string|null); } /** Represents a Column. */ @@ -41612,6 +41615,9 @@ export namespace vschema { /** Column invisible. */ public invisible: boolean; + /** Column default. */ + public default: string; + /** * Creates a new Column instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 9ddce1d0059..dc1679ee3c0 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -101273,6 +101273,7 @@ export const vschema = $root.vschema = (() => { * @property {string|null} [name] Column name * @property {query.Type|null} [type] Column type * @property {boolean|null} [invisible] Column invisible + * @property {string|null} ["default"] Column default */ /** @@ -101314,6 +101315,14 @@ export const vschema = $root.vschema = (() => { */ Column.prototype.invisible = false; + /** + * Column default. + * @member {string} default + * @memberof vschema.Column + * @instance + */ + Column.prototype["default"] = ""; + /** * Creates a new Column instance using the specified properties. * @function create @@ -101344,6 +101353,8 @@ export const vschema = $root.vschema = (() => { writer.uint32(/* id 2, wireType 0 =*/16).int32(message.type); if (message.invisible != null && Object.hasOwnProperty.call(message, "invisible")) writer.uint32(/* id 3, wireType 0 =*/24).bool(message.invisible); + if (message["default"] != null && Object.hasOwnProperty.call(message, "default")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message["default"]); return writer; }; @@ -101390,6 +101401,10 @@ export const vschema = $root.vschema = (() => { message.invisible = reader.bool(); break; } + case 4: { + message["default"] = reader.string(); + break; + } default: reader.skipType(tag & 7); break; @@ -101472,6 +101487,9 @@ export const vschema = $root.vschema = (() => { if (message.invisible != null && message.hasOwnProperty("invisible")) if (typeof message.invisible !== "boolean") return "invisible: boolean expected"; + if (message["default"] != null && message.hasOwnProperty("default")) + if (!$util.isString(message["default"])) + return "default: string expected"; return null; }; @@ -101639,6 +101657,8 @@ export const vschema = $root.vschema = (() => { } if (object.invisible != null) message.invisible = Boolean(object.invisible); + if (object["default"] != null) + message["default"] = String(object["default"]); return message; }; @@ -101659,6 +101679,7 @@ export const vschema = $root.vschema = (() => { object.name = ""; object.type = options.enums === String ? "NULL_TYPE" : 0; object.invisible = false; + object["default"] = ""; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; @@ -101666,6 +101687,8 @@ export const vschema = $root.vschema = (() => { object.type = options.enums === String ? $root.query.Type[message.type] === undefined ? message.type : $root.query.Type[message.type] : message.type; if (message.invisible != null && message.hasOwnProperty("invisible")) object.invisible = message.invisible; + if (message["default"] != null && message.hasOwnProperty("default")) + object["default"] = message["default"]; return object; }; From 22e4c200e8ce67a30d958207a0704a9575d9e766 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Wed, 15 Nov 2023 22:10:27 +0100 Subject: [PATCH 018/119] Reduce wait time in test helpers (#14476) Signed-off-by: Dirkjan Bussink Signed-off-by: Manan Gupta Co-authored-by: Manan Gupta --- go/test/endtoend/utils/utils.go | 50 +++++++++++++++---- .../foreignkey/stress/fk_stress_test.go | 8 +++ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/go/test/endtoend/utils/utils.go b/go/test/endtoend/utils/utils.go index fa270ba30a0..0231cae7baf 100644 --- a/go/test/endtoend/utils/utils.go +++ b/go/test/endtoend/utils/utils.go @@ -236,16 +236,17 @@ func WaitForAuthoritative(t *testing.T, ks, tbl string, readVSchema func() (*int case <-timeout: return fmt.Errorf("schema tracking didn't mark table t2 as authoritative until timeout") default: - time.Sleep(1 * time.Second) res, err := readVSchema() require.NoError(t, err, res) t2Map := getTableT2Map(res, ks, tbl) authoritative, fieldPresent := t2Map["column_list_authoritative"] if !fieldPresent { + time.Sleep(100 * time.Millisecond) continue } authoritativeBool, isBool := authoritative.(bool) if !isBool || !authoritativeBool { + time.Sleep(100 * time.Millisecond) continue } return nil @@ -262,24 +263,46 @@ func WaitForKsError(t *testing.T, vtgateProcess cluster.VtgateProcess, ks string t.Fatalf("schema tracking did not find error in '%s'", ks) return "" default: - time.Sleep(1 * time.Second) res, err := vtgateProcess.ReadVSchema() require.NoError(t, err, res) kss := convertToMap(*res)["keyspaces"] ksMap := convertToMap(convertToMap(kss)[ks]) ksErr, fieldPresent := ksMap["error"] if !fieldPresent { - break + time.Sleep(100 * time.Millisecond) + continue } errString, isErr := ksErr.(string) if !isErr { - break + time.Sleep(100 * time.Millisecond) + continue } return errString } } } +// WaitForTableDeletions waits for a table to be deleted +func WaitForTableDeletions(ctx context.Context, t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl string) error { + for { + select { + case <-ctx.Done(): + return fmt.Errorf("schema tracking still found the table '%s'", tbl) + default: + res, err := vtgateProcess.ReadVSchema() + require.NoError(t, err, res) + keyspacesMap := convertToMap(*res)["keyspaces"] + ksMap := convertToMap(keyspacesMap)[ks] + tablesMap := convertToMap(ksMap)["tables"] + _, isPresent := convertToMap(tablesMap)[tbl] + if !isPresent { + return nil + } + time.Sleep(100 * time.Millisecond) + } + } +} + // WaitForColumn waits for a table's column to be present func WaitForColumn(t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl, col string) error { timeout := time.After(60 * time.Second) @@ -288,25 +311,28 @@ func WaitForColumn(t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl, c case <-timeout: return fmt.Errorf("schema tracking did not find column '%s' in table '%s'", col, tbl) default: - time.Sleep(1 * time.Second) res, err := vtgateProcess.ReadVSchema() require.NoError(t, err, res) t2Map := getTableT2Map(res, ks, tbl) authoritative, fieldPresent := t2Map["column_list_authoritative"] if !fieldPresent { - break + time.Sleep(100 * time.Millisecond) + continue } authoritativeBool, isBool := authoritative.(bool) if !isBool || !authoritativeBool { - break + time.Sleep(100 * time.Millisecond) + continue } colMap, exists := t2Map["columns"] if !exists { - break + time.Sleep(100 * time.Millisecond) + continue } colList, isSlice := colMap.([]interface{}) if !isSlice { - break + time.Sleep(100 * time.Millisecond) + continue } for _, c := range colList { colDef, isMap := c.(map[string]interface{}) @@ -317,6 +343,7 @@ func WaitForColumn(t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl, c return nil } } + time.Sleep(100 * time.Millisecond) } } } @@ -330,7 +357,10 @@ func getTableT2Map(res *interface{}, ks, tbl string) map[string]interface{} { } func convertToMap(input interface{}) map[string]interface{} { - output := input.(map[string]interface{}) + output, ok := input.(map[string]interface{}) + if !ok { + return make(map[string]interface{}) + } return output } diff --git a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go index e9f0602d235..91e64e67d1e 100644 --- a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go +++ b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go @@ -704,6 +704,14 @@ func createInitialSchema(t *testing.T, tcase *testCase) { require.NoError(t, err) } }) + t.Run("waiting for vschema deletions to apply", func(t *testing.T) { + timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Minute) + defer cancel() + for _, tableName := range tableNames { + err := utils.WaitForTableDeletions(timeoutCtx, t, clusterInstance.VtgateProcess, keyspaceName, tableName) + require.NoError(t, err) + } + }) t.Run("creating tables", func(t *testing.T) { // Create the stress tables var b strings.Builder From fd0450299171d9c088840459d1fa0bc3377c54b1 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 15 Nov 2023 22:40:09 +0100 Subject: [PATCH 019/119] VReplication: VTTablet flag cleanup (#14297) Signed-off-by: Matt Lord Signed-off-by: Andrew Mason Co-authored-by: Andrew Mason --- changelog/19.0/19.0.0/summary.md | 7 +++++++ go/flags/endtoend/vtcombo.txt | 4 ---- go/flags/endtoend/vttablet.txt | 4 ---- go/test/endtoend/backup/vtbackup/main_test.go | 2 -- .../endtoend/backup/vtctlbackup/backup_utils.go | 2 -- go/test/endtoend/cellalias/cell_alias_test.go | 2 -- go/test/endtoend/cluster/vttablet_process.go | 3 --- .../endtoend/recovery/pitr/shardedpitr_test.go | 5 ----- .../recovery/unshardedrecovery/recovery.go | 2 -- go/test/endtoend/topoconncache/main_test.go | 2 -- go/test/endtoend/vault/vault_test.go | 2 -- go/test/endtoend/vreplication/cluster_test.go | 5 ++--- .../vtgate/foreignkey/stress/fk_stress_test.go | 1 - go/vt/vtctl/vtctl.go | 2 +- .../tabletmanager/vreplication/flags.go | 17 ++++++----------- go/vt/wrangler/traffic_switcher.go | 5 +---- vitess-mixin/e2e/vttablet-up.sh | 1 - 17 files changed, 17 insertions(+), 49 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index aa0d1a90227..be560d50f58 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -4,6 +4,7 @@ - **[Major Changes](#major-changes)** - **[Deprecations and Deletions](#deprecations-and-deletions)** + - [VTTablet Flags](#vttablet-flags) - **[Docker](#docker)** - [New MySQL Image](#mysql-image) - **[Query Compatibility](#query-compatibility)** @@ -15,6 +16,12 @@ - The `MYSQL_FLAVOR` environment variable is now removed from all Docker Images. +#### VTTablet Flags + +- The following flags — which were deprecated in Vitess 7.0 — have been removed: +`--vreplication_healthcheck_topology_refresh`, `--vreplication_healthcheck_retry_delay`, and `--vreplication_healthcheck_timeout`. +- The `--vreplication_tablet_type` flag is now deprecated and ignored. + ### Docker #### New MySQL Image diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index 5a029b8dd84..c416af11e31 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -401,9 +401,6 @@ Flags: --vreplication_copy_phase_max_innodb_history_list_length int The maximum InnoDB transaction history that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 1000000) --vreplication_copy_phase_max_mysql_replication_lag int The maximum MySQL replication lag (in seconds) that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 43200) --vreplication_experimental_flags int (Bitmask) of experimental features in vreplication to enable (default 3) - --vreplication_healthcheck_retry_delay duration healthcheck retry delay (default 5s) - --vreplication_healthcheck_timeout duration healthcheck retry delay (default 1m0s) - --vreplication_healthcheck_topology_refresh duration refresh interval for re-reading the topology (default 30s) --vreplication_heartbeat_update_interval int Frequency (in seconds, default 1, max 60) at which the time_updated column of a vreplication stream when idling (default 1) --vreplication_max_time_to_retry_on_error duration stop automatically retrying when we've had consecutive failures with the same error for this long after the first occurrence --vreplication_net_read_timeout int Session value of net_read_timeout for vreplication, in seconds (default 300) @@ -411,7 +408,6 @@ Flags: --vreplication_replica_lag_tolerance duration Replica lag threshold duration: once lag is below this we switch from copy phase to the replication (streaming) phase (default 1m0s) --vreplication_retry_delay duration delay before retrying a failed workflow event in the replication phase (default 5s) --vreplication_store_compressed_gtid Store compressed gtids in the pos column of the sidecar database's vreplication table - --vreplication_tablet_type string comma separated list of tablet types used as a source (default "in_order:REPLICA,PRIMARY") --vschema-persistence-dir string If set, per-keyspace vschema will be persisted in this directory and reloaded into the in-memory topology server across restarts. Bookkeeping is performed using a simple watcher goroutine. This is useful when running vtcombo as an application development container (e.g. vttestserver) where you want to keep the same vschema even if developer's machine reboots. This works in tandem with vttestserver's --persistent_mode flag. Needless to say, this is neither a perfect nor a production solution for vschema persistence. Consider using the --external_topo_server flag if you require a more complete solution. This flag is ignored if --external_topo_server is set. --vschema_ddl_authorized_users string List of users authorized to execute vschema ddl operations, or '%' to allow all users. --vstream-binlog-rotation-threshold int Byte size at which a VStreamer will attempt to rotate the source's open binary log before starting a GTID snapshot based stream (e.g. a ResultStreamer or RowStreamer) (default 67108864) diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index 7f18d8dc76b..c0926a6f701 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -406,9 +406,6 @@ Flags: --vreplication_copy_phase_max_innodb_history_list_length int The maximum InnoDB transaction history that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 1000000) --vreplication_copy_phase_max_mysql_replication_lag int The maximum MySQL replication lag (in seconds) that can exist on a vstreamer (source) before starting another round of copying rows. This helps to limit the impact on the source tablet. (default 43200) --vreplication_experimental_flags int (Bitmask) of experimental features in vreplication to enable (default 3) - --vreplication_healthcheck_retry_delay duration healthcheck retry delay (default 5s) - --vreplication_healthcheck_timeout duration healthcheck retry delay (default 1m0s) - --vreplication_healthcheck_topology_refresh duration refresh interval for re-reading the topology (default 30s) --vreplication_heartbeat_update_interval int Frequency (in seconds, default 1, max 60) at which the time_updated column of a vreplication stream when idling (default 1) --vreplication_max_time_to_retry_on_error duration stop automatically retrying when we've had consecutive failures with the same error for this long after the first occurrence --vreplication_net_read_timeout int Session value of net_read_timeout for vreplication, in seconds (default 300) @@ -416,7 +413,6 @@ Flags: --vreplication_replica_lag_tolerance duration Replica lag threshold duration: once lag is below this we switch from copy phase to the replication (streaming) phase (default 1m0s) --vreplication_retry_delay duration delay before retrying a failed workflow event in the replication phase (default 5s) --vreplication_store_compressed_gtid Store compressed gtids in the pos column of the sidecar database's vreplication table - --vreplication_tablet_type string comma separated list of tablet types used as a source (default "in_order:REPLICA,PRIMARY") --vstream-binlog-rotation-threshold int Byte size at which a VStreamer will attempt to rotate the source's open binary log before starting a GTID snapshot based stream (e.g. a ResultStreamer or RowStreamer) (default 67108864) --vstream_dynamic_packet_size Enable dynamic packet sizing for VReplication. This will adjust the packet size during replication to improve performance. (default true) --vstream_packet_size int Suggested packet size for VReplication streamer. This is used only as a recommendation. The actual packet size may be more or less than this amount. (default 250000) diff --git a/go/test/endtoend/backup/vtbackup/main_test.go b/go/test/endtoend/backup/vtbackup/main_test.go index 36bfae123d8..367956c9827 100644 --- a/go/test/endtoend/backup/vtbackup/main_test.go +++ b/go/test/endtoend/backup/vtbackup/main_test.go @@ -43,8 +43,6 @@ var ( shardKsName = fmt.Sprintf("%s/%s", keyspaceName, shardName) dbCredentialFile string commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/backup/vtctlbackup/backup_utils.go b/go/test/endtoend/backup/vtctlbackup/backup_utils.go index 1ca56db68c2..e470652f7ee 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_utils.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_utils.go @@ -74,8 +74,6 @@ var ( dbCredentialFile string shardName = "0" commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/cellalias/cell_alias_test.go b/go/test/endtoend/cellalias/cell_alias_test.go index 9c2a29d2eb1..d357331d8cd 100644 --- a/go/test/endtoend/cellalias/cell_alias_test.go +++ b/go/test/endtoend/cellalias/cell_alias_test.go @@ -53,8 +53,6 @@ var ( ) Engine=InnoDB ` commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index 517f4bf3874..ed6a97a15c2 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -76,7 +76,6 @@ type VttabletProcess struct { ServingStatus string DbPassword string DbPort int - VreplicationTabletType string DbFlavor string Charset string ConsolidationsURL string @@ -109,7 +108,6 @@ func (vttablet *VttabletProcess) Setup() (err error) { "--backup_storage_implementation", vttablet.BackupStorageImplementation, "--file_backup_storage_root", vttablet.FileBackupStorageRoot, "--service_map", vttablet.ServiceMap, - "--vreplication_tablet_type", vttablet.VreplicationTabletType, "--db_charset", vttablet.Charset, ) if v, err := GetMajorVersion("vttablet"); err != nil { @@ -659,7 +657,6 @@ func VttabletProcessInstance(port, grpcPort, tabletUID int, cell, shard, keyspac ServingStatus: "NOT_SERVING", BackupStorageImplementation: "file", FileBackupStorageRoot: path.Join(os.Getenv("VTDATAROOT"), "/backups"), - VreplicationTabletType: "replica", TabletUID: tabletUID, Charset: charset, } diff --git a/go/test/endtoend/recovery/pitr/shardedpitr_test.go b/go/test/endtoend/recovery/pitr/shardedpitr_test.go index d04b5600362..7f70a926be3 100644 --- a/go/test/endtoend/recovery/pitr/shardedpitr_test.go +++ b/go/test/endtoend/recovery/pitr/shardedpitr_test.go @@ -89,8 +89,6 @@ var ( } }` commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", @@ -558,9 +556,6 @@ func launchRecoveryTablet(t *testing.T, tablet *cluster.Vttablet, binlogServer * "--binlog_user", binlogServer.username, "--binlog_password", binlogServer.password, "--pitr_gtid_lookup_timeout", lookupTimeout, - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", - "--vreplication_tablet_type", "replica", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/recovery/unshardedrecovery/recovery.go b/go/test/endtoend/recovery/unshardedrecovery/recovery.go index f4db74bbf4e..8966e66ed47 100644 --- a/go/test/endtoend/recovery/unshardedrecovery/recovery.go +++ b/go/test/endtoend/recovery/unshardedrecovery/recovery.go @@ -51,8 +51,6 @@ var ( dbCredentialFile string shardName = "0" commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/topoconncache/main_test.go b/go/test/endtoend/topoconncache/main_test.go index 7cfea8839b0..4c17481ec84 100644 --- a/go/test/endtoend/topoconncache/main_test.go +++ b/go/test/endtoend/topoconncache/main_test.go @@ -48,8 +48,6 @@ var ( ) Engine=InnoDB ` commonTabletArg = []string{ - "--vreplication_healthcheck_topology_refresh", "1s", - "--vreplication_healthcheck_retry_delay", "1s", "--vreplication_retry_delay", "1s", "--degraded_threshold", "5s", "--lock_tables_timeout", "5s", diff --git a/go/test/endtoend/vault/vault_test.go b/go/test/endtoend/vault/vault_test.go index 9bc5b9cb977..73b5a89b156 100644 --- a/go/test/endtoend/vault/vault_test.go +++ b/go/test/endtoend/vault/vault_test.go @@ -56,8 +56,6 @@ var ( 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", diff --git a/go/test/endtoend/vreplication/cluster_test.go b/go/test/endtoend/vreplication/cluster_test.go index af93ac40726..4735e94560f 100644 --- a/go/test/endtoend/vreplication/cluster_test.go +++ b/go/test/endtoend/vreplication/cluster_test.go @@ -541,7 +541,6 @@ func (vc *VitessCluster) AddShards(t *testing.T, cells []*Cell, keyspace *Keyspa require.NoError(t, err) require.NotNil(t, primary) tabletIndex++ - primary.Vttablet.VreplicationTabletType = "PRIMARY" tablets = append(tablets, primary) dbProcesses = append(dbProcesses, proc) primaryTabletUID = primary.Vttablet.TabletUID @@ -776,7 +775,7 @@ func (vc *VitessCluster) getVttabletsInKeyspace(t *testing.T, cell *Cell, ksName tablets := make(map[string]*cluster.VttabletProcess) for _, shard := range keyspace.Shards { for _, tablet := range shard.Tablets { - if tablet.Vttablet.GetTabletStatus() == "SERVING" && strings.EqualFold(tablet.Vttablet.VreplicationTabletType, tabletType) { + if tablet.Vttablet.GetTabletStatus() == "SERVING" { log.Infof("Serving status of tablet %s is %s, %s", tablet.Name, tablet.Vttablet.ServingStatus, tablet.Vttablet.GetTabletStatus()) tablets[tablet.Name] = tablet.Vttablet } @@ -796,7 +795,7 @@ func (vc *VitessCluster) getPrimaryTablet(t *testing.T, ksName, shardName string continue } for _, tablet := range shard.Tablets { - if tablet.Vttablet.GetTabletStatus() == "SERVING" && strings.EqualFold(tablet.Vttablet.VreplicationTabletType, "primary") { + if tablet.Vttablet.GetTabletStatus() == "SERVING" { return tablet.Vttablet } } diff --git a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go index 91e64e67d1e..00b7d9ca0cc 100644 --- a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go +++ b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go @@ -333,7 +333,6 @@ func TestMain(m *testing.M) { "--heartbeat_on_demand_duration", "5s", "--migration_check_interval", "5s", "--watch_replication_stream", - "--vreplication_tablet_type", "primary", } clusterInstance.VtGateExtraArgs = []string{} diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 11d3cf85e68..90e5d0d8ddd 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2089,7 +2089,7 @@ func commandVReplicationWorkflow(ctx context.Context, wr *wrangler.Wrangler, sub const defaultMaxReplicationLagAllowed = defaultWaitTime cells := subFlags.String("cells", "", "Cell(s) or CellAlias(es) (comma-separated) to replicate from.") - tabletTypesStr := subFlags.String("tablet_types", "in_order:REPLICA,PRIMARY", "Source tablet types to replicate from (e.g. PRIMARY, REPLICA, RDONLY). Defaults to --vreplication_tablet_type parameter value for the tablet, which has the default value of in_order:REPLICA,PRIMARY. Note: SwitchTraffic overrides this default and uses in_order:RDONLY,REPLICA,PRIMARY to switch all traffic by default.") + tabletTypesStr := subFlags.String("tablet_types", "in_order:REPLICA,PRIMARY", "Source tablet types to replicate from (e.g. PRIMARY, REPLICA, RDONLY). Note: SwitchTraffic overrides this default and uses in_order:RDONLY,REPLICA,PRIMARY to switch all traffic by default.") dryRun := subFlags.Bool("dry_run", false, "Does a dry run of SwitchTraffic and only reports the actions to be taken. --dry_run is only supported for SwitchTraffic, ReverseTraffic and Complete.") timeout := subFlags.Duration("timeout", defaultWaitTime, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on primary migrations. The migration will be cancelled on a timeout. --timeout is only supported for SwitchTraffic and ReverseTraffic.") reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication (default true). --reverse_replication is only supported for SwitchTraffic.") diff --git a/go/vt/vttablet/tabletmanager/vreplication/flags.go b/go/vt/vttablet/tabletmanager/vreplication/flags.go index 44f07f87a0f..9f328f48a68 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/flags.go +++ b/go/vt/vttablet/tabletmanager/vreplication/flags.go @@ -26,9 +26,9 @@ import ( var ( retryDelay = 5 * time.Second - maxTimeToRetryError time.Duration // default behavior is to keep retrying, for backward compatibility + maxTimeToRetryError time.Duration // Default behavior is to keep retrying, for backward compatibility - tabletTypesStr = "in_order:REPLICA,PRIMARY" + tabletTypesStr = "in_order:REPLICA,PRIMARY" // Default value relayLogMaxSize = 250000 relayLogMaxItems = 5000 @@ -45,10 +45,6 @@ func registerVReplicationFlags(fs *pflag.FlagSet) { fs.DurationVar(&retryDelay, "vreplication_retry_delay", retryDelay, "delay before retrying a failed workflow event in the replication phase") fs.DurationVar(&maxTimeToRetryError, "vreplication_max_time_to_retry_on_error", maxTimeToRetryError, "stop automatically retrying when we've had consecutive failures with the same error for this long after the first occurrence") - // these are the default tablet_types that will be used by the tablet picker to find source tablets for a vreplication stream - // it can be overridden by passing a different list to the MoveTables or Reshard commands - fs.StringVar(&tabletTypesStr, "vreplication_tablet_type", tabletTypesStr, "comma separated list of tablet types used as a source") - fs.IntVar(&relayLogMaxSize, "relay_log_max_size", relayLogMaxSize, "Maximum buffer size (in bytes) for VReplication target buffering. If single rows are larger than this, a single row is buffered at a time.") fs.IntVar(&relayLogMaxItems, "relay_log_max_items", relayLogMaxItems, "Maximum number of rows for VReplication target buffering.") @@ -62,12 +58,11 @@ func registerVReplicationFlags(fs *pflag.FlagSet) { fs.IntVar(&vreplicationHeartbeatUpdateInterval, "vreplication_heartbeat_update_interval", vreplicationHeartbeatUpdateInterval, "Frequency (in seconds, default 1, max 60) at which the time_updated column of a vreplication stream when idling") fs.BoolVar(&vreplicationStoreCompressedGTID, "vreplication_store_compressed_gtid", vreplicationStoreCompressedGTID, "Store compressed gtids in the pos column of the sidecar database's vreplication table") - // deprecated flags (7.0), however there are several e2e tests that still depend on them - fs.Duration("vreplication_healthcheck_topology_refresh", 30*time.Second, "refresh interval for re-reading the topology") - fs.Duration("vreplication_healthcheck_retry_delay", 5*time.Second, "healthcheck retry delay") - fs.Duration("vreplication_healthcheck_timeout", 1*time.Minute, "healthcheck retry delay") - fs.IntVar(&vreplicationParallelInsertWorkers, "vreplication-parallel-insert-workers", vreplicationParallelInsertWorkers, "Number of parallel insertion workers to use during copy phase. Set <= 1 to disable parallelism, or > 1 to enable concurrent insertion during copy phase.") + + // Deprecated and ignored in v19. + fs.String("vreplication_tablet_type", tabletTypesStr, "Comma-separated list of tablet types used as a source.") + fs.MarkDeprecated("vreplication_tablet_type", "As of v19 this is ignored and will be removed in a future release.") } func init() { diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index 654a5bd1588..ccbcee9c3b0 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -437,11 +437,8 @@ func (wr *Wrangler) areTabletsAvailableToStreamFrom(ctx context.Context, ts *tra if ts.optCells != "" { cells = strings.Split(ts.optCells, ",") } - // FIXME: currently there is a default setting in the tablet that is used if user does not specify a tablet type, - // we use the value specified in the tablet flag `-vreplication_tablet_type` - // but ideally we should populate the vreplication table with a default value when we setup the workflow if tabletTypes == "" { - tabletTypes = "PRIMARY,REPLICA" + tabletTypes = "in_order:REPLICA,PRIMARY" // default } var wg sync.WaitGroup diff --git a/vitess-mixin/e2e/vttablet-up.sh b/vitess-mixin/e2e/vttablet-up.sh index f41b31f025c..89709cf750f 100755 --- a/vitess-mixin/e2e/vttablet-up.sh +++ b/vitess-mixin/e2e/vttablet-up.sh @@ -133,7 +133,6 @@ if [ $tablet_role = "externalprimary" ]; then --enable_replication_reporter=false \ --enforce_strict_trans_tables=false \ --track_schema_versions=true \ - --vreplication_tablet_type=primary \ --watch_replication_stream=true" else external_db_args="--init_db_name_override $DB_NAME \ From 29c1272aec01f568351645500443b189b3604437 Mon Sep 17 00:00:00 2001 From: aquarapid Date: Wed, 15 Nov 2023 16:24:05 -0800 Subject: [PATCH 020/119] Fix #14414: resilient_server metrics name/prefix logic is inverted, leading to no metrics being recorded (#14415) Signed-off-by: Jacques Grove Signed-off-by: deepthi Co-authored-by: deepthi --- go/vt/srvtopo/resilient_server.go | 6 ++---- go/vt/srvtopo/resilient_server_test.go | 2 +- go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go | 5 ++++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index d1521952ab0..0cbccbdb31c 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -84,11 +84,9 @@ func NewResilientServer(ctx context.Context, base *topo.Server, counterPrefix st log.Fatalf("srv_topo_cache_refresh must be less than or equal to srv_topo_cache_ttl") } - var metric string - if counterPrefix == "" { + metric := "" + if counterPrefix != "" { metric = counterPrefix + "Counts" - } else { - metric = "" } counts := stats.NewCountersWithSingleLabel(metric, "Resilient srvtopo server operations", "type") diff --git a/go/vt/srvtopo/resilient_server_test.go b/go/vt/srvtopo/resilient_server_test.go index c237d43f300..fe248f56087 100644 --- a/go/vt/srvtopo/resilient_server_test.go +++ b/go/vt/srvtopo/resilient_server_test.go @@ -811,7 +811,7 @@ func TestSrvKeyspaceListener(t *testing.T) { srvTopoCacheRefresh = 1 * time.Second }() - rs := NewResilientServer(ctx, ts, "TestGetSrvKeyspaceWatcher") + rs := NewResilientServer(ctx, ts, "TestGetSrvKeyspaceListener") cancelCtx, cancelFunc := context.WithCancel(context.Background()) var callbackCount atomic.Int32 diff --git a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go index c40e180110f..a05dc3b2c05 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go +++ b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go @@ -20,6 +20,7 @@ package testenv import ( "context" "fmt" + "math/rand" "os" "regexp" "strings" @@ -75,7 +76,9 @@ func Init(ctx context.Context) (*Env, error) { if err := te.TopoServ.CreateShard(ctx, te.KeyspaceName, te.ShardName); err != nil { panic(err) } - te.SrvTopo = srvtopo.NewResilientServer(ctx, te.TopoServ, "TestTopo") + // Add a random suffix to metric name to avoid panic. Another option would have been to generate a random string. + suffix := rand.Int() + te.SrvTopo = srvtopo.NewResilientServer(ctx, te.TopoServ, "TestTopo"+fmt.Sprint(suffix)) cfg := vttest.Config{ Topology: &vttestpb.VTTestTopology{ From 18819254e669e2f54a6576f6da1a8ba63c95176f Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Wed, 15 Nov 2023 20:40:22 -0600 Subject: [PATCH 021/119] Add HealthCheck's `healthy` map to the VTGate UI (#14521) --- go/cmd/vtcombo/cli/status.go | 5 +- go/cmd/vtgate/cli/status.go | 5 +- go/vt/discovery/fake_healthcheck.go | 11 +++ go/vt/discovery/healthcheck.go | 67 +++++++++++++++---- go/vt/discovery/healthcheck_test.go | 4 +- go/vt/vtgate/tabletgateway.go | 5 ++ .../txthrottler/mock_healthcheck_test.go | 8 +++ 7 files changed, 87 insertions(+), 18 deletions(-) diff --git a/go/cmd/vtcombo/cli/status.go b/go/cmd/vtcombo/cli/status.go index 8069fc72606..80176d4a11a 100644 --- a/go/cmd/vtcombo/cli/status.go +++ b/go/cmd/vtcombo/cli/status.go @@ -41,7 +41,10 @@ func addStatusParts(vtg *vtgate.VTGate) { servenv.AddStatusPart("Gateway Status", vtgate.StatusTemplate, func() any { return vtg.GetGatewayCacheStatus() }) - servenv.AddStatusPart("Health Check Cache", discovery.HealthCheckTemplate, func() any { + servenv.AddStatusPart("Health Check - Cache", discovery.HealthCheckCacheTemplate, func() any { return vtg.Gateway().TabletsCacheStatus() }) + servenv.AddStatusPart("Health Check - Healthy Tablets", discovery.HealthCheckHealthyTemplate, func() any { + return vtg.Gateway().TabletsHealthyStatus() + }) } diff --git a/go/cmd/vtgate/cli/status.go b/go/cmd/vtgate/cli/status.go index 2fdab073d5a..9652392dc65 100644 --- a/go/cmd/vtgate/cli/status.go +++ b/go/cmd/vtgate/cli/status.go @@ -37,7 +37,10 @@ func addStatusParts(vtg *vtgate.VTGate) { servenv.AddStatusPart("Gateway Status", vtgate.StatusTemplate, func() any { return vtg.GetGatewayCacheStatus() }) - servenv.AddStatusPart("Health Check Cache", discovery.HealthCheckTemplate, func() any { + servenv.AddStatusPart("Health Check - Cache", discovery.HealthCheckCacheTemplate, func() any { return vtg.Gateway().TabletsCacheStatus() }) + servenv.AddStatusPart("Health Check - Healthy Tablets", discovery.HealthCheckHealthyTemplate, func() any { + return vtg.Gateway().TabletsHealthyStatus() + }) } diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index cb959902c19..1c83de5b149 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -252,6 +252,17 @@ func (fhc *FakeHealthCheck) CacheStatus() TabletsCacheStatusList { return tcsl } +// HealthyStatus returns the status for each healthy tablet +func (fhc *FakeHealthCheck) HealthyStatus() TabletsCacheStatusList { + tcsMap := fhc.CacheStatusMap() + tcsl := make(TabletsCacheStatusList, 0, len(tcsMap)) + for _, tcs := range tcsMap { + tcsl = append(tcsl, tcs) + } + sort.Sort(tcsl) + return tcsl +} + // CacheStatusMap returns a map of the health check cache. func (fhc *FakeHealthCheck) CacheStatusMap() map[string]*TabletsCacheStatus { tcsMap := make(map[string]*TabletsCacheStatus) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 9d17005d0ad..20e16875748 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -92,6 +92,14 @@ var ( // How much to sleep between each check. waitAvailableTabletInterval = 100 * time.Millisecond + + // HealthCheckCacheTemplate uses healthCheckTemplate with the `HealthCheck Tablet - Cache` title to create the + // HTML code required to render the cache of the HealthCheck. + HealthCheckCacheTemplate = fmt.Sprintf(healthCheckTemplate, "HealthCheck - Cache") + + // HealthCheckHealthyTemplate uses healthCheckTemplate with the `HealthCheck Tablet - Healthy Tablets` title to + // create the HTML code required to render the list of healthy tablets from the HealthCheck. + HealthCheckHealthyTemplate = fmt.Sprintf(healthCheckTemplate, "HealthCheck - Healthy Tablets") ) // See the documentation for NewHealthCheck below for an explanation of these parameters. @@ -104,8 +112,9 @@ const ( // DefaultTopologyWatcherRefreshInterval is used as the default value for // the refresh interval of a topology watcher. DefaultTopologyWatcherRefreshInterval = 1 * time.Minute - // HealthCheckTemplate is the HTML code to display a TabletsCacheStatusList - HealthCheckTemplate = ` + // healthCheckTemplate is the HTML code to display a TabletsCacheStatusList, it takes a parameter for the title + // as the template can be used for both HealthCheck's cache and healthy tablets list. + healthCheckTemplate = ` - + @@ -193,6 +202,9 @@ type HealthCheck interface { // CacheStatus returns a displayable version of the health check cache. CacheStatus() TabletsCacheStatusList + // HealthyStatus returns a displayable version of the health check healthy list. + HealthyStatus() TabletsCacheStatusList + // CacheStatusMap returns a map of the health check cache. CacheStatusMap() map[string]*TabletsCacheStatus @@ -622,28 +634,55 @@ func (hc *HealthCheckImpl) CacheStatus() TabletsCacheStatusList { return tcsl } +// HealthyStatus returns a displayable version of the cache. +func (hc *HealthCheckImpl) HealthyStatus() TabletsCacheStatusList { + tcsMap := hc.HealthyStatusMap() + tcsl := make(TabletsCacheStatusList, 0, len(tcsMap)) + for _, tcs := range tcsMap { + tcsl = append(tcsl, tcs) + } + sort.Sort(tcsl) + return tcsl +} + func (hc *HealthCheckImpl) CacheStatusMap() map[string]*TabletsCacheStatus { tcsMap := make(map[string]*TabletsCacheStatus) hc.mu.Lock() defer hc.mu.Unlock() for _, ths := range hc.healthData { for _, th := range ths { - key := fmt.Sprintf("%v.%v.%v.%v", th.Tablet.Alias.Cell, th.Target.Keyspace, th.Target.Shard, th.Target.TabletType.String()) - var tcs *TabletsCacheStatus - var ok bool - if tcs, ok = tcsMap[key]; !ok { - tcs = &TabletsCacheStatus{ - Cell: th.Tablet.Alias.Cell, - Target: th.Target, - } - tcsMap[key] = tcs - } - tcs.TabletsStats = append(tcs.TabletsStats, th) + tabletHealthToTabletCacheStatus(th, tcsMap) } } return tcsMap } +func (hc *HealthCheckImpl) HealthyStatusMap() map[string]*TabletsCacheStatus { + tcsMap := make(map[string]*TabletsCacheStatus) + hc.mu.Lock() + defer hc.mu.Unlock() + for _, ths := range hc.healthy { + for _, th := range ths { + tabletHealthToTabletCacheStatus(th, tcsMap) + } + } + return tcsMap +} + +func tabletHealthToTabletCacheStatus(th *TabletHealth, tcsMap map[string]*TabletsCacheStatus) { + key := fmt.Sprintf("%v.%v.%v.%v", th.Tablet.Alias.Cell, th.Target.Keyspace, th.Target.Shard, th.Target.TabletType.String()) + var tcs *TabletsCacheStatus + var ok bool + if tcs, ok = tcsMap[key]; !ok { + tcs = &TabletsCacheStatus{ + Cell: th.Tablet.Alias.Cell, + Target: th.Target, + } + tcsMap[key] = tcs + } + tcs.TabletsStats = append(tcs.TabletsStats, th) +} + // Close stops the healthcheck. func (hc *HealthCheckImpl) Close() error { hc.mu.Lock() diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 5fadc57eb2e..9563d9bfdc5 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -1267,7 +1267,7 @@ func TestTemplate(t *testing.T) { TabletsStats: ts, } templ := template.New("") - templ, err := templ.Parse(HealthCheckTemplate) + templ, err := templ.Parse(healthCheckTemplate) require.Nil(t, err, "error parsing template: %v", err) wr := &bytes.Buffer{} err = templ.Execute(wr, []*TabletsCacheStatus{tcs}) @@ -1295,7 +1295,7 @@ func TestDebugURLFormatting(t *testing.T) { TabletsStats: ts, } templ := template.New("") - templ, err := templ.Parse(HealthCheckTemplate) + templ, err := templ.Parse(healthCheckTemplate) require.Nil(t, err, "error parsing template") wr := &bytes.Buffer{} err = templ.Execute(wr, []*TabletsCacheStatus{tcs}) diff --git a/go/vt/vtgate/tabletgateway.go b/go/vt/vtgate/tabletgateway.go index de63da87907..9d62be2d357 100644 --- a/go/vt/vtgate/tabletgateway.go +++ b/go/vt/vtgate/tabletgateway.go @@ -428,6 +428,11 @@ func (gw *TabletGateway) TabletsCacheStatus() discovery.TabletsCacheStatusList { return gw.hc.CacheStatus() } +// TabletsHealthyStatus returns a displayable version of the health check healthy list. +func (gw *TabletGateway) TabletsHealthyStatus() discovery.TabletsCacheStatusList { + return gw.hc.HealthyStatus() +} + func (gw *TabletGateway) updateDefaultConnCollation(tablet *topodatapb.Tablet) { if atomic.CompareAndSwapUint32(&gw.defaultConnCollation, 0, tablet.DefaultConnCollation) { return diff --git a/go/vt/vttablet/tabletserver/txthrottler/mock_healthcheck_test.go b/go/vt/vttablet/tabletserver/txthrottler/mock_healthcheck_test.go index 1e503dc7020..3b298cacddf 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/mock_healthcheck_test.go +++ b/go/vt/vttablet/tabletserver/txthrottler/mock_healthcheck_test.go @@ -59,6 +59,14 @@ func (m *MockHealthCheck) CacheStatus() discovery.TabletsCacheStatusList { return ret0 } +// HealthyStatus mocks base method. +func (m *MockHealthCheck) HealthyStatus() discovery.TabletsCacheStatusList { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthyStatus") + ret0, _ := ret[0].(discovery.TabletsCacheStatusList) + return ret0 +} + // CacheStatus indicates an expected call of CacheStatus. func (mr *MockHealthCheckMockRecorder) CacheStatus() *gomock.Call { mr.mock.ctrl.T.Helper() From 4edc0f3116bbcdf870023668773d4d6eea628745 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Wed, 15 Nov 2023 21:09:30 -0600 Subject: [PATCH 022/119] Fix missing query serving error code (#14520) Signed-off-by: Florent Poinsard --- go/vt/vterrors/code.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/vt/vterrors/code.go b/go/vt/vterrors/code.go index 80e1b0edd34..e619c6fff59 100644 --- a/go/vt/vterrors/code.go +++ b/go/vt/vterrors/code.go @@ -22,6 +22,9 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) +// Errors added to the list of variables below must be added to the Errors slice a little below in this same file. +// This will enable the auto-documentation of error code in the website repository. + var ( VT03001 = errorWithState("VT03001", vtrpcpb.Code_INVALID_ARGUMENT, SyntaxError, "aggregate functions take a single argument '%s'", "This aggregation function only takes a single argument.") VT03002 = errorWithState("VT03002", vtrpcpb.Code_INVALID_ARGUMENT, ForbidSchemaChange, "changing schema from '%s' to '%s' is not allowed", "This schema change is not allowed. You cannot change the keyspace of a table.") @@ -99,6 +102,8 @@ var ( VT14004 = errorWithoutState("VT14004", vtrpcpb.Code_UNAVAILABLE, "cannot find keyspace for: %s", "The specified keyspace could not be found.") VT14005 = errorWithoutState("VT14005", vtrpcpb.Code_UNAVAILABLE, "cannot lookup sidecar database for keyspace: %s", "Failed to read sidecar database identifier.") + // Errors is a list of errors that must match all the variables + // defined above to enable auto-documentation of error codes. Errors = []func(args ...any) *VitessError{ VT03001, VT03002, @@ -154,6 +159,7 @@ var ( VT09016, VT09017, VT09018, + VT09019, VT10001, VT10002, VT12001, From e6229928d1adbb6262fbf72085e16686dc083bdd Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:10:22 +0530 Subject: [PATCH 023/119] Fix type coercion in cascading non-literal updates (#14524) Signed-off-by: Manan Gupta --- go/test/endtoend/vtgate/foreignkey/fk_test.go | 7 ++++ go/vt/vtgate/engine/cached_size.go | 4 +-- go/vt/vtgate/engine/fk_cascade.go | 27 ++++++++++---- go/vt/vtgate/planbuilder/operators/update.go | 8 +++++ .../testdata/foreignkey_cases.json | 35 +++++++++++-------- 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index a05f0de7ac1..7a29136e915 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -880,6 +880,13 @@ func TestFkQueries(t *testing.T) { "insert into fk_multicol_t16 (id, cola, colb) values (1,1,1),(2,2,2)", "update fk_multicol_t15 set cola = 3, colb = (id * 2) - 2", }, + }, { + name: "Update that sets to 0 and -0 values", + queries: []string{ + "insert into fk_t15 (id, col) values (1,'-0'), (2, '0'), (3, '5'), (4, '-5')", + "insert into fk_t16 (id, col) values (1,'-0'), (2, '0'), (3, '5'), (4, '-5')", + "update fk_t15 set col = col * (col - (col))", + }, }, } diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 6121ad5f675..a18e2108c4a 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -290,7 +290,7 @@ func (cached *FkChild) CachedSize(alloc bool) int64 { } // field NonLiteralInfo []vitess.io/vitess/go/vt/vtgate/engine.NonLiteralUpdateInfo { - size += hack.RuntimeAllocSize(int64(cap(cached.NonLiteralInfo)) * int64(32)) + size += hack.RuntimeAllocSize(int64(cap(cached.NonLiteralInfo)) * int64(40)) for _, elem := range cached.NonLiteralInfo { size += elem.CachedSize(false) } @@ -625,7 +625,7 @@ func (cached *NonLiteralUpdateInfo) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(32) + size += int64(48) } // field UpdateExprBvName string size += hack.RuntimeAllocSize(int64(len(cached.UpdateExprBvName))) diff --git a/go/vt/vtgate/engine/fk_cascade.go b/go/vt/vtgate/engine/fk_cascade.go index 691e326fec7..94732ae161b 100644 --- a/go/vt/vtgate/engine/fk_cascade.go +++ b/go/vt/vtgate/engine/fk_cascade.go @@ -25,6 +25,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) // FkChild contains the Child Primitive to be executed collecting the values from the Selection Primitive using the column indexes. @@ -40,14 +41,16 @@ type FkChild struct { } // NonLiteralUpdateInfo stores the information required to process non-literal update queries. -// It stores 3 information- -// 1. UpdateExprCol- The index of the updated expression in the select query. -// 2. UpdateExprBvName- The bind variable name to store the updated expression into. -// 3. CompExprCol- The index of the comparison expression in the select query to know if the row value is actually being changed or not. +// It stores 4 information- +// 1. ExprCol- The index of the column being updated in the select query. +// 2. CompExprCol- The index of the comparison expression in the select query to know if the row value is actually being changed or not. +// 3. UpdateExprCol- The index of the updated expression in the select query. +// 4. UpdateExprBvName- The bind variable name to store the updated expression into. type NonLiteralUpdateInfo struct { + ExprCol int + CompExprCol int UpdateExprCol int UpdateExprBvName string - CompExprCol int } // FkCascade is a primitive that implements foreign key cascading using Selection as values required to execute the FkChild Primitives. @@ -185,7 +188,19 @@ func (fkc *FkCascade) executeNonLiteralExprFkChild(ctx context.Context, vcursor // Next, we need to copy the updated expressions value into the bind variables map. for _, info := range child.NonLiteralInfo { - bindVars[info.UpdateExprBvName] = sqltypes.ValueBindVariable(row[info.UpdateExprCol]) + // Type case the value to that of the column that we are updating. + // This is required for example when we receive an updated float value of -0, but + // the column being updated is a varchar column, then if we don't coerce the value of -0 to + // varchar, MySQL ends up setting it to '0' instead of '-0'. + finalVal := row[info.UpdateExprCol] + if !finalVal.IsNull() { + var err error + finalVal, err = evalengine.CoerceTo(finalVal, selectionRes.Fields[info.ExprCol].Type) + if err != nil { + return err + } + } + bindVars[info.UpdateExprBvName] = sqltypes.ValueBindVariable(finalVal) } _, err := vcursor.ExecutePrimitive(ctx, child.Exec, bindVars, wantfields) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index b7a3a4da2d6..9d39b2f4fc7 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -334,6 +334,7 @@ func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sql info := engine.NonLiteralUpdateInfo{ CompExprCol: -1, UpdateExprCol: -1, + ExprCol: -1, } // Add the expressions to the select expressions. We make sure to reuse the offset if it has already been added once. for idx, selectExpr := range exprs { @@ -343,6 +344,9 @@ func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sql if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, updExpr.Expr) { info.UpdateExprCol = idx } + if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, updExpr.Name) { + info.ExprCol = idx + } } // If the expression doesn't exist, then we add the expression and store the offset. if info.CompExprCol == -1 { @@ -353,6 +357,10 @@ func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sql info.UpdateExprCol = len(exprs) exprs = append(exprs, aeWrap(updExpr.Expr)) } + if info.ExprCol == -1 { + info.ExprCol = len(exprs) + exprs = append(exprs, aeWrap(updExpr.Name)) + } return info, exprs } diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index 0a57806cb1d..f77cb4aeac3 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -840,9 +840,10 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 1, "UpdateExprCol": 2, - "UpdateExprBvName": "fkc_upd", - "CompExprCol": 1 + "UpdateExprBvName": "fkc_upd" } ], "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", @@ -901,9 +902,10 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 1, "UpdateExprCol": 2, - "UpdateExprBvName": "fkc_upd", - "CompExprCol": 1 + "UpdateExprBvName": "fkc_upd" } ], "Inputs": [ @@ -958,9 +960,10 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 1, "UpdateExprCol": 2, - "UpdateExprBvName": "fkc_upd1", - "CompExprCol": 1 + "UpdateExprBvName": "fkc_upd1" } ], "Inputs": [ @@ -2102,9 +2105,10 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 1, "UpdateExprCol": 2, - "UpdateExprBvName": "fkc_upd", - "CompExprCol": 1 + "UpdateExprBvName": "fkc_upd" } ], "Inputs": [ @@ -2199,9 +2203,10 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 2, "UpdateExprCol": 3, - "UpdateExprBvName": "fkc_upd", - "CompExprCol": 2 + "UpdateExprBvName": "fkc_upd" } ], "Inputs": [ @@ -2327,14 +2332,16 @@ ], "NonLiteralUpdateInfo": [ { + "ExprCol": 0, + "CompExprCol": 2, "UpdateExprCol": 3, - "UpdateExprBvName": "fkc_upd", - "CompExprCol": 2 + "UpdateExprBvName": "fkc_upd" }, { + "ExprCol": 1, + "CompExprCol": 4, "UpdateExprCol": 5, - "UpdateExprBvName": "fkc_upd1", - "CompExprCol": 4 + "UpdateExprBvName": "fkc_upd1" } ], "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl3 set cola = :fkc_upd, colb = :fkc_upd1 where (cola, colb) in ::fkc_vals", From ccf3017d52a433439593fa7cac47a7a0ed322e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 16 Nov 2023 10:43:54 +0100 Subject: [PATCH 024/119] Use hash joins when nested loop joins are not feasible (#14448) --- go/sqltypes/type.go | 4 + .../queries/aggregation/distinct_test.go | 8 +- .../vtgate/queries/derived/derived_test.go | 35 +- .../vtgate/queries/derived/schema.sql | 4 +- .../vtgate/queries/orderby/orderby_test.go | 4 +- .../vtgate/queries/random/simplifier_test.go | 32 +- .../queries/reference/reference_test.go | 2 +- .../vtgate/queries/subquery/subquery_test.go | 2 +- go/vt/vtgate/engine/fake_vcursor_test.go | 30 +- go/vt/vtgate/engine/hash_join.go | 266 +++++---- go/vt/vtgate/engine/hash_join_test.go | 244 ++++---- go/vt/vtgate/engine/insert_test.go | 16 +- go/vt/vtgate/engine/join.go | 2 +- go/vt/vtgate/engine/join_test.go | 12 +- go/vt/vtgate/engine/route_test.go | 112 ++-- go/vt/vtgate/engine/semi_join_test.go | 2 +- go/vt/vtgate/engine/simple_projection_test.go | 6 +- .../engine/uncorrelated_subquery_test.go | 4 +- go/vt/vtgate/evalengine/api_coerce.go | 68 +++ go/vt/vtgate/evalengine/api_hash_test.go | 10 +- go/vt/vtgate/evalengine/collation.go | 4 +- go/vt/vtgate/evalengine/compiler.go | 2 +- go/vt/vtgate/evalengine/eval.go | 2 +- go/vt/vtgate/evalengine/expr_compare.go | 2 +- go/vt/vtgate/planbuilder/join.go | 13 + .../planbuilder/operator_transformers.go | 57 ++ .../operators/aggregation_pushing.go | 20 +- .../planbuilder/operators/aggregator.go | 7 +- .../planbuilder/operators/apply_join.go | 14 +- .../vtgate/planbuilder/operators/ast_to_op.go | 2 +- .../vtgate/planbuilder/operators/distinct.go | 3 +- .../planbuilder/operators/expressions.go | 4 +- go/vt/vtgate/planbuilder/operators/filter.go | 7 +- .../vtgate/planbuilder/operators/hash_join.go | 327 +++++++++++ .../planbuilder/operators/hash_join_test.go | 100 ++++ .../operators/horizon_expanding.go | 6 +- go/vt/vtgate/planbuilder/operators/join.go | 5 +- go/vt/vtgate/planbuilder/operators/joins.go | 7 +- .../planbuilder/operators/offset_planning.go | 11 +- .../vtgate/planbuilder/operators/ordering.go | 3 +- go/vt/vtgate/planbuilder/operators/phases.go | 21 +- .../planbuilder/operators/projection.go | 13 +- .../planbuilder/operators/query_planning.go | 48 +- .../operators/rewrite/rewriters.go | 20 +- go/vt/vtgate/planbuilder/operators/route.go | 7 +- .../planbuilder/operators/route_planning.go | 22 +- .../vtgate/planbuilder/operators/subquery.go | 5 +- .../operators/subquery_planning.go | 18 +- .../planbuilder/operators/union_merging.go | 2 +- .../planbuilder/operators/utils_test.go | 90 +++ .../planbuilder/testdata/from_cases.json | 125 +++++ .../planbuilder/testdata/hash_joins.txt | 531 ------------------ .../testdata/unsupported_cases.json | 9 +- go/vt/vtgate/semantics/semantic_state.go | 10 +- go/vt/vttablet/tabletserver/rules/rules.go | 15 +- 55 files changed, 1391 insertions(+), 1004 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/operators/hash_join.go create mode 100644 go/vt/vtgate/planbuilder/operators/hash_join_test.go create mode 100644 go/vt/vtgate/planbuilder/operators/utils_test.go delete mode 100644 go/vt/vtgate/planbuilder/testdata/hash_joins.txt diff --git a/go/sqltypes/type.go b/go/sqltypes/type.go index 9157db685e9..d3436ed8718 100644 --- a/go/sqltypes/type.go +++ b/go/sqltypes/type.go @@ -89,6 +89,10 @@ func IsText(t querypb.Type) bool { return int(t)&flagIsText == flagIsText } +func IsTextOrBinary(t querypb.Type) bool { + return int(t)&flagIsText == flagIsText || int(t)&flagIsBinary == flagIsBinary +} + // IsBinary returns true if querypb.Type is a binary. // If you have a Value object, use its member function. func IsBinary(t querypb.Type) bool { diff --git a/go/test/endtoend/vtgate/queries/aggregation/distinct_test.go b/go/test/endtoend/vtgate/queries/aggregation/distinct_test.go index 0a06190923c..3ec27dae6a6 100644 --- a/go/test/endtoend/vtgate/queries/aggregation/distinct_test.go +++ b/go/test/endtoend/vtgate/queries/aggregation/distinct_test.go @@ -46,9 +46,9 @@ func TestDistinctIt(t *testing.T) { mcmp.AssertMatchesNoOrder("select distinct id from aggr_test", `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(5)] [INT64(4)] [INT64(6)] [INT64(7)] [INT64(8)]]`) if utils.BinaryIsAtLeastAtVersion(17, "vtgate") { - mcmp.AssertMatches("select /*vt+ PLANNER=Gen4 */ distinct val1 from aggr_test order by val1 desc", `[[VARCHAR("e")] [VARCHAR("d")] [VARCHAR("c")] [VARCHAR("b")] [VARCHAR("a")]]`) - mcmp.AssertMatchesNoOrder("select /*vt+ PLANNER=Gen4 */ distinct val1, count(*) from aggr_test group by val1", `[[VARCHAR("a") INT64(2)] [VARCHAR("b") INT64(1)] [VARCHAR("c") INT64(2)] [VARCHAR("d") INT64(1)] [VARCHAR("e") INT64(2)]]`) - mcmp.AssertMatchesNoOrder("select /*vt+ PLANNER=Gen4 */ distinct val1+val2 from aggr_test", `[[NULL] [FLOAT64(1)] [FLOAT64(3)] [FLOAT64(4)]]`) - mcmp.AssertMatchesNoOrder("select /*vt+ PLANNER=Gen4 */ distinct count(*) from aggr_test group by val1", `[[INT64(2)] [INT64(1)]]`) + mcmp.AssertMatches("select distinct val1 from aggr_test order by val1 desc", `[[VARCHAR("e")] [VARCHAR("d")] [VARCHAR("c")] [VARCHAR("b")] [VARCHAR("a")]]`) + mcmp.AssertMatchesNoOrder("select distinct val1, count(*) from aggr_test group by val1", `[[VARCHAR("a") INT64(2)] [VARCHAR("b") INT64(1)] [VARCHAR("c") INT64(2)] [VARCHAR("d") INT64(1)] [VARCHAR("e") INT64(2)]]`) + mcmp.AssertMatchesNoOrder("select distinct val1+val2 from aggr_test", `[[NULL] [FLOAT64(1)] [FLOAT64(3)] [FLOAT64(4)]]`) + mcmp.AssertMatchesNoOrder("select distinct count(*) from aggr_test group by val1", `[[INT64(2)] [INT64(1)]]`) } } diff --git a/go/test/endtoend/vtgate/queries/derived/derived_test.go b/go/test/endtoend/vtgate/queries/derived/derived_test.go index c3360ee4135..293dddb355c 100644 --- a/go/test/endtoend/vtgate/queries/derived/derived_test.go +++ b/go/test/endtoend/vtgate/queries/derived/derived_test.go @@ -52,7 +52,7 @@ func TestDerivedTableWithOrderByLimit(t *testing.T) { mcmp, closer := start(t) defer closer() - mcmp.Exec("select /*vt+ PLANNER=Gen4 */ music.id from music join (select id,name from user order by id limit 2) as d on music.user_id = d.id") + mcmp.Exec("select music.id from music join (select id,name from user order by id limit 2) as d on music.user_id = d.id") } func TestDerivedAggregationOnRHS(t *testing.T) { @@ -60,14 +60,14 @@ func TestDerivedAggregationOnRHS(t *testing.T) { defer closer() mcmp.Exec("set sql_mode = ''") - mcmp.Exec("select /*vt+ PLANNER=Gen4 */ d.a from music join (select id, count(*) as a from user) as d on music.user_id = d.id group by 1") + mcmp.Exec("select d.a from music join (select id, count(*) as a from user) as d on music.user_id = d.id group by 1") } func TestDerivedRemoveInnerOrderBy(t *testing.T) { mcmp, closer := start(t) defer closer() - mcmp.Exec("select /*vt+ PLANNER=Gen4 */ count(*) from (select user.id as oui, music.id as non from user join music on user.id = music.user_id order by user.name) as toto") + mcmp.Exec("select count(*) from (select user.id as oui, music.id as non from user join music on user.id = music.user_id order by user.name) as toto") } func TestDerivedTableWithHaving(t *testing.T) { @@ -76,7 +76,7 @@ func TestDerivedTableWithHaving(t *testing.T) { mcmp.Exec("set sql_mode = ''") // For the given query, we can get any id back, because we aren't grouping by it. - mcmp.AssertMatchesAnyNoCompare("select /*vt+ PLANNER=Gen4 */ * from (select id from user having count(*) >= 1) s", + mcmp.AssertMatchesAnyNoCompare("select * from (select id from user having count(*) >= 1) s", "[[INT64(1)]]", "[[INT64(2)]]", "[[INT64(3)]]", "[[INT64(4)]]", "[[INT64(5)]]") } @@ -84,6 +84,31 @@ func TestDerivedTableColumns(t *testing.T) { mcmp, closer := start(t) defer closer() - mcmp.AssertMatches(`SELECT /*vt+ PLANNER=gen4 */ t.id FROM (SELECT id FROM user) AS t(id) ORDER BY t.id DESC`, + mcmp.AssertMatches(`SELECT t.id FROM (SELECT id FROM user) AS t(id) ORDER BY t.id DESC`, `[[INT64(5)] [INT64(4)] [INT64(3)] [INT64(2)] [INT64(1)]]`) } + +// TestDerivedTablesWithLimit tests queries where we have to limit the right hand side of the join. +// We do this by not using the apply join we usually use, and instead use the hash join engine primitive +// These tests exercise these situations +func TestDerivedTablesWithLimit(t *testing.T) { + // We need full type info before planning this, so we wait for the schema tracker + require.NoError(t, + utils.WaitForAuthoritative(t, keyspaceName, "user", clusterInstance.VtgateProcess.ReadVSchema)) + + mcmp, closer := start(t) + defer closer() + + mcmp.Exec("insert into user(id, name) values(6,'pikachu')") + + mcmp.AssertMatchesNoOrder( + `SELECT u.id, m.id FROM + (SELECT id, name FROM user LIMIT 10) AS u JOIN + (SELECT id, user_id FROM music LIMIT 10) as m on u.id = m.user_id`, + `[[INT64(1) INT64(1)] [INT64(5) INT64(2)] [INT64(1) INT64(3)] [INT64(2) INT64(4)] [INT64(3) INT64(5)] [INT64(5) INT64(7)] [INT64(4) INT64(6)]]`) + + mcmp.AssertMatchesNoOrder( + `SELECT u.id, m.id FROM user AS u LEFT JOIN + (SELECT id, user_id FROM music LIMIT 10) as m on u.id = m.user_id`, + `[[INT64(1) INT64(1)] [INT64(5) INT64(2)] [INT64(1) INT64(3)] [INT64(2) INT64(4)] [INT64(3) INT64(5)] [INT64(5) INT64(7)] [INT64(4) INT64(6)] [INT64(6) NULL]]`) +} diff --git a/go/test/endtoend/vtgate/queries/derived/schema.sql b/go/test/endtoend/vtgate/queries/derived/schema.sql index cf608028ed5..3cb8619d93b 100644 --- a/go/test/endtoend/vtgate/queries/derived/schema.sql +++ b/go/test/endtoend/vtgate/queries/derived/schema.sql @@ -1,13 +1,13 @@ create table user ( - id bigint, + id bigint, name varchar(255), primary key (id) ) Engine = InnoDB; create table music ( - id bigint, + id bigint, user_id bigint, primary key (id) ) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/queries/orderby/orderby_test.go b/go/test/endtoend/vtgate/queries/orderby/orderby_test.go index dd48a09fec7..43f800ee24c 100644 --- a/go/test/endtoend/vtgate/queries/orderby/orderby_test.go +++ b/go/test/endtoend/vtgate/queries/orderby/orderby_test.go @@ -68,7 +68,7 @@ func TestOrderBy(t *testing.T) { mcmp.AssertMatches("select id1, id2 from t4 order by id1 desc", `[[INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(5) VARCHAR("test")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`) // test ordering of complex column if utils.BinaryIsAtLeastAtVersion(17, "vtgate") { - mcmp.AssertMatches("select /*vt+ PLANNER=Gen4 */ id1, id2 from t4 order by reverse(id2) desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(2) VARCHAR("Abc")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(1) VARCHAR("a")]]`) + mcmp.AssertMatches("select id1, id2 from t4 order by reverse(id2) desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(2) VARCHAR("Abc")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(1) VARCHAR("a")]]`) } defer func() { @@ -80,6 +80,6 @@ func TestOrderBy(t *testing.T) { mcmp.AssertMatches("select id1, id2 from t4 order by id2 desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`) mcmp.AssertMatches("select id1, id2 from t4 order by id1 desc", `[[INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(5) VARCHAR("test")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`) if utils.BinaryIsAtLeastAtVersion(17, "vtgate") { - mcmp.AssertMatches("select /*vt+ PLANNER=Gen4 */ id1, id2 from t4 order by reverse(id2) desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(2) VARCHAR("Abc")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(1) VARCHAR("a")]]`) + mcmp.AssertMatches("select id1, id2 from t4 order by reverse(id2) desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(2) VARCHAR("Abc")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(1) VARCHAR("a")]]`) } } diff --git a/go/test/endtoend/vtgate/queries/random/simplifier_test.go b/go/test/endtoend/vtgate/queries/random/simplifier_test.go index 478ee355d34..2be9ef8ab93 100644 --- a/go/test/endtoend/vtgate/queries/random/simplifier_test.go +++ b/go/test/endtoend/vtgate/queries/random/simplifier_test.go @@ -36,22 +36,22 @@ func TestSimplifyResultsMismatchedQuery(t *testing.T) { t.Skip("Skip CI") var queries []string - queries = append(queries, "select /*vt+ PLANNER=Gen4 */ (68 - -16) / case false when -45 then 3 when 28 then -43 else -62 end as crandom0 from dept as tbl0, (select /*vt+ PLANNER=Gen4 */ distinct not not false and count(*) from emp as tbl0, emp as tbl1 where tbl1.ename) as tbl1 limit 1", - "select /*vt+ PLANNER=Gen4 */ distinct case true when 'burro' then 'trout' else 'elf' end < case count(distinct true) when 'bobcat' then 'turkey' else 'penguin' end from dept as tbl0, emp as tbl1 where 'spider'", - "select /*vt+ PLANNER=Gen4 */ distinct sum(distinct tbl1.deptno) from dept as tbl0, emp as tbl1 where tbl0.deptno and tbl1.comm in (12, tbl0.deptno, case false when 67 then -17 when -78 then -35 end, -76 >> -68)", - "select /*vt+ PLANNER=Gen4 */ count(*) + 1 from emp as tbl0 order by count(*) desc", - "select /*vt+ PLANNER=Gen4 */ count(2 >> tbl2.mgr), sum(distinct tbl2.empno <=> 15) from emp as tbl0 left join emp as tbl2 on -32", - "select /*vt+ PLANNER=Gen4 */ sum(case false when true then tbl1.deptno else -154 / 132 end) as caggr1 from emp as tbl0, dept as tbl1", - "select /*vt+ PLANNER=Gen4 */ tbl1.dname as cgroup0, tbl1.dname as cgroup1 from dept as tbl0, dept as tbl1 group by tbl1.dname, tbl1.deptno order by tbl1.deptno desc", - "select /*vt+ PLANNER=Gen4 */ tbl0.ename as cgroup1 from emp as tbl0 group by tbl0.job, tbl0.ename having sum(tbl0.mgr) = sum(tbl0.mgr) order by tbl0.job desc, tbl0.ename asc limit 8", - "select /*vt+ PLANNER=Gen4 */ distinct count(*) as caggr1 from dept as tbl0, emp as tbl1 group by tbl1.sal having max(tbl1.comm) != true", - "select /*vt+ PLANNER=Gen4 */ distinct sum(tbl1.loc) as caggr0 from dept as tbl0, dept as tbl1 group by tbl1.deptno having max(tbl1.dname) <= 1", - "select /*vt+ PLANNER=Gen4 */ min(tbl0.deptno) as caggr0 from dept as tbl0, emp as tbl1 where case when false then tbl0.dname end group by tbl1.comm", - "select /*vt+ PLANNER=Gen4 */ count(*) as caggr0, 1 as crandom0 from dept as tbl0, emp as tbl1 where 1 = 0", - "select /*vt+ PLANNER=Gen4 */ count(*) as caggr0, 1 as crandom0 from dept as tbl0, emp as tbl1 where 'octopus'", - "select /*vt+ PLANNER=Gen4 */ distinct 'octopus' as crandom0 from dept as tbl0, emp as tbl1 where tbl0.deptno = tbl1.empno having count(*) = count(*)", - "select /*vt+ PLANNER=Gen4 */ max(tbl0.deptno) from dept as tbl0 right join emp as tbl1 on tbl0.deptno = tbl1.empno and tbl0.deptno = tbl1.deptno group by tbl0.deptno", - "select /*vt+ PLANNER=Gen4 */ count(tbl1.comm) from emp as tbl1 right join emp as tbl2 on tbl1.mgr = tbl2.sal") + queries = append(queries, "select (68 - -16) / case false when -45 then 3 when 28 then -43 else -62 end as crandom0 from dept as tbl0, (select distinct not not false and count(*) from emp as tbl0, emp as tbl1 where tbl1.ename) as tbl1 limit 1", + "select distinct case true when 'burro' then 'trout' else 'elf' end < case count(distinct true) when 'bobcat' then 'turkey' else 'penguin' end from dept as tbl0, emp as tbl1 where 'spider'", + "select distinct sum(distinct tbl1.deptno) from dept as tbl0, emp as tbl1 where tbl0.deptno and tbl1.comm in (12, tbl0.deptno, case false when 67 then -17 when -78 then -35 end, -76 >> -68)", + "select count(*) + 1 from emp as tbl0 order by count(*) desc", + "select count(2 >> tbl2.mgr), sum(distinct tbl2.empno <=> 15) from emp as tbl0 left join emp as tbl2 on -32", + "select sum(case false when true then tbl1.deptno else -154 / 132 end) as caggr1 from emp as tbl0, dept as tbl1", + "select tbl1.dname as cgroup0, tbl1.dname as cgroup1 from dept as tbl0, dept as tbl1 group by tbl1.dname, tbl1.deptno order by tbl1.deptno desc", + "select tbl0.ename as cgroup1 from emp as tbl0 group by tbl0.job, tbl0.ename having sum(tbl0.mgr) = sum(tbl0.mgr) order by tbl0.job desc, tbl0.ename asc limit 8", + "select distinct count(*) as caggr1 from dept as tbl0, emp as tbl1 group by tbl1.sal having max(tbl1.comm) != true", + "select distinct sum(tbl1.loc) as caggr0 from dept as tbl0, dept as tbl1 group by tbl1.deptno having max(tbl1.dname) <= 1", + "select min(tbl0.deptno) as caggr0 from dept as tbl0, emp as tbl1 where case when false then tbl0.dname end group by tbl1.comm", + "select count(*) as caggr0, 1 as crandom0 from dept as tbl0, emp as tbl1 where 1 = 0", + "select count(*) as caggr0, 1 as crandom0 from dept as tbl0, emp as tbl1 where 'octopus'", + "select distinct 'octopus' as crandom0 from dept as tbl0, emp as tbl1 where tbl0.deptno = tbl1.empno having count(*) = count(*)", + "select max(tbl0.deptno) from dept as tbl0 right join emp as tbl1 on tbl0.deptno = tbl1.empno and tbl0.deptno = tbl1.deptno group by tbl0.deptno", + "select count(tbl1.comm) from emp as tbl1 right join emp as tbl2 on tbl1.mgr = tbl2.sal") for _, query := range queries { var simplified string diff --git a/go/test/endtoend/vtgate/queries/reference/reference_test.go b/go/test/endtoend/vtgate/queries/reference/reference_test.go index 75efc840880..9c2508a889f 100644 --- a/go/test/endtoend/vtgate/queries/reference/reference_test.go +++ b/go/test/endtoend/vtgate/queries/reference/reference_test.go @@ -114,7 +114,7 @@ func TestReferenceRouting(t *testing.T) { utils.AssertMatches( t, conn, - `SELECT /*vt+ PLANNER=gen4 */ COUNT(zd.id) + `SELECT COUNT(zd.id) FROM delivery_failure df JOIN zip_detail zd ON zd.id = df.zip_detail_id WHERE zd.id = 3`, `[[INT64(0)]]`, diff --git a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go index 01cc7b2ee54..371de19dbe6 100644 --- a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go +++ b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go @@ -106,7 +106,7 @@ func TestSubqueryInUpdate(t *testing.T) { utils.Exec(t, conn, `insert into t1(id1, id2) values (1, 10), (2, 20), (3, 30), (4, 40), (5, 50)`) utils.Exec(t, conn, `insert into t2(id3, id4) values (1, 3), (2, 4)`) utils.AssertMatches(t, conn, `SELECT id2, keyspace_id FROM t1_id2_idx WHERE id2 IN (2,10)`, `[[INT64(10) VARBINARY("\x16k@\xb4J\xbaK\xd6")]]`) - utils.Exec(t, conn, `update /*vt+ PLANNER=gen4 */ t1 set id2 = (select count(*) from t2) where id1 = 1`) + utils.Exec(t, conn, `update t1 set id2 = (select count(*) from t2) where id1 = 1`) utils.AssertMatches(t, conn, `SELECT id2 FROM t1 WHERE id1 = 1`, `[[INT64(2)]]`) utils.AssertMatches(t, conn, `SELECT id2, keyspace_id FROM t1_id2_idx WHERE id2 IN (2,10)`, `[[INT64(2) VARBINARY("\x16k@\xb4J\xbaK\xd6")]]`) } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 6c99af33313..9776572f1a5 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -21,12 +21,15 @@ import ( "context" "fmt" "reflect" + "slices" "sort" "strings" "sync" "testing" "time" + "github.com/google/go-cmp/cmp" + "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" @@ -806,18 +809,39 @@ func (t *noopVCursor) GetLogs() ([]ExecuteEntry, error) { return nil, nil } -func expectResult(t *testing.T, msg string, result, want *sqltypes.Result) { +func expectResult(t *testing.T, result, want *sqltypes.Result) { t.Helper() fieldsResult := fmt.Sprintf("%v", result.Fields) fieldsWant := fmt.Sprintf("%v", want.Fields) if fieldsResult != fieldsWant { - t.Errorf("%s (mismatch in Fields):\n%s\nwant:\n%s", msg, fieldsResult, fieldsWant) + t.Errorf("mismatch in Fields\n%s\nwant:\n%s", fieldsResult, fieldsWant) } rowsResult := fmt.Sprintf("%v", result.Rows) rowsWant := fmt.Sprintf("%v", want.Rows) if rowsResult != rowsWant { - t.Errorf("%s (mismatch in Rows):\n%s\nwant:\n%s", msg, rowsResult, rowsWant) + t.Errorf("mismatch in Rows:\n%s\nwant:\n%s", rowsResult, rowsWant) + } +} + +func expectResultAnyOrder(t *testing.T, result, want *sqltypes.Result) { + t.Helper() + f := func(a, b sqltypes.Row) int { + for i := range a { + l := a[i].RawStr() + r := b[i].RawStr() + x := strings.Compare(l, r) + if x == 0 { + continue + } + return x + } + return 0 + } + slices.SortFunc(result.Rows, f) + slices.SortFunc(want.Rows, f) + if diff := cmp.Diff(want, result); diff != "" { + t.Errorf("result: %+v, want %+v\ndiff: %s", result, want, diff) } } diff --git a/go/vt/vtgate/engine/hash_join.go b/go/vt/vtgate/engine/hash_join.go index a38fc21bf97..4f205f1bcdc 100644 --- a/go/vt/vtgate/engine/hash_join.go +++ b/go/vt/vtgate/engine/hash_join.go @@ -20,48 +20,69 @@ import ( "context" "fmt" "strings" + "sync" + "sync/atomic" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vthash" ) var _ Primitive = (*HashJoin)(nil) -// HashJoin specifies the parameters for a join primitive -// Hash joins work by fetch all the input from the LHS, and building a hash map, known as the probe table, for this input. -// The key to the map is the hashcode of the value for column that we are joining by. -// Then the RHS is fetched, and we can check if the rows from the RHS matches any from the LHS. -// When they match by hash code, we double-check that we are not working with a false positive by comparing the values. -type HashJoin struct { - Opcode JoinOpcode - - // Left and Right are the LHS and RHS primitives - // of the Join. They can be any primitive. - Left, Right Primitive `json:",omitempty"` - - // Cols defines which columns from the left - // or right results should be used to build the - // return result. For results coming from the - // left query, the index values go as -1, -2, etc. - // For the right query, they're 1, 2, etc. - // If Cols is {-1, -2, 1, 2}, it means that - // the returned result will be {Left0, Left1, Right0, Right1}. - Cols []int `json:",omitempty"` - - // The keys correspond to the column offset in the inputs where - // the join columns can be found - LHSKey, RHSKey int - - // The join condition. Used for plan descriptions - ASTPred sqlparser.Expr - - // collation and type are used to hash the incoming values correctly - Collation collations.ID - ComparisonType querypb.Type -} +type ( + // HashJoin specifies the parameters for a join primitive + // Hash joins work by fetch all the input from the LHS, and building a hash map, known as the probe table, for this input. + // The key to the map is the hashcode of the value for column that we are joining by. + // Then the RHS is fetched, and we can check if the rows from the RHS matches any from the LHS. + // When they match by hash code, we double-check that we are not working with a false positive by comparing the values. + HashJoin struct { + Opcode JoinOpcode + + // Left and Right are the LHS and RHS primitives + // of the Join. They can be any primitive. + Left, Right Primitive `json:",omitempty"` + + // Cols defines which columns from the left + // or right results should be used to build the + // return result. For results coming from the + // left query, the index values go as -1, -2, etc. + // For the right query, they're 1, 2, etc. + // If Cols is {-1, -2, 1, 2}, it means that + // the returned result will be {Left0, Left1, Right0, Right1}. + Cols []int `json:",omitempty"` + + // The keys correspond to the column offset in the inputs where + // the join columns can be found + LHSKey, RHSKey int + + // The join condition. Used for plan descriptions + ASTPred sqlparser.Expr + + // collation and type are used to hash the incoming values correctly + Collation collations.ID + ComparisonType querypb.Type + } + + hashJoinProbeTable struct { + innerMap map[vthash.Hash]*probeTableEntry + + coll collations.ID + typ querypb.Type + lhsKey, rhsKey int + cols []int + hasher vthash.Hasher + } + + probeTableEntry struct { + row sqltypes.Row + next *probeTableEntry + seen bool + } +) // TryExecute implements the Primitive interface func (hj *HashJoin) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { @@ -70,10 +91,13 @@ func (hj *HashJoin) TryExecute(ctx context.Context, vcursor VCursor, bindVars ma return nil, err } + pt := newHashJoinProbeTable(hj.Collation, hj.ComparisonType, hj.LHSKey, hj.RHSKey, hj.Cols) // build the probe table from the LHS result - probeTable, err := hj.buildProbeTable(lresult) - if err != nil { - return nil, err + for _, row := range lresult.Rows { + err := pt.addLeftRow(row) + if err != nil { + return nil, err + } } rresult, err := vcursor.ExecutePrimitive(ctx, hj.Right, bindVars, wantfields) @@ -86,68 +110,37 @@ func (hj *HashJoin) TryExecute(ctx context.Context, vcursor VCursor, bindVars ma } for _, currentRHSRow := range rresult.Rows { - joinVal := currentRHSRow[hj.RHSKey] - if joinVal.IsNull() { - continue - } - hashcode, err := evalengine.NullsafeHashcode(joinVal, hj.Collation, hj.ComparisonType) + matches, err := pt.get(currentRHSRow) if err != nil { return nil, err } - lftRows := probeTable[hashcode] - for _, currentLHSRow := range lftRows { - lhsVal := currentLHSRow[hj.LHSKey] - // hash codes can give false positives, so we need to check with a real comparison as well - cmp, err := evalengine.NullsafeCompare(joinVal, lhsVal, hj.Collation) - if err != nil { - return nil, err - } + result.Rows = append(result.Rows, matches...) + } - if cmp == 0 { - // we have a match! - result.Rows = append(result.Rows, joinRows(currentLHSRow, currentRHSRow, hj.Cols)) - } - } + if hj.Opcode == LeftJoin { + result.Rows = append(result.Rows, pt.notFetched()...) } return result, nil } -func (hj *HashJoin) buildProbeTable(lresult *sqltypes.Result) (map[evalengine.HashCode][]sqltypes.Row, error) { - probeTable := map[evalengine.HashCode][]sqltypes.Row{} - for _, current := range lresult.Rows { - joinVal := current[hj.LHSKey] - if joinVal.IsNull() { - continue - } - hashcode, err := evalengine.NullsafeHashcode(joinVal, hj.Collation, hj.ComparisonType) - if err != nil { - return nil, err - } - probeTable[hashcode] = append(probeTable[hashcode], current) - } - return probeTable, nil -} - // TryStreamExecute implements the Primitive interface func (hj *HashJoin) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { // build the probe table from the LHS result - probeTable := map[evalengine.HashCode][]sqltypes.Row{} + pt := newHashJoinProbeTable(hj.Collation, hj.ComparisonType, hj.LHSKey, hj.RHSKey, hj.Cols) var lfields []*querypb.Field + var mu sync.Mutex err := vcursor.StreamExecutePrimitive(ctx, hj.Left, bindVars, wantfields, func(result *sqltypes.Result) error { + mu.Lock() + defer mu.Unlock() if len(lfields) == 0 && len(result.Fields) != 0 { lfields = result.Fields } for _, current := range result.Rows { - joinVal := current[hj.LHSKey] - if joinVal.IsNull() { - continue - } - hashcode, err := evalengine.NullsafeHashcode(joinVal, hj.Collation, hj.ComparisonType) + err := pt.addLeftRow(current) if err != nil { return err } - probeTable[hashcode] = append(probeTable[hashcode], current) } return nil }) @@ -155,43 +148,50 @@ func (hj *HashJoin) TryStreamExecute(ctx context.Context, vcursor VCursor, bindV return err } - return vcursor.StreamExecutePrimitive(ctx, hj.Right, bindVars, wantfields, func(result *sqltypes.Result) error { + var sendFields atomic.Bool + sendFields.Store(wantfields) + + err = vcursor.StreamExecutePrimitive(ctx, hj.Right, bindVars, sendFields.Load(), func(result *sqltypes.Result) error { + mu.Lock() + defer mu.Unlock() // compare the results coming from the RHS with the probe-table res := &sqltypes.Result{} - if len(result.Fields) != 0 { - res = &sqltypes.Result{ - Fields: joinFields(lfields, result.Fields, hj.Cols), - } + if len(result.Fields) != 0 && sendFields.CompareAndSwap(true, false) { + res.Fields = joinFields(lfields, result.Fields, hj.Cols) } for _, currentRHSRow := range result.Rows { - joinVal := currentRHSRow[hj.RHSKey] - if joinVal.IsNull() { - continue - } - hashcode, err := evalengine.NullsafeHashcode(joinVal, hj.Collation, hj.ComparisonType) + results, err := pt.get(currentRHSRow) if err != nil { return err } - lftRows := probeTable[hashcode] - for _, currentLHSRow := range lftRows { - lhsVal := currentLHSRow[hj.LHSKey] - // hash codes can give false positives, so we need to check with a real comparison as well - cmp, err := evalengine.NullsafeCompare(joinVal, lhsVal, hj.Collation) - if err != nil { - return err - } - - if cmp == 0 { - // we have a match! - res.Rows = append(res.Rows, joinRows(currentLHSRow, currentRHSRow, hj.Cols)) - } - } + res.Rows = append(res.Rows, results...) } if len(res.Rows) != 0 || len(res.Fields) != 0 { return callback(res) } return nil }) + if err != nil { + return err + } + + if hj.Opcode == LeftJoin { + res := &sqltypes.Result{} + if sendFields.CompareAndSwap(true, false) { + // If we still have not sent the fields, we need to fetch + // the fields from the RHS to be able to build the result fields + rres, err := hj.Right.GetFields(ctx, vcursor, bindVars) + if err != nil { + return err + } + res.Fields = joinFields(lfields, rres.Fields, hj.Cols) + } + // this will only be called when all the concurrent access to the pt has + // ceased, so we don't need to lock it here + res.Rows = pt.notFetched() + return callback(res) + } + return nil } // RouteType implements the Primitive interface @@ -256,3 +256,69 @@ func (hj *HashJoin) description() PrimitiveDescription { Other: other, } } + +func newHashJoinProbeTable(coll collations.ID, typ querypb.Type, lhsKey, rhsKey int, cols []int) *hashJoinProbeTable { + return &hashJoinProbeTable{ + innerMap: map[vthash.Hash]*probeTableEntry{}, + coll: coll, + typ: typ, + lhsKey: lhsKey, + rhsKey: rhsKey, + cols: cols, + hasher: vthash.New(), + } +} + +func (pt *hashJoinProbeTable) addLeftRow(r sqltypes.Row) error { + hash, err := pt.hash(r[pt.lhsKey]) + if err != nil { + return err + } + pt.innerMap[hash] = &probeTableEntry{ + row: r, + next: pt.innerMap[hash], + } + + return nil +} + +func (pt *hashJoinProbeTable) hash(val sqltypes.Value) (vthash.Hash, error) { + err := evalengine.NullsafeHashcode128(&pt.hasher, val, pt.coll, pt.typ) + if err != nil { + return vthash.Hash{}, err + } + + res := pt.hasher.Sum128() + pt.hasher.Reset() + return res, nil +} + +func (pt *hashJoinProbeTable) get(rrow sqltypes.Row) (result []sqltypes.Row, err error) { + val := rrow[pt.rhsKey] + if val.IsNull() { + return + } + + hash, err := pt.hash(val) + if err != nil { + return nil, err + } + + for e := pt.innerMap[hash]; e != nil; e = e.next { + e.seen = true + result = append(result, joinRows(e.row, rrow, pt.cols)) + } + + return +} + +func (pt *hashJoinProbeTable) notFetched() (rows []sqltypes.Row) { + for _, e := range pt.innerMap { + for ; e != nil; e = e.next { + if !e.seen { + rows = append(rows, joinRows(e.row, nil, pt.cols)) + } + } + } + return +} diff --git a/go/vt/vtgate/engine/hash_join_test.go b/go/vt/vtgate/engine/hash_join_test.go index 8add0b78fa2..c0a3075c6ad 100644 --- a/go/vt/vtgate/engine/hash_join_test.go +++ b/go/vt/vtgate/engine/hash_join_test.go @@ -22,126 +22,152 @@ import ( "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) -func TestHashJoinExecuteSameType(t *testing.T) { - leftPrim := &fakePrimitive{ - results: []*sqltypes.Result{ - sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2|col3", - "int64|varchar|varchar", +func TestHashJoinVariations(t *testing.T) { + // This test tries the different variations of hash-joins: + // comparing values of same type and different types, and both left and right outer joins + lhs := func() Primitive { + return &fakePrimitive{ + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2", + "int64|varchar", + ), + "1|1", + "2|2", + "3|b", + "null|b", ), - "1|a|aa", - "2|b|bb", - "3|c|cc", - ), - }, + }, + } } - rightPrim := &fakePrimitive{ - results: []*sqltypes.Result{ - sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col4|col5|col6", - "int64|varchar|varchar", + rhs := func() Primitive { + return &fakePrimitive{ + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col4|col5", + "int64|varchar", + ), + "1|1", + "3|2", + "5|null", + "4|b", ), - "1|d|dd", - "3|e|ee", - "4|f|ff", - "3|g|gg", - ), - }, + }, + } } - // Normal join - jn := &HashJoin{ - Opcode: InnerJoin, - Left: leftPrim, - Right: rightPrim, - Cols: []int{-1, -2, 1, 2}, - LHSKey: 0, - RHSKey: 0, - } - r, err := jn.TryExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{}, true) - require.NoError(t, err) - leftPrim.ExpectLog(t, []string{ - `Execute true`, - }) - rightPrim.ExpectLog(t, []string{ - `Execute true`, - }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2|col4|col5", - "int64|varchar|int64|varchar", - ), - "1|a|1|d", - "3|c|3|e", - "3|c|3|g", - )) -} + rows := func(r ...string) []string { return r } -func TestHashJoinExecuteDifferentType(t *testing.T) { - leftPrim := &fakePrimitive{ - results: []*sqltypes.Result{ - sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2|col3", - "int64|varchar|varchar", - ), - "1|a|aa", - "2|b|bb", - "3|c|cc", - "5|c|cc", - ), - }, - } - rightPrim := &fakePrimitive{ - results: []*sqltypes.Result{ - sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col4|col5|col6", - "varchar|varchar|varchar", - ), - "1.00|d|dd", - "3|e|ee", - "2.89|z|zz", - "4|f|ff", - "3|g|gg", - " 5.0toto|g|gg", - "w|ww|www", - ), - }, + tests := []struct { + name string + typ JoinOpcode + lhs, rhs int + expected []string + reverse bool + }{{ + name: "inner join, same type", + typ: InnerJoin, + lhs: 0, + rhs: 0, + expected: rows("1|1|1|1", "3|b|3|2"), + }, { + name: "inner join, coercion", + typ: InnerJoin, + lhs: 0, + rhs: 1, + expected: rows("1|1|1|1", "2|2|3|2"), + }, { + name: "left join, same type", + typ: LeftJoin, + lhs: 0, + rhs: 0, + expected: rows("1|1|1|1", "3|b|3|2", "2|2|null|null", "null|b|null|null"), + }, { + name: "left join, coercion", + typ: LeftJoin, + lhs: 0, + rhs: 1, + expected: rows("1|1|1|1", "2|2|3|2", "3|b|null|null", "null|b|null|null"), + }, { + name: "right join, same type", + typ: LeftJoin, + lhs: 0, + rhs: 0, + expected: rows("1|1|1|1", "3|2|3|b", "4|b|null|null", "5|null|null|null"), + reverse: true, + }, { + name: "right join, coercion", + typ: LeftJoin, + lhs: 0, + rhs: 1, + reverse: true, + expected: rows("1|1|1|1", "3|2|null|null", "4|b|null|null", "5|null|null|null"), + }} + + for _, tc := range tests { + + var fields []*querypb.Field + var first, last func() Primitive + if tc.reverse { + first, last = rhs, lhs + fields = sqltypes.MakeTestFields( + "col4|col5|col1|col2", + "int64|varchar|int64|varchar", + ) + } else { + first, last = lhs, rhs + fields = sqltypes.MakeTestFields( + "col1|col2|col4|col5", + "int64|varchar|int64|varchar", + ) + } + + expected := sqltypes.MakeTestResult(fields, tc.expected...) + + typ, err := evalengine.CoerceTypes(typeForOffset(tc.lhs), typeForOffset(tc.rhs)) + require.NoError(t, err) + + jn := &HashJoin{ + Opcode: tc.typ, + Cols: []int{-1, -2, 1, 2}, + LHSKey: tc.lhs, + RHSKey: tc.rhs, + Collation: typ.Coll, + ComparisonType: typ.Type, + } + + t.Run(tc.name, func(t *testing.T) { + jn.Left = first() + jn.Right = last() + r, err := jn.TryExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{}, true) + require.NoError(t, err) + expectResultAnyOrder(t, r, expected) + }) + t.Run("Streaming "+tc.name, func(t *testing.T) { + jn.Left = first() + jn.Right = last() + r, err := wrapStreamExecute(jn, &noopVCursor{}, map[string]*querypb.BindVariable{}, true) + require.NoError(t, err) + expectResultAnyOrder(t, r, expected) + }) } +} - // Normal join - jn := &HashJoin{ - Opcode: InnerJoin, - Left: leftPrim, - Right: rightPrim, - Cols: []int{-1, -2, 1, 2}, - LHSKey: 0, - RHSKey: 0, - ComparisonType: querypb.Type_FLOAT64, +func typeForOffset(i int) evalengine.Type { + switch i { + case 0: + return evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID} + case 1: + return evalengine.Type{Type: sqltypes.VarChar, Coll: collations.Default()} + default: + panic(i) } - r, err := jn.TryExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{}, true) - require.NoError(t, err) - leftPrim.ExpectLog(t, []string{ - `Execute true`, - }) - rightPrim.ExpectLog(t, []string{ - `Execute true`, - }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2|col4|col5", - "int64|varchar|varchar|varchar", - ), - "1|a|1.00|d", - "3|c|3|e", - "3|c|3|g", - "5|c| 5.0toto|g", - )) } diff --git a/go/vt/vtgate/engine/insert_test.go b/go/vt/vtgate/engine/insert_test.go index 014654f37d6..d08ef856275 100644 --- a/go/vt/vtgate/engine/insert_test.go +++ b/go/vt/vtgate/engine/insert_test.go @@ -55,7 +55,7 @@ func TestInsertUnsharded(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.0: dummy_insert {} true true`, }) - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4}) + expectResult(t, result, &sqltypes.Result{InsertID: 4}) // Failure cases vc = &loggingVCursor{shardErr: errors.New("shard_error")} @@ -117,7 +117,7 @@ func TestInsertUnshardedGenerate(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4}) + expectResult(t, result, &sqltypes.Result{InsertID: 4}) } func TestInsertUnshardedGenerate_Zeros(t *testing.T) { @@ -170,7 +170,7 @@ func TestInsertUnshardedGenerate_Zeros(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4}) + expectResult(t, result, &sqltypes.Result{InsertID: 4}) } func TestInsertShardedSimple(t *testing.T) { @@ -462,7 +462,7 @@ func TestInsertShardedGenerate(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 2}) + expectResult(t, result, &sqltypes.Result{InsertID: 2}) } func TestInsertShardedOwned(t *testing.T) { @@ -1797,7 +1797,7 @@ func TestInsertSelectGenerate(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 2}) + expectResult(t, result, &sqltypes.Result{InsertID: 2}) } func TestStreamingInsertSelectGenerate(t *testing.T) { @@ -1893,7 +1893,7 @@ func TestStreamingInsertSelectGenerate(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", output, &sqltypes.Result{InsertID: 2}) + expectResult(t, output, &sqltypes.Result{InsertID: 2}) } func TestInsertSelectGenerateNotProvided(t *testing.T) { @@ -1981,7 +1981,7 @@ func TestInsertSelectGenerateNotProvided(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 10}) + expectResult(t, result, &sqltypes.Result{InsertID: 10}) } func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { @@ -2073,7 +2073,7 @@ func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { }) // The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues. - expectResult(t, "Execute", output, &sqltypes.Result{InsertID: 10}) + expectResult(t, output, &sqltypes.Result{InsertID: 10}) } func TestInsertSelectUnowned(t *testing.T) { diff --git a/go/vt/vtgate/engine/join.go b/go/vt/vtgate/engine/join.go index ef50389c989..45b0d182dd7 100644 --- a/go/vt/vtgate/engine/join.go +++ b/go/vt/vtgate/engine/join.go @@ -225,7 +225,7 @@ func joinFields(lfields, rfields []*querypb.Field, cols []int) []*querypb.Field return fields } -func joinRows(lrow, rrow []sqltypes.Value, cols []int) []sqltypes.Value { +func joinRows(lrow, rrow sqltypes.Row, cols []int) sqltypes.Row { row := make([]sqltypes.Value, len(cols)) for i, index := range cols { if index < 0 { diff --git a/go/vt/vtgate/engine/join_test.go b/go/vt/vtgate/engine/join_test.go index 2df507f9512..eef5810ce69 100644 --- a/go/vt/vtgate/engine/join_test.go +++ b/go/vt/vtgate/engine/join_test.go @@ -89,7 +89,7 @@ func TestJoinExecute(t *testing.T) { `Execute a: type:INT64 value:"10" bv: type:VARCHAR value:"b" false`, `Execute a: type:INT64 value:"10" bv: type:VARCHAR value:"c" false`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col4|col5", "int64|varchar|int64|varchar", @@ -116,7 +116,7 @@ func TestJoinExecute(t *testing.T) { `Execute a: type:INT64 value:"10" bv: type:VARCHAR value:"b" false`, `Execute a: type:INT64 value:"10" bv: type:VARCHAR value:"c" false`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col4|col5", "int64|varchar|int64|varchar", @@ -251,7 +251,7 @@ func TestJoinExecuteNoResult(t *testing.T) { "int64|varchar|int64|varchar", ), ) - expectResult(t, "jn.Execute", r, wantResult) + expectResult(t, r, wantResult) } func TestJoinExecuteErrors(t *testing.T) { @@ -389,7 +389,7 @@ func TestJoinStreamExecute(t *testing.T) { `StreamExecute bv: type:VARCHAR value:"b" false`, `StreamExecute bv: type:VARCHAR value:"c" false`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col4|col5", "int64|varchar|int64|varchar", @@ -418,7 +418,7 @@ func TestJoinStreamExecute(t *testing.T) { `StreamExecute bv: type:VARCHAR value:"b" false`, `StreamExecute bv: type:VARCHAR value:"c" false`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col4|col5", "int64|varchar|int64|varchar", @@ -475,7 +475,7 @@ func TestGetFields(t *testing.T) { `GetFields bv: `, `Execute bv: true`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col4|col5", "int64|varchar|int64|varchar", diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index 274ac58c7d4..54c7b5c6fb4 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -74,7 +74,7 @@ func TestSelectUnsharded(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.0: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -83,7 +83,7 @@ func TestSelectUnsharded(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `StreamExecuteMulti dummy_select ks.0: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) { @@ -219,7 +219,7 @@ func TestSelectScatter(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -228,7 +228,7 @@ func TestSelectScatter(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `StreamExecuteMulti dummy_select ks.-20: {} ks.20-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectEqualUnique(t *testing.T) { @@ -257,7 +257,7 @@ func TestSelectEqualUnique(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -266,7 +266,7 @@ func TestSelectEqualUnique(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectNone(t *testing.T) { @@ -290,7 +290,7 @@ func TestSelectNone(t *testing.T) { result, err := sel.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) require.NoError(t, err) require.Empty(t, vc.log) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -308,7 +308,7 @@ func TestSelectNone(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -317,7 +317,7 @@ func TestSelectNone(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) } func TestSelectEqualUniqueScatter(t *testing.T) { @@ -351,7 +351,7 @@ func TestSelectEqualUniqueScatter(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyRange(-)`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -360,7 +360,7 @@ func TestSelectEqualUniqueScatter(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyRange(-)`, `StreamExecuteMulti dummy_select ks.-20: {} ks.20-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectEqual(t *testing.T) { @@ -403,7 +403,7 @@ func TestSelectEqual(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyspaceIDs(00,80)`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -413,7 +413,7 @@ func TestSelectEqual(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationKeyspaceIDs(00,80)`, `StreamExecuteMulti dummy_select ks.-20: {} ks.20-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectEqualNoRoute(t *testing.T) { @@ -443,7 +443,7 @@ func TestSelectEqualNoRoute(t *testing.T) { `Execute select from, toc from lkp where from in ::from from: type:TUPLE values:{type:INT64 value:"1"} false`, `ResolveDestinations ks [type:INT64 value:"1"] Destinations:DestinationNone()`, }) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -466,7 +466,7 @@ func TestSelectEqualNoRoute(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -477,7 +477,7 @@ func TestSelectEqualNoRoute(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) } func TestINUnique(t *testing.T) { @@ -513,7 +513,7 @@ func TestINUnique(t *testing.T) { `ks.20-: dummy_select {__vals: type:TUPLE values:{type:INT64 value:"4"}} ` + `false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -522,7 +522,7 @@ func TestINUnique(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1" type:INT64 value:"2" type:INT64 value:"4"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(d2fd8867d50d2dfe)`, `StreamExecuteMulti dummy_select ks.-20: {__vals: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"2"}} ks.20-: {__vals: type:TUPLE values:{type:INT64 value:"4"}} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestINNonUnique(t *testing.T) { @@ -579,7 +579,7 @@ func TestINNonUnique(t *testing.T) { `ks.20-: dummy_select {__vals: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"4"}} ` + `false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -589,7 +589,7 @@ func TestINNonUnique(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1" type:INT64 value:"2" type:INT64 value:"4"] Destinations:DestinationKeyspaceIDs(00,80),DestinationKeyspaceIDs(00),DestinationKeyspaceIDs(80)`, `StreamExecuteMulti dummy_select ks.-20: {__vals: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"2"}} ks.20-: {__vals: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"4"}} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestMultiEqual(t *testing.T) { @@ -623,7 +623,7 @@ func TestMultiEqual(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1" type:INT64 value:"2" type:INT64 value:"4"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(d2fd8867d50d2dfe)`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -632,7 +632,7 @@ func TestMultiEqual(t *testing.T) { `ResolveDestinations ks [type:INT64 value:"1" type:INT64 value:"2" type:INT64 value:"4"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(d2fd8867d50d2dfe)`, `StreamExecuteMulti dummy_select ks.-20: {} ks.20-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectLike(t *testing.T) { @@ -670,7 +670,7 @@ func TestSelectLike(t *testing.T) { `ResolveDestinations ks [type:VARCHAR value:"a%"] Destinations:DestinationKeyRange(0c-0d)`, `ExecuteMultiShard ks.-0c80: dummy_select {} ks.0c80-0d: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() @@ -681,7 +681,7 @@ func TestSelectLike(t *testing.T) { `ResolveDestinations ks [type:VARCHAR value:"a%"] Destinations:DestinationKeyRange(0c-0d)`, `StreamExecuteMulti dummy_select ks.-0c80: {} ks.0c80-0d: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() @@ -700,7 +700,7 @@ func TestSelectLike(t *testing.T) { `ResolveDestinations ks [type:VARCHAR value:"ab%"] Destinations:DestinationKeyRange(0c92-0c93)`, `ExecuteMultiShard ks.0c80-0d: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() @@ -711,7 +711,7 @@ func TestSelectLike(t *testing.T) { `ResolveDestinations ks [type:VARCHAR value:"ab%"] Destinations:DestinationKeyRange(0c92-0c93)`, `StreamExecuteMulti dummy_select ks.0c80-0d: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } @@ -736,7 +736,7 @@ func TestSelectNext(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, _ = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -744,7 +744,7 @@ func TestSelectNext(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `StreamExecuteMulti dummy_select ks.-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectDBA(t *testing.T) { @@ -768,7 +768,7 @@ func TestSelectDBA(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, _ = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -776,7 +776,7 @@ func TestSelectDBA(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectReference(t *testing.T) { @@ -800,7 +800,7 @@ func TestSelectReference(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, _ = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -808,7 +808,7 @@ func TestSelectReference(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestRouteGetFields(t *testing.T) { @@ -840,7 +840,7 @@ func TestRouteGetFields(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select_field {} false false`, }) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, true) @@ -851,7 +851,7 @@ func TestRouteGetFields(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select_field {} false false`, }) - expectResult(t, "sel.StreamExecute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() // test with special no-routes handling @@ -864,7 +864,7 @@ func TestRouteGetFields(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, true) @@ -875,7 +875,7 @@ func TestRouteGetFields(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, &sqltypes.Result{}) + expectResult(t, result, &sqltypes.Result{}) } func TestRouteSort(t *testing.T) { @@ -924,7 +924,7 @@ func TestRouteSort(t *testing.T) { "2", "3", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) sel.OrderBy[0].Desc = true vc.Rewind() @@ -940,7 +940,7 @@ func TestRouteSort(t *testing.T) { "1", "1", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) vc = &loggingVCursor{ shards: []string{"0"}, @@ -1013,7 +1013,7 @@ func TestRouteSortWeightStrings(t *testing.T) { "g|d", "v|x", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) }) t.Run("Descending ordering using weighted strings", func(t *testing.T) { @@ -1032,7 +1032,7 @@ func TestRouteSortWeightStrings(t *testing.T) { "c|t", "a|a", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) }) t.Run("Error when no weight string set", func(t *testing.T) { @@ -1118,7 +1118,7 @@ func TestRouteSortCollation(t *testing.T) { "cs", "d", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) }) t.Run("Descending ordering using Collation", func(t *testing.T) { @@ -1137,7 +1137,7 @@ func TestRouteSortCollation(t *testing.T) { "c", "c", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) }) t.Run("Error when Unknown Collation", func(t *testing.T) { @@ -1239,7 +1239,7 @@ func TestRouteSortTruncate(t *testing.T) { "2", "3", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) } func TestRouteStreamTruncate(t *testing.T) { @@ -1281,7 +1281,7 @@ func TestRouteStreamTruncate(t *testing.T) { "1", "2", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) } func TestRouteStreamSortTruncate(t *testing.T) { @@ -1330,7 +1330,7 @@ func TestRouteStreamSortTruncate(t *testing.T) { "1", "2", ) - expectResult(t, "sel.Execute", result, wantResult) + expectResult(t, result, wantResult) } func TestParamsFail(t *testing.T) { @@ -1432,7 +1432,7 @@ func TestExecFail(t *testing.T) { `ResolveDestinations ks [] Destinations:DestinationAllShards()`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() vc.resultErr = sqlerror.NewSQLError(sqlerror.ERQueryInterrupted, "", "query timeout -20") @@ -1474,7 +1474,7 @@ func TestSelectEqualUniqueMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(2)]] Destinations:DestinationKeyspaceID(0106e7ea22ce92708f)`, `ExecuteMultiShard ks.-20: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -1483,7 +1483,7 @@ func TestSelectEqualUniqueMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(2)]] Destinations:DestinationKeyspaceID(0106e7ea22ce92708f)`, `StreamExecuteMulti dummy_select ks.-20: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestSelectEqualMultiColumnVindex(t *testing.T) { @@ -1511,7 +1511,7 @@ func TestSelectEqualMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(32)]] Destinations:DestinationKeyRange(20-21)`, `ExecuteMultiShard ks.-20: dummy_select {} ks.20-: dummy_select {} false false`, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -1520,7 +1520,7 @@ func TestSelectEqualMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(32)]] Destinations:DestinationKeyRange(20-21)`, `StreamExecuteMulti dummy_select ks.-20: {} ks.20-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestINMultiColumnVindex(t *testing.T) { @@ -1557,7 +1557,7 @@ func TestINMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(3)] [INT64(1) INT64(4)] [INT64(2) INT64(3)] [INT64(2) INT64(4)]] Destinations:DestinationKeyspaceID(014eb190c9a2fa169c),DestinationKeyspaceID(01d2fd8867d50d2dfe),DestinationKeyspaceID(024eb190c9a2fa169c),DestinationKeyspaceID(02d2fd8867d50d2dfe)`, `ExecuteMultiShard ks.-20: dummy_select {__vals0: type:TUPLE values:{type:INT64 value:"1"} __vals1: type:TUPLE values:{type:INT64 value:"3"}} ks.20-: dummy_select {__vals0: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"2"} __vals1: type:TUPLE values:{type:INT64 value:"4"} values:{type:INT64 value:"3"}} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -1566,7 +1566,7 @@ func TestINMultiColumnVindex(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(3)] [INT64(1) INT64(4)] [INT64(2) INT64(3)] [INT64(2) INT64(4)]] Destinations:DestinationKeyspaceID(014eb190c9a2fa169c),DestinationKeyspaceID(01d2fd8867d50d2dfe),DestinationKeyspaceID(024eb190c9a2fa169c),DestinationKeyspaceID(02d2fd8867d50d2dfe)`, `StreamExecuteMulti dummy_select ks.-20: {__vals0: type:TUPLE values:{type:INT64 value:"1"} __vals1: type:TUPLE values:{type:INT64 value:"3"}} ks.20-: {__vals0: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"2"} __vals1: type:TUPLE values:{type:INT64 value:"4"} values:{type:INT64 value:"3"}} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestINMixedMultiColumnComparision(t *testing.T) { @@ -1600,7 +1600,7 @@ func TestINMixedMultiColumnComparision(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(3)] [INT64(1) INT64(4)]] Destinations:DestinationKeyspaceID(014eb190c9a2fa169c),DestinationKeyspaceID(01d2fd8867d50d2dfe)`, `ExecuteMultiShard ks.-20: dummy_select {__vals1: type:TUPLE values:{type:INT64 value:"3"}} ks.20-: dummy_select {__vals1: type:TUPLE values:{type:INT64 value:"4"}} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -1609,7 +1609,7 @@ func TestINMixedMultiColumnComparision(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(3)] [INT64(1) INT64(4)]] Destinations:DestinationKeyspaceID(014eb190c9a2fa169c),DestinationKeyspaceID(01d2fd8867d50d2dfe)`, `StreamExecuteMulti dummy_select ks.-20: {__vals1: type:TUPLE values:{type:INT64 value:"3"}} ks.20-: {__vals1: type:TUPLE values:{type:INT64 value:"4"}} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestMultiEqualMultiCol(t *testing.T) { @@ -1643,7 +1643,7 @@ func TestMultiEqualMultiCol(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(2)] [INT64(3) INT64(4)]] Destinations:DestinationKeyspaceID(0106e7ea22ce92708f),DestinationKeyspaceID(03d2fd8867d50d2dfe)`, `ExecuteMultiShard ks.-20: dummy_select {} ks.40-: dummy_select {} false false`, }) - expectResult(t, "sel.Execute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) vc.Rewind() result, err = wrapStreamExecute(sel, vc, map[string]*querypb.BindVariable{}, false) @@ -1652,7 +1652,7 @@ func TestMultiEqualMultiCol(t *testing.T) { `ResolveDestinationsMultiCol ks [[INT64(1) INT64(2)] [INT64(3) INT64(4)]] Destinations:DestinationKeyspaceID(0106e7ea22ce92708f),DestinationKeyspaceID(03d2fd8867d50d2dfe)`, `StreamExecuteMulti dummy_select ks.-20: {} ks.40-: {} `, }) - expectResult(t, "sel.StreamExecute", result, defaultSelectResult) + expectResult(t, result, defaultSelectResult) } func TestBuildRowColValues(t *testing.T) { diff --git a/go/vt/vtgate/engine/semi_join_test.go b/go/vt/vtgate/engine/semi_join_test.go index ca89882ab8a..9cf55d4f78f 100644 --- a/go/vt/vtgate/engine/semi_join_test.go +++ b/go/vt/vtgate/engine/semi_join_test.go @@ -152,7 +152,7 @@ func TestSemiJoinStreamExecute(t *testing.T) { `StreamExecute bv: type:VARCHAR value:"c" false`, `StreamExecute bv: type:VARCHAR value:"d" false`, }) - expectResult(t, "jn.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col2|col3", "int64|varchar|varchar", diff --git a/go/vt/vtgate/engine/simple_projection_test.go b/go/vt/vtgate/engine/simple_projection_test.go index 99d644c93af..6fdc288095c 100644 --- a/go/vt/vtgate/engine/simple_projection_test.go +++ b/go/vt/vtgate/engine/simple_projection_test.go @@ -59,7 +59,7 @@ func TestSubqueryExecute(t *testing.T) { prim.ExpectLog(t, []string{ `Execute a: type:INT64 value:"1" true`, }) - expectResult(t, "sq.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col3", "int64|varchar", @@ -108,7 +108,7 @@ func TestSubqueryStreamExecute(t *testing.T) { prim.ExpectLog(t, []string{ `StreamExecute a: type:INT64 value:"1" true`, }) - expectResult(t, "sq.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col3", "int64|varchar", @@ -158,7 +158,7 @@ func TestSubqueryGetFields(t *testing.T) { `GetFields a: type:INT64 value:"1"`, `Execute a: type:INT64 value:"1" true`, }) - expectResult(t, "sq.Execute", r, sqltypes.MakeTestResult( + expectResult(t, r, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "col1|col3", "int64|varchar", diff --git a/go/vt/vtgate/engine/uncorrelated_subquery_test.go b/go/vt/vtgate/engine/uncorrelated_subquery_test.go index 3e80c6369a7..085fe09238f 100644 --- a/go/vt/vtgate/engine/uncorrelated_subquery_test.go +++ b/go/vt/vtgate/engine/uncorrelated_subquery_test.go @@ -65,7 +65,7 @@ func TestPulloutSubqueryValueGood(t *testing.T) { require.NoError(t, err) sfp.ExpectLog(t, []string{`Execute aa: type:INT64 value:"1" false`}) ufp.ExpectLog(t, []string{`Execute aa: type:INT64 value:"1" sq: type:INT64 value:"1" false`}) - expectResult(t, "ps.Execute", result, underlyingResult) + expectResult(t, result, underlyingResult) } func TestPulloutSubqueryValueNone(t *testing.T) { @@ -279,7 +279,7 @@ func TestPulloutSubqueryStream(t *testing.T) { require.NoError(t, err) sfp.ExpectLog(t, []string{`Execute aa: type:INT64 value:"1" false`}) ufp.ExpectLog(t, []string{`StreamExecute aa: type:INT64 value:"1" sq: type:INT64 value:"1" true`}) - expectResult(t, "ps.StreamExecute", result, underlyingResult) + expectResult(t, result, underlyingResult) } func TestPulloutSubqueryGetFields(t *testing.T) { diff --git a/go/vt/vtgate/evalengine/api_coerce.go b/go/vt/vtgate/evalengine/api_coerce.go index 130727d8f31..5e92431e555 100644 --- a/go/vt/vtgate/evalengine/api_coerce.go +++ b/go/vt/vtgate/evalengine/api_coerce.go @@ -19,6 +19,8 @@ package evalengine import ( "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" ) func CoerceTo(value sqltypes.Value, typ sqltypes.Type) (sqltypes.Value, error) { @@ -28,3 +30,69 @@ func CoerceTo(value sqltypes.Value, typ sqltypes.Type) (sqltypes.Value, error) { } return evalToSQLValueWithType(cast, typ), nil } + +// CoerceTypes takes two input types, and decides how they should be coerced before compared +func CoerceTypes(v1, v2 Type) (out Type, err error) { + if v1 == v2 { + return v1, nil + } + if sqltypes.IsNull(v1.Type) || sqltypes.IsNull(v2.Type) { + return Type{Type: sqltypes.Null, Coll: collations.CollationBinaryID, Nullable: true}, nil + } + fail := func() error { + return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "types does not support hashcode yet: %v vs %v", v1.Type, v2.Type) + } + + out = Type{Nullable: v1.Nullable || v2.Nullable} + + switch { + case sqltypes.IsTextOrBinary(v1.Type) && sqltypes.IsTextOrBinary(v2.Type): + out.Type = sqltypes.VarChar + mergedCollation, _, _, ferr := mergeCollations(typedCoercionCollation(v1.Type, v1.Coll), typedCoercionCollation(v2.Type, v2.Coll), v1.Type, v2.Type) + if err != nil { + return Type{}, ferr + } + out.Coll = mergedCollation.Collation + return + + case sqltypes.IsDateOrTime(v1.Type): + out.Coll = collations.CollationBinaryID + out.Type = v1.Type + return + + case sqltypes.IsDateOrTime(v2.Type): + out.Coll = collations.CollationBinaryID + out.Type = v2.Type + return + + case sqltypes.IsNumber(v1.Type) || sqltypes.IsNumber(v2.Type): + out.Coll = collations.CollationBinaryID + switch { + case sqltypes.IsTextOrBinary(v1.Type) || sqltypes.IsFloat(v1.Type) || sqltypes.IsDecimal(v1.Type) || + sqltypes.IsTextOrBinary(v2.Type) || sqltypes.IsFloat(v2.Type) || sqltypes.IsDecimal(v2.Type): + out.Type = sqltypes.Float64 + return + case sqltypes.IsSigned(v1.Type): + switch { + case sqltypes.IsUnsigned(v2.Type): + out.Type = sqltypes.Uint64 + return + case sqltypes.IsSigned(v2.Type): + out.Type = sqltypes.Int64 + return + default: + return Type{}, fail() + } + case sqltypes.IsUnsigned(v1.Type): + switch { + case sqltypes.IsSigned(v2.Type) || sqltypes.IsUnsigned(v2.Type): + out.Type = sqltypes.Uint64 + return + default: + return Type{}, fail() + } + } + } + + return Type{}, fail() +} diff --git a/go/vt/vtgate/evalengine/api_hash_test.go b/go/vt/vtgate/evalengine/api_hash_test.go index 832a1ed3b88..0add16de89d 100644 --- a/go/vt/vtgate/evalengine/api_hash_test.go +++ b/go/vt/vtgate/evalengine/api_hash_test.go @@ -24,13 +24,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/sqltypes" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vthash" - - "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/sqltypes" ) func TestHashCodes(t *testing.T) { @@ -197,7 +195,7 @@ func coerceTo(v1, v2 sqltypes.Type) (sqltypes.Type, error) { if sqltypes.IsNull(v1) || sqltypes.IsNull(v2) { return sqltypes.Null, nil } - if (sqltypes.IsText(v1) || sqltypes.IsBinary(v1)) && (sqltypes.IsText(v2) || sqltypes.IsBinary(v2)) { + if (sqltypes.IsTextOrBinary(v1)) && (sqltypes.IsTextOrBinary(v2)) { return sqltypes.VarChar, nil } if sqltypes.IsDateOrTime(v1) { @@ -209,7 +207,7 @@ func coerceTo(v1, v2 sqltypes.Type) (sqltypes.Type, error) { if sqltypes.IsNumber(v1) || sqltypes.IsNumber(v2) { switch { - case sqltypes.IsText(v1) || sqltypes.IsBinary(v1) || sqltypes.IsText(v2) || sqltypes.IsBinary(v2): + case sqltypes.IsTextOrBinary(v1) || sqltypes.IsTextOrBinary(v2): return sqltypes.Float64, nil case sqltypes.IsFloat(v2) || v2 == sqltypes.Decimal || sqltypes.IsFloat(v1) || v1 == sqltypes.Decimal: return sqltypes.Float64, nil diff --git a/go/vt/vtgate/evalengine/collation.go b/go/vt/vtgate/evalengine/collation.go index 7cb341f52b0..b4e589c9724 100644 --- a/go/vt/vtgate/evalengine/collation.go +++ b/go/vt/vtgate/evalengine/collation.go @@ -59,8 +59,8 @@ func mergeCollations(c1, c2 collations.TypedCollation, t1, t2 sqltypes.Type) (co return c1, nil, nil, nil } - lt := sqltypes.IsText(t1) || sqltypes.IsBinary(t1) - rt := sqltypes.IsText(t2) || sqltypes.IsBinary(t2) + lt := sqltypes.IsTextOrBinary(t1) + rt := sqltypes.IsTextOrBinary(t2) if !lt || !rt { if lt { return c1, nil, nil, nil diff --git a/go/vt/vtgate/evalengine/compiler.go b/go/vt/vtgate/evalengine/compiler.go index 21a25ad3163..1c2feeb5f15 100644 --- a/go/vt/vtgate/evalengine/compiler.go +++ b/go/vt/vtgate/evalengine/compiler.go @@ -67,7 +67,7 @@ func (ct ctype) nullable() bool { } func (ct ctype) isTextual() bool { - return sqltypes.IsText(ct.Type) || sqltypes.IsBinary(ct.Type) + return sqltypes.IsTextOrBinary(ct.Type) } func (ct ctype) isHexOrBitLiteral() bool { diff --git a/go/vt/vtgate/evalengine/eval.go b/go/vt/vtgate/evalengine/eval.go index e327b9d5651..82f1ec688c7 100644 --- a/go/vt/vtgate/evalengine/eval.go +++ b/go/vt/vtgate/evalengine/eval.go @@ -312,7 +312,7 @@ func valueToEvalCast(v sqltypes.Value, typ sqltypes.Type, collation collations.I return newEvalUint64(uint64(i.i)), nil } - case sqltypes.IsText(typ) || sqltypes.IsBinary(typ): + case sqltypes.IsTextOrBinary(typ): switch { case v.IsText() || v.IsBinary(): return newEvalRaw(v.Type(), v.Raw(), typedCoercionCollation(v.Type(), collation)), nil diff --git a/go/vt/vtgate/evalengine/expr_compare.go b/go/vt/vtgate/evalengine/expr_compare.go index 6639bb7f7e2..90c2d313b07 100644 --- a/go/vt/vtgate/evalengine/expr_compare.go +++ b/go/vt/vtgate/evalengine/expr_compare.go @@ -114,7 +114,7 @@ func (compareNullSafeEQ) compare(left, right eval) (boolean, error) { } func typeIsTextual(tt sqltypes.Type) bool { - return sqltypes.IsText(tt) || sqltypes.IsBinary(tt) || tt == sqltypes.Time + return sqltypes.IsTextOrBinary(tt) || tt == sqltypes.Time } func compareAsStrings(l, r sqltypes.Type) bool { diff --git a/go/vt/vtgate/planbuilder/join.go b/go/vt/vtgate/planbuilder/join.go index 02027a8b49e..462b45fa00a 100644 --- a/go/vt/vtgate/planbuilder/join.go +++ b/go/vt/vtgate/planbuilder/join.go @@ -55,3 +55,16 @@ func (j *join) Primitive() engine.Primitive { Opcode: j.Opcode, } } + +type hashJoin struct { + lhs, rhs logicalPlan + inner *engine.HashJoin +} + +func (hj *hashJoin) Primitive() engine.Primitive { + lhs := hj.lhs.Primitive() + rhs := hj.rhs.Primitive() + hj.inner.Left = lhs + hj.inner.Right = rhs + return hj.inner +} diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 5f59a96000a..7d3223a48e9 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -68,6 +68,8 @@ func transformToLogicalPlan(ctx *plancontext.PlanningContext, op ops.Operator) ( return transformFkVerify(ctx, op) case *operators.InsertSelection: return transformInsertionSelection(ctx, op) + case *operators.HashJoin: + return transformHashJoin(ctx, op) case *operators.Sequential: return transformSequential(ctx, op) } @@ -810,3 +812,58 @@ func createLimit(input logicalPlan, limit *sqlparser.Limit) (logicalPlan, error) return plan, nil } + +func transformHashJoin(ctx *plancontext.PlanningContext, op *operators.HashJoin) (logicalPlan, error) { + lhs, err := transformToLogicalPlan(ctx, op.LHS) + if err != nil { + return nil, err + } + rhs, err := transformToLogicalPlan(ctx, op.RHS) + if err != nil { + return nil, err + } + + if len(op.LHSKeys) != 1 { + return nil, vterrors.VT12001("hash joins must have exactly one join predicate") + } + + joinOp := engine.InnerJoin + if op.LeftJoin { + joinOp = engine.LeftJoin + } + + var missingTypes []string + + ltyp, found := ctx.SemTable.TypeForExpr(op.JoinComparisons[0].LHS) + if !found { + missingTypes = append(missingTypes, sqlparser.String(op.JoinComparisons[0].LHS)) + } + rtyp, found := ctx.SemTable.TypeForExpr(op.JoinComparisons[0].RHS) + if !found { + missingTypes = append(missingTypes, sqlparser.String(op.JoinComparisons[0].RHS)) + } + + if len(missingTypes) > 0 { + return nil, vterrors.VT12001( + fmt.Sprintf("missing type information for [%s]", strings.Join(missingTypes, ", "))) + } + + comparisonType, err := evalengine.CoerceTypes(ltyp, rtyp) + if err != nil { + return nil, err + } + + return &hashJoin{ + lhs: lhs, + rhs: rhs, + inner: &engine.HashJoin{ + Opcode: joinOp, + Cols: op.ColumnOffsets, + LHSKey: op.LHSKeys[0], + RHSKey: op.RHSKeys[0], + ASTPred: op.JoinPredicate(), + Collation: comparisonType.Coll, + ComparisonType: comparisonType.Type, + }, + }, nil +} diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index 0127e81b4c4..edba5c51256 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -116,12 +116,12 @@ func pushAggregationThroughSubquery( src.Outer = pushedAggr if !rootAggr.Original { - return src, rewrite.NewTree("push Aggregation under subquery - keep original", rootAggr), nil + return src, rewrite.NewTree("push Aggregation under subquery - keep original"), nil } rootAggr.aggregateTheAggregates() - return rootAggr, rewrite.NewTree("push Aggregation under subquery", rootAggr), nil + return rootAggr, rewrite.NewTree("push Aggregation under subquery"), nil } func (a *Aggregator) aggregateTheAggregates() { @@ -161,10 +161,10 @@ func pushAggregationThroughRoute( if !aggregator.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return aggregator.Source, rewrite.NewTree("push aggregation under route - remove original", aggregator), nil + return aggregator.Source, rewrite.NewTree("push aggregation under route - remove original"), nil } - return aggregator, rewrite.NewTree("push aggregation under route - keep original", aggregator), nil + return aggregator, rewrite.NewTree("push aggregation under route - keep original"), nil } // pushAggregations splits aggregations between the original aggregator and the one we are pushing down @@ -264,10 +264,10 @@ withNextColumn: if !aggregator.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return aggregator.Source, rewrite.NewTree("push aggregation under filter - remove original", aggregator), nil + return aggregator.Source, rewrite.NewTree("push aggregation under filter - remove original"), nil } aggregator.aggregateTheAggregates() - return aggregator, rewrite.NewTree("push aggregation under filter - keep original", aggregator), nil + return aggregator, rewrite.NewTree("push aggregation under filter - keep original"), nil } func collectColNamesNeeded(ctx *plancontext.PlanningContext, f *Filter) (columnsNeeded []*sqlparser.ColName) { @@ -411,12 +411,12 @@ func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggr if !rootAggr.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return output, rewrite.NewTree("push Aggregation under join - keep original", rootAggr), nil + return output, rewrite.NewTree("push Aggregation under join - keep original"), nil } rootAggr.aggregateTheAggregates() rootAggr.Source = output - return rootAggr, rewrite.NewTree("push Aggregation under join", rootAggr), nil + return rootAggr, rewrite.NewTree("push Aggregation under join"), nil } var errAbortAggrPushing = fmt.Errorf("abort aggregation pushing") @@ -473,7 +473,7 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg RHSExpr: expr, }) case deps.IsSolvedBy(lhs.tableID.Merge(rhs.tableID)): - jc, err := BreakExpressionInLHSandRHS(ctx, groupBy.SimplifiedExpr, lhs.tableID) + jc, err := breakExpressionInLHSandRHSForApplyJoin(ctx, groupBy.SimplifiedExpr, lhs.tableID) if err != nil { return nil, err } @@ -877,5 +877,5 @@ func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (o aggr.Columns = append(aggr.Columns, columns...) aggr.Aggregations = append(aggr.Aggregations, aggregations...) - return proj, rewrite.NewTree("split avg aggregation", proj), nil + return proj, rewrite.NewTree("split avg aggregation"), nil } diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index 33846f83365..685a418339a 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -259,16 +259,16 @@ func (a *Aggregator) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy return a.Source.GetOrdering(ctx) } -func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) { +func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { if a.offsetPlanned { - return + return nil } defer func() { a.offsetPlanned = true }() if !a.Pushed { a.planOffsetsNotPushed(ctx) - return + return nil } for idx, gb := range a.Grouping { @@ -291,6 +291,7 @@ func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) { offset := a.internalAddColumn(ctx, aeWrap(weightStringFor(aggr.Func.GetArg())), true) a.Aggregations[idx].WSOffset = offset } + return nil } func (aggr Aggr) getPushColumn() sqlparser.Expr { diff --git a/go/vt/vtgate/planbuilder/operators/apply_join.go b/go/vt/vtgate/planbuilder/operators/apply_join.go index 138c17f2da7..95d7d962738 100644 --- a/go/vt/vtgate/planbuilder/operators/apply_join.go +++ b/go/vt/vtgate/planbuilder/operators/apply_join.go @@ -148,18 +148,16 @@ func (aj *ApplyJoin) IsInner() bool { return !aj.LeftJoin } -func (aj *ApplyJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) error { +func (aj *ApplyJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) { aj.Predicate = ctx.SemTable.AndExpressions(expr, aj.Predicate) - col, err := BreakExpressionInLHSandRHS(ctx, expr, TableID(aj.LHS)) + col, err := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, TableID(aj.LHS)) if err != nil { - return err + panic(err) } aj.JoinPredicates = append(aj.JoinPredicates, col) rhs := aj.RHS.AddPredicate(ctx, col.RHSExpr) aj.RHS = rhs - - return nil } func (aj *ApplyJoin) pushColRight(ctx *plancontext.PlanningContext, e *sqlparser.AliasedExpr, addToGroupBy bool) (int, error) { @@ -203,7 +201,7 @@ func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sq case deps.IsSolvedBy(rhs): col.RHSExpr = e case deps.IsSolvedBy(both): - col, err = BreakExpressionInLHSandRHS(ctx, e, TableID(aj.LHS)) + col, err = breakExpressionInLHSandRHSForApplyJoin(ctx, e, TableID(aj.LHS)) if err != nil { return JoinColumn{}, err } @@ -243,7 +241,7 @@ func (aj *ApplyJoin) AddColumn( return offset } -func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) { +func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { for _, col := range aj.JoinColumns { // Read the type description for JoinColumn to understand the following code for _, lhsExpr := range col.LHSExprs { @@ -272,6 +270,8 @@ func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) { offset := aj.LHS.AddColumn(ctx, true, false, aeWrap(lhsExpr.Expr)) aj.Vars[lhsExpr.Name] = offset } + + return nil } func (aj *ApplyJoin) addOffset(offset int) { diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index 64d9826a80e..46286b2778f 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -165,7 +165,7 @@ func (jpc *joinPredicateCollector) inspectPredicate( // then we can use this predicate to connect the subquery to the outer query if !deps.IsSolvedBy(jpc.subqID) && deps.IsSolvedBy(jpc.totalID) { jpc.predicates = append(jpc.predicates, predicate) - jc, err := BreakExpressionInLHSandRHS(ctx, predicate, jpc.outerID) + jc, err := breakExpressionInLHSandRHSForApplyJoin(ctx, predicate, jpc.outerID) if err != nil { return err } diff --git a/go/vt/vtgate/planbuilder/operators/distinct.go b/go/vt/vtgate/planbuilder/operators/distinct.go index 88503514615..d7aad08d206 100644 --- a/go/vt/vtgate/planbuilder/operators/distinct.go +++ b/go/vt/vtgate/planbuilder/operators/distinct.go @@ -46,7 +46,7 @@ type ( } ) -func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) { +func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { columns := d.GetColumns(ctx) for idx, col := range columns { e, err := d.QP.GetSimplifiedExpr(ctx, col.Expr) @@ -68,6 +68,7 @@ func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) { Type: typ, }) } + return nil } func (d *Distinct) Clone(inputs []ops.Operator) ops.Operator { diff --git a/go/vt/vtgate/planbuilder/operators/expressions.go b/go/vt/vtgate/planbuilder/operators/expressions.go index 7ab27e787e8..0df875a6fbd 100644 --- a/go/vt/vtgate/planbuilder/operators/expressions.go +++ b/go/vt/vtgate/planbuilder/operators/expressions.go @@ -22,9 +22,9 @@ import ( "vitess.io/vitess/go/vt/vtgate/semantics" ) -// BreakExpressionInLHSandRHS takes an expression and +// breakExpressionInLHSandRHSForApplyJoin takes an expression and // extracts the parts that are coming from one of the sides into `ColName`s that are needed -func BreakExpressionInLHSandRHS( +func breakExpressionInLHSandRHSForApplyJoin( ctx *plancontext.PlanningContext, expr sqlparser.Expr, lhs semantics.TableSet, diff --git a/go/vt/vtgate/planbuilder/operators/filter.go b/go/vt/vtgate/planbuilder/operators/filter.go index ed43910b75d..cee57c74943 100644 --- a/go/vt/vtgate/planbuilder/operators/filter.go +++ b/go/vt/vtgate/planbuilder/operators/filter.go @@ -107,7 +107,7 @@ func (f *Filter) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { func (f *Filter) Compact(*plancontext.PlanningContext) (ops.Operator, *rewrite.ApplyResult, error) { if len(f.Predicates) == 0 { - return f.Source, rewrite.NewTree("filter with no predicates removed", f), nil + return f.Source, rewrite.NewTree("filter with no predicates removed"), nil } other, isFilter := f.Source.(*Filter) @@ -116,10 +116,10 @@ func (f *Filter) Compact(*plancontext.PlanningContext) (ops.Operator, *rewrite.A } f.Source = other.Source f.Predicates = append(f.Predicates, other.Predicates...) - return f, rewrite.NewTree("two filters merged into one", f), nil + return f, rewrite.NewTree("two filters merged into one"), nil } -func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) { +func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { cfg := &evalengine.Config{ ResolveType: ctx.SemTable.TypeForExpr, Collation: ctx.SemTable.Collation, @@ -136,6 +136,7 @@ func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) { } f.PredicateWithOffsets = eexpr + return nil } func (f *Filter) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/hash_join.go b/go/vt/vtgate/planbuilder/operators/hash_join.go new file mode 100644 index 00000000000..e9cfeb7d107 --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/hash_join.go @@ -0,0 +1,327 @@ +/* +Copyright 2023 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 operators + +import ( + "fmt" + "slices" + "strings" + + "vitess.io/vitess/go/slice" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" +) + +type ( + HashJoin struct { + LHS, RHS ops.Operator + + // LeftJoin will be true in the case of an outer join + LeftJoin bool + + // Before offset planning + JoinComparisons []Comparison + + // These columns are the output columns of the hash join. While in operator mode we keep track of complex expression, + // but once we move to the engine primitives, the hash join only passes through column from either left or right. + // anything more complex will be solved by a projection on top of the hash join + columns []sqlparser.Expr + + // After offset planning + + // Columns stores the column indexes of the columns coming from the left and right side + // negative value comes from LHS and positive from RHS + ColumnOffsets []int + + // These are the values that will be hashed together + LHSKeys, RHSKeys []int + + offset bool + } + + Comparison struct { + LHS, RHS sqlparser.Expr + } +) + +var _ ops.Operator = (*HashJoin)(nil) +var _ JoinOp = (*HashJoin)(nil) + +func NewHashJoin(lhs, rhs ops.Operator, outerJoin bool) *HashJoin { + hj := &HashJoin{ + LHS: lhs, + RHS: rhs, + LeftJoin: outerJoin, + } + return hj +} + +func (hj *HashJoin) Clone(inputs []ops.Operator) ops.Operator { + kopy := *hj + kopy.LHS, kopy.RHS = inputs[0], inputs[1] + kopy.columns = slices.Clone(hj.columns) + kopy.LHSKeys = slices.Clone(hj.LHSKeys) + kopy.RHSKeys = slices.Clone(hj.RHSKeys) + return &kopy +} + +func (hj *HashJoin) Inputs() []ops.Operator { + return []ops.Operator{hj.LHS, hj.RHS} +} + +func (hj *HashJoin) SetInputs(operators []ops.Operator) { + hj.LHS, hj.RHS = operators[0], operators[1] +} + +func (hj *HashJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { + return AddPredicate(ctx, hj, expr, false, newFilter) +} + +func (hj *HashJoin) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int { + if reuseExisting { + offset := hj.FindCol(ctx, expr.Expr, false) + if offset >= 0 { + return offset + } + } + + hj.columns = append(hj.columns, expr.Expr) + return len(hj.columns) - 1 +} + +func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { + if hj.offset { + return nil + } + hj.offset = true + for _, cmp := range hj.JoinComparisons { + lOffset := hj.LHS.AddColumn(ctx, true, false, aeWrap(cmp.LHS)) + hj.LHSKeys = append(hj.LHSKeys, lOffset) + rOffset := hj.RHS.AddColumn(ctx, true, false, aeWrap(cmp.RHS)) + hj.RHSKeys = append(hj.RHSKeys, rOffset) + } + + eexprs := slice.Map(hj.columns, func(in sqlparser.Expr) *ProjExpr { + return hj.addColumn(ctx, in) + }) + + proj := newAliasedProjection(hj) + _, err := proj.addProjExpr(eexprs...) + if err != nil { + panic(err) + } + + return proj +} + +func (hj *HashJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int { + for offset, col := range hj.columns { + if ctx.SemTable.EqualsExprWithDeps(expr, col) { + return offset + } + } + return -1 +} + +func (hj *HashJoin) GetColumns(*plancontext.PlanningContext) []*sqlparser.AliasedExpr { + return slice.Map(hj.columns, aeWrap) +} + +func (hj *HashJoin) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { + return transformColumnsToSelectExprs(ctx, hj) +} + +func (hj *HashJoin) ShortDescription() string { + comparisons := slice.Map(hj.JoinComparisons, func(from Comparison) string { + return from.String() + }) + cmp := strings.Join(comparisons, " AND ") + + if len(hj.columns) > 0 { + return fmt.Sprintf("%s columns %v", cmp, hj.columns) + } + + return cmp +} + +func (hj *HashJoin) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { + return nil // hash joins will never promise an output order +} + +func (hj *HashJoin) GetLHS() ops.Operator { + return hj.LHS +} + +func (hj *HashJoin) GetRHS() ops.Operator { + return hj.RHS +} + +func (hj *HashJoin) SetLHS(op ops.Operator) { + hj.LHS = op +} + +func (hj *HashJoin) SetRHS(op ops.Operator) { + hj.RHS = op +} + +func (hj *HashJoin) MakeInner() { + hj.LeftJoin = false +} + +func (hj *HashJoin) IsInner() bool { + return !hj.LeftJoin +} + +func (hj *HashJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) { + cmp, ok := expr.(*sqlparser.ComparisonExpr) + if !ok || !canBeSolvedWithHashJoin(cmp.Operator) { + panic(vterrors.VT12001(fmt.Sprintf("can't use [%s] with hash joins", sqlparser.String(expr)))) + } + lExpr := cmp.Left + lDeps := ctx.SemTable.RecursiveDeps(lExpr) + rExpr := cmp.Right + rDeps := ctx.SemTable.RecursiveDeps(rExpr) + lID := TableID(hj.LHS) + rID := TableID(hj.RHS) + if !lDeps.IsSolvedBy(lID) || !rDeps.IsSolvedBy(rID) { + // we'll switch and see if things work out then + lExpr, rExpr = rExpr, lExpr + lDeps, rDeps = rDeps, lDeps + } + + if !lDeps.IsSolvedBy(lID) || !rDeps.IsSolvedBy(rID) { + panic(vterrors.VT12001(fmt.Sprintf("can't use [%s] with hash joins", sqlparser.String(expr)))) + } + + hj.JoinComparisons = append(hj.JoinComparisons, Comparison{ + LHS: lExpr, + RHS: rExpr, + }) +} + +func canBeSolvedWithHashJoin(op sqlparser.ComparisonExprOperator) bool { + switch op { + case sqlparser.EqualOp, sqlparser.NullSafeEqualOp: + return true + default: + return false + } +} + +func (c Comparison) String() string { + return sqlparser.String(c.LHS) + " = " + sqlparser.String(c.RHS) +} + +func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Expr) *ProjExpr { + lId, rId := TableID(hj.LHS), TableID(hj.RHS) + var replaceExpr sqlparser.Expr // this is the expression we will put in instead of whatever we find there + pre := func(node, parent sqlparser.SQLNode) bool { + expr, ok := node.(sqlparser.Expr) + if !ok { + return true + } + deps := ctx.SemTable.RecursiveDeps(expr) + check := func(id semantics.TableSet, op ops.Operator, offsetter func(int) int) int { + if !deps.IsSolvedBy(id) { + return -1 + } + inOffset := op.FindCol(ctx, expr, false) + if inOffset == -1 { + if !fetchByOffset(expr) { + return -1 + } + + // aha! this is an expression that we have to get from the input. let's force it in there + inOffset = op.AddColumn(ctx, false, false, aeWrap(expr)) + } + + // we turn the + internalOffset := offsetter(inOffset) + + // ok, we have an offset from the input operator. Let's check if we already have it + // in our list of incoming columns + + for idx, offset := range hj.ColumnOffsets { + if internalOffset == offset { + return idx + } + } + + hj.ColumnOffsets = append(hj.ColumnOffsets, internalOffset) + + return len(hj.ColumnOffsets) - 1 + } + + f := func(i int) int { return (i * -1) - 1 } + if lOffset := check(lId, hj.LHS, f); lOffset >= 0 { + replaceExpr = sqlparser.NewOffset(lOffset, expr) + return false // we want to stop going down the expression tree and start coming back up again + } + + f = func(i int) int { return i + 1 } + if rOffset := check(rId, hj.RHS, f); rOffset >= 0 { + replaceExpr = sqlparser.NewOffset(rOffset, expr) + return false + } + + return true + } + + post := func(cursor *sqlparser.CopyOnWriteCursor) { + if replaceExpr != nil { + node := cursor.Node() + _, ok := node.(sqlparser.Expr) + if !ok { + panic(fmt.Sprintf("can't replace this node with an expression: %s", sqlparser.String(node))) + } + cursor.Replace(replaceExpr) + replaceExpr = nil + } + } + + rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) + cfg := &evalengine.Config{ + ResolveType: ctx.SemTable.TypeForExpr, + Collation: ctx.SemTable.Collation, + } + eexpr, err := evalengine.Translate(rewrittenExpr, cfg) + if err != nil { + panic(err) + } + + return &ProjExpr{ + Original: aeWrap(in), + EvalExpr: rewrittenExpr, + ColExpr: rewrittenExpr, + Info: &EvalEngine{EExpr: eexpr}, + } +} + +// JoinPredicate produces an AST representation of the join condition this join has +func (hj *HashJoin) JoinPredicate() sqlparser.Expr { + exprs := slice.Map(hj.JoinComparisons, func(from Comparison) sqlparser.Expr { + return &sqlparser.ComparisonExpr{ + Left: from.LHS, + Right: from.RHS, + } + }) + return sqlparser.AndExpressions(exprs...) +} diff --git a/go/vt/vtgate/planbuilder/operators/hash_join_test.go b/go/vt/vtgate/planbuilder/operators/hash_join_test.go new file mode 100644 index 00000000000..69f21bd4b78 --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/hash_join_test.go @@ -0,0 +1,100 @@ +/* +Copyright 2023 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 operators + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" +) + +func TestJoinPredicates(t *testing.T) { + lcol := sqlparser.NewColName("lhs") + rcol := sqlparser.NewColName("rhs") + ctx := &plancontext.PlanningContext{SemTable: semantics.EmptySemTable()} + lid := semantics.SingleTableSet(0) + rid := semantics.SingleTableSet(1) + ctx.SemTable.Recursive[lcol] = lid + ctx.SemTable.Recursive[rcol] = rid + lhs := &fakeOp{id: lid} + rhs := &fakeOp{id: rid} + hj := &HashJoin{ + LHS: lhs, + RHS: rhs, + LeftJoin: false, + } + + cmp := &sqlparser.ComparisonExpr{ + Operator: sqlparser.EqualOp, + Left: lcol, + Right: rcol, + } + hj.AddJoinPredicate(ctx, cmp) + require.Len(t, hj.JoinComparisons, 1) + hj.planOffsets(ctx) + require.Len(t, hj.LHSKeys, 1) + require.Len(t, hj.RHSKeys, 1) +} + +func TestOffsetPlanning(t *testing.T) { + lcol1, lcol2 := sqlparser.NewColName("lhs1"), sqlparser.NewColName("lhs2") + rcol1, rcol2 := sqlparser.NewColName("rhs1"), sqlparser.NewColName("rhs2") + ctx := &plancontext.PlanningContext{SemTable: semantics.EmptySemTable()} + lid := semantics.SingleTableSet(0) + rid := semantics.SingleTableSet(1) + ctx.SemTable.Recursive[lcol1] = lid + ctx.SemTable.Recursive[lcol2] = lid + ctx.SemTable.Recursive[rcol1] = rid + ctx.SemTable.Recursive[rcol2] = rid + lhs := &fakeOp{id: lid} + rhs := &fakeOp{id: rid} + + tests := []struct { + expr sqlparser.Expr + expectedColOffsets []int + }{{ + expr: lcol1, + expectedColOffsets: []int{-1}, + }, { + expr: rcol1, + expectedColOffsets: []int{1}, + }, { + expr: sqlparser.AndExpressions(lcol1, lcol2), + expectedColOffsets: []int{-1, -2}, + }, { + expr: sqlparser.AndExpressions(lcol1, rcol1, lcol2, rcol2), + expectedColOffsets: []int{-1, 1, -2, 2}, + }} + + for _, test := range tests { + t.Run(sqlparser.String(test.expr), func(t *testing.T) { + hj := &HashJoin{ + LHS: lhs, + RHS: rhs, + LeftJoin: false, + } + hj.AddColumn(ctx, true, false, aeWrap(test.expr)) + hj.planOffsets(ctx) + assert.Equal(t, test.expectedColOffsets, hj.ColumnOffsets) + }) + } +} diff --git a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go index 7ec141a1b8b..06bcf2aaeb5 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go +++ b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go @@ -72,10 +72,10 @@ func expandUnionHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, unio } if op == horizon.Source { - return op, rewrite.NewTree("removed UNION horizon not used", op), nil + return op, rewrite.NewTree("removed UNION horizon not used"), nil } - return op, rewrite.NewTree("expand UNION horizon into smaller components", op), nil + return op, rewrite.NewTree("expand UNION horizon into smaller components"), nil } func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel *sqlparser.Select) (ops.Operator, *rewrite.ApplyResult, error) { @@ -126,7 +126,7 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel extracted = append(extracted, "Limit") } - return op, rewrite.NewTree(fmt.Sprintf("expand SELECT horizon into (%s)", strings.Join(extracted, ", ")), op), nil + return op, rewrite.NewTree(fmt.Sprintf("expand SELECT horizon into (%s)", strings.Join(extracted, ", "))), nil } func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horizon) (out ops.Operator) { diff --git a/go/vt/vtgate/planbuilder/operators/join.go b/go/vt/vtgate/planbuilder/operators/join.go index 828b15f5b79..1d50a688df4 100644 --- a/go/vt/vtgate/planbuilder/operators/join.go +++ b/go/vt/vtgate/planbuilder/operators/join.go @@ -82,7 +82,7 @@ func (j *Join) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *rewrite if j.Predicate != nil { newOp.collectPredicate(ctx, j.Predicate) } - return newOp, rewrite.NewTree("merge querygraphs into a single one", newOp), nil + return newOp, rewrite.NewTree("merge querygraphs into a single one"), nil } func createOuterJoin(tableExpr *sqlparser.JoinTableExpr, lhs, rhs ops.Operator) (ops.Operator, error) { @@ -162,9 +162,8 @@ func (j *Join) IsInner() bool { return !j.LeftJoin } -func (j *Join) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) error { +func (j *Join) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) { j.Predicate = ctx.SemTable.AndExpressions(j.Predicate, expr) - return nil } func (j *Join) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/joins.go b/go/vt/vtgate/planbuilder/operators/joins.go index 3b5c31c5dce..ad61a6c5a00 100644 --- a/go/vt/vtgate/planbuilder/operators/joins.go +++ b/go/vt/vtgate/planbuilder/operators/joins.go @@ -31,7 +31,7 @@ type JoinOp interface { SetRHS(ops.Operator) MakeInner() IsInner() bool - AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) error + AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) } func AddPredicate( @@ -79,10 +79,7 @@ func AddPredicate( return newFilter(join, expr) } - err := join.AddJoinPredicate(ctx, expr) - if err != nil { - panic(err) - } + join.AddJoinPredicate(ctx, expr) return join } diff --git a/go/vt/vtgate/planbuilder/operators/offset_planning.go b/go/vt/vtgate/planbuilder/operators/offset_planning.go index 7e7be49874a..d2fc266790c 100644 --- a/go/vt/vtgate/planbuilder/operators/offset_planning.go +++ b/go/vt/vtgate/planbuilder/operators/offset_planning.go @@ -30,7 +30,7 @@ import ( // planOffsets will walk the tree top down, adding offset information to columns in the tree for use in further optimization, func planOffsets(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { type offsettable interface { - planOffsets(ctx *plancontext.PlanningContext) + planOffsets(ctx *plancontext.PlanningContext) ops.Operator } visitor := func(in ops.Operator, _ semantics.TableSet, _ bool) (ops.Operator, *rewrite.ApplyResult, error) { @@ -39,7 +39,10 @@ func planOffsets(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Opera case *Horizon: return nil, nil, vterrors.VT13001(fmt.Sprintf("should not see %T here", in)) case offsettable: - op.planOffsets(ctx) + newOp := op.planOffsets(ctx) + if newOp != nil { + return newOp, rewrite.NewTree("new operator after offset planning"), nil + } } if err != nil { return nil, nil, err @@ -116,7 +119,7 @@ func addColumnsToInput(ctx *plancontext.PlanningContext, root ops.Operator) (ops _ = sqlparser.CopyOnRewrite(expr, visitor, nil, ctx.SemTable.CopySemanticInfo) } if addedColumns { - return in, rewrite.NewTree("added columns because filter needs it", in), nil + return in, rewrite.NewTree("added columns because filter needs it"), nil } return in, rewrite.SameTree, nil @@ -140,7 +143,7 @@ func pullDistinctFromUNION(_ *plancontext.PlanningContext, root ops.Operator) (o Required: true, Source: union, } - return distinct, rewrite.NewTree("pulled out DISTINCT from union", union), nil + return distinct, rewrite.NewTree("pulled out DISTINCT from union"), nil } return rewrite.TopDown(root, TableID, visitor, stopAtRoute) diff --git a/go/vt/vtgate/planbuilder/operators/ordering.go b/go/vt/vtgate/planbuilder/operators/ordering.go index b3d0310eadb..66436f6a47d 100644 --- a/go/vt/vtgate/planbuilder/operators/ordering.go +++ b/go/vt/vtgate/planbuilder/operators/ordering.go @@ -78,7 +78,7 @@ func (o *Ordering) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { return o.Order } -func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) { +func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { for _, order := range o.Order { offset := o.Source.AddColumn(ctx, true, false, aeWrap(order.SimplifiedExpr)) o.Offset = append(o.Offset, offset) @@ -92,6 +92,7 @@ func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) { offset = o.Source.AddColumn(ctx, true, false, aeWrap(wsExpr)) o.WOffset = append(o.WOffset, offset) } + return nil } func (o *Ordering) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/phases.go b/go/vt/vtgate/planbuilder/operators/phases.go index 36149f89985..f180cfc2ce0 100644 --- a/go/vt/vtgate/planbuilder/operators/phases.go +++ b/go/vt/vtgate/planbuilder/operators/phases.go @@ -96,15 +96,18 @@ func (p Phase) act(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Opera } } -// getPhases returns the ordered phases that the planner will undergo. -// These phases ensure the appropriate collaboration between rewriters. -func getPhases(ctx *plancontext.PlanningContext) (phases []Phase) { - for p := Phase(0); p < DONE; p++ { - if p.shouldRun(ctx.SemTable.QuerySignature) { - phases = append(phases, p) +type phaser struct { + current Phase +} + +func (p *phaser) next(ctx *plancontext.PlanningContext) Phase { + for phas := p.current; phas < DONE; phas++ { + if phas.shouldRun(ctx.SemTable.QuerySignature) { + p.current = p.current + 1 + return phas } } - return + return DONE } func removePerformanceDistinctAboveRoute(_ *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { @@ -114,7 +117,7 @@ func removePerformanceDistinctAboveRoute(_ *plancontext.PlanningContext, op ops. return innerOp, rewrite.SameTree, nil } - return d.Source, rewrite.NewTree("removed distinct not required that was not pushed under route", d), nil + return d.Source, rewrite.NewTree("removed distinct not required that was not pushed under route"), nil }, stopAtRoute) } @@ -138,7 +141,7 @@ func addOrderingForAllAggregations(ctx *plancontext.PlanningContext, root ops.Op var res *rewrite.ApplyResult if requireOrdering { addOrderingFor(aggrOp) - res = rewrite.NewTree("added ordering before aggregation", in) + res = rewrite.NewTree("added ordering before aggregation") } return in, res, nil } diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index bad9cb0e87e..7e9f2d71a71 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -263,14 +263,14 @@ func (p *Projection) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Ex return -1 } -func (p *Projection) addProjExpr(pe *ProjExpr) (int, error) { +func (p *Projection) addProjExpr(pe ...*ProjExpr) (int, error) { ap, err := p.GetAliasedProjections() if err != nil { return 0, err } offset := len(ap) - ap = append(ap, pe) + ap = append(ap, pe...) p.Columns = ap return offset, nil @@ -471,7 +471,7 @@ func (p *Projection) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *r } if !needed { - return p.Source, rewrite.NewTree("removed projection only passing through the input", p), nil + return p.Source, rewrite.NewTree("removed projection only passing through the input"), nil } switch src := p.Source.(type) { @@ -517,7 +517,7 @@ func (p *Projection) compactWithJoin(ctx *plancontext.PlanningContext, join *App } join.Columns = newColumns join.JoinColumns = newColumnsAST - return join, rewrite.NewTree("remove projection from before join", join), nil + return join, rewrite.NewTree("remove projection from before join"), nil } func (p *Projection) compactWithRoute(ctx *plancontext.PlanningContext, rb *Route) (ops.Operator, *rewrite.ApplyResult, error) { @@ -538,7 +538,7 @@ func (p *Projection) compactWithRoute(ctx *plancontext.PlanningContext, rb *Rout } if len(columns) == len(ap) { - return rb, rewrite.NewTree("remove projection from before route", rb), nil + return rb, rewrite.NewTree("remove projection from before route"), nil } rb.ResultColumns = len(columns) return rb, rewrite.SameTree, nil @@ -561,7 +561,7 @@ func (p *Projection) needsEvaluation(ctx *plancontext.PlanningContext, e sqlpars return false } -func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) { +func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { ap, err := p.GetAliasedProjections() if err != nil { panic(err) @@ -597,6 +597,7 @@ func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) { EExpr: eexpr, } } + return nil } func (p *Projection) introducesTableID() semantics.TableSet { diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index e66abd02feb..1f239a31973 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -65,7 +65,9 @@ func planQuery(ctx *plancontext.PlanningContext, root ops.Operator) (output ops. // smaller operators and try to push these down as far as possible func runPhases(ctx *plancontext.PlanningContext, root ops.Operator) (op ops.Operator, err error) { op = root - for _, phase := range getPhases(ctx) { + + p := phaser{} + for phase := p.next(ctx); phase != DONE; phase = p.next(ctx) { ctx.CurrentPhase = int(phase) if rewrite.DebugOperatorTree { fmt.Printf("PHASE: %s\n", phase.String()) @@ -134,7 +136,7 @@ func pushLockAndComment(l *LockAndComment) (ops.Operator, *rewrite.ApplyResult, case *Route: src.Comments = l.Comments src.Lock = l.Lock - return src, rewrite.NewTree("put lock and comment into route", l), nil + return src, rewrite.NewTree("put lock and comment into route"), nil default: inputs := src.Inputs() for i, op := range inputs { @@ -145,7 +147,7 @@ func pushLockAndComment(l *LockAndComment) (ops.Operator, *rewrite.ApplyResult, } } src.SetInputs(inputs) - return src, rewrite.NewTree("pushed down lock and comments", l), nil + return src, rewrite.NewTree("pushed down lock and comments"), nil } } @@ -256,7 +258,7 @@ func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq * } // all projections can be pushed to the outer sq.Outer, p.Source = p, sq.Outer - return sq, rewrite.NewTree("push projection into outer side of subquery", p), nil + return sq, rewrite.NewTree("push projection into outer side of subquery"), nil } func pushProjectionInVindex( @@ -271,7 +273,7 @@ func pushProjectionInVindex( for _, pe := range ap { src.AddColumn(ctx, true, false, aeWrap(pe.EvalExpr)) } - return src, rewrite.NewTree("push projection into vindex", p), nil + return src, rewrite.NewTree("push projection into vindex"), nil } func (p *projector) add(pe *ProjExpr, col *sqlparser.IdentifierCI) { @@ -331,7 +333,7 @@ func pushProjectionInApplyJoin( return nil, nil, err } - return src, rewrite.NewTree("split projection to either side of join", src), nil + return src, rewrite.NewTree("split projection to either side of join"), nil } // splitProjectionAcrossJoin creates JoinPredicates for all projections, @@ -521,7 +523,7 @@ func setUpperLimit(in *Limit) (ops.Operator, *rewrite.ApplyResult, error) { Pushed: false, } op.Source = newSrc - result = result.Merge(rewrite.NewTree("push limit under route", newSrc)) + result = result.Merge(rewrite.NewTree("push limit under route")) return rewrite.SkipChildren default: return rewrite.VisitChildren @@ -544,12 +546,12 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operat // ApplyJoin is stable in regard to the columns coming from the LHS, // so if all the ordering columns come from the LHS, we can push down the Ordering there src.LHS, in.Source = in, src.LHS - return src, rewrite.NewTree("push down ordering on the LHS of a join", in), nil + return src, rewrite.NewTree("push down ordering on the LHS of a join"), nil } case *Ordering: // we'll just remove the order underneath. The top order replaces whatever was incoming in.Source = src.Source - return in, rewrite.NewTree("remove double ordering", src), nil + return in, rewrite.NewTree("remove double ordering"), nil case *Projection: // we can move ordering under a projection if it's not introducing a column we're sorting by for _, by := range in.Order { @@ -573,7 +575,7 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operat } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push ordering into outer side of subquery", in), nil + return src, rewrite.NewTree("push ordering into outer side of subquery"), nil case *SubQuery: outerTableID := TableID(src.Outer) for _, order := range in.Order { @@ -583,7 +585,7 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operat } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push ordering into outer side of subquery", in), nil + return src, rewrite.NewTree("push ordering into outer side of subquery"), nil } return in, rewrite.SameTree, nil } @@ -662,7 +664,7 @@ func pushOrderingUnderAggr(ctx *plancontext.PlanningContext, order *Ordering, ag order.Source = aggrSource.Source aggrSource.Source = nil // removing from plan tree aggregator.Source = order - return aggregator, rewrite.NewTree("push ordering under aggregation, removing extra ordering", aggregator), nil + return aggregator, rewrite.NewTree("push ordering under aggregation, removing extra ordering"), nil } return rewrite.Swap(order, aggregator, "push ordering under aggregation") } @@ -719,7 +721,7 @@ func tryPushFilter(ctx *plancontext.PlanningContext, in *Filter) (ops.Operator, } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push filter to outer query in subquery container", in), nil + return src, rewrite.NewTree("push filter to outer query in subquery container"), nil } return in, rewrite.SameTree, nil @@ -756,7 +758,7 @@ func tryPushDistinct(in *Distinct) (ops.Operator, *rewrite.ApplyResult, error) { switch src := in.Source.(type) { case *Route: if isDistinct(src.Source) && src.IsSingleShard() { - return src, rewrite.NewTree("distinct not needed", in), nil + return src, rewrite.NewTree("distinct not needed"), nil } if src.IsSingleShard() || !in.Required { return rewrite.Swap(in, src, "push distinct under route") @@ -769,31 +771,31 @@ func tryPushDistinct(in *Distinct) (ops.Operator, *rewrite.ApplyResult, error) { src.Source = &Distinct{Source: src.Source} in.PushedPerformance = true - return in, rewrite.NewTree("added distinct under route - kept original", src), nil + return in, rewrite.NewTree("added distinct under route - kept original"), nil case *Distinct: src.Required = false src.PushedPerformance = false - return src, rewrite.NewTree("remove double distinct", src), nil + return src, rewrite.NewTree("remove double distinct"), nil case *Union: for i := range src.Sources { src.Sources[i] = &Distinct{Source: src.Sources[i]} } in.PushedPerformance = true - return in, rewrite.NewTree("push down distinct under union", src), nil + return in, rewrite.NewTree("push down distinct under union"), nil case *ApplyJoin: src.LHS = &Distinct{Source: src.LHS} src.RHS = &Distinct{Source: src.RHS} in.PushedPerformance = true if in.Required { - return in, rewrite.NewTree("push distinct under join - kept original", in.Source), nil + return in, rewrite.NewTree("push distinct under join - kept original"), nil } - return in.Source, rewrite.NewTree("push distinct under join", in.Source), nil + return in.Source, rewrite.NewTree("push distinct under join"), nil case *Ordering: in.Source = src.Source - return in, rewrite.NewTree("remove ordering under distinct", in), nil + return in, rewrite.NewTree("remove ordering under distinct"), nil } return in, rewrite.SameTree, nil @@ -835,19 +837,19 @@ func tryPushUnion(ctx *plancontext.PlanningContext, op *Union) (ops.Operator, *r if len(sources) == 1 { result := sources[0].(*Route) if result.IsSingleShard() || !op.distinct { - return result, rewrite.NewTree("push union under route", op), nil + return result, rewrite.NewTree("push union under route"), nil } return &Distinct{ Source: result, Required: true, - }, rewrite.NewTree("push union under route", op), nil + }, rewrite.NewTree("push union under route"), nil } if len(sources) == len(op.Sources) { return op, rewrite.SameTree, nil } - return newUnion(sources, selects, op.unionColumns, op.distinct), rewrite.NewTree("merge union inputs", op), nil + return newUnion(sources, selects, op.unionColumns, op.distinct), rewrite.NewTree("merge union inputs"), nil } // addTruncationOrProjectionToReturnOutput uses the original Horizon to make sure that the output columns line up with what the user asked for diff --git a/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go b/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go index c5a8b0a6fa2..1ecc0cd8e76 100644 --- a/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go +++ b/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go @@ -45,7 +45,6 @@ type ( Rewrite struct { Message string - Op ops.Operator } // VisitRule signals to the rewriter if the children of this operator should be visited or not @@ -61,11 +60,11 @@ const ( SkipChildren VisitRule = false ) -func NewTree(message string, op ops.Operator) *ApplyResult { +func NewTree(message string) *ApplyResult { if DebugOperatorTree { fmt.Println(">>>>>>>> " + message) } - return &ApplyResult{Transformations: []Rewrite{{Message: message, Op: op}}} + return &ApplyResult{Transformations: []Rewrite{{Message: message}}} } func (ar *ApplyResult) Merge(other *ApplyResult) *ApplyResult { @@ -145,19 +144,6 @@ func FixedPointBottomUp( return op, nil } -// BottomUpAll rewrites an operator tree from the bottom up. BottomUp applies a transformation function to -// the given operator tree from the bottom up. Each callback [f] returns a ApplyResult that is aggregated -// into a final output indicating whether the operator tree was changed. -func BottomUpAll( - root ops.Operator, - resolveID func(ops.Operator) semantics.TableSet, - visit VisitF, -) (ops.Operator, error) { - return BottomUp(root, resolveID, visit, func(ops.Operator) VisitRule { - return VisitChildren - }) -} - // TopDown rewrites an operator tree from the bottom up. BottomUp applies a transformation function to // the given operator tree from the bottom up. Each callback [f] returns a ApplyResult that is aggregated // into a final output indicating whether the operator tree was changed. @@ -208,7 +194,7 @@ func Swap(parent, child ops.Operator, message string) (ops.Operator, *ApplyResul child.SetInputs([]ops.Operator{parent}) parent.SetInputs(aInputs) - return child, NewTree(message, parent), nil + return child, NewTree(message), nil } func bottomUp( diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go index d4b2c43ecff..acbc28553dd 100644 --- a/go/vt/vtgate/planbuilder/operators/route.go +++ b/go/vt/vtgate/planbuilder/operators/route.go @@ -681,17 +681,17 @@ func isSpecialOrderBy(o ops.OrderBy) bool { return isFunction && f.Name.Lowered() == "rand" } -func (r *Route) planOffsets(ctx *plancontext.PlanningContext) { +func (r *Route) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { // if operator is returning data from a single shard, we don't need to do anything more if r.IsSingleShard() { - return + return nil } // if we are getting results from multiple shards, we need to do a merge-sort // between them to get the final output correctly sorted ordering := r.Source.GetOrdering(ctx) if len(ordering) == 0 { - return + return nil } for _, order := range ordering { @@ -713,6 +713,7 @@ func (r *Route) planOffsets(ctx *plancontext.PlanningContext) { } r.Ordering = append(r.Ordering, o) } + return nil } func weightStringFor(expr sqlparser.Expr) sqlparser.Expr { diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index 306158a06da..5bce334a609 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -75,7 +75,7 @@ func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (resul result = newFilter(result, ctx.SemTable.AndExpressions(unresolved...)) } - changed = rewrite.NewTree("solved query graph", result) + changed = rewrite.NewTree("solved query graph") return } @@ -365,16 +365,18 @@ func requiresSwitchingSides(ctx *plancontext.PlanningContext, op ops.Operator) b func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPredicates []sqlparser.Expr, inner bool) (ops.Operator, *rewrite.ApplyResult, error) { newPlan := mergeJoinInputs(ctx, lhs, rhs, joinPredicates, newJoinMerge(joinPredicates, inner)) if newPlan != nil { - return newPlan, rewrite.NewTree("merge routes into single operator", newPlan), nil + return newPlan, rewrite.NewTree("merge routes into single operator"), nil } if len(joinPredicates) > 0 && requiresSwitchingSides(ctx, rhs) { - if !inner { - return nil, nil, vterrors.VT12001("LEFT JOIN with LIMIT on the outer side") - } - - if requiresSwitchingSides(ctx, lhs) { - return nil, nil, vterrors.VT12001("JOIN between derived tables with LIMIT") + if !inner || requiresSwitchingSides(ctx, lhs) { + // we can't switch sides, so let's see if we can use a HashJoin to solve it + join := NewHashJoin(lhs, rhs, !inner) + for _, pred := range joinPredicates { + join.AddJoinPredicate(ctx, pred) + } + ctx.SemTable.QuerySignature.HashJoin = true + return join, rewrite.NewTree("use a hash join because we have LIMIT on the LHS"), nil } join := NewApplyJoin(Clone(rhs), Clone(lhs), nil, !inner) @@ -382,7 +384,7 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPr if err != nil { return nil, nil, err } - return newOp, rewrite.NewTree("logical join to applyJoin, switching side because LIMIT", newOp), nil + return newOp, rewrite.NewTree("logical join to applyJoin, switching side because LIMIT"), nil } join := NewApplyJoin(Clone(lhs), Clone(rhs), nil, !inner) @@ -390,7 +392,7 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPr if err != nil { return nil, nil, err } - return newOp, rewrite.NewTree("logical join to applyJoin ", newOp), nil + return newOp, rewrite.NewTree("logical join to applyJoin "), nil } func operatorsToRoutes(a, b ops.Operator) (*Route, *Route) { diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index e06e595f689..ae28dd8d9c6 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -54,7 +54,7 @@ type SubQuery struct { IsProjection bool } -func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) { +func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { sq.Vars = make(map[string]int) columns, err := sq.GetJoinColumns(ctx, sq.Outer) if err != nil { @@ -66,6 +66,7 @@ func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) { sq.Vars[lhsExpr.Name] = offset } } + return nil } func (sq *SubQuery) OuterExpressionsNeeded(ctx *plancontext.PlanningContext, outer ops.Operator) (result []*sqlparser.ColName, err error) { @@ -97,7 +98,7 @@ func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer ops.O } sq.outerID = outerID mapper := func(in sqlparser.Expr) (JoinColumn, error) { - return BreakExpressionInLHSandRHS(ctx, in, outerID) + return breakExpressionInLHSandRHSForApplyJoin(ctx, in, outerID) } joinPredicates, err := slice.MapWithError(sq.Predicates, mapper) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operators/subquery_planning.go b/go/vt/vtgate/planbuilder/operators/subquery_planning.go index 7740ca3d46d..74761aef5c5 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_planning.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_planning.go @@ -87,7 +87,7 @@ func settleSubqueries(ctx *plancontext.PlanningContext, op ops.Operator) ops.Ope subq.Outer = newOuter outer = subq } - return outer, rewrite.NewTree("extracted subqueries from subquery container", outer), nil + return outer, rewrite.NewTree("extracted subqueries from subquery container"), nil case *Projection: ap, err := op.GetAliasedProjections() if err != nil { @@ -233,7 +233,7 @@ func tryPushSubQueryInJoin( if deps.IsSolvedBy(lhs) { // we can safely push down the subquery on the LHS outer.LHS = addSubQuery(outer.LHS, inner) - return outer, rewrite.NewTree("push subquery into LHS of join", inner), nil + return outer, rewrite.NewTree("push subquery into LHS of join"), nil } if outer.LeftJoin || len(inner.Predicates) == 0 { @@ -245,7 +245,7 @@ func tryPushSubQueryInJoin( if deps.IsSolvedBy(rhs) { // we can push down the subquery filter on RHS of the join outer.RHS = addSubQuery(outer.RHS, inner) - return outer, rewrite.NewTree("push subquery into RHS of join", inner), nil + return outer, rewrite.NewTree("push subquery into RHS of join"), nil } if deps.IsSolvedBy(joinID) { @@ -258,7 +258,7 @@ func tryPushSubQueryInJoin( } outer.RHS = addSubQuery(outer.RHS, inner) - return outer, rewrite.NewTree("push subquery into RHS of join rewriting predicates", inner), nil + return outer, rewrite.NewTree("push subquery into RHS of join rewriting predicates"), nil } return nil, rewrite.SameTree, nil @@ -272,7 +272,7 @@ func extractLHSExpr( lhs semantics.TableSet, ) func(expr sqlparser.Expr) (sqlparser.Expr, error) { return func(expr sqlparser.Expr) (sqlparser.Expr, error) { - col, err := BreakExpressionInLHSandRHS(ctx, expr, lhs) + col, err := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, lhs) if err != nil { return nil, err } @@ -316,7 +316,7 @@ func tryMergeWithRHS(ctx *plancontext.PlanningContext, inner *SubQuery, outer *A outer.RHS = newOp ctx.MergedSubqueries = append(ctx.MergedSubqueries, inner.originalSubquery) - return outer, rewrite.NewTree("merged subquery with rhs of join", inner), nil + return outer, rewrite.NewTree("merged subquery with rhs of join"), nil } // addSubQuery adds a SubQuery to the given operator. If the operator is a SubQueryContainer, @@ -387,7 +387,7 @@ func pushProjectionToOuterContainer(ctx *plancontext.PlanningContext, p *Project } // all projections can be pushed to the outer src.Outer, p.Source = p, src.Outer - return src, rewrite.NewTree("push projection into outer side of subquery container", p), nil + return src, rewrite.NewTree("push projection into outer side of subquery container"), nil } func rewriteColNameToArgument(ctx *plancontext.PlanningContext, in sqlparser.Expr, se SubQueryExpression, subqueries ...*SubQuery) sqlparser.Expr { @@ -512,7 +512,7 @@ func tryMergeSubqueriesRecursively( } op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}} - return op, finalResult.Merge(rewrite.NewTree("merge outer of two subqueries", subQuery)), nil + return op, finalResult.Merge(rewrite.NewTree("merge outer of two subqueries")), nil } func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQuery, outer *Route, inner ops.Operator) (ops.Operator, *rewrite.ApplyResult, error) { @@ -533,7 +533,7 @@ func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQu op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}} } ctx.MergedSubqueries = append(ctx.MergedSubqueries, subQuery.originalSubquery) - return op, rewrite.NewTree("merged subquery with outer", subQuery), nil + return op, rewrite.NewTree("merged subquery with outer"), nil } // This checked if subquery is part of the changed vindex values. Subquery cannot be merged with the outer route. diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go index 4c8b02f76d8..03b7a212893 100644 --- a/go/vt/vtgate/planbuilder/operators/union_merging.go +++ b/go/vt/vtgate/planbuilder/operators/union_merging.go @@ -255,5 +255,5 @@ func compactUnion(u *Union) *rewrite.ApplyResult { u.Sources = newSources u.Selects = newSelects - return rewrite.NewTree("merged UNIONs", u) + return rewrite.NewTree("merged UNIONs") } diff --git a/go/vt/vtgate/planbuilder/operators/utils_test.go b/go/vt/vtgate/planbuilder/operators/utils_test.go new file mode 100644 index 00000000000..a7e25c1337c --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/utils_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 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 operators + +import ( + "slices" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" +) + +type fakeOp struct { + id semantics.TableSet + inputs []ops.Operator + cols []*sqlparser.AliasedExpr +} + +var _ ops.Operator = (*fakeOp)(nil) + +func (f *fakeOp) Clone(inputs []ops.Operator) ops.Operator { + return f +} + +func (f *fakeOp) Inputs() []ops.Operator { + return f.inputs +} + +func (f *fakeOp) SetInputs(operators []ops.Operator) { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, _ bool, expr *sqlparser.AliasedExpr) int { + if offset := f.FindCol(ctx, expr.Expr, false); reuseExisting && offset >= 0 { + return offset + } + f.cols = append(f.cols, expr) + return len(f.cols) - 1 +} + +func (f *fakeOp) FindCol(ctx *plancontext.PlanningContext, a sqlparser.Expr, underRoute bool) int { + return slices.IndexFunc(f.cols, func(b *sqlparser.AliasedExpr) bool { + return a == b.Expr + }) +} + +func (f *fakeOp) GetColumns(ctx *plancontext.PlanningContext) []*sqlparser.AliasedExpr { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) ShortDescription() string { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { + // TODO implement me + panic("implement me") +} + +func (f *fakeOp) introducesTableID() semantics.TableSet { + return f.id +} diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index 7a3c13c3635..476a16f8a11 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -4050,5 +4050,130 @@ "comment": "select with a target destination", "query": "select * from `user[-]`.user_metadata", "plan": "VT09017: SELECT with a target destination is not allowed" + }, + { + "comment": "query that needs a hash join", + "query": "select id from user left join (select col from user_extra limit 10) ue on user.col = ue.col", + "plan": { + "QueryType": "SELECT", + "Original": "select id from user left join (select col from user_extra limit 10) ue on user.col = ue.col", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "id as id" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "HashLeftJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-2", + "Predicate": "`user`.col = ue.col", + "TableName": "`user`_user_extra", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col, id from `user` where 1 != 1", + "Query": "select `user`.col, id from `user`", + "Table": "`user`" + }, + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col from (select col from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col from (select col from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "query that needs a hash join - both sides have limits", + "query": "select id, user_id from (select id, col from user limit 10) u join (select col, user_id from user_extra limit 10) ue on u.col = ue.col", + "plan": { + "QueryType": "SELECT", + "Original": "select id, user_id from (select id, col from user limit 10) u join (select col, user_id from user_extra limit 10) ue on u.col = ue.col", + "Instructions": { + "OperatorType": "Projection", + "Expressions": [ + "id as id", + "user_id as user_id" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "HashJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-1,2", + "Predicate": "u.col = ue.col", + "TableName": "`user`_user_extra", + "Inputs": [ + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id, col from (select id, col from `user` where 1 != 1) as u where 1 != 1", + "Query": "select id, col from (select id, col from `user`) as u limit :__upper_limit", + "Table": "`user`" + } + ] + }, + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col, user_id from (select col, user_id from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col, user_id from (select col, user_id from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/hash_joins.txt b/go/vt/vtgate/planbuilder/testdata/hash_joins.txt deleted file mode 100644 index afc175a581c..00000000000 --- a/go/vt/vtgate/planbuilder/testdata/hash_joins.txt +++ /dev/null @@ -1,531 +0,0 @@ -# Test cases in this file are currently turned off -# Multi-route unique vindex constraint (with hash join) -"select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5" -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1", - "JoinVars": { - "user_col": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.col from `user` where `user`.id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } -} -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT16", - "JoinColumnIndexes": "2", - "Predicate": "`user`.col = user_extra.col", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.col from `user` where `user`.id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col, user_extra.id from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.col, user_extra.id from user_extra", - "Table": "user_extra" - } - ] - } -} - - -# Multi-route with non-route constraint, should use first route. -"select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1" -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1", - "JoinVars": { - "user_col": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.col from `user` where 1 = 1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } -} -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1", - "Instructions": { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT16", - "JoinColumnIndexes": "2", - "Predicate": "`user`.col = user_extra.col", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.col from `user` where 1 = 1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col, user_extra.id from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.col, user_extra.id from user_extra where 1 = 1", - "Table": "user_extra" - } - ] - } -} - -# wire-up on within cross-shard derived table (hash-join version) -"select /*vt+ ALLOW_HASH_JOIN */ t.id from (select user.id, user.col1 from user join user_extra on user_extra.col = user.col) as t" -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ t.id from (select user.id, user.col1 from user join user_extra on user_extra.col = user.col) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2", - "JoinVars": { - "user_col": 2 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.col1, `user`.col from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.id, `user`.col1, `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ 1 from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } - ] - } -} -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ t.id from (select user.id, user.col1 from user join user_extra on user_extra.col = user.col) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT16", - "JoinColumnIndexes": "-2,-3", - "Predicate": "user_extra.col = `user`.col", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col, `user`.id, `user`.col1 from `user` where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ `user`.col, `user`.id, `user`.col1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ user_extra.col from user_extra", - "Table": "user_extra" - } - ] - } - ] - } -} - -# hash join on int columns -"select /*vt+ ALLOW_HASH_JOIN */ u.id from user as u join user as uu on u.intcol = uu.intcol" -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ u.id from user as u join user as uu on u.intcol = uu.intcol", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1", - "JoinVars": { - "u_intcol": 1 - }, - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, u.intcol from `user` as u where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ u.id, u.intcol from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as uu where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ 1 from `user` as uu where uu.intcol = :u_intcol", - "Table": "`user`" - } - ] - } -} -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ u.id from user as u join user as uu on u.intcol = uu.intcol", - "Instructions": { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT16", - "JoinColumnIndexes": "-2", - "Predicate": "u.intcol = uu.intcol", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.intcol, u.id from `user` as u where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ u.intcol, u.id from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select uu.intcol from `user` as uu where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ uu.intcol from `user` as uu", - "Table": "`user`" - } - ] - } -} - -# Author5.joins(books: [{orders: :customer}, :supplier]) (with hash join) -"select /*vt+ ALLOW_HASH_JOIN */ author5s.* from author5s join book6s on book6s.author5_id = author5s.id join book6s_order2s on book6s_order2s.book6_id = book6s.id join order2s on order2s.id = book6s_order2s.order2_id join customer2s on customer2s.id = order2s.customer2_id join supplier5s on supplier5s.id = book6s.supplier5_id" -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ author5s.* from author5s join book6s on book6s.author5_id = author5s.id join book6s_order2s on book6s_order2s.book6_id = book6s.id join order2s on order2s.id = book6s_order2s.order2_id join customer2s on customer2s.id = order2s.customer2_id join supplier5s on supplier5s.id = book6s.supplier5_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2,-3,-4", - "JoinVars": { - "book6s_supplier5_id": 4 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s_customer2s_supplier5s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2,-3,-4,-5", - "JoinVars": { - "order2s_customer2_id": 5 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s_customer2s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2,-3,-4,-5,1", - "JoinVars": { - "book6s_order2s_order2_id": 5 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2,-3,-4,-5,1", - "JoinVars": { - "book6s_id": 5 - }, - "TableName": "author5s, book6s_book6s_order2s", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select author5s.id, author5s.`name`, author5s.created_at, author5s.updated_at, book6s.supplier5_id, book6s.id from author5s join book6s on book6s.author5_id = author5s.id where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ author5s.id, author5s.`name`, author5s.created_at, author5s.updated_at, book6s.supplier5_id, book6s.id from author5s join book6s on book6s.author5_id = author5s.id", - "Table": "author5s, book6s" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select book6s_order2s.order2_id from book6s_order2s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ book6s_order2s.order2_id from book6s_order2s where book6s_order2s.book6_id = :book6s_id", - "Table": "book6s_order2s", - "Values": [ - ":book6s_id" - ], - "Vindex": "binary_md5" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select order2s.customer2_id from order2s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ order2s.customer2_id from order2s where order2s.id = :book6s_order2s_order2_id", - "Table": "order2s" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from customer2s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ 1 from customer2s where customer2s.id = :order2s_customer2_id", - "Table": "customer2s", - "Values": [ - ":order2s_customer2_id" - ], - "Vindex": "binary_md5" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from supplier5s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ 1 from supplier5s where supplier5s.id = :book6s_supplier5_id", - "Table": "supplier5s", - "Values": [ - ":book6s_supplier5_id" - ], - "Vindex": "binary_md5" - } - ] - } -} -{ - "QueryType": "SELECT", - "Original": "select /*vt+ ALLOW_HASH_JOIN */ author5s.* from author5s join book6s on book6s.author5_id = author5s.id join book6s_order2s on book6s_order2s.book6_id = book6s.id join order2s on order2s.id = book6s_order2s.order2_id join customer2s on customer2s.id = order2s.customer2_id join supplier5s on supplier5s.id = book6s.supplier5_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT64", - "JoinColumnIndexes": "2,3,4,5", - "Predicate": "order2s.id = book6s_order2s.order2_id", - "TableName": "customer2s, order2s_author5s, book6s_book6s_order2s_supplier5s", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select order2s.id from order2s, customer2s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ order2s.id from order2s, customer2s where customer2s.id = order2s.customer2_id", - "Table": "customer2s, order2s" - }, - { - "OperatorType": "Join", - "Variant": "HashJoin", - "ComparisonType": "INT64", - "JoinColumnIndexes": "-1,-2,-3,-4,-5", - "Predicate": "supplier5s.id = book6s.supplier5_id", - "TableName": "author5s, book6s_book6s_order2s_supplier5s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1,-3,-4,-5,-6", - "JoinVars": { - "book6s_id": 0 - }, - "Predicate": "book6s_order2s.book6_id = book6s.id", - "TableName": "author5s, book6s_book6s_order2s", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select book6s.id, book6s.supplier5_id, author5s.id as id, author5s.`name` as `name`, author5s.created_at as created_at, author5s.updated_at as updated_at from author5s, book6s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ book6s.id, book6s.supplier5_id, author5s.id as id, author5s.`name` as `name`, author5s.created_at as created_at, author5s.updated_at as updated_at from author5s, book6s where book6s.author5_id = author5s.id", - "Table": "author5s, book6s" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select book6s_order2s.order2_id from book6s_order2s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ book6s_order2s.order2_id from book6s_order2s where book6s_order2s.book6_id = :book6s_id", - "Table": "book6s_order2s", - "Values": [ - ":book6s_id" - ], - "Vindex": "binary_md5" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select supplier5s.id from supplier5s where 1 != 1", - "Query": "select /*vt+ ALLOW_HASH_JOIN */ supplier5s.id from supplier5s", - "Table": "supplier5s" - } - ] - } - ] - } -} diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index 1ea07455486..fdab7835738 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -330,14 +330,9 @@ "plan": "VT12001: unsupported: unmergable subquery can not be inside complex expression" }, { - "comment": "cant switch sides for outer joins", - "query": "select id from user left join (select user_id from user_extra limit 10) ue on user.id = ue.user_id", - "plan": "VT12001: unsupported: LEFT JOIN with LIMIT on the outer side" - }, - { - "comment": "limit on both sides means that we can't evaluate this at all", + "comment": "this query needs better type information to be able to use the hash join", "query": "select id from (select id from user limit 10) u join (select user_id from user_extra limit 10) ue on u.id = ue.user_id", - "plan": "VT12001: unsupported: JOIN between derived tables with LIMIT" + "plan": "VT12001: unsupported: missing type information for [u.id, ue.user_id]" }, { "comment": "multi-shard union", diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 48ab4322bc8..48060524dba 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -76,10 +76,11 @@ type ( // QuerySignature is used to identify shortcuts in the planning process QuerySignature struct { - Union bool - Aggregation bool - Distinct bool - SubQueries bool + Union, + Aggregation, + Distinct, + SubQueries, + HashJoin bool } // SemTable contains semantic analysis information about the query. @@ -505,6 +506,7 @@ func EmptySemTable() *SemTable { Direct: map[sqlparser.Expr]TableSet{}, ColumnEqualities: map[columnName][]sqlparser.Expr{}, columns: map[*sqlparser.Union]sqlparser.SelectExprs{}, + ExprTypes: make(map[sqlparser.Expr]evalengine.Type), } } diff --git a/go/vt/vttablet/tabletserver/rules/rules.go b/go/vt/vttablet/tabletserver/rules/rules.go index efbfcdf87e4..c1e572caa2c 100644 --- a/go/vt/vttablet/tabletserver/rules/rules.go +++ b/go/vt/vttablet/tabletserver/rules/rules.go @@ -27,15 +27,14 @@ import ( "time" "vitess.io/vitess/go/sqltypes" + 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/vttablet/tabletserver/planbuilder" - - querypb "vitess.io/vitess/go/vt/proto/query" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) -//----------------------------------------------- +// ----------------------------------------------- const ( bufferedTableRuleName = "buffered_table" @@ -189,7 +188,7 @@ func (qrs *Rules) GetAction( return QRContinue, nil, 0, "" } -//----------------------------------------------- +// ----------------------------------------------- // Rule represents one rule (conditions-action). // Name is meant to uniquely identify a rule. @@ -561,7 +560,7 @@ func bvMatch(bvcond BindVarCond, bindVars map[string]*querypb.BindVariable) bool return bvcond.value.eval(bv, bvcond.op, bvcond.onMismatch) } -//----------------------------------------------- +// ----------------------------------------------- // Support types for Rule // Action speficies the list of actions to perform @@ -852,13 +851,13 @@ func getint64(val *querypb.BindVariable) (iv int64, status int) { // TODO(sougou): this is inefficient. Optimize to use []byte. func getstring(val *querypb.BindVariable) (s string, status int) { - if sqltypes.IsIntegral(val.Type) || sqltypes.IsFloat(val.Type) || sqltypes.IsText(val.Type) || sqltypes.IsBinary(val.Type) { + if sqltypes.IsIntegral(val.Type) || sqltypes.IsFloat(val.Type) || sqltypes.IsTextOrBinary(val.Type) { return string(val.Value), QROK } return "", QRMismatch } -//----------------------------------------------- +// ----------------------------------------------- // Support functions for JSON // MapStrOperator maps a string representation to an Operator. From b6ce0a0341abda9eaf6e8e14609039779375d976 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 16 Nov 2023 13:37:21 +0100 Subject: [PATCH 025/119] Support cluster bootstrapping in vtctldclient (#14315) Signed-off-by: Matt Lord --- examples/common/scripts/consul-up.sh | 8 +-- examples/common/scripts/etcd-up.sh | 9 ++- examples/common/scripts/zk-up.sh | 8 +-- go/cmd/vtctldclient/command/root.go | 65 ++++++++++++++++++ go/cmd/vtctldclient/command/root_test.go | 67 +++++++++++++++++++ go/flags/endtoend/vtctldclient.txt | 7 ++ go/vt/vtctl/grpcvtctldserver/server.go | 4 +- .../vreplication/vcopier_atomic.go | 1 - 8 files changed, 153 insertions(+), 16 deletions(-) diff --git a/examples/common/scripts/consul-up.sh b/examples/common/scripts/consul-up.sh index 584a25f437a..fb75495b278 100755 --- a/examples/common/scripts/consul-up.sh +++ b/examples/common/scripts/consul-up.sh @@ -40,13 +40,13 @@ sleep 5 # Add the CellInfo description for the cell. # If the node already exists, it's fine, means we used existing data. -echo "add $cell CellInfo" +echo "add ${cell} CellInfo" set +e # shellcheck disable=SC2086 -vtctl $TOPOLOGY_FLAGS VtctldCommand AddCellInfo \ - --root "vitess/$cell" \ +command vtctldclient --server internal --topo-implementation consul --topo-global-server "${CONSUL_SERVER}:${consul_http_port}" AddCellInfo \ + --root "/vitess/${cell}" \ --server-address "${CONSUL_SERVER}:${consul_http_port}" \ - "$cell" + "${cell}" set -e echo "consul start done..." diff --git a/examples/common/scripts/etcd-up.sh b/examples/common/scripts/etcd-up.sh index ac81c1fbd28..1ed22ffce2e 100755 --- a/examples/common/scripts/etcd-up.sh +++ b/examples/common/scripts/etcd-up.sh @@ -32,13 +32,12 @@ sleep 5 # And also add the CellInfo description for the cell. # If the node already exists, it's fine, means we used existing data. -echo "add $cell CellInfo" +echo "add ${cell} CellInfo" set +e -# shellcheck disable=SC2086 -vtctl $TOPOLOGY_FLAGS VtctldCommand AddCellInfo \ - --root /vitess/$cell \ +command vtctldclient --server internal AddCellInfo \ + --root "/vitess/${cell}" \ --server-address "${ETCD_SERVER}" \ - $cell + "${cell}" set -e echo "etcd is running!" diff --git a/examples/common/scripts/zk-up.sh b/examples/common/scripts/zk-up.sh index 3137ed724cc..2b79053d2f6 100755 --- a/examples/common/scripts/zk-up.sh +++ b/examples/common/scripts/zk-up.sh @@ -52,10 +52,10 @@ echo "Started zk servers." # If the node already exists, it's fine, means we used existing data. set +e # shellcheck disable=SC2086 -vtctl $TOPOLOGY_FLAGS VtctldCommand AddCellInfo \ - --root /vitess/$cell \ - --server-address $ZK_SERVER \ - $cell +command vtctldclient --server internal --topo-implementation zk2 --topo-global-server "${ZK_SERVER}" AddCellInfo \ + --root "/vitess/${cell}" \ + --server-address "${ZK_SERVER}" \ + "${cell}" set -e echo "Configured zk servers." diff --git a/go/cmd/vtctldclient/command/root.go b/go/cmd/vtctldclient/command/root.go index 1194b49ec8f..a5848a7b42a 100644 --- a/go/cmd/vtctldclient/command/root.go +++ b/go/cmd/vtctldclient/command/root.go @@ -22,6 +22,8 @@ import ( "fmt" "io" "strconv" + "strings" + "sync" "time" "github.com/spf13/cobra" @@ -29,7 +31,11 @@ import ( "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/servenv" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" + "vitess.io/vitess/go/vt/vtctl/localvtctldclient" "vitess.io/vitess/go/vt/vtctl/vtctldclient" + "vitess.io/vitess/go/vt/vttablet/tmclient" // These imports ensure init()s within them get called and they register their commands/subcommands. "vitess.io/vitess/go/cmd/vtctldclient/cli" @@ -42,8 +48,16 @@ import ( _ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/reshard" _ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/vdiff" _ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/workflow" + + // These imports register the topo factories to use when --server=internal. + _ "vitess.io/vitess/go/vt/topo/consultopo" + _ "vitess.io/vitess/go/vt/topo/etcd2topo" + _ "vitess.io/vitess/go/vt/topo/zk2topo" ) +// The --server value if you want to use a "local" vtctld server. +const useInternalVtctld = "internal" + var ( // VtctldClientProtocol is the protocol to use when creating the vtctldclient.VtctldClient. VtctldClientProtocol = "grpc" @@ -54,14 +68,37 @@ var ( commandCtx context.Context commandCancel func() + // Register functions to be called when the command completes. + onTerm = []func(){} + + // Register our nil tmclient grpc handler only one time. + // This is primarily for tests where we execute the root + // command multiple times. + once = sync.Once{} + server string actionTimeout time.Duration compactOutput bool + topoOptions = struct { + implementation string + globalServerAddresses []string + globalRoot string + }{ // Set defaults + implementation: "etcd2", + globalServerAddresses: []string{"localhost:2379"}, + globalRoot: "/vitess/global", + } + // Root is the main entrypoint to the vtctldclient CLI. Root = &cobra.Command{ Use: "vtctldclient", Short: "Executes a cluster management command on the remote vtctld server.", + Long: fmt.Sprintf(`Executes a cluster management command on the remote vtctld server. +If there are no running vtctld servers -- for example when bootstrapping +a new Vitess cluster -- you can specify a --server value of '%s'. +When doing so, you would use the --topo* flags so that the client can +connect directly to the topo server(s).`, useInternalVtctld), // We use PersistentPreRun to set up the tracer, grpc client, and // command context for every command. PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { @@ -87,6 +124,10 @@ var ( if client != nil { err = client.Close() } + // Execute any registered onTerm functions. + for _, f := range onTerm { + f() + } trace.LogErrorsWhenClosing(traceCloser) return err }, @@ -152,6 +193,27 @@ func getClientForCommand(cmd *cobra.Command) (vtctldclient.VtctldClient, error) return nil, errNoServer } + if server == useInternalVtctld { + ts, err := topo.OpenServer(topoOptions.implementation, strings.Join(topoOptions.globalServerAddresses, ","), topoOptions.globalRoot) + if err != nil { + return nil, fmt.Errorf("failed to connect to the topology server: %v", err) + } + onTerm = append(onTerm, ts.Close) + + // Use internal vtctld server implementation. + // Register a nil grpc handler -- we will not use tmclient at all but + // a factory still needs to be registered. + once.Do(func() { + tmclient.RegisterTabletManagerClientFactory("grpc", func() tmclient.TabletManagerClient { + return nil + }) + }) + vtctld := grpcvtctldserver.NewVtctldServer(ts) + localvtctldclient.SetServer(vtctld) + VtctldClientProtocol = "local" + server = "" + } + return vtctldclient.New(VtctldClientProtocol, server) } @@ -159,5 +221,8 @@ func init() { Root.PersistentFlags().StringVar(&server, "server", "", "server to use for the connection (required)") Root.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout to use for the command") Root.PersistentFlags().BoolVar(&compactOutput, "compact", false, "use compact format for otherwise verbose outputs") + Root.PersistentFlags().StringVar(&topoOptions.implementation, "topo-implementation", topoOptions.implementation, "the topology implementation to use") + Root.PersistentFlags().StringSliceVar(&topoOptions.globalServerAddresses, "topo-global-server-address", topoOptions.globalServerAddresses, "the address of the global topology server(s)") + Root.PersistentFlags().StringVar(&topoOptions.globalRoot, "topo-global-root", topoOptions.globalRoot, "the path of the global topology data in the global topology server") vreplcommon.RegisterCommands(Root) } diff --git a/go/cmd/vtctldclient/command/root_test.go b/go/cmd/vtctldclient/command/root_test.go index 155fac78705..5efe844e1a1 100644 --- a/go/cmd/vtctldclient/command/root_test.go +++ b/go/cmd/vtctldclient/command/root_test.go @@ -17,13 +17,19 @@ limitations under the License. package command_test import ( + "context" + "fmt" "os" + "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/cmd/vtctldclient/command" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/vtctl/localvtctldclient" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" @@ -52,3 +58,64 @@ func TestRoot(t *testing.T) { assert.Contains(t, err.Error(), "unknown command") }) } + +// TestRootWithInternalVtctld tests that the internal VtctldServer +// implementation -- used with --server=internal -- works for +// commands as expected. +func TestRootWithInternalVtctld(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + cell := "zone1" + ts, factory := memorytopo.NewServerAndFactory(ctx, cell) + topo.RegisterFactory("test", factory) + command.VtctldClientProtocol = "local" + baseArgs := []string{"vtctldclient", "--server", "internal", "--topo-implementation", "test"} + + args := append([]string{}, os.Args...) + protocol := command.VtctldClientProtocol + t.Cleanup(func() { + ts.Close() + os.Args = append([]string{}, args...) + command.VtctldClientProtocol = protocol + }) + + testCases := []struct { + command string + args []string + expectErr string + }{ + { + command: "AddCellInfo", + args: []string{"--root", fmt.Sprintf("/vitess/%s", cell), "--server-address", "", cell}, + expectErr: "node already exists", // Cell already exists + }, + { + command: "GetTablets", + }, + { + command: "NoCommandDrJones", + expectErr: "unknown command", // Invalid command + }, + } + + for _, tc := range testCases { + t.Run(tc.command, func(t *testing.T) { + defer func() { + // Reset the OS args. + os.Args = append([]string{}, args...) + }() + + os.Args = append(baseArgs, tc.command) + os.Args = append(os.Args, tc.args...) + + err := command.Root.Execute() + if tc.expectErr != "" { + if !strings.Contains(err.Error(), tc.expectErr) { + t.Errorf(fmt.Sprintf("%s error = %v, expectErr = %v", tc.command, err, tc.expectErr)) + } + } else { + require.NoError(t, err, "unexpected error: %v", err) + } + }) + } +} diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt index f70f17f8136..86c1bb3bfa2 100644 --- a/go/flags/endtoend/vtctldclient.txt +++ b/go/flags/endtoend/vtctldclient.txt @@ -1,4 +1,8 @@ Executes a cluster management command on the remote vtctld server. +If there are no running vtctld servers -- for example when bootstrapping +a new Vitess cluster -- you can specify a --server value of 'internal'. +When doing so, you would use the --topo* flags so that the client can +connect directly to the topo server(s). Usage: vtctldclient [flags] @@ -126,6 +130,9 @@ Flags: --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --server string server to use for the connection (required) --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) + --topo-global-root string the path of the global topology data in the global topology server (default "/vitess/global") + --topo-global-server-address strings the address of the global topology server(s) (default [localhost:2379]) + --topo-implementation string the topology implementation to use (default "etcd2") -v, --v Level log level for V logs --version version for vtctldclient --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 25b711e1019..21c4dc272f6 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -2018,7 +2018,7 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable tablets := make([]*topodatapb.Tablet, 0, len(tabletMap)) for _, ti := range tabletMap { - if req.TabletType != 0 && ti.Type != req.TabletType { + if req.TabletType != topodatapb.TabletType_UNKNOWN && ti.Type != req.TabletType { continue } adjustTypeForStalePrimary(ti, truePrimaryTimestamp) @@ -2086,7 +2086,7 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable if req.Keyspace != "" && tablet.Keyspace != req.Keyspace { continue } - if req.TabletType != 0 && tablet.Type != req.TabletType { + if req.TabletType != topodatapb.TabletType_UNKNOWN && tablet.Type != req.TabletType { continue } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go index 4da072e3955..fe92f284ce8 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go @@ -303,7 +303,6 @@ func (vc *vcopier) copyAll(ctx context.Context, settings binlogplayer.VRSettings // deleteCopyState deletes the copy state entry for a table, signifying that the copy phase is complete for that table. func (vc *vcopier) deleteCopyState(tableName string) error { log.Infof("Deleting copy state for table %s", tableName) - //FIXME get sidecar db name delQuery := fmt.Sprintf("delete from _vt.copy_state where table_name=%s and vrepl_id = %d", encodeString(tableName), vc.vr.id) if _, err := vc.vr.dbClient.Execute(delQuery); err != nil { return err From cf5f2742bee774acc3e0d7e512e8497b725c8d63 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Thu, 16 Nov 2023 16:37:21 +0100 Subject: [PATCH 026/119] Add support for new lock syntax in MySQL8 (#13965) Signed-off-by: Patrick Carnahan Signed-off-by: Arthur Schreiber Signed-off-by: Harshit Gangal Co-authored-by: Patrick Carnahan Co-authored-by: Harshit Gangal --- go/vt/sqlparser/ast_funcs.go | 10 + go/vt/sqlparser/constants.go | 16 +- go/vt/sqlparser/keywords.go | 3 + go/vt/sqlparser/parse_test.go | 10 + go/vt/sqlparser/sql.go | 11774 ++++++++-------- go/vt/sqlparser/sql.y | 20 + go/vt/sqlparser/testdata/union_cases.txt | 2 +- .../planbuilder/testdata/lock_cases.json | 90 + 8 files changed, 6064 insertions(+), 5861 deletions(-) diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 4885f33ccec..5ab4e0ba98c 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -1325,6 +1325,16 @@ func (lock Lock) ToString() string { return NoLockStr case ForUpdateLock: return ForUpdateStr + case ForUpdateLockNoWait: + return ForUpdateNoWaitStr + case ForUpdateLockSkipLocked: + return ForUpdateSkipLockedStr + case ForShareLock: + return ForShareStr + case ForShareLockNoWait: + return ForShareNoWaitStr + case ForShareLockSkipLocked: + return ForShareSkipLockedStr case ShareModeLock: return ShareModeStr default: diff --git a/go/vt/sqlparser/constants.go b/go/vt/sqlparser/constants.go index 30effe51586..56e8d4637b0 100644 --- a/go/vt/sqlparser/constants.go +++ b/go/vt/sqlparser/constants.go @@ -27,9 +27,14 @@ const ( SQLCalcFoundRowsStr = "sql_calc_found_rows " // Select.Lock - NoLockStr = "" - ForUpdateStr = " for update" - ShareModeStr = " lock in share mode" + NoLockStr = "" + ForUpdateStr = " for update" + ForUpdateNoWaitStr = " for update nowait" + ForUpdateSkipLockedStr = " for update skip locked" + ForShareStr = " for share" + ForShareNoWaitStr = " for share nowait" + ForShareSkipLockedStr = " for share skip locked" + ShareModeStr = " lock in share mode" // Select.Cache SQLCacheStr = "sql_cache " @@ -516,6 +521,11 @@ const ( NoLock Lock = iota ForUpdateLock ShareModeLock + ForShareLock + ForShareLockNoWait + ForShareLockSkipLocked + ForUpdateLockNoWait + ForUpdateLockSkipLocked ) // Constants for Enum Type - TrimType diff --git a/go/vt/sqlparser/keywords.go b/go/vt/sqlparser/keywords.go index 36c329d8e0a..6eaa41a0386 100644 --- a/go/vt/sqlparser/keywords.go +++ b/go/vt/sqlparser/keywords.go @@ -413,6 +413,7 @@ var keywords = []keyword{ {"localtimestamp", LOCALTIMESTAMP}, {"locate", LOCATE}, {"lock", LOCK}, + {"locked", LOCKED}, {"logs", LOGS}, {"long", UNUSED}, {"longblob", LONGBLOB}, @@ -457,6 +458,7 @@ var keywords = []keyword{ {"none", NONE}, {"not", NOT}, {"now", NOW}, + {"nowait", NOWAIT}, {"no_write_to_binlog", NO_WRITE_TO_BINLOG}, {"nth_value", NTH_VALUE}, {"ntile", NTILE}, @@ -575,6 +577,7 @@ var keywords = []keyword{ {"signal", UNUSED}, {"signed", SIGNED}, {"simple", SIMPLE}, + {"skip", SKIP}, {"slow", SLOW}, {"smallint", SMALLINT}, {"snapshot", SNAPSHOT}, diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index ce5a5e14a3a..a6c9d9ccf88 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -693,8 +693,18 @@ var ( input: "select /* distinct */ distinct 1 from t", }, { input: "select /* straight_join */ straight_join 1 from t", + }, { + input: "select /* for share */ 1 from t for share", + }, { + input: "select /* for share */ 1 from t for share nowait", + }, { + input: "select /* for share */ 1 from t for share skip locked", }, { input: "select /* for update */ 1 from t for update", + }, { + input: "select /* for update */ 1 from t for update nowait", + }, { + input: "select /* for update */ 1 from t for update skip locked", }, { input: "select /* lock in share mode */ 1 from t lock in share mode", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index d4949c76839..aef17b630f1 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1515,7 +1515,7 @@ var yyExca = [...]int{ 243, 813, -2, 811, -1, 122, - 240, 1588, + 240, 1593, -2, 133, -1, 124, 1, 160, @@ -1534,76 +1534,76 @@ var yyExca = [...]int{ 164, 41, -2, 45, -1, 939, - 87, 1605, + 87, 1610, -2, 1459, -1, 940, - 87, 1606, - 223, 1610, + 87, 1611, + 223, 1615, -2, 1460, -1, 941, - 223, 1609, + 223, 1614, -2, 42, -1, 1024, 60, 887, -2, 902, - -1, 1111, + -1, 1112, 251, 43, 256, 43, -2, 419, - -1, 1196, + -1, 1197, 1, 580, 732, 580, -2, 167, - -1, 1499, - 223, 1610, + -1, 1500, + 223, 1615, -2, 1460, - -1, 1708, + -1, 1709, 60, 888, -2, 907, - -1, 1709, + -1, 1710, 60, 889, -2, 908, - -1, 1760, + -1, 1765, 136, 167, 178, 167, 347, 167, -2, 458, - -1, 1841, + -1, 1846, 137, 408, 246, 408, -2, 512, - -1, 1850, + -1, 1855, 251, 44, 256, 44, -2, 420, - -1, 2288, - 223, 1614, - -2, 1608, - -1, 2289, - 223, 1610, - -2, 1606, - -1, 2389, + -1, 2293, + 223, 1619, + -2, 1613, + -1, 2294, + 223, 1615, + -2, 1611, + -1, 2396, 136, 167, 178, 167, 347, 167, -2, 459, - -1, 2396, + -1, 2403, 26, 188, -2, 190, - -1, 2850, + -1, 2857, 78, 98, 88, 98, -2, 966, - -1, 2919, + -1, 2926, 707, 698, -2, 672, - -1, 3127, - 50, 1556, - -2, 1550, - -1, 3942, + -1, 3134, + 50, 1561, + -2, 1555, + -1, 3949, 707, 698, -2, 686, - -1, 4029, + -1, 4036, 90, 630, 95, 630, 105, 630, @@ -1649,1131 +1649,1134 @@ var yyExca = [...]int{ 219, 630, 220, 630, 221, 630, - -2, 1977, + -2, 1982, } const yyPrivate = 57344 -const yyLast = 55495 +const yyLast = 55650 var yyAct = [...]int{ - 955, 3604, 3605, 87, 3603, 4027, 4104, 3923, 943, 3279, - 4117, 4008, 4071, 1264, 950, 3555, 942, 2082, 4072, 2386, - 1969, 3996, 3907, 3832, 2317, 3179, 3408, 3186, 3228, 2094, - 3237, 3242, 3239, 3238, 3236, 3241, 1763, 1262, 3140, 2025, - 3905, 3240, 5, 3542, 2746, 2319, 3257, 3080, 2460, 737, - 3194, 3256, 3144, 3141, 3453, 3447, 3642, 2983, 2341, 3128, - 2810, 731, 3439, 764, 904, 2357, 903, 2423, 908, 3973, - 3259, 42, 1819, 732, 2884, 3286, 2965, 2916, 2448, 1723, - 3473, 2428, 2886, 2885, 2360, 2374, 1022, 1073, 87, 2491, - 2361, 1041, 163, 1143, 1019, 2835, 1866, 2816, 2362, 41, - 3138, 2272, 2786, 1710, 2802, 2240, 43, 1022, 2284, 2239, - 2078, 2117, 2469, 2957, 2447, 2033, 149, 2349, 2430, 1848, - 1106, 1101, 1083, 2508, 2877, 1752, 2852, 1732, 2364, 1119, - 100, 2823, 1689, 1511, 104, 2121, 2337, 105, 2053, 1438, - 1423, 1965, 1855, 747, 3143, 1077, 1080, 2445, 1109, 1112, - 1947, 1081, 2419, 2420, 1021, 1107, 1025, 1108, 1751, 1058, - 1737, 1060, 2190, 735, 3637, 2129, 1031, 2148, 1040, 742, - 3895, 2784, 2342, 107, 1471, 1043, 1028, 2024, 1252, 85, - 1977, 1814, 167, 127, 125, 126, 99, 1026, 1192, 905, - 1495, 1017, 1840, 132, 1027, 133, 1053, 741, 1029, 734, - 98, 4105, 1260, 3543, 84, 1238, 106, 1515, 2462, 2463, - 2464, 3958, 1520, 93, 3225, 2285, 2462, 2939, 2938, 2506, - 2907, 3535, 1016, 1048, 1052, 4054, 2973, 2974, 3954, 2040, - 1034, 3953, 2314, 2315, 669, 128, 3608, 3959, 724, 2039, - 1074, 3498, 2038, 2037, 2036, 1145, 134, 1148, 2035, 2008, - 1208, 1685, 666, 2554, 667, 2782, 4048, 1434, 1162, 1163, - 1164, 1932, 1167, 1168, 1169, 1170, 1123, 3124, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1122, 1067, 1035, 1156, 1068, - 1020, 1018, 2812, 1717, 1209, 3608, 2, 4075, 1090, 1085, - 2495, 1098, 3084, 3932, 1149, 1152, 1153, 128, 1097, 1096, - 1095, 725, 3247, 2909, 1455, 4127, 4070, 4095, 3413, 3412, - 1042, 709, 4110, 3607, 2932, 709, 727, 3908, 4058, 1066, - 1070, 907, 3954, 4056, 95, 2747, 95, 909, 95, 3247, - 1165, 111, 112, 113, 2494, 116, 1015, 4109, 122, 190, - 2045, 191, 3244, 4057, 661, 703, 3305, 2056, 4055, 1066, - 1070, 907, 3828, 3827, 1147, 1146, 722, 723, 3245, 190, - 703, 4085, 3838, 129, 703, 128, 1010, 1011, 1012, 1013, - 4052, 95, 3607, 1024, 3567, 2929, 172, 959, 960, 961, - 1425, 3556, 3997, 129, 3251, 3245, 3548, 1099, 4005, 3549, - 2488, 3837, 2087, 4032, 703, 3325, 172, 2563, 1829, 3176, - 3177, 1055, 1056, 700, 959, 960, 961, 2783, 86, 3566, - 1094, 3251, 1201, 1202, 3175, 2493, 2381, 2382, 86, 2866, - 1089, 2972, 86, 1091, 1753, 2861, 1754, 4009, 2860, 4037, - 2560, 2862, 169, 2017, 2018, 170, 2380, 2956, 1228, 1257, - 1452, 1008, 1453, 1454, 1204, 1007, 2826, 4035, 1233, 1234, - 3924, 685, 169, 1229, 1216, 170, 4041, 4042, 189, 1217, - 1973, 1435, 2561, 1222, 683, 3196, 3197, 3655, 1092, 1216, - 2873, 2827, 4036, 3018, 1217, 2399, 2398, 703, 189, 3313, - 1191, 3311, 1215, 2439, 1214, 3283, 95, 3281, 2819, 2820, - 703, 703, 2552, 2316, 717, 703, 95, 2016, 3248, 2020, - 95, 721, 1749, 4013, 680, 715, 2433, 2942, 3287, 2958, - 1693, 2470, 3937, 695, 2917, 1953, 86, 1922, 3274, 88, - 2345, 4107, 1094, 2509, 1086, 3248, 3275, 3879, 690, 3880, - 4013, 1088, 1087, 2515, 2345, 1948, 2513, 1166, 693, 4076, - 1249, 1254, 1424, 1231, 1232, 1059, 1237, 1230, 1256, 1245, - 1197, 1247, 1235, 2960, 1255, 2511, 704, 1223, 3537, 3536, - 4077, 1923, 1236, 1924, 2533, 2555, 2556, 2558, 2557, 1172, - 1171, 704, 173, 1132, 3195, 704, 3812, 3284, 2512, 3282, - 1092, 179, 3533, 2530, 1696, 2531, 3198, 2532, 2516, 1244, - 1246, 2514, 173, 2473, 95, 1130, 1093, 1974, 1102, 3612, - 2358, 179, 1103, 1103, 1833, 704, 670, 4082, 672, 686, - 1141, 706, 1140, 705, 676, 1139, 674, 678, 687, 679, - 1138, 673, 1137, 684, 1136, 1135, 675, 688, 689, 692, - 696, 697, 698, 694, 691, 1142, 682, 707, 3019, 1069, - 1063, 1061, 4049, 2946, 2947, 1134, 1129, 3198, 4128, 1078, - 1114, 1472, 1486, 1486, 1115, 2432, 1151, 1078, 1078, 1966, - 2910, 1076, 1114, 2446, 1054, 2961, 1150, 3450, 3218, 1069, - 1063, 1061, 2499, 3302, 2498, 1473, 1474, 1475, 1476, 1477, - 1478, 1479, 1481, 1480, 1482, 1483, 1962, 1426, 704, 2941, - 1261, 1159, 1261, 1261, 1827, 1242, 1826, 3532, 1825, 1243, - 3083, 704, 704, 2927, 1963, 164, 704, 1823, 1093, 1248, - 1207, 660, 2343, 2344, 4050, 2522, 2518, 2520, 2521, 2519, - 2523, 2524, 1133, 1487, 1488, 164, 2343, 2344, 1750, 3920, - 1956, 3487, 1954, 1955, 1241, 1957, 1958, 3469, 2977, 2575, - 1022, 1496, 1501, 1502, 1131, 1505, 1507, 1508, 1509, 1510, - 2857, 1513, 1514, 1516, 1516, 2822, 1516, 1516, 1521, 1521, - 1521, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, - 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, - 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, - 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, - 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, - 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, - 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, - 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, - 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, - 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, - 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, - 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, - 1643, 1644, 1645, 1493, 3606, 1250, 3931, 1646, 2492, 1648, - 1649, 1650, 1651, 1652, 1417, 1418, 2908, 1489, 1490, 1491, - 1492, 1521, 1521, 1521, 1521, 1521, 1521, 1503, 1433, 1416, - 708, 3565, 3496, 3497, 1062, 1100, 1659, 1660, 1661, 1662, - 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, - 1497, 701, 1934, 1933, 1935, 1936, 1937, 956, 1439, 956, - 2875, 956, 165, 3606, 1062, 1506, 702, 1686, 4011, 177, - 1203, 1200, 2562, 4040, 1213, 1212, 2911, 1218, 1219, 1220, - 1221, 1517, 165, 1518, 1519, 3451, 3249, 3250, 2931, 177, - 3396, 1522, 1523, 1121, 2759, 4011, 89, 94, 1195, 3253, - 4010, 1258, 1259, 2436, 1158, 2561, 1854, 94, 1226, 2944, - 185, 94, 2964, 3249, 3250, 1716, 1121, 4039, 2787, 2789, - 1692, 2955, 2490, 2090, 2954, 1741, 3253, 4010, 1647, 1022, - 185, 1206, 2930, 1022, 1683, 3092, 1439, 3091, 1952, 1022, - 124, 2817, 668, 2437, 1121, 2387, 1486, 1483, 2586, 3174, - 2435, 1121, 1239, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 4121, 1684, 1449, 1466, 1978, 184, - 186, 187, 188, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 2438, 1037, 1717, 1253, 1121, 184, - 186, 187, 188, 3945, 2434, 3004, 1120, 1700, 1144, 119, - 3528, 1704, 1114, 1117, 1118, 94, 1078, 1021, 3303, 1211, - 1111, 1115, 3463, 2900, 2510, 1853, 1121, 2029, 1959, 1120, - 1755, 2122, 2122, 1702, 2595, 4086, 1703, 104, 2130, 1454, - 105, 1110, 1684, 1653, 1654, 1655, 1656, 1657, 1658, 3651, - 1453, 1454, 2131, 3503, 1449, 3502, 1690, 1120, 2047, 2049, - 2050, 2477, 1124, 1114, 1120, 1094, 1190, 1126, 1677, 1124, - 1114, 1127, 1125, 1863, 1126, 2586, 107, 2487, 1127, 1125, - 1862, 2967, 120, 2048, 1445, 2482, 2966, 1437, 2967, 1852, - 4078, 2485, 1128, 2966, 1132, 1130, 3488, 2788, 1949, 2482, - 1950, 1120, 1033, 1951, 2058, 4123, 1698, 1114, 1117, 1118, - 1240, 1078, 1830, 1831, 1832, 1111, 1115, 1846, 2059, 1484, - 1485, 2057, 1455, 1225, 2486, 3182, 1979, 4129, 2489, 1120, - 1194, 1157, 1701, 1719, 1227, 1154, 3820, 3975, 2484, 3913, - 1971, 1917, 1839, 1196, 3819, 3810, 1868, 1018, 1869, 1722, - 1871, 1873, 1699, 1020, 1877, 1879, 1881, 1883, 1885, 1858, - 3578, 1899, 1445, 1210, 3562, 1687, 3563, 1856, 1856, 1261, - 3183, 2157, 1746, 1747, 2567, 2568, 2569, 1472, 3577, 1907, - 1908, 1857, 3976, 2128, 3914, 1913, 1914, 1478, 1479, 1481, - 1480, 1482, 1483, 1822, 3185, 4119, 3510, 3509, 4120, 2634, - 4118, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, - 1482, 1483, 3180, 1849, 4130, 3499, 1942, 1836, 1837, 1455, - 1835, 1476, 1477, 1478, 1479, 1481, 1480, 1482, 1483, 3226, - 3196, 3197, 1860, 1940, 3214, 1193, 1455, 3181, 2882, 2881, - 1705, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, - 1483, 1093, 1903, 1455, 959, 960, 961, 2880, 1452, 1895, - 1453, 1454, 1898, 2442, 1900, 1967, 1717, 3006, 1943, 2149, - 1929, 3187, 3320, 2127, 2151, 2984, 1455, 1927, 2156, 2152, - 1941, 1455, 2153, 2154, 2155, 1472, 1926, 2150, 2158, 2159, - 2160, 2161, 2162, 2163, 2164, 2165, 2166, 1939, 2622, 128, - 1097, 1096, 1095, 4091, 1717, 1925, 1915, 1828, 1909, 1473, - 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, 1483, - 4089, 1717, 1906, 1905, 1904, 1984, 1459, 1460, 1461, 1462, - 1463, 1464, 1465, 1457, 1928, 1875, 1261, 1261, 1717, 3195, - 1980, 1981, 1697, 1455, 3493, 709, 4079, 2277, 2006, 1455, - 87, 3198, 3278, 87, 1985, 1452, 1455, 1453, 1454, 2986, - 2592, 1992, 1993, 1994, 709, 4019, 1717, 2630, 2864, 709, - 1749, 2005, 1452, 1420, 1453, 1454, 2458, 2457, 1444, 1441, - 1442, 1443, 1448, 1450, 1447, 1455, 1446, 2456, 2455, 1452, - 3940, 1453, 1454, 2454, 2453, 3939, 1440, 3917, 1455, 2114, - 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, - 1483, 3916, 1452, 3915, 1453, 1454, 3815, 1452, 42, 1453, - 1454, 42, 2085, 2085, 2083, 2083, 2086, 4017, 1717, 2996, - 2995, 2994, 2632, 2591, 2988, 1717, 2992, 1982, 2987, 1455, - 2985, 1717, 1451, 1717, 1986, 2990, 1988, 1989, 1990, 1991, - 2808, 4106, 2051, 1995, 2989, 3799, 1444, 1441, 1442, 1443, - 1448, 1450, 1447, 3798, 1446, 2007, 3650, 3184, 3648, 4015, - 1717, 1726, 2991, 2993, 1440, 101, 4066, 1717, 3933, 1452, - 3574, 1453, 1454, 1717, 3846, 1452, 102, 1453, 1454, 1451, - 1717, 3845, 1452, 2168, 1453, 1454, 1683, 2106, 2095, 2096, - 2097, 2098, 2108, 2099, 2100, 2101, 2113, 2109, 2102, 2103, - 2110, 2111, 2112, 2104, 2105, 2107, 1682, 1727, 2808, 4004, - 3803, 1452, 1681, 1453, 1454, 1455, 85, 1684, 1680, 85, - 2030, 2055, 1455, 3507, 1452, 3492, 1453, 1454, 2013, 2014, - 1472, 1717, 3802, 1468, 3288, 1469, 3285, 1455, 3217, 2350, - 2351, 2808, 3983, 3554, 2062, 3216, 2808, 3979, 2918, 1470, - 1484, 1485, 1467, 2060, 1473, 1474, 1475, 1476, 1477, 1478, - 1479, 1481, 1480, 1482, 1483, 1452, 2891, 1453, 1454, 3966, - 1717, 2288, 3546, 3930, 3823, 1717, 2808, 3811, 2287, 2061, - 2878, 2063, 2064, 2065, 2066, 2067, 2068, 2070, 2072, 2073, - 2074, 2075, 2076, 2077, 1455, 2286, 1497, 2089, 1472, 1455, - 2976, 2132, 2133, 2134, 2135, 1679, 3892, 1717, 3546, 1717, - 2896, 2275, 2543, 2123, 2273, 2146, 1472, 2542, 2574, 2504, - 2167, 3841, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, - 1480, 1482, 1483, 2503, 2116, 2118, 2808, 3544, 2482, 1717, - 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, - 1483, 1452, 2340, 1453, 1454, 101, 2322, 2366, 1452, 2009, - 1453, 1454, 103, 2182, 1455, 2288, 102, 2277, 2291, 2292, - 1975, 2274, 2355, 1452, 1938, 1453, 1454, 2804, 3890, 1717, - 2276, 3467, 1717, 3887, 1717, 104, 1930, 110, 105, 2286, - 2714, 1717, 103, 2396, 954, 3207, 3206, 3188, 109, 1920, - 108, 3192, 3204, 3205, 2395, 110, 104, 1916, 3191, 105, - 3202, 3203, 3169, 2180, 1912, 2054, 109, 103, 108, 3202, - 3201, 1717, 2561, 2191, 2333, 2368, 1455, 103, 1911, 1083, - 1452, 1910, 1453, 1454, 1728, 1452, 1251, 1453, 1454, 2832, - 1717, 2483, 3193, 2405, 2406, 2407, 2408, 3189, 3869, 1717, - 2588, 2400, 3190, 2401, 2402, 2403, 2404, 2561, 2940, 2391, - 1034, 1455, 1083, 2390, 3462, 2321, 1818, 2921, 1717, 2411, - 2412, 2413, 2414, 2372, 2290, 1455, 1717, 2293, 2294, 2853, - 2327, 2309, 2328, 2914, 2915, 95, 1717, 109, 2853, 2808, - 2807, 2425, 2394, 2264, 2265, 2266, 2267, 2268, 2335, 2482, - 1452, 1451, 1453, 1454, 2471, 2824, 2431, 2824, 1455, 2353, - 3438, 1717, 86, 44, 45, 88, 1455, 3464, 2377, 2378, - 2376, 1455, 2588, 1717, 2088, 1717, 2831, 2393, 1067, 2392, - 3971, 1068, 92, 2332, 1455, 3944, 48, 76, 77, 1455, - 74, 78, 2854, 2468, 2808, 3431, 1717, 2441, 2311, 75, - 1455, 2854, 2856, 2832, 2191, 1455, 1451, 1730, 3417, 3428, - 1717, 2561, 1452, 3204, 1453, 1454, 1818, 1817, 1761, 1760, - 2426, 2415, 2417, 2418, 2422, 3112, 2379, 2832, 62, 3462, - 2440, 2832, 2476, 2444, 1123, 2479, 2452, 2480, 1455, 2588, - 95, 3139, 3426, 1717, 1856, 2714, 2496, 1452, 2619, 1453, - 1454, 4080, 3462, 1122, 2618, 2426, 3928, 2478, 2475, 2474, - 2582, 1452, 1455, 1453, 1454, 3511, 2482, 2465, 3388, 1717, - 1455, 2348, 2497, 1729, 2500, 1721, 2312, 190, 2501, 2502, - 2088, 2031, 2015, 1961, 3386, 1717, 83, 1748, 2912, 3382, - 1717, 1105, 1718, 1720, 1452, 1104, 1453, 1454, 4045, 3986, - 1023, 129, 1452, 151, 1453, 1454, 2566, 1452, 1891, 1453, - 1454, 3834, 1455, 1724, 172, 3800, 3512, 3513, 3514, 1455, - 1452, 2507, 1453, 1454, 3662, 1452, 1455, 1453, 1454, 3527, - 1507, 3524, 1507, 3505, 3330, 3329, 1452, 1820, 1453, 1454, - 1455, 1452, 2424, 1453, 1454, 162, 3379, 1717, 2578, 1455, - 3276, 150, 3231, 1455, 3377, 1717, 3229, 1455, 3227, 1892, - 1893, 1894, 2922, 4101, 2288, 2536, 2421, 2416, 2410, 1455, - 169, 2287, 2409, 170, 1452, 1455, 1453, 1454, 95, 1945, - 51, 54, 57, 56, 59, 1851, 73, 1847, 2581, 82, - 79, 1816, 1842, 1843, 161, 160, 189, 3807, 1452, 121, - 1453, 1454, 2888, 3375, 1717, 1195, 1452, 3280, 1453, 1454, - 3373, 1717, 3835, 61, 91, 90, 2551, 2439, 71, 72, - 58, 3474, 3475, 4099, 3371, 1717, 80, 81, 1455, 2887, - 2325, 2559, 2011, 3369, 1717, 4073, 3952, 3367, 1717, 1455, - 3874, 3365, 1717, 3477, 3223, 1455, 3222, 3221, 1452, 1455, - 1453, 1454, 3139, 3363, 1717, 1452, 2570, 1453, 1454, 3361, - 1717, 2055, 1452, 2901, 1453, 1454, 1455, 2537, 63, 64, - 1455, 65, 66, 67, 68, 1455, 1452, 2888, 1453, 1454, - 3480, 3161, 3479, 2572, 3948, 1452, 3162, 1453, 1454, 1452, - 3158, 1453, 1454, 1452, 2012, 1453, 1454, 155, 1844, 158, - 3157, 1841, 2584, 156, 157, 1452, 3836, 1453, 1454, 3515, - 173, 1452, 2583, 1453, 1454, 665, 2594, 3159, 2571, 179, - 2573, 2339, 3160, 3359, 1717, 1887, 1725, 2331, 3468, 2576, - 3529, 2577, 60, 3357, 1717, 2545, 2546, 3117, 2579, 1455, - 2548, 3116, 3912, 3163, 1455, 2841, 2842, 2758, 3641, 2549, - 3355, 1717, 1455, 3643, 3353, 1717, 3516, 3517, 3518, 3351, - 1717, 3129, 3131, 3455, 1452, 3126, 1453, 1454, 1455, 2628, - 3132, 3454, 1888, 1889, 1890, 1452, 1455, 1453, 1454, 2790, - 1455, 1452, 3458, 1453, 1454, 1452, 1455, 1453, 1454, 726, - 3632, 1455, 3631, 2892, 1960, 1038, 1006, 1022, 2085, 3200, - 2083, 2793, 1452, 1039, 1453, 1454, 1452, 2871, 1453, 1454, - 1455, 1452, 3296, 1453, 1454, 1455, 1161, 1160, 2829, 2830, - 2130, 101, 89, 3349, 1717, 1455, 2791, 2366, 3335, 1717, - 1022, 2849, 102, 2887, 2131, 101, 3318, 1717, 2970, 2928, - 3630, 2601, 103, 164, 3460, 2794, 102, 2796, 1419, 129, - 2350, 2351, 2779, 1717, 103, 2054, 4115, 2828, 2616, 2809, - 2777, 1717, 3219, 2540, 2752, 1717, 4024, 3929, 3830, 3199, - 2729, 1717, 2845, 1455, 110, 1452, 2883, 1453, 1454, 2336, - 1452, 2529, 1453, 1454, 2528, 109, 42, 108, 1452, 2527, - 1453, 1454, 2526, 1455, 3482, 2846, 103, 2805, 2848, 2721, - 1717, 1690, 2818, 2525, 1452, 2781, 1453, 1454, 3440, 2712, - 1717, 2847, 1452, 1455, 1453, 1454, 1452, 1455, 1453, 1454, - 2874, 2876, 1452, 2801, 1453, 1454, 1684, 1452, 2565, 1453, - 1454, 94, 1455, 3115, 1046, 1047, 2821, 108, 109, 159, - 2806, 3114, 2867, 3900, 2926, 3899, 1452, 2851, 1453, 1454, - 3877, 1452, 3649, 1453, 1454, 1455, 110, 2710, 1717, 1455, - 2855, 1452, 3647, 1453, 1454, 2858, 3646, 109, 2431, 108, - 2865, 4102, 2868, 3639, 3525, 1455, 3459, 2697, 1717, 3457, - 2937, 1455, 2125, 3232, 2466, 1834, 2890, 2126, 1455, 110, - 1045, 2893, 2894, 1455, 3638, 2879, 3448, 2695, 1717, 1455, - 109, 2693, 1717, 2824, 1455, 4103, 4102, 4103, 2889, 1452, - 3918, 1453, 1454, 3616, 2804, 3491, 2691, 1717, 3020, 2620, - 1455, 2897, 2323, 2186, 2902, 2903, 2904, 1742, 2898, 1452, - 1734, 1453, 1454, 114, 115, 2934, 1036, 70, 2028, 2689, - 1717, 10, 1839, 2687, 1717, 2026, 3, 152, 9, 1452, - 153, 1453, 1454, 1452, 97, 1453, 1454, 2923, 2924, 2685, - 1717, 2027, 1455, 2913, 8, 3433, 2980, 2981, 1452, 2933, - 1453, 1454, 2683, 1717, 1, 1014, 1422, 2681, 1717, 1455, - 165, 1421, 3495, 2679, 1717, 1455, 4034, 177, 2677, 1717, - 681, 1452, 2313, 1453, 1454, 1452, 1688, 1453, 1454, 4074, - 4030, 2997, 2959, 2270, 2675, 1717, 4031, 1931, 2978, 1455, - 1921, 1452, 2962, 1453, 1454, 3557, 2238, 1452, 3831, 1453, - 1454, 3235, 1455, 2472, 1452, 3523, 1453, 1454, 185, 1452, - 2429, 1453, 1454, 2303, 1113, 1452, 154, 1453, 1454, 2388, - 1452, 2389, 1453, 1454, 3999, 1455, 2673, 1717, 2935, 118, - 1718, 2310, 1071, 1455, 117, 2998, 1452, 1116, 1453, 1454, - 3001, 1224, 2467, 2671, 1717, 3547, 2872, 2397, 1767, 2669, - 1717, 166, 171, 168, 174, 175, 176, 178, 180, 181, - 182, 183, 1765, 1766, 1764, 2334, 1455, 184, 186, 187, - 188, 1769, 1768, 2667, 1717, 3304, 2621, 3395, 1452, 2979, - 1453, 1454, 2019, 3022, 716, 2844, 2665, 1717, 3078, 710, - 2968, 1715, 1711, 2969, 192, 1452, 1756, 1453, 1454, 1735, - 3409, 1452, 1155, 1453, 1454, 671, 1712, 3208, 2505, 2663, - 1717, 677, 1504, 2010, 3113, 2859, 1065, 3429, 2982, 1057, - 2324, 2795, 1064, 3808, 3147, 1452, 2999, 1453, 1454, 3452, - 3125, 2329, 2330, 1714, 3085, 1713, 3127, 3096, 1452, 3087, - 1453, 1454, 2811, 3130, 3123, 2366, 3911, 1455, 3013, 3640, - 2658, 1717, 2275, 3984, 2275, 2273, 2869, 2273, 1731, 3416, - 3058, 1452, 2593, 1453, 1454, 2120, 1494, 2443, 3146, 1452, - 87, 1453, 1454, 2366, 2366, 2366, 2366, 2366, 1455, 3000, - 3068, 3069, 3070, 3071, 3072, 2365, 3611, 1455, 2046, 739, - 738, 736, 3086, 2366, 3088, 2797, 2366, 2825, 1458, 944, - 3096, 2785, 1452, 1743, 1453, 1454, 2836, 3095, 1455, 2834, - 3151, 1971, 2833, 2368, 2538, 3168, 1455, 2373, 3476, 3472, - 4026, 1455, 2367, 2363, 2803, 895, 894, 3111, 3107, 3120, - 748, 2654, 1717, 740, 1455, 730, 893, 892, 1025, 3262, - 3263, 2368, 2368, 2368, 2368, 2368, 3118, 1455, 2943, 3121, - 3277, 3133, 3134, 1455, 2945, 2870, 3273, 3108, 3109, 3110, - 3252, 2368, 3394, 3152, 2368, 1436, 3155, 3150, 1707, 1026, - 3260, 3390, 3153, 3154, 3119, 3156, 1027, 3170, 104, 3164, - 3171, 105, 3172, 1452, 1455, 1453, 1454, 1084, 3301, 3935, - 2564, 3324, 2652, 1717, 1706, 3942, 3243, 3541, 3224, 3178, - 2645, 1717, 2919, 2459, 1455, 2643, 1717, 69, 3210, 3060, - 3211, 3062, 46, 3209, 1452, 3906, 1453, 1454, 3327, 3972, - 887, 3212, 3213, 1452, 884, 1453, 1454, 3073, 3074, 3075, - 3076, 3326, 3136, 3261, 3264, 3613, 3265, 3323, 3614, 3615, - 2431, 1455, 3233, 3254, 1452, 3081, 1453, 1454, 3082, 3955, - 3956, 3271, 1452, 883, 1453, 1454, 3142, 1452, 3957, 1453, - 1454, 3142, 1455, 2175, 1432, 1429, 4047, 2021, 2775, 96, - 1452, 36, 1453, 1454, 35, 3289, 34, 33, 3292, 3291, - 32, 26, 25, 1452, 24, 1453, 1454, 23, 2774, 1452, - 3299, 1453, 1454, 22, 29, 19, 3309, 3306, 3307, 3255, - 3308, 21, 20, 3310, 18, 3312, 3246, 3314, 2837, 2840, - 2841, 2842, 2838, 4069, 2839, 2843, 4114, 123, 3474, 3475, - 1452, 55, 1453, 1454, 52, 2770, 1472, 50, 131, 130, - 1507, 53, 49, 1198, 1507, 2580, 47, 31, 30, 2585, - 1452, 17, 1453, 1454, 16, 15, 2769, 3234, 14, 13, - 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1481, 1480, 1482, - 1483, 12, 2589, 11, 2590, 3411, 7, 6, 39, 2597, - 38, 37, 3415, 2599, 2600, 28, 27, 1452, 40, 1453, - 1454, 3300, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, - 2614, 2615, 4, 2617, 2906, 2461, 0, 0, 1452, 0, - 1453, 1454, 0, 0, 0, 3145, 0, 0, 0, 0, - 2366, 0, 3441, 3442, 3444, 0, 2623, 2624, 2625, 2626, - 2627, 0, 2629, 3489, 3449, 0, 2631, 3456, 0, 0, - 2636, 2637, 728, 2638, 0, 1455, 2641, 0, 2642, 2644, - 2646, 2647, 2648, 2649, 2650, 2651, 2653, 2655, 2656, 2657, - 2659, 1455, 2661, 2662, 2664, 2666, 2668, 2670, 2672, 2674, - 2676, 2678, 2680, 2682, 2684, 2686, 2688, 2690, 2692, 2694, - 2696, 2698, 2699, 2700, 3483, 2702, 3478, 2704, 2368, 2706, - 2707, 3461, 2709, 2711, 2713, 3481, 3261, 3264, 2716, 3265, - 3446, 0, 2720, 3490, 3484, 0, 2725, 2726, 2727, 2728, - 3506, 0, 3508, 3294, 3295, 0, 0, 0, 0, 2739, - 2740, 2741, 2742, 2743, 2744, 3551, 3552, 2748, 2749, 2768, - 1455, 0, 0, 3471, 0, 2751, 3500, 3501, 2114, 3418, - 2757, 3420, 3421, 3422, 1455, 2767, 2760, 2761, 2762, 2763, - 2764, 1044, 3485, 3486, 1050, 1050, 0, 2771, 2772, 0, - 2773, 0, 0, 2776, 2778, 2334, 0, 2780, 0, 0, - 0, 1455, 0, 0, 0, 1455, 0, 2792, 0, 0, - 0, 1452, 0, 1453, 1454, 0, 1455, 0, 0, 3534, - 1455, 0, 0, 3538, 3539, 3540, 0, 1452, 0, 1453, - 1454, 1455, 3553, 2837, 2840, 2841, 2842, 2838, 0, 2839, - 2843, 0, 0, 0, 2766, 1455, 3569, 0, 3530, 3531, - 0, 0, 0, 0, 1455, 0, 0, 0, 2765, 0, - 0, 0, 1455, 0, 0, 0, 2106, 2095, 2096, 2097, - 2098, 2108, 2099, 2100, 2101, 2113, 2109, 2102, 2103, 2110, - 2111, 2112, 2104, 2105, 2107, 2756, 0, 1455, 0, 2755, - 0, 1455, 0, 0, 0, 0, 1452, 0, 1453, 1454, - 2754, 1455, 0, 0, 2753, 1455, 0, 0, 0, 0, - 1452, 1455, 1453, 1454, 0, 2750, 0, 0, 0, 1455, - 3629, 0, 3633, 3634, 1455, 0, 0, 0, 3619, 2745, - 3620, 3621, 3622, 1455, 3609, 0, 0, 1452, 2738, 1453, - 1454, 1452, 0, 1453, 1454, 3146, 2737, 87, 3635, 3146, - 0, 0, 1452, 0, 1453, 1454, 1452, 0, 1453, 1454, - 0, 1455, 0, 0, 0, 0, 0, 1452, 0, 1453, - 1454, 2736, 0, 3573, 0, 2735, 0, 2085, 0, 2083, - 3664, 1452, 3636, 1453, 1454, 2734, 3656, 3645, 3644, 2733, - 1452, 0, 1453, 1454, 0, 2732, 3652, 3654, 1452, 1455, - 1453, 1454, 0, 2731, 0, 0, 0, 0, 2730, 0, - 1455, 0, 0, 0, 3814, 42, 0, 2724, 0, 0, - 0, 3668, 0, 1452, 0, 1453, 1454, 1452, 0, 1453, - 1454, 0, 0, 0, 0, 0, 0, 1452, 0, 1453, - 1454, 1452, 0, 1453, 1454, 2723, 0, 1452, 0, 1453, - 1454, 0, 0, 0, 3806, 1452, 3805, 1453, 1454, 0, - 1452, 0, 1453, 1454, 0, 0, 3821, 0, 0, 1452, - 0, 1453, 1454, 3826, 3833, 3825, 0, 1715, 1711, 3804, - 0, 0, 0, 2722, 0, 3871, 3872, 3008, 3009, 3010, - 3011, 3012, 1712, 3658, 2719, 3665, 3666, 1452, 0, 1453, - 1454, 0, 0, 2085, 0, 2083, 3875, 3017, 0, 3816, - 3817, 3818, 0, 0, 0, 0, 0, 1708, 1709, 1714, - 0, 1713, 3600, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3142, 0, 0, 1452, 3146, 1453, 1454, 0, - 0, 3878, 0, 3660, 3809, 3881, 1452, 0, 1453, 1454, - 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, - 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1544, - 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, - 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, - 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, - 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, - 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, - 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, - 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1619, 1621, 1622, 1623, 1624, 1625, - 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1636, 1642, 1643, 1644, 1645, 1659, 1660, 1661, 1662, 1663, - 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 3922, - 3919, 3904, 3145, 3876, 3901, 3902, 3145, 3903, 1455, 0, - 0, 0, 1455, 3936, 0, 0, 0, 1455, 0, 0, - 0, 0, 0, 0, 1455, 0, 0, 0, 0, 3921, - 0, 87, 0, 0, 0, 3148, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1455, - 0, 0, 0, 3166, 0, 0, 0, 3925, 0, 0, - 0, 0, 3938, 0, 0, 0, 0, 3941, 0, 0, - 3943, 3813, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1455, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3910, 2718, 0, 0, 0, 2717, 0, 0, 42, - 0, 2715, 0, 0, 0, 0, 0, 0, 2708, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1456, 3961, 0, 3981, 3962, 0, 0, 0, - 87, 0, 0, 2705, 0, 0, 0, 3927, 0, 0, - 0, 0, 0, 0, 1452, 3970, 1453, 1454, 1452, 0, - 1453, 1454, 1512, 1452, 0, 1453, 1454, 3977, 0, 0, - 1452, 3987, 1453, 1454, 0, 2703, 4012, 0, 3998, 3985, - 0, 3946, 0, 3990, 3995, 3992, 3991, 3989, 3994, 0, - 0, 3298, 3833, 4001, 3993, 1452, 0, 1453, 1454, 0, - 0, 0, 0, 3145, 4022, 0, 0, 0, 42, 0, - 0, 0, 0, 3315, 3316, 4025, 3317, 4043, 3319, 3321, - 4033, 0, 4038, 0, 4051, 0, 0, 1452, 4012, 1453, - 1454, 4053, 3328, 0, 0, 4064, 0, 3332, 3333, 3334, - 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, - 3346, 3347, 3348, 3350, 3352, 3354, 3356, 3358, 3360, 3362, - 3364, 3366, 3368, 3370, 3372, 3374, 3376, 3378, 3380, 3381, - 3383, 3384, 3385, 3387, 1971, 4068, 3389, 4084, 3391, 3392, - 3393, 4083, 4094, 3397, 3398, 3399, 3400, 3401, 3402, 3403, - 3404, 3405, 3406, 3407, 2085, 4100, 2083, 4097, 4096, 4087, - 4098, 4093, 3414, 4063, 3982, 4012, 3419, 1455, 4108, 0, - 3423, 3424, 0, 3425, 3427, 4116, 3430, 3432, 3142, 3434, - 3435, 3436, 3437, 4124, 4122, 0, 1455, 3443, 0, 0, - 1455, 3950, 0, 0, 0, 0, 0, 0, 0, 3960, - 1455, 0, 0, 4133, 4134, 3872, 4132, 0, 0, 1455, - 0, 0, 2085, 1455, 2083, 4131, 0, 1455, 0, 0, - 3934, 0, 3465, 3466, 0, 1455, 3470, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2701, 4081, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2660, 0, 0, 0, 2640, 1691, 0, 0, 0, 0, - 0, 0, 0, 4059, 2639, 0, 0, 0, 0, 0, - 0, 0, 0, 2635, 0, 0, 0, 2633, 0, 0, - 0, 2598, 0, 1452, 0, 1453, 1454, 0, 1733, 2587, - 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, - 2277, 0, 1452, 958, 1453, 1454, 1452, 0, 1453, 1454, - 0, 0, 3545, 2084, 663, 0, 1452, 0, 1453, 1454, - 0, 0, 0, 0, 0, 1452, 1821, 1453, 1454, 1452, - 0, 1453, 1454, 1452, 1009, 1453, 1454, 0, 0, 0, - 0, 1452, 0, 1453, 1454, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3564, 0, 0, - 3568, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1079, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3579, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 940, 0, 0, 0, 0, 0, 0, 0, - 0, 3602, 0, 0, 1976, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3610, 0, 0, 0, 0, 0, - 0, 0, 3617, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 955, 3611, 3612, 87, 3610, 4034, 4111, 3930, 4015, 3286, + 4124, 943, 4078, 1265, 950, 3562, 942, 2087, 4079, 2393, + 1974, 4003, 3914, 3839, 2322, 3186, 3415, 3193, 3235, 2099, + 3244, 3249, 3246, 3245, 3243, 3248, 1768, 1263, 3147, 3912, + 2030, 3247, 2753, 5, 3549, 2324, 3264, 3087, 2467, 737, + 3201, 3263, 3151, 3148, 3649, 3460, 3454, 2990, 2348, 3135, + 904, 764, 908, 2430, 903, 42, 3266, 2364, 1724, 3980, + 1824, 2817, 732, 2891, 3293, 2367, 2972, 2923, 2455, 2435, + 2892, 2498, 3446, 3480, 1074, 2893, 1022, 163, 87, 2381, + 1042, 2842, 1144, 1871, 2823, 1019, 2368, 41, 1711, 2369, + 2809, 2793, 2245, 2122, 2277, 2289, 2083, 1022, 43, 2244, + 3145, 2964, 2476, 2038, 2454, 2356, 1853, 2515, 149, 2437, + 1102, 2884, 1084, 1107, 1757, 2859, 1737, 2371, 1512, 1690, + 2126, 100, 2058, 104, 1439, 731, 2342, 1424, 105, 1970, + 1081, 1078, 1860, 747, 1113, 3150, 2452, 1952, 1021, 1082, + 1025, 1120, 2426, 2427, 1108, 2830, 1110, 1109, 1756, 1059, + 1742, 1061, 2195, 2153, 99, 1031, 3644, 2134, 1041, 1044, + 1496, 3902, 2791, 2349, 107, 742, 1472, 2029, 1253, 1028, + 2290, 1982, 85, 167, 127, 1026, 125, 1819, 132, 905, + 1017, 126, 1845, 133, 1193, 1054, 1027, 93, 741, 734, + 1029, 98, 1261, 4112, 3550, 1239, 106, 1516, 3232, 84, + 2469, 1521, 724, 3965, 2914, 1049, 1053, 2469, 2470, 2471, + 2946, 2945, 2513, 3542, 1016, 1937, 1440, 4061, 2980, 2981, + 3961, 1034, 2319, 2320, 2045, 669, 128, 3505, 2044, 3966, + 2043, 2042, 1149, 1075, 1146, 3960, 134, 2041, 2040, 2013, + 1686, 1209, 666, 2561, 667, 2789, 4055, 1163, 1164, 1165, + 3131, 1168, 1169, 1170, 1171, 1035, 3615, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, + 1187, 1188, 1189, 1190, 2, 725, 4082, 735, 1124, 2819, + 1069, 1018, 1068, 1123, 1210, 1020, 3615, 3091, 4102, 1435, + 2502, 3939, 1099, 2916, 1043, 4134, 4077, 95, 128, 1098, + 1157, 1097, 1150, 1153, 1154, 1728, 1096, 1091, 3420, 3254, + 1726, 3254, 3419, 1718, 4117, 727, 4065, 709, 703, 111, + 112, 113, 3251, 116, 1450, 909, 122, 1086, 95, 191, + 95, 1166, 661, 709, 2501, 1729, 3961, 1456, 1015, 4116, + 1727, 4064, 2345, 3614, 722, 723, 4063, 2061, 2344, 2939, + 3915, 95, 2754, 2050, 1010, 1011, 1012, 1013, 3312, 3835, + 1100, 1024, 703, 3834, 1148, 3252, 128, 3252, 1147, 2936, + 4092, 4062, 3845, 3614, 4059, 959, 960, 961, 3555, 1426, + 3574, 3556, 959, 960, 961, 1067, 1071, 907, 3563, 1056, + 1057, 3258, 4004, 3258, 4012, 2495, 1067, 1071, 907, 86, + 3844, 2092, 4039, 86, 3332, 700, 1834, 3183, 3184, 3573, + 1095, 2790, 1202, 1203, 86, 2868, 3182, 2979, 2867, 2388, + 2389, 2869, 2567, 2833, 1440, 4016, 2022, 2023, 2387, 2570, + 703, 2963, 1446, 1090, 2500, 1438, 1092, 1758, 1229, 1759, + 1008, 703, 1217, 4044, 1205, 1007, 3931, 1218, 2834, 1217, + 1234, 1235, 3662, 685, 1218, 1216, 2880, 1215, 3320, 2917, + 1978, 4042, 1230, 1223, 703, 2446, 683, 703, 1093, 3290, + 4048, 4049, 703, 1453, 3318, 1454, 1455, 95, 3025, 3203, + 3204, 95, 2406, 2405, 2559, 3944, 4043, 2021, 2440, 1258, + 2826, 2827, 95, 2321, 2568, 3288, 717, 2025, 721, 1192, + 2965, 4020, 715, 1436, 3294, 3255, 680, 3255, 4020, 1754, + 2352, 1694, 2949, 2924, 1167, 695, 1927, 86, 2516, 2477, + 88, 2529, 2525, 2527, 2528, 2526, 2530, 2531, 4083, 704, + 690, 3886, 1450, 3887, 2537, 1095, 2538, 1087, 2539, 3281, + 693, 1425, 4114, 1953, 1089, 1088, 2162, 3282, 2520, 4084, + 1473, 1246, 2522, 1248, 1236, 1250, 1231, 1224, 1232, 1233, + 1928, 3291, 1929, 1255, 1237, 2562, 2563, 2565, 2564, 2953, + 2954, 1238, 3309, 704, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1482, 1481, 1483, 1484, 3544, 1198, 3289, 3202, 2967, + 2519, 1245, 1247, 1093, 3543, 95, 1094, 1979, 1257, 2540, + 3205, 1173, 1172, 2521, 1256, 2518, 3819, 2523, 670, 3540, + 672, 686, 1697, 706, 2480, 705, 676, 3619, 674, 678, + 687, 679, 1060, 673, 2365, 684, 1104, 1142, 675, 688, + 689, 692, 696, 697, 698, 694, 691, 2439, 682, 707, + 1446, 704, 4056, 3026, 2154, 1141, 1103, 1140, 1838, 2156, + 1104, 1139, 704, 2161, 2157, 1138, 3457, 2158, 2159, 2160, + 1137, 1136, 2155, 2163, 2164, 2165, 2166, 2167, 2168, 2169, + 2170, 2171, 1135, 1130, 1143, 704, 1079, 3205, 704, 4135, + 1079, 1116, 4089, 704, 1077, 1079, 1115, 1971, 1152, 2453, + 1262, 2968, 1262, 1262, 1115, 3090, 1055, 1243, 1151, 2506, + 2505, 1244, 2350, 2351, 1967, 1070, 1064, 1062, 1427, 1160, + 3225, 1249, 2948, 1832, 1831, 1830, 1070, 1064, 1062, 4057, + 2934, 1094, 1968, 1828, 3539, 1208, 1445, 1442, 1443, 1444, + 1449, 1451, 1448, 660, 1447, 1755, 1242, 1488, 1489, 3927, + 1022, 1497, 1502, 1503, 1441, 1506, 1508, 1509, 1510, 1511, + 3494, 1514, 1515, 1517, 1517, 2918, 1517, 1517, 1522, 1522, + 1522, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, + 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, + 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, + 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, + 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, + 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, + 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, + 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, + 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, + 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, + 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, + 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, + 1644, 1645, 1646, 1494, 3938, 1251, 2915, 1647, 1101, 1649, + 1650, 1651, 1652, 1653, 1418, 1419, 1939, 1938, 1940, 1941, + 1942, 1522, 1522, 1522, 1522, 1522, 1522, 2499, 3503, 3504, + 956, 3572, 708, 703, 3613, 2951, 1660, 1661, 1662, 1663, + 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, + 1498, 1417, 1196, 701, 1445, 1442, 1443, 1444, 1449, 1451, + 1448, 956, 1447, 956, 3613, 1507, 4018, 1687, 702, 3189, + 1434, 1214, 1441, 4018, 3458, 1213, 2352, 1219, 1220, 1221, + 1222, 1518, 2938, 1519, 1520, 2443, 1487, 4047, 94, 1204, + 1523, 1524, 94, 3256, 3257, 3256, 3257, 89, 4017, 1133, + 1063, 1259, 1260, 94, 2569, 4017, 3260, 3310, 3260, 1201, + 1487, 1063, 1131, 1122, 3190, 1717, 1859, 1227, 3099, 2568, + 1693, 2991, 2971, 3403, 2962, 2444, 2937, 2961, 1684, 1022, + 3476, 4046, 2442, 1022, 2497, 1958, 2864, 2829, 3192, 1022, + 1122, 1490, 1491, 1492, 1493, 2794, 2796, 2766, 2095, 1746, + 1648, 1504, 1207, 1122, 2394, 3098, 3187, 1957, 124, 2824, + 668, 1487, 1484, 1685, 3181, 4128, 2445, 1718, 2593, 1240, + 1467, 1038, 2984, 1254, 3203, 3204, 2441, 1159, 2135, 1983, + 3952, 3188, 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, + 1145, 1701, 2136, 3535, 3470, 1705, 2582, 2063, 2517, 119, + 2034, 1021, 1964, 2127, 1760, 2993, 94, 1122, 3011, 1095, + 1191, 2064, 1485, 1486, 2062, 3194, 1121, 1212, 2907, 2127, + 4093, 2602, 1703, 3658, 2494, 1858, 104, 1704, 1456, 1455, + 1685, 105, 1654, 1655, 1656, 1657, 1658, 1659, 1454, 1455, + 3510, 3509, 2484, 1121, 704, 1691, 2593, 3327, 1134, 1115, + 1118, 1119, 1868, 1079, 1867, 1857, 1121, 1112, 1116, 1678, + 2489, 1132, 1115, 1118, 1119, 1122, 1079, 107, 2350, 2351, + 1112, 1116, 120, 2492, 1195, 3003, 3002, 3001, 1111, 1133, + 2995, 4085, 2999, 3202, 2994, 2974, 2992, 1131, 2974, 1122, + 2973, 2997, 3495, 2973, 1033, 3205, 1699, 4136, 4130, 2493, + 2996, 1720, 1835, 1836, 1837, 1851, 3569, 1954, 3570, 1955, + 1121, 3827, 1956, 1718, 2795, 1125, 1115, 1241, 2998, 3000, + 1127, 1702, 1226, 2133, 1128, 1126, 1700, 1984, 3826, 1688, + 2496, 1976, 1922, 1228, 1873, 1844, 1874, 1018, 1876, 1878, + 3982, 1723, 1882, 1884, 1886, 1888, 1890, 1863, 1020, 1904, + 1961, 1197, 1959, 1960, 2489, 1962, 1963, 1456, 1718, 2282, + 1262, 1211, 1751, 1752, 1453, 2132, 1454, 1455, 1121, 1912, + 1913, 1947, 1862, 1125, 1115, 1918, 1919, 1456, 1127, 1194, + 1861, 1861, 1128, 1126, 4137, 3983, 4126, 1945, 1934, 4127, + 1827, 4125, 1121, 2491, 1158, 1094, 3817, 3285, 1155, 1456, + 1473, 3920, 2983, 1129, 1842, 2574, 2575, 2576, 1841, 1840, + 1854, 3191, 1479, 1480, 1482, 1481, 1483, 1484, 1706, 3585, + 2052, 2054, 2055, 1865, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1482, 1481, 1483, 1484, 1946, 3584, 190, 1473, 3517, + 3516, 1469, 1718, 1470, 1908, 2053, 3921, 959, 960, 961, + 1900, 1944, 1933, 1903, 1972, 1905, 3506, 1471, 1485, 1486, + 1468, 129, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, + 1481, 1483, 1484, 1456, 172, 3233, 1473, 3221, 2889, 2888, + 2887, 2449, 2882, 4098, 1718, 1948, 1833, 1932, 1931, 1930, + 1920, 128, 1098, 1453, 1097, 1454, 1455, 1914, 2641, 1096, + 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, 1483, + 1484, 1911, 190, 1453, 1910, 1454, 1455, 1989, 1460, 1461, + 1462, 1463, 1464, 1465, 1466, 1458, 1909, 1262, 1262, 1456, + 169, 1985, 1986, 170, 1880, 1453, 129, 1454, 1455, 2011, + 1473, 87, 1698, 1421, 87, 1990, 3500, 709, 709, 172, + 1754, 2629, 1997, 1998, 1999, 1473, 189, 2581, 2871, 709, + 4086, 1456, 2010, 3947, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1482, 1481, 1483, 1484, 1456, 2465, 2464, 3946, 1474, + 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, + 2463, 2462, 2873, 1475, 1476, 1477, 1478, 1479, 1480, 1482, + 1481, 1483, 1484, 42, 3924, 169, 42, 3923, 170, 1453, + 1456, 1454, 1455, 2090, 2090, 2088, 2088, 2091, 3013, 1456, + 2282, 2461, 2460, 1456, 2279, 1731, 3922, 1456, 1987, 2815, + 4113, 189, 2589, 2281, 3822, 1991, 3806, 1993, 1994, 1995, + 1996, 3805, 2056, 101, 2000, 4096, 1718, 954, 4073, 1718, + 103, 3195, 3657, 101, 102, 3199, 2012, 1452, 1718, 4026, + 1718, 1473, 3198, 110, 102, 1453, 3655, 1454, 1455, 3581, + 173, 1732, 2815, 4011, 109, 1683, 108, 2815, 3990, 179, + 1682, 1684, 1681, 1456, 2173, 1474, 1475, 1476, 1477, 1478, + 1479, 1480, 1482, 1481, 1483, 1484, 3200, 1453, 3514, 1454, + 1455, 3196, 3499, 4024, 1718, 1718, 3197, 4022, 1718, 1718, + 3940, 1453, 4087, 1454, 1455, 2639, 1685, 2815, 3986, 1718, + 85, 2035, 2060, 85, 3295, 1452, 1718, 3973, 1718, 2018, + 2019, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, + 1483, 1484, 2119, 1456, 1718, 173, 1453, 3292, 1454, 1455, + 3553, 3937, 3853, 1456, 179, 1453, 2065, 1454, 1455, 1453, + 3224, 1454, 1455, 1453, 3223, 1454, 1455, 3899, 1718, 3830, + 1718, 3852, 2293, 2815, 3818, 3553, 1718, 3810, 2094, 2292, + 2066, 2898, 2068, 2069, 2070, 2071, 2072, 2073, 2075, 2077, + 2078, 2079, 2080, 2081, 2082, 2885, 2291, 1498, 1680, 1456, + 2121, 2123, 2550, 164, 2137, 2138, 2139, 2140, 2815, 3551, + 3809, 2278, 110, 2549, 2128, 2489, 1718, 2172, 2151, 1453, + 2511, 1454, 1455, 109, 2510, 108, 2347, 3897, 1718, 3474, + 1718, 3561, 1456, 2327, 103, 2721, 1718, 3894, 1718, 2925, + 2111, 2100, 2101, 2102, 2103, 2113, 2104, 2105, 2106, 2118, + 2114, 2107, 2108, 2115, 2116, 2117, 2109, 2110, 2112, 3214, + 3213, 2903, 2373, 2014, 2187, 1980, 2296, 2297, 1456, 2067, + 2293, 3211, 3212, 3209, 3210, 3209, 3208, 2362, 164, 1453, + 103, 1454, 1455, 3876, 1718, 104, 2280, 2839, 1718, 1453, + 105, 1454, 1455, 1718, 2291, 2568, 2947, 1456, 2403, 1823, + 2928, 2921, 2922, 2815, 2814, 1456, 104, 2811, 2637, 2595, + 1718, 105, 1943, 2185, 2059, 2860, 3445, 1718, 109, 1456, + 2338, 1935, 103, 2196, 2375, 2093, 1718, 2490, 1456, 1925, + 2599, 2838, 1921, 1917, 1084, 1453, 1456, 1454, 1455, 1718, + 2295, 1916, 1915, 2298, 2299, 2860, 1823, 1822, 2412, 2413, + 2414, 2415, 3438, 1718, 2407, 1733, 2408, 2409, 2410, 2411, + 2314, 2398, 1034, 2397, 1766, 1765, 2326, 1084, 1453, 1252, + 1454, 1455, 2418, 2419, 2420, 2421, 2379, 2831, 2861, 2831, + 2595, 2332, 1718, 2333, 2402, 2489, 2839, 1452, 2863, 3435, + 1718, 3146, 2432, 2269, 2270, 2271, 2272, 2273, 2340, 2337, + 2401, 3469, 3469, 2598, 1453, 1452, 1454, 1455, 2861, 2478, + 3471, 2438, 3433, 1718, 2360, 1456, 4074, 3176, 2568, 1456, + 3395, 1718, 3978, 2384, 2385, 2383, 1789, 2568, 3951, 1456, + 2815, 2400, 2839, 1453, 2399, 1454, 1455, 1069, 3424, 1068, + 165, 1453, 3211, 1454, 1455, 2475, 3119, 177, 2316, 2839, + 2448, 3469, 2386, 2595, 2196, 1453, 2721, 1454, 1455, 2626, + 1456, 2625, 2489, 2472, 1453, 2355, 1454, 1455, 1722, 2317, + 2093, 2433, 1453, 2036, 1454, 1455, 2422, 2424, 2425, 2429, + 2020, 1023, 1966, 2447, 2483, 2451, 1753, 2486, 185, 2487, + 2459, 1456, 1106, 1105, 95, 1456, 4052, 3993, 2503, 3393, + 1718, 1456, 3236, 3389, 1718, 3841, 2433, 2482, 1456, 2481, + 1725, 1124, 2485, 3386, 1718, 165, 1123, 3807, 3669, 3534, + 3531, 1861, 177, 3512, 3337, 2507, 3336, 2504, 1825, 2508, + 2509, 166, 171, 168, 174, 175, 176, 178, 180, 181, + 182, 183, 1719, 1721, 3384, 1718, 2431, 184, 186, 187, + 188, 1453, 3283, 1454, 1455, 1453, 3238, 1454, 1455, 95, + 3234, 2573, 2929, 185, 2428, 1453, 2423, 1454, 1455, 2417, + 1456, 2416, 1777, 1950, 2514, 3382, 1718, 1856, 3287, 3380, + 1718, 1852, 1821, 121, 2119, 1508, 3935, 1508, 2894, 2895, + 1196, 3842, 3378, 1718, 3481, 3482, 1453, 3518, 1454, 1455, + 1896, 2446, 2330, 2585, 4108, 4106, 166, 171, 168, 174, + 175, 176, 178, 180, 181, 182, 183, 3522, 2543, 2293, + 4080, 3959, 184, 186, 187, 188, 2292, 1453, 3881, 1454, + 1455, 1453, 1456, 1454, 1455, 3484, 2895, 1453, 1456, 1454, + 1455, 3230, 2016, 2588, 1453, 3487, 1454, 1455, 3519, 3520, + 3521, 1897, 1898, 1899, 3376, 1718, 1790, 3229, 3228, 3146, + 2908, 2544, 2357, 2358, 3523, 3524, 3525, 1456, 2558, 3486, + 2844, 2847, 2848, 2849, 2845, 1456, 2846, 2850, 3165, 1456, + 3164, 2566, 2111, 2100, 2101, 2102, 2103, 2113, 2104, 2105, + 2106, 2118, 2114, 2107, 2108, 2115, 2116, 2117, 2109, 2110, + 2112, 3955, 3168, 1456, 2017, 2577, 1453, 3169, 1454, 1455, + 3166, 3170, 1456, 2848, 2849, 3167, 2060, 3814, 1803, 1806, + 1807, 1808, 1809, 1810, 1811, 1456, 1812, 1813, 1815, 1816, + 1814, 1817, 1818, 1791, 1792, 1793, 1794, 1775, 1776, 1804, + 3843, 1778, 665, 1779, 1780, 1781, 1782, 1783, 1784, 1785, + 1786, 1787, 3536, 1456, 1788, 1795, 1796, 1797, 1798, 3848, + 1799, 1800, 1801, 1802, 2890, 1456, 2601, 2346, 1453, 1730, + 1454, 1455, 2336, 2578, 1453, 2580, 1454, 1455, 3475, 3919, + 1892, 1456, 1036, 1735, 2583, 1456, 2584, 3374, 1718, 1456, + 2552, 2553, 3124, 2586, 1456, 2555, 3372, 1718, 3136, 3138, + 3123, 3648, 2765, 1453, 2556, 1454, 1455, 3139, 3650, 3370, + 1718, 1453, 1456, 1454, 1455, 1453, 726, 1454, 1455, 2635, + 3465, 3639, 1456, 3638, 3462, 1039, 1456, 1893, 1894, 1895, + 3133, 1037, 3461, 1040, 2797, 3207, 1965, 3368, 1718, 1453, + 1006, 1454, 1455, 2878, 2135, 2899, 1162, 1161, 1453, 1734, + 1454, 1455, 1022, 2090, 3303, 2088, 2800, 2894, 2136, 2977, + 1456, 1453, 2579, 1454, 1455, 3366, 1718, 1420, 1456, 3364, + 1718, 3637, 2935, 3362, 1718, 2836, 2837, 129, 3360, 1718, + 3467, 2798, 101, 101, 2373, 2357, 2358, 1022, 2856, 1453, + 103, 1454, 1455, 102, 102, 2608, 3358, 1718, 103, 4122, + 3226, 1453, 2547, 1454, 1455, 1456, 3356, 1718, 2059, 4031, + 3342, 1718, 2623, 3936, 3837, 2835, 2816, 1453, 110, 1454, + 1455, 1453, 3206, 1454, 1455, 1453, 1456, 1454, 1455, 109, + 1453, 108, 1454, 1455, 1456, 2852, 3447, 42, 2341, 1456, + 103, 1047, 1048, 2536, 3325, 1718, 2853, 2812, 1453, 2855, + 1454, 1455, 2786, 1718, 2572, 1691, 2825, 2788, 1453, 2854, + 1454, 1455, 1453, 3122, 1454, 1455, 1456, 2535, 2534, 1805, + 1456, 3121, 3907, 2533, 2801, 2532, 2803, 2881, 2883, 2808, + 110, 1685, 108, 1456, 3906, 3884, 3455, 3656, 3654, 2784, + 1718, 109, 2828, 108, 2874, 2813, 1453, 3653, 1454, 1455, + 1456, 2933, 2858, 3646, 1453, 1456, 1454, 1455, 3532, 1456, + 2759, 1718, 3466, 1456, 3464, 3239, 2862, 2473, 2736, 1718, + 1839, 2865, 1046, 2728, 1718, 2438, 2872, 109, 110, 3645, + 1456, 2831, 2875, 2130, 4110, 4109, 4109, 2944, 2131, 109, + 3623, 1453, 2897, 1454, 1455, 2811, 3027, 2900, 2901, 2886, + 2719, 1718, 2627, 2328, 2717, 1718, 1747, 1739, 114, 115, + 4110, 3925, 1453, 3498, 1454, 1455, 2896, 2704, 1718, 3, + 1453, 97, 1454, 1455, 2191, 1453, 2904, 1454, 1455, 2905, + 1, 2909, 2910, 2911, 2702, 1718, 1456, 1014, 1423, 2700, + 1718, 1456, 2941, 2698, 1718, 1456, 2033, 2696, 1718, 10, + 1422, 1844, 1453, 1456, 1454, 1455, 1453, 1456, 1454, 1455, + 3502, 2930, 2931, 1456, 2694, 1718, 4041, 681, 2318, 1453, + 2920, 1454, 1455, 2987, 2988, 2031, 2940, 1689, 9, 2032, + 1456, 4081, 8, 4037, 4038, 1456, 1453, 1936, 1454, 1455, + 1926, 1453, 3564, 1454, 1455, 1453, 2243, 1454, 1455, 1453, + 3838, 1454, 1455, 1456, 2275, 3242, 2479, 2966, 3004, 3530, + 2436, 1114, 154, 1456, 2985, 2395, 1453, 2969, 1454, 1455, + 2692, 1718, 2396, 4006, 1456, 2690, 1718, 118, 1072, 2688, + 1718, 117, 1117, 1225, 2308, 2474, 3554, 2686, 1718, 2879, + 2404, 2684, 1718, 1456, 1772, 1770, 1771, 2682, 1718, 1456, + 1769, 1719, 2315, 1774, 1773, 2942, 3311, 2628, 3005, 3008, + 1456, 3402, 2024, 716, 2680, 1718, 2851, 710, 192, 2678, + 1718, 1761, 1453, 1740, 1454, 1455, 3416, 1453, 1156, 1454, + 1455, 1453, 671, 1454, 1455, 3215, 2339, 2676, 1718, 1453, + 2512, 1454, 1455, 1453, 677, 1454, 1455, 2674, 1718, 1453, + 1505, 1454, 1455, 2015, 3120, 1456, 3029, 2866, 2672, 1718, + 1456, 1066, 1058, 2329, 2802, 3085, 1453, 2975, 1454, 1455, + 2976, 1453, 1065, 1454, 1455, 3815, 3154, 2670, 1718, 3459, + 3132, 3134, 2818, 2665, 1718, 3137, 3130, 3918, 3647, 1453, + 3991, 1454, 1455, 2876, 3489, 2989, 1736, 3423, 2600, 1453, + 2125, 1454, 1455, 3006, 1495, 2372, 3618, 2051, 739, 3092, + 1453, 738, 1454, 1455, 3103, 736, 3094, 2804, 2832, 1459, + 944, 2792, 2373, 1748, 3020, 2843, 1456, 2841, 2278, 1453, + 2278, 1454, 1455, 2840, 3065, 1453, 2545, 1454, 1455, 2661, + 1718, 2380, 2450, 3483, 3440, 3153, 1453, 87, 1454, 1455, + 2373, 2373, 2373, 2373, 2373, 3007, 1456, 3075, 3076, 3077, + 3078, 3079, 3479, 4033, 2374, 2370, 2810, 895, 894, 748, + 2373, 740, 3093, 2373, 3095, 730, 1456, 3103, 893, 892, + 2986, 3102, 3269, 1456, 2375, 3270, 2950, 3158, 1976, 3284, + 2952, 1453, 3175, 1454, 1455, 2877, 1453, 3127, 1454, 1455, + 3280, 3118, 1437, 2280, 3114, 2280, 1456, 1708, 1085, 1025, + 2659, 1718, 2375, 2375, 2375, 2375, 2375, 3308, 3942, 3125, + 2571, 3128, 3331, 1707, 3949, 3140, 3141, 3250, 3548, 1456, + 2591, 3231, 2375, 2926, 2466, 2375, 69, 3259, 46, 3913, + 2590, 3157, 3979, 887, 1026, 3177, 3159, 3267, 3178, 3162, + 3160, 3161, 3171, 3163, 104, 1027, 3115, 3116, 3117, 105, + 2652, 1718, 1453, 3179, 1454, 1455, 1456, 2650, 1718, 884, + 3620, 3185, 3621, 3622, 3088, 3126, 3089, 1456, 3962, 3963, + 883, 3964, 3216, 2180, 3218, 3067, 1433, 3069, 3217, 1430, + 3436, 4054, 1453, 1456, 1454, 1455, 2026, 3219, 3220, 96, + 36, 35, 34, 3080, 3081, 3082, 3083, 3271, 3268, 3143, + 33, 3272, 1453, 3401, 1454, 1455, 3240, 2438, 3261, 1453, + 32, 1454, 1455, 26, 25, 24, 23, 22, 3278, 29, + 19, 21, 20, 3149, 1456, 18, 3253, 4076, 3149, 1456, + 4121, 123, 1453, 1456, 1454, 1455, 55, 52, 50, 131, + 3397, 3296, 130, 53, 3299, 49, 3298, 1199, 47, 31, + 30, 3334, 17, 16, 15, 1453, 3306, 1454, 1455, 3316, + 14, 13, 3313, 3314, 12, 3315, 3262, 3333, 3317, 11, + 3319, 7, 3321, 2844, 2847, 2848, 2849, 2845, 6, 2846, + 2850, 39, 38, 3481, 3482, 37, 28, 27, 40, 4, + 2913, 2468, 1453, 0, 1454, 1455, 0, 1508, 0, 0, + 2587, 1508, 0, 1453, 2592, 1454, 1455, 0, 3330, 0, + 0, 0, 0, 2782, 3241, 0, 0, 2781, 0, 1453, + 0, 1454, 1455, 0, 0, 0, 0, 2596, 0, 2597, + 3418, 0, 0, 0, 2604, 0, 0, 3422, 2606, 2607, + 0, 0, 0, 0, 0, 0, 0, 2613, 2614, 2615, + 2616, 2617, 2618, 2619, 2620, 2621, 2622, 0, 2624, 0, + 1453, 0, 1454, 1455, 0, 1453, 0, 1454, 1455, 1453, + 3152, 1454, 1455, 0, 0, 0, 0, 2373, 0, 0, + 0, 2630, 2631, 2632, 2633, 2634, 0, 2636, 0, 1456, + 3496, 2638, 0, 0, 3463, 2643, 2644, 728, 2645, 3448, + 3449, 2648, 3456, 2649, 2651, 2653, 2654, 2655, 2656, 2657, + 2658, 2660, 2662, 2663, 2664, 2666, 0, 2668, 2669, 2671, + 2673, 2675, 2677, 2679, 2681, 2683, 2685, 2687, 2689, 2691, + 2693, 2695, 2697, 2699, 2701, 2703, 2705, 2706, 2707, 2375, + 2709, 3488, 2711, 3490, 2713, 2714, 3485, 2716, 2718, 2720, + 3271, 3268, 3491, 2723, 3272, 3451, 3497, 2727, 3468, 1456, + 0, 2732, 2733, 2734, 2735, 0, 0, 3513, 0, 3515, + 3301, 3302, 3307, 2777, 2746, 2747, 2748, 2749, 2750, 2751, + 0, 3453, 2755, 2756, 0, 3558, 3559, 0, 0, 0, + 2758, 0, 3507, 3508, 0, 2764, 3425, 0, 3427, 3428, + 3429, 2767, 2768, 2769, 2770, 2771, 1045, 1456, 0, 1051, + 1051, 957, 2778, 2779, 3478, 2780, 958, 0, 2783, 2785, + 2339, 0, 2787, 1716, 1712, 1453, 2089, 1454, 1455, 0, + 0, 0, 2799, 3492, 3493, 0, 0, 0, 1713, 0, + 0, 1716, 1712, 2776, 0, 3541, 0, 0, 3560, 3545, + 3546, 3547, 0, 0, 0, 0, 1713, 0, 0, 0, + 1456, 0, 0, 2334, 2335, 1715, 0, 1714, 0, 0, + 0, 0, 0, 3576, 0, 3537, 3538, 0, 0, 0, + 1456, 1709, 1710, 1715, 0, 1714, 0, 0, 0, 1456, + 0, 2775, 0, 1456, 0, 1453, 0, 1454, 1455, 1456, + 0, 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, 1453, 2774, 1454, 1455, 3636, 0, 3640, + 3641, 0, 0, 0, 0, 3626, 0, 3627, 3628, 3629, + 1456, 3616, 0, 0, 2773, 0, 0, 1456, 0, 0, + 0, 1456, 3153, 2772, 87, 3642, 3153, 2763, 0, 0, + 0, 0, 0, 2762, 1456, 0, 0, 0, 1456, 0, + 0, 0, 0, 0, 0, 0, 1453, 0, 1454, 1455, + 3580, 0, 1456, 0, 2090, 0, 2088, 3671, 0, 0, + 3643, 0, 0, 3651, 3663, 3652, 1453, 0, 1454, 1455, + 0, 0, 0, 3659, 3661, 1453, 0, 1454, 1455, 1453, + 0, 1454, 1455, 0, 0, 1453, 42, 1454, 1455, 0, + 0, 3821, 0, 0, 2761, 0, 0, 0, 3675, 0, + 0, 2760, 0, 0, 0, 2757, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2752, 0, + 0, 0, 2745, 0, 0, 0, 0, 0, 0, 0, + 0, 3813, 0, 3812, 0, 0, 2744, 0, 0, 0, + 0, 0, 0, 3828, 0, 3811, 1453, 0, 1454, 1455, + 3833, 3840, 3832, 1453, 0, 1454, 1455, 1453, 0, 1454, + 1455, 0, 3878, 3879, 3015, 3016, 3017, 3018, 3019, 0, + 1453, 3665, 1454, 1455, 1453, 0, 1454, 1455, 0, 0, + 2090, 0, 2088, 3882, 3024, 3823, 3824, 3825, 1453, 0, + 1454, 1455, 0, 0, 0, 0, 3672, 3673, 3607, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3149, + 0, 0, 0, 3153, 0, 0, 0, 0, 3885, 3667, + 0, 3816, 3888, 0, 0, 0, 0, 1525, 1526, 1527, + 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, + 1538, 1539, 1540, 1541, 1542, 1543, 1545, 1546, 1547, 1548, + 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, + 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, + 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, + 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, + 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, + 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, + 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, + 1619, 1620, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, + 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1643, 1644, + 1645, 1646, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, + 1668, 1669, 1670, 1671, 1672, 1673, 3929, 3152, 3926, 3883, + 3911, 3152, 3908, 3909, 1456, 3910, 0, 0, 0, 0, + 3943, 0, 1456, 0, 0, 0, 0, 1456, 0, 0, + 0, 1456, 0, 0, 0, 1456, 3928, 0, 87, 0, + 0, 0, 3155, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1456, 0, 0, 0, + 3173, 0, 0, 3932, 1456, 0, 0, 0, 0, 3945, + 1456, 0, 0, 0, 0, 3948, 3820, 0, 3950, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1456, 0, + 0, 0, 0, 0, 0, 0, 0, 3917, 2743, 0, + 42, 0, 0, 0, 0, 0, 2742, 0, 0, 0, + 0, 2741, 0, 0, 0, 2740, 0, 0, 0, 2739, + 0, 0, 0, 0, 0, 0, 0, 1457, 3968, 0, + 0, 3969, 3988, 0, 0, 0, 0, 87, 0, 0, + 2738, 0, 0, 0, 3934, 0, 0, 0, 2737, 0, + 1453, 3977, 1454, 1455, 2731, 0, 0, 1513, 1453, 0, + 1454, 1455, 0, 1453, 3984, 1454, 1455, 1453, 3994, 1454, + 1455, 1453, 2730, 1454, 1455, 4005, 4019, 3992, 3953, 0, + 3997, 4002, 3999, 3998, 3996, 4001, 0, 0, 3305, 3840, + 4008, 4000, 1453, 0, 1454, 1455, 0, 0, 3152, 42, + 1453, 4029, 1454, 1455, 0, 0, 1453, 0, 1454, 1455, + 3322, 3323, 4032, 3324, 4050, 3326, 3328, 4040, 0, 4045, + 0, 4058, 0, 0, 1453, 4060, 1454, 1455, 4019, 3335, + 0, 0, 4071, 0, 3339, 3340, 3341, 3343, 3344, 3345, + 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, + 3357, 3359, 3361, 3363, 3365, 3367, 3369, 3371, 3373, 3375, + 3377, 3379, 3381, 3383, 3385, 3387, 3388, 3390, 3391, 3392, + 3394, 1976, 4075, 3396, 4091, 3398, 3399, 3400, 4090, 4101, + 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, + 3414, 2090, 4107, 2088, 4104, 4103, 4094, 4105, 4100, 3421, + 4070, 3989, 4115, 3426, 1456, 4019, 0, 3430, 3431, 1456, + 3432, 3434, 4123, 3437, 3439, 3149, 3441, 3442, 3443, 3444, + 4131, 4129, 0, 1456, 3450, 0, 0, 3957, 1456, 0, + 0, 0, 0, 0, 0, 3967, 0, 1456, 0, 0, + 4140, 4141, 3879, 4139, 0, 0, 0, 1456, 0, 2090, + 0, 2088, 4138, 1456, 0, 3941, 0, 1456, 0, 3472, + 3473, 0, 1456, 3477, 0, 0, 1456, 0, 0, 0, + 1456, 0, 0, 0, 1789, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1456, 2729, 4088, + 0, 0, 0, 2726, 1456, 0, 0, 0, 0, 0, + 1456, 0, 0, 0, 0, 0, 0, 2725, 0, 0, + 0, 0, 2724, 0, 0, 0, 0, 0, 0, 0, + 4066, 2722, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2715, 0, 0, 0, 0, 0, 2712, 0, 0, + 1453, 2710, 1454, 1455, 1738, 1453, 2708, 1454, 1455, 0, + 2667, 1456, 0, 0, 2647, 957, 1456, 2282, 0, 1453, + 958, 1454, 1455, 0, 1453, 0, 1454, 1455, 0, 3552, + 2089, 2646, 0, 1453, 0, 1454, 1455, 0, 2642, 0, + 0, 0, 1826, 1453, 2640, 1454, 1455, 0, 0, 1453, + 0, 1454, 1455, 1453, 0, 1454, 1455, 0, 1453, 0, + 1454, 1455, 1453, 0, 1454, 1455, 1453, 0, 1454, 1455, + 0, 0, 0, 0, 3571, 0, 0, 3575, 0, 0, + 1777, 0, 0, 1453, 0, 1454, 1455, 0, 0, 0, + 1453, 0, 1454, 1455, 0, 2605, 1453, 0, 1454, 1455, + 2594, 0, 0, 940, 3586, 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, 1453, 0, 1454, + 1455, 0, 1453, 0, 1454, 1455, 0, 0, 0, 195, + 0, 0, 195, 0, 1790, 0, 714, 0, 3609, 0, + 1981, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3617, 195, 0, 0, 0, 0, 0, 0, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, - 0, 195, 0, 0, 0, 714, 0, 0, 0, 0, - 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 195, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3822, 0, 0, - 0, 0, 0, 0, 0, 0, 3829, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3839, 3840, 0, 3842, - 0, 3843, 3844, 0, 0, 0, 3847, 3848, 3849, 3850, - 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, - 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 0, 3870, - 3873, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3882, 3883, 3884, 3885, 3886, - 3888, 3889, 3891, 3893, 3894, 3896, 0, 0, 0, 0, - 0, 0, 0, 0, 2041, 2042, 2043, 2044, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2052, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3926, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2091, 2092, 0, 0, 0, 0, - 2115, 1050, 1050, 2119, 0, 0, 0, 2124, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, - 2144, 2145, 0, 2147, 0, 0, 0, 2169, 2170, 2171, - 2172, 2173, 2174, 2176, 0, 2181, 0, 2183, 2184, 2185, - 0, 2187, 2188, 2189, 0, 2192, 2193, 2194, 2195, 2196, - 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, - 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, - 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, - 2237, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, - 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, - 2260, 2261, 2262, 2263, 0, 0, 0, 0, 0, 2269, - 0, 2271, 0, 2278, 2279, 2280, 2281, 2282, 2283, 1050, - 0, 1050, 1050, 1050, 1050, 1050, 0, 0, 0, 0, - 0, 0, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, - 0, 2304, 2305, 2306, 2307, 2308, 1199, 0, 1205, 0, - 0, 0, 0, 0, 0, 0, 0, 3951, 0, 0, - 0, 0, 0, 0, 0, 0, 4067, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1784, 0, 0, 0, - 1050, 3967, 0, 0, 0, 0, 0, 3968, 3969, 190, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2346, 2347, 0, 0, 0, 0, 1428, 3980, - 0, 0, 0, 129, 0, 151, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 172, 0, 2385, 0, - 0, 0, 0, 0, 0, 4006, 4007, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4014, - 4016, 4018, 0, 0, 0, 0, 0, 162, 0, 0, - 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4046, 0, 0, 0, 0, 0, - 0, 0, 169, 0, 0, 170, 0, 0, 0, 2427, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 138, 139, 161, 160, 189, 0, - 0, 0, 4065, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1772, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4088, 4090, 4092, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 0, 720, 720, 0, 0, 0, 4113, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 720, 195, 0, 4125, 4126, 0, - 0, 0, 0, 0, 0, 0, 1785, 0, 0, 155, - 136, 158, 143, 135, 0, 156, 157, 0, 0, 0, - 0, 0, 173, 1499, 0, 0, 0, 0, 0, 0, - 0, 179, 144, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 147, 145, 140, 141, - 142, 146, 0, 0, 0, 0, 0, 0, 137, 0, - 0, 0, 0, 0, 0, 0, 0, 148, 1798, 1801, - 1802, 1803, 1804, 1805, 1806, 0, 1807, 1808, 1810, 1811, - 1809, 1812, 1813, 1786, 1787, 1788, 1789, 1770, 1771, 1799, - 0, 1773, 0, 1774, 1775, 1776, 1777, 1778, 1779, 1780, - 1781, 1782, 0, 0, 1783, 1790, 1791, 1792, 1793, 0, - 1794, 1795, 1796, 1797, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1745, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 164, 0, 0, 1762, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2596, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2602, 2603, 2604, 2605, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1499, 0, 0, 0, 0, 0, 0, - 0, 0, 1784, 0, 0, 0, 0, 0, 0, 0, - 0, 1901, 0, 0, 0, 0, 0, 0, 1512, 0, - 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1946, 0, 0, 0, - 195, 0, 0, 0, 720, 720, 0, 0, 0, 0, - 0, 0, 0, 1972, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 0, 1983, - 0, 0, 0, 0, 0, 0, 1987, 0, 0, 1800, - 0, 0, 0, 720, 0, 0, 195, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 0, 0, 0, 0, 720, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, - 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1772, 0, - 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 165, 0, 0, 1499, 0, 0, 0, 177, - 0, 720, 720, 0, 720, 0, 720, 720, 0, 720, - 720, 720, 720, 720, 720, 0, 0, 0, 0, 0, - 0, 1733, 1499, 0, 0, 1499, 720, 1499, 195, 0, + 0, 0, 0, 720, 195, 720, 1803, 1806, 1807, 1808, + 1809, 1810, 1811, 0, 1812, 1813, 1815, 1816, 1814, 1817, + 1818, 1791, 1792, 1793, 1794, 1775, 1776, 1804, 0, 1778, + 0, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, + 0, 0, 1788, 1795, 1796, 1797, 1798, 0, 1799, 1800, + 1801, 1802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 1785, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 195, - 195, 0, 0, 166, 171, 168, 174, 175, 176, 178, - 180, 181, 182, 183, 0, 0, 195, 0, 0, 184, - 186, 187, 188, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 720, 0, 2034, 1798, 1801, 1802, 1803, 1804, 1805, - 1806, 0, 1807, 1808, 1810, 1811, 1809, 1812, 1813, 1786, - 1787, 1788, 1789, 1770, 1771, 1799, 0, 1773, 0, 1774, - 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 0, 0, - 1783, 1790, 1791, 1792, 1793, 0, 1794, 1795, 1796, 1797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3829, 0, 0, 0, 0, 0, + 0, 0, 0, 3836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3846, 3847, 0, 3849, 0, 3850, 3851, + 0, 0, 0, 3854, 3855, 3856, 3857, 3858, 3859, 3860, + 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, + 3871, 3872, 3873, 3874, 3875, 0, 3877, 3880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3889, 3890, 3891, 3892, 3893, 3895, 3896, 3898, + 3900, 3901, 3903, 0, 0, 0, 0, 0, 0, 0, + 2046, 2047, 2048, 2049, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2096, 2097, 0, 0, 0, 0, 2120, 1051, 1051, 2124, + 0, 0, 0, 2129, 0, 0, 0, 1805, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2141, 2142, + 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 0, 2152, + 0, 0, 0, 2174, 2175, 2176, 2177, 2178, 2179, 2181, + 0, 2186, 0, 2188, 2189, 2190, 0, 2192, 2193, 2194, + 0, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, + 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, + 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, + 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, + 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2246, 2247, 2248, + 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, + 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, + 0, 0, 0, 0, 0, 2274, 0, 2276, 0, 2283, + 2284, 2285, 2286, 2287, 2288, 1051, 0, 1051, 1051, 1051, + 1051, 1051, 0, 0, 0, 0, 0, 0, 2300, 2301, + 2302, 2303, 2304, 2305, 2306, 2307, 0, 2309, 2310, 2311, + 2312, 2313, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2975, + 0, 0, 0, 0, 0, 0, 1051, 0, 3974, 0, + 0, 0, 0, 0, 3975, 3976, 0, 0, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2353, 2354, 0, 0, 3987, 0, 0, 0, + 0, 0, 129, 0, 151, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 0, 0, 2392, 0, + 0, 0, 4013, 4014, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4021, 4023, 4025, 0, + 0, 0, 0, 0, 0, 0, 162, 0, 1692, 0, + 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, + 0, 4053, 0, 0, 195, 0, 195, 0, 0, 0, + 0, 169, 0, 0, 170, 0, 0, 0, 0, 2434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1050, 0, 0, 3002, 3003, 0, 0, 3005, 0, - 0, 3007, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 720, 720, - 0, 3014, 3015, 3016, 0, 0, 0, 0, 0, 0, - 0, 720, 0, 3021, 0, 0, 3023, 3024, 3025, 0, - 195, 0, 3026, 3027, 0, 0, 3028, 0, 3029, 0, - 0, 0, 0, 0, 0, 3030, 0, 3031, 0, 0, - 0, 3032, 0, 3033, 0, 0, 3034, 0, 3035, 0, - 3036, 0, 3037, 0, 3038, 0, 3039, 0, 3040, 0, - 3041, 0, 3042, 0, 3043, 0, 3044, 0, 3045, 720, - 3046, 0, 3047, 0, 3048, 0, 3049, 0, 3050, 1499, - 3051, 0, 0, 0, 3052, 1800, 3053, 0, 3054, 0, - 0, 3055, 0, 3056, 0, 3057, 1499, 2241, 3059, 0, - 0, 3061, 0, 0, 3063, 3064, 3065, 3066, 0, 0, - 0, 0, 3067, 2241, 2241, 2241, 2241, 2241, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3077, 0, - 2352, 0, 0, 0, 0, 0, 3090, 0, 2356, 3094, - 2359, 1050, 0, 2034, 0, 0, 0, 0, 3097, 3098, - 3099, 3100, 3101, 3102, 0, 0, 0, 3103, 3104, 0, - 3105, 0, 3106, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 139, 161, 160, 189, 0, 4072, + 0, 0, 0, 720, 0, 720, 720, 663, 0, 0, + 0, 0, 0, 190, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2919, 720, 195, 1009, 0, 0, + 0, 0, 0, 4095, 4097, 4099, 0, 129, 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172, 0, 0, 0, 1500, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4120, 0, 0, 1080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 162, 0, 0, 4132, 4133, 0, 150, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 155, 136, + 158, 143, 135, 0, 156, 157, 169, 0, 0, 170, + 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, + 179, 144, 0, 0, 0, 0, 0, 0, 1847, 1848, + 161, 160, 189, 0, 0, 147, 145, 140, 141, 142, + 146, 0, 0, 0, 0, 0, 0, 137, 0, 0, + 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2289, 0, 3167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 190, 0, 0, 0, 720, - 0, 0, 0, 0, 0, 0, 1838, 0, 0, 0, - 0, 0, 0, 3230, 0, 0, 0, 0, 0, 129, - 0, 151, 0, 0, 195, 0, 0, 720, 0, 0, - 0, 0, 172, 0, 0, 0, 0, 195, 0, 0, - 0, 720, 0, 0, 2289, 195, 0, 195, 0, 195, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2034, 0, 162, 720, 0, 0, 0, 2517, 150, - 0, 0, 0, 0, 0, 0, 0, 2534, 2535, 0, - 0, 2539, 0, 0, 0, 0, 0, 0, 169, 0, - 0, 170, 0, 2544, 0, 0, 0, 0, 0, 0, - 2547, 0, 0, 0, 0, 0, 0, 0, 0, 3322, - 1842, 1843, 161, 160, 189, 0, 0, 0, 0, 0, - 0, 720, 0, 3331, 0, 0, 2550, 0, 0, 0, - 0, 939, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, - 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 155, 1849, 158, 0, 1846, 0, 156, + 157, 0, 0, 0, 164, 0, 173, 0, 0, 0, + 0, 0, 0, 0, 1500, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 699, 0, 0, 0, 0, 0, 719, - 0, 720, 0, 0, 0, 0, 720, 0, 0, 0, - 720, 720, 0, 0, 0, 155, 1844, 158, 0, 1841, - 0, 156, 157, 0, 0, 0, 0, 0, 173, 0, - 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, - 0, 719, 0, 719, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 195, 0, 0, 195, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 0, 0, 2603, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2609, 2610, 2611, 2612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 720, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, - 3526, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 1513, 0, + 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 195, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 164, 0, 3550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1499, 0, 2289, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, + 0, 0, 0, 720, 720, 0, 720, 0, 720, 720, + 0, 720, 720, 720, 720, 720, 720, 0, 152, 0, + 0, 153, 0, 0, 1500, 0, 0, 1500, 720, 1500, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, + 195, 165, 0, 0, 0, 0, 0, 0, 177, 0, + 0, 0, 0, 720, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 195, 195, 1738, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 185, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 171, 168, 174, 175, 176, 178, 180, + 181, 182, 183, 152, 0, 0, 153, 0, 184, 186, + 187, 188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1200, + 0, 1206, 0, 0, 0, 0, 165, 0, 0, 0, + 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3570, 0, 3571, 0, 0, 3572, 0, 0, 3575, - 3576, 0, 0, 0, 0, 0, 0, 0, 3580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3581, 0, 3582, 0, 3583, 159, 3584, 0, - 3585, 0, 3586, 0, 3587, 0, 3588, 0, 3589, 0, - 3590, 0, 3591, 0, 3592, 0, 3593, 0, 3594, 0, - 3595, 0, 3596, 0, 0, 3597, 0, 2850, 0, 3598, - 0, 3599, 0, 0, 0, 0, 0, 3601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, + 0, 1429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3618, 0, 0, 0, 0, 0, 0, 0, 0, 3623, - 0, 3624, 3625, 0, 3626, 0, 3627, 0, 0, 0, - 0, 3628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2899, 0, 0, 0, 152, 3653, 0, 153, 0, - 0, 0, 0, 0, 0, 0, 0, 3661, 0, 0, - 3663, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3667, 0, 0, 0, 0, 0, 165, 0, - 0, 0, 0, 0, 0, 177, 0, 0, 3801, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 2948, 2949, 2950, - 2951, 2952, 2953, 0, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 185, 0, 0, 0, - 0, 0, 2034, 2963, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 0, 195, 0, 0, 2971, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, - 171, 168, 174, 175, 176, 178, 180, 181, 182, 183, - 0, 0, 0, 0, 0, 184, 186, 187, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 166, 171, 168, + 174, 175, 176, 178, 180, 181, 182, 183, 0, 0, + 720, 720, 0, 184, 186, 187, 188, 0, 0, 0, + 0, 2982, 0, 720, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1051, 0, 0, 3009, 3010, 0, 0, + 3012, 0, 0, 3014, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3021, 3022, 3023, 0, 0, 0, 0, + 0, 720, 0, 0, 0, 3028, 0, 0, 3030, 3031, + 3032, 1500, 0, 0, 3033, 3034, 0, 0, 3035, 0, + 3036, 0, 0, 0, 0, 0, 0, 3037, 1500, 3038, + 0, 0, 0, 3039, 0, 3040, 0, 0, 3041, 0, + 3042, 0, 3043, 0, 3044, 0, 3045, 0, 3046, 0, + 3047, 0, 3048, 0, 3049, 0, 3050, 0, 3051, 0, + 3052, 0, 3053, 0, 3054, 0, 3055, 0, 3056, 0, + 3057, 0, 3058, 0, 0, 0, 3059, 0, 3060, 0, + 3061, 0, 0, 3062, 0, 3063, 0, 3064, 0, 2246, + 3066, 0, 0, 3068, 0, 0, 3070, 3071, 3072, 3073, + 0, 0, 0, 0, 3074, 2246, 2246, 2246, 2246, 2246, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 0, + 3084, 0, 0, 0, 0, 0, 0, 0, 3097, 0, + 0, 3101, 0, 1051, 0, 0, 0, 0, 0, 0, + 3104, 3105, 3106, 3107, 3108, 3109, 0, 0, 0, 3110, + 3111, 0, 3112, 0, 3113, 0, 0, 0, 0, 0, + 0, 0, 2294, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 699, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3144, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, + 0, 720, 0, 1750, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3174, 0, 0, 0, 0, 0, + 0, 0, 1767, 0, 0, 0, 195, 0, 719, 720, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 720, 0, 0, + 2294, 195, 0, 195, 0, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3909, 720, 0, 0, 0, 0, 0, 195, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 957, 0, - 0, 1499, 0, 958, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2084, 195, 195, 195, 195, 195, 195, + 0, 0, 0, 0, 0, 1906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 1415, 719, 719, 0, 0, 0, 0, 195, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1498, 0, 0, 0, 0, 720, 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, - 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, - 897, 0, 0, 0, 3949, 0, 0, 0, 0, 0, + 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 1977, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3329, 0, 1988, 0, 0, 0, 0, 0, 0, + 1992, 0, 0, 0, 0, 3338, 0, 0, 0, 0, + 0, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 0, 0, + 86, 44, 45, 88, 0, 0, 0, 720, 0, 0, + 0, 0, 720, 0, 0, 0, 720, 720, 0, 0, + 92, 0, 0, 0, 48, 76, 77, 0, 74, 78, + 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 62, 0, 0, 0, + 195, 195, 0, 0, 195, 0, 195, 0, 95, 0, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, + 0, 0, 0, 0, 83, 0, 0, 0, 720, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 190, 0, 0, 0, 0, 0, 0, 2039, 0, 0, + 0, 1843, 3533, 0, 0, 0, 0, 1500, 0, 2294, + 0, 0, 0, 0, 129, 0, 151, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 172, 51, 54, + 57, 56, 59, 0, 73, 3557, 0, 82, 79, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, + 0, 61, 91, 90, 150, 0, 71, 72, 58, 0, + 0, 0, 0, 0, 80, 81, 0, 0, 0, 0, + 0, 0, 0, 169, 0, 0, 170, 0, 0, 0, + 0, 0, 0, 3577, 0, 3578, 0, 0, 3579, 0, + 0, 3582, 3583, 0, 0, 1847, 1848, 161, 160, 189, + 3587, 0, 0, 0, 0, 0, 63, 64, 0, 65, + 66, 67, 68, 0, 3588, 0, 3589, 0, 3590, 0, + 3591, 0, 3592, 0, 3593, 0, 3594, 0, 3595, 0, + 3596, 0, 3597, 0, 3598, 0, 3599, 0, 3600, 0, + 3601, 0, 3602, 0, 3603, 0, 0, 3604, 0, 0, + 0, 3605, 0, 3606, 0, 0, 0, 0, 0, 3608, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3625, 0, 0, 0, 0, 0, 0, 0, + 0, 3630, 0, 3631, 3632, 0, 3633, 0, 3634, 0, + 155, 1849, 158, 3635, 1846, 0, 156, 157, 719, 1416, + 719, 719, 0, 173, 0, 0, 0, 0, 0, 0, + 0, 195, 179, 0, 0, 0, 0, 0, 3660, 195, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 3668, + 720, 0, 3670, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 720, 3674, 0, 0, 0, 0, 1499, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3808, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 2359, 0, + 0, 0, 0, 0, 0, 0, 2363, 0, 2366, 0, + 0, 2039, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 195, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 94, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 720, 0, 0, 0, 897, 0, 0, + 0, 0, 0, 3916, 0, 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 195, 195, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3963, 0, 0, 3964, 0, 3965, 193, 0, 0, 664, + 0, 0, 159, 0, 0, 0, 0, 195, 195, 0, + 0, 0, 0, 193, 0, 0, 664, 0, 0, 1499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3220, 0, 664, + 0, 0, 195, 0, 0, 70, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, - 0, 0, 0, 3258, 0, 0, 0, 0, 0, 0, - 720, 0, 1051, 1051, 0, 0, 0, 3272, 0, 0, - 0, 664, 720, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3290, 0, 0, - 3293, 0, 1498, 0, 0, 0, 0, 0, 0, 4044, + 0, 0, 1032, 0, 0, 720, 0, 0, 0, 2039, + 0, 0, 0, 0, 0, 0, 2524, 0, 0, 1052, + 1052, 0, 0, 0, 0, 2541, 2542, 0, 664, 2546, + 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2551, 0, 0, 0, 0, 0, 0, 2554, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 4060, 0, - 4061, 0, 4062, 0, 0, 720, 0, 0, 0, 1499, - 0, 0, 720, 720, 1499, 195, 195, 195, 195, 195, - 0, 0, 0, 719, 719, 0, 0, 195, 0, 0, - 0, 0, 0, 195, 0, 195, 0, 0, 195, 195, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 152, 0, 0, 153, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 2557, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 165, 0, 0, 1820, 0, 0, 0, + 177, 0, 0, 0, 0, 0, 1829, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3956, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 1855, 0, 0, 0, 0, 0, 0, 0, 1864, + 0, 185, 1499, 1866, 0, 0, 1869, 1870, 719, 719, + 0, 719, 0, 719, 719, 0, 719, 719, 719, 719, + 719, 719, 3970, 0, 0, 3971, 0, 3972, 720, 1499, + 1901, 1902, 1499, 719, 1499, 0, 1907, 0, 0, 0, + 720, 0, 0, 0, 166, 171, 168, 174, 175, 176, + 178, 180, 181, 182, 183, 0, 0, 0, 0, 0, + 184, 186, 187, 188, 0, 0, 0, 0, 719, 0, + 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1969, 0, 0, 719, 195, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4111, 0, 4112, 0, 0, 719, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 1815, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 1824, 0, - 1499, 0, 0, 0, 0, 720, 0, 0, 0, 3445, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 896, 1850, 195, 0, 0, 0, 0, 0, - 0, 1859, 0, 0, 1498, 1861, 0, 0, 1864, 1865, - 719, 719, 0, 719, 195, 719, 719, 195, 719, 719, - 719, 719, 719, 719, 0, 0, 0, 0, 0, 0, - 0, 1498, 1896, 1897, 1498, 719, 1498, 0, 1902, 0, + 0, 0, 0, 720, 0, 0, 0, 1500, 0, 0, + 720, 720, 1500, 195, 195, 195, 195, 195, 0, 0, + 0, 4051, 0, 0, 0, 195, 0, 0, 719, 0, + 0, 195, 0, 195, 0, 0, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4067, 0, 4068, 0, 4069, 0, 0, 0, 95, 0, + 0, 957, 0, 0, 0, 945, 958, 959, 960, 961, + 946, 0, 0, 947, 948, 0, 949, 0, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 954, 962, 963, 0, 0, 720, 0, 0, 1500, 0, + 0, 0, 0, 720, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 718, 0, 0, 0, 3504, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1964, 3519, 0, 719, 3520, 3521, 3522, + 0, 0, 195, 0, 4118, 0, 4119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3273, + 3274, 0, 195, 0, 0, 195, 0, 0, 0, 0, + 0, 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, 0, 0, 719, 719, 2857, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 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, 1082, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 2906, 0, 0, 0, 0, 1499, 0, 0, 0, + 0, 0, 0, 0, 0, 2098, 0, 0, 0, 0, + 0, 0, 0, 1499, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 896, 3276, 3277, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, + 664, 0, 0, 0, 0, 0, 0, 2955, 2956, 2957, + 2958, 2959, 2960, 0, 0, 0, 0, 0, 0, 0, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2039, 2970, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 718, 195, + 0, 0, 0, 0, 0, 0, 0, 2978, 0, 0, + 664, 0, 0, 0, 0, 910, 0, 0, 0, 195, + 0, 914, 195, 195, 195, 911, 912, 0, 0, 0, + 913, 915, 720, 720, 0, 0, 0, 0, 1501, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, + 1076, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 720, 720, 720, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 195, 195, 195, 0, 0, 0, - 0, 0, 0, 0, 720, 720, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 720, 720, 720, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 2456, + 2457, 2458, 0, 0, 0, 0, 0, 0, 1501, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 719, + 0, 0, 0, 0, 0, 719, 1864, 0, 0, 1864, + 0, 1864, 0, 1500, 0, 0, 0, 2488, 720, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 664, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1498, 0, - 0, 0, 0, 0, 0, 0, 0, 2093, 0, 0, - 0, 0, 0, 0, 0, 1498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 719, 0, 0, + 0, 719, 719, 0, 0, 0, 0, 0, 1032, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 195, 664, 0, 720, 0, 0, 3227, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, + 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3265, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3297, 0, 0, + 3300, 1501, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 720, 0, 0, 0, 720, 720, 0, 0, 1501, 0, + 0, 1501, 0, 1501, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 720, 1923, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1499, 0, 719, 1975, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 2001, 2002, + 664, 664, 664, 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1499, 0, 0, 0, 0, - 720, 0, 720, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1264, 0, 1264, 1264, 0, 720, 195, 0, 0, 0, + 0, 0, 0, 0, 3511, 0, 0, 0, 0, 0, + 0, 0, 1428, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3526, 0, 0, 3527, 3528, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, - 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 720, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1500, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, + 0, 720, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 2294, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 720, 0, 0, 1501, 0, 0, 0, 0, + 0, 0, 0, 2870, 0, 0, 0, 1052, 1052, 0, + 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 0, 0, 0, 720, 720, 0, 0, - 0, 0, 1263, 0, 1263, 1263, 0, 0, 664, 0, - 719, 3947, 0, 0, 0, 0, 0, 2449, 2450, 2451, - 0, 0, 0, 0, 1427, 720, 0, 0, 0, 0, - 0, 1032, 0, 0, 0, 0, 0, 719, 0, 0, - 0, 0, 0, 719, 1859, 0, 0, 1859, 0, 1859, - 0, 0, 0, 0, 664, 2481, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 720, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 0, 720, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 719, + 0, 0, 0, 1864, 1864, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 719, 0, 0, 0, 719, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1499, 2943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1052, 1975, 1052, 1052, 1052, + 1052, 1052, 1695, 1696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1500, 0, 0, 1500, 0, 1500, 664, 0, 0, 0, - 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1918, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 720, 195, 0, - 0, 0, 0, 0, 0, 0, 0, 1970, 664, 0, - 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 1996, 1997, 664, 664, 664, 664, 664, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1923, 0, 1744, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 1052, 1762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, - 1498, 1499, 719, 720, 0, 0, 0, 0, 0, 0, + 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, + 0, 0, 0, 0, 1975, 664, 0, 664, 719, 664, + 2382, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 2289, 0, - 0, 0, 0, 0, 1694, 1695, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 1872, 1872, 0, 1872, 0, 1872, 1872, 0, 1881, 1872, + 1872, 1872, 1872, 1872, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 1739, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, - 0, 0, 1075, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 720, - 0, 1867, 1867, 0, 1867, 0, 1867, 1867, 664, 1876, - 1867, 1867, 1867, 1867, 1867, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1075, 0, 0, 0, + 1949, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1944, 0, 0, 0, 0, 0, 1500, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1968, 0, 1051, - 1051, 0, 0, 0, 1500, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 1499, 0, 0, 719, 719, 1499, 664, 0, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 0, 0, 664, 664, 0, 0, 664, 0, + 2548, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 664, 0, 0, + 0, 3954, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3222, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 1499, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2863, + 0, 0, 0, 0, 0, 0, 0, 1264, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3304, 1501, 0, 1975, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1051, 1970, 1051, - 1051, 1051, 1051, 1051, 0, 0, 0, 0, 719, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 1859, - 1859, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1498, 2936, 1918, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1051, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1263, 1263, - 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, - 0, 2022, 0, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 1970, 664, 0, 664, 0, 664, 2375, 95, - 0, 0, 957, 0, 0, 0, 945, 958, 959, 960, - 961, 946, 0, 0, 947, 948, 0, 949, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, - 0, 954, 962, 963, 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 3266, 3267, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3268, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 1263, 719, 0, 664, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 664, 0, 0, 664, 0, 2541, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 719, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2326, - 719, 0, 3269, 3270, 0, 0, 0, 0, 0, 0, - 0, 664, 0, 0, 719, 0, 0, 0, 1498, 0, - 0, 719, 719, 1498, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1739, 0, 0, 1263, 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, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3215, 0, 910, 0, 0, 1500, - 0, 1970, 914, 0, 0, 0, 911, 912, 0, 0, - 0, 913, 915, 0, 0, 0, 719, 0, 0, 1498, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 1082, 0, 0, 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, 1082, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2331, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1075, 0, 0, 0, 0, 2079, 0, 0, 0, - 2079, 2079, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2343, 0, 0, 0, + 0, 664, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 0, 1744, 0, 0, 1264, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 719, 719, 719, + 0, 0, 0, 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 2912, 0, 0, + 0, 0, 0, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1076, 0, 0, 0, 0, 0, 1083, 0, 0, + 0, 0, 0, 1501, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 664, 664, 664, + 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 664, 664, 0, 1076, 0, 0, 0, 0, 2084, + 0, 0, 0, 2084, 2084, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1499, 0, + 0, 0, 0, 719, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 1052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, - 0, 1918, 2553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 3494, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 0, 0, 0, 0, 2560, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 0, 2905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 719, 719, 719, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1264, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 719, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1052, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 664, 664, 664, 664, 664, 0, 0, + 0, 1501, 0, 0, 0, 0, 1501, 664, 664, 664, + 664, 664, 0, 0, 0, 0, 0, 0, 0, 3172, + 0, 0, 0, 0, 0, 1923, 0, 664, 0, 0, + 664, 3180, 1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 2805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1051, + 2820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1499, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2798, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2813, 0, 0, 0, 0, - 0, 0, 0, 0, 1498, 0, 0, 0, 0, 719, - 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 2902, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2343, 0, 0, 0, 664, 0, + 0, 2927, 0, 0, 0, 0, 0, 0, 0, 0, + 2932, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, + 719, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, - 0, 0, 2895, 0, 0, 0, 0, 0, 719, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1051, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2338, - 0, 0, 0, 0, 0, 0, 2920, 0, 0, 0, - 0, 0, 0, 0, 0, 2925, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 664, 664, 664, 0, + 0, 0, 2084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 0, 0, 0, 719, 719, 1500, 0, 0, - 0, 0, 1500, 664, 664, 664, 664, 664, 0, 0, - 0, 0, 0, 0, 0, 3165, 0, 0, 0, 0, - 0, 1918, 0, 664, 719, 0, 664, 3173, 1970, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3696, + 3698, 3697, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3079, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3086, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1867, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1498, 3122, 719, 0, 664, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1263, 0, 0, 0, 0, - 0, 0, 3149, 1867, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1872, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1923, 0, + 0, 0, 0, 0, 0, 0, 3129, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1501, 0, 0, + 1264, 0, 0, 0, 0, 0, 0, 3156, 1872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 664, 0, 0, 719, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, + 3710, 3711, 0, 0, 3786, 3785, 3784, 0, 0, 3782, + 3783, 3781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 1075, 0, 664, - 0, 0, 664, 664, 664, 2338, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 3689, 3691, - 3690, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 789, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 719, 0, + 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, + 2343, 0, 0, 0, 3787, 910, 0, 765, 766, 3788, + 3789, 914, 3790, 768, 769, 911, 912, 0, 763, 767, + 913, 915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3693, 3694, 3695, 3699, + 3700, 3701, 3712, 3759, 3760, 3768, 3770, 866, 3769, 3771, + 3772, 3773, 3776, 3777, 3778, 3779, 3774, 3775, 3780, 3676, + 3680, 3677, 3678, 3679, 3691, 3681, 3682, 3683, 3684, 3685, + 3686, 3687, 3688, 3689, 3690, 3692, 3791, 3792, 3793, 3794, + 3795, 3796, 3705, 3709, 3708, 3706, 3707, 3703, 3704, 3731, + 3730, 3732, 3733, 3734, 3735, 3736, 3737, 3739, 3738, 3740, + 3741, 3742, 3743, 3744, 3745, 3713, 3714, 3717, 3718, 3716, + 3715, 3719, 3728, 3729, 3720, 3721, 3722, 3723, 3724, 3725, + 3727, 3726, 3746, 3747, 3748, 3749, 3750, 3752, 3751, 3755, + 3756, 3754, 3753, 3758, 3757, 0, 3417, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 916, 0, 917, + 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, + 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1923, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3410, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2343, + 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1501, 0, 0, 0, 0, 3565, 3566, + 3567, 3568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4007, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1500, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3695, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3703, - 3704, 0, 0, 3779, 3778, 3777, 0, 0, 3775, 3776, - 3774, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2338, 2338, 0, 0, 0, 0, - 0, 1918, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3780, 910, 0, 765, 766, 3781, 3782, - 914, 3783, 768, 769, 911, 912, 0, 763, 767, 913, - 915, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3558, 3559, 3560, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3686, 3687, 3688, 3692, 3693, - 3694, 3705, 3752, 3753, 3761, 3763, 866, 3762, 3764, 3765, - 3766, 3769, 3770, 3771, 3772, 3767, 3768, 3773, 3669, 3673, - 3670, 3671, 3672, 3684, 3674, 3675, 3676, 3677, 3678, 3679, - 3680, 3681, 3682, 3683, 3685, 3784, 3785, 3786, 3787, 3788, - 3789, 3698, 3702, 3701, 3699, 3700, 3696, 3697, 3724, 3723, - 3725, 3726, 3727, 3728, 3729, 3730, 3732, 3731, 3733, 3734, - 3735, 3736, 3737, 3738, 3706, 3707, 3710, 3711, 3709, 3708, - 3712, 3721, 3722, 3713, 3714, 3715, 3716, 3717, 3718, 3720, - 3719, 3739, 3740, 3741, 3742, 3743, 3745, 3744, 3748, 3749, - 3747, 3746, 3751, 3750, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 916, 0, 917, 0, - 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, - 885, 0, 0, 918, 919, 0, 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3657, 0, 3659, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 0, - 0, 0, 0, 0, 0, 0, 0, 1918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2338, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3824, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3664, 0, 3666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3897, 0, 0, 0, 3897, 3897, 0, 0, - 0, 0, 0, 0, 0, 0, 4000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2338, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1918, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3831, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1970, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3904, 0, 0, + 0, 3904, 3904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2781,1111 +2784,618 @@ 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, 3974, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1263, 1263, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 392, 3410, 0, 4028, - 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, - 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, - 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, 362, 266, - 1275, 1300, 425, 1316, 203, 1365, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 1407, 366, 1351, 0, 491, 396, 0, 0, 0, 1330, - 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, - 1403, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 4002, 941, 0, 0, 0, 0, 4003, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 1308, 1357, 1397, 1309, 1359, 264, 319, 271, 263, 572, - 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, 228, 1399, - 1332, 0, 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, - 1410, 1394, 1303, 274, 0, 0, 0, 0, 0, 0, - 0, 1329, 1340, 1374, 1378, 1323, 0, 0, 0, 0, - 0, 0, 0, 0, 1301, 0, 1349, 0, 0, 0, - 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1327, 0, 0, 0, 0, 1282, - 0, 1302, 1375, 0, 1265, 296, 1276, 397, 256, 0, - 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, - 1388, 1315, 361, 1278, 328, 197, 224, 0, 1313, 407, - 456, 468, 1387, 1298, 1307, 252, 1305, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 1348, 1367, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 1277, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 1293, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 1383, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 1372, 1413, - 420, 467, 239, 596, 490, 199, 1287, 1292, 1285, 0, - 253, 254, 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, - 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 1376, 1281, 0, 1290, 1291, 1385, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 1347, 196, 220, 364, - 1409, 449, 287, 637, 606, 601, 205, 222, 1284, 261, - 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, - 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, - 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 1346, - 1352, 377, 280, 303, 318, 1361, 605, 496, 226, 461, - 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 1342, 1370, - 372, 568, 569, 314, 392, 0, 0, 0, 1398, 1384, - 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, - 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, - 1328, 269, 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, - 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 1407, 366, - 1351, 0, 491, 396, 0, 0, 0, 1330, 1390, 1339, - 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 1308, 1357, - 1397, 1309, 1359, 264, 319, 271, 263, 572, 1408, 1389, - 1272, 1338, 1396, 1333, 0, 0, 228, 1399, 1332, 0, - 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, - 1303, 274, 0, 0, 0, 0, 0, 0, 0, 1329, - 1340, 1374, 1378, 1323, 0, 0, 0, 0, 0, 0, - 3174, 0, 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3981, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1327, 0, 0, 0, 0, 1282, 0, 1302, - 1375, 0, 1265, 296, 1276, 397, 256, 0, 448, 1382, - 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, - 361, 1278, 328, 197, 224, 0, 1313, 407, 456, 468, - 1387, 1298, 1307, 252, 1305, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 1348, 1367, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 1277, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 1293, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 1383, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 1372, 1413, 420, 467, - 239, 596, 490, 199, 1287, 1292, 1285, 0, 253, 254, - 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, - 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 1376, - 1281, 0, 1290, 1291, 1385, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 1347, 196, 220, 364, 1409, 449, - 287, 637, 606, 601, 205, 222, 1284, 261, 1296, 1304, - 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, - 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 1346, 1352, 377, - 280, 303, 318, 1361, 605, 496, 226, 461, 289, 250, - 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 1342, 1370, 372, 568, - 569, 314, 392, 0, 0, 0, 1398, 1384, 520, 0, - 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, - 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, - 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, 425, 1316, - 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 1407, 366, 1351, 0, - 491, 396, 0, 0, 0, 1330, 1390, 1339, 1377, 1325, - 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 1308, 1357, 1397, 1309, - 1359, 264, 319, 271, 263, 572, 1408, 1389, 1272, 1338, - 1396, 1333, 0, 0, 228, 1399, 1332, 0, 1362, 0, - 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, - 0, 0, 0, 0, 0, 0, 0, 1329, 1340, 1374, - 1378, 1323, 0, 0, 0, 0, 0, 0, 3135, 0, - 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, + 0, 0, 1264, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4027, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1327, 0, 0, 0, 0, 1282, 0, 1302, 1375, 0, - 1265, 296, 1276, 397, 256, 0, 448, 1382, 1393, 1324, - 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, - 328, 197, 224, 0, 1313, 407, 456, 468, 1387, 1298, - 1307, 252, 1305, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 1348, 1367, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 1277, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 1293, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 1383, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 1372, 1413, 420, 467, 239, 596, - 490, 199, 1287, 1292, 1285, 0, 253, 254, 1354, 567, - 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 1376, 1281, 0, - 1290, 1291, 1385, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 1347, 196, 220, 364, 1409, 449, 287, 637, - 606, 601, 205, 222, 1284, 261, 1296, 1304, 0, 1310, - 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, - 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 1346, 1352, 377, 280, 303, - 318, 1361, 605, 496, 226, 461, 289, 250, 1379, 1381, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 1342, 1370, 372, 568, 569, 314, - 392, 0, 0, 0, 1398, 1384, 520, 0, 1326, 1401, - 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, 411, 1311, - 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, 1294, 1386, - 1345, 1400, 362, 266, 1275, 1300, 425, 1316, 203, 1365, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 1407, 366, 1351, 0, 491, 396, - 0, 0, 0, 1330, 1390, 1339, 1377, 1325, 1364, 1283, - 1350, 1402, 1312, 1360, 1403, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 941, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 1308, 1357, 1397, 1309, 1359, 264, - 319, 271, 263, 572, 1408, 1389, 1272, 1338, 1396, 1333, - 0, 0, 228, 1399, 1332, 0, 1362, 0, 1414, 1267, - 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, 0, 0, - 0, 0, 0, 0, 0, 1329, 1340, 1374, 1378, 1323, - 0, 0, 0, 0, 0, 0, 2354, 0, 1301, 0, - 1349, 0, 0, 0, 1279, 1271, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1327, 0, - 0, 0, 0, 1282, 0, 1302, 1375, 0, 1265, 296, - 1276, 397, 256, 0, 448, 1382, 1393, 1324, 616, 1395, - 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, 328, 197, - 224, 0, 1313, 407, 456, 468, 1387, 1298, 1307, 252, - 1305, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 1348, 1367, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 1277, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 1293, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 1383, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 1372, 1413, 420, 467, 239, 596, 490, 199, - 1287, 1292, 1285, 0, 253, 254, 1354, 567, 1288, 1286, - 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 1376, 1281, 0, 1290, 1291, - 1385, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 1347, 196, 220, 364, 1409, 449, 287, 637, 606, 601, - 205, 222, 1284, 261, 1296, 1304, 0, 1310, 1318, 1319, - 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, 1366, 1368, - 1371, 1373, 1380, 1392, 1412, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 1346, 1352, 377, 280, 303, 318, 1361, - 605, 496, 226, 461, 289, 250, 1379, 1381, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 1342, 1370, 372, 568, 569, 314, 392, 0, - 0, 0, 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, - 1411, 1317, 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, - 1268, 1306, 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, - 362, 266, 1275, 1300, 425, 1316, 203, 1365, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 1407, 366, 1351, 0, 491, 396, 0, 0, - 0, 1330, 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, - 1312, 1360, 1403, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 1308, 1357, 1397, 1309, 1359, 264, 319, 271, - 263, 572, 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, - 228, 1399, 1332, 0, 1362, 0, 1414, 1267, 1353, 0, - 1270, 1274, 1410, 1394, 1303, 274, 0, 0, 0, 0, - 0, 0, 0, 1329, 1340, 1374, 1378, 1323, 0, 0, - 0, 0, 0, 0, 0, 0, 1301, 0, 1349, 0, - 0, 0, 1279, 1271, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1327, 0, 0, 0, - 0, 1282, 0, 1302, 1375, 0, 1265, 296, 1276, 397, - 256, 0, 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, - 1369, 1280, 1388, 1315, 361, 1278, 328, 197, 224, 0, - 1313, 407, 456, 468, 1387, 1298, 1307, 252, 1305, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 1348, - 1367, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 1277, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 1293, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 1383, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 1372, 1413, 420, 467, 239, 596, 490, 199, 1287, 1292, - 1285, 0, 253, 254, 1354, 567, 1288, 1286, 1343, 1344, - 1289, 1404, 1405, 1406, 1391, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 1376, 1281, 0, 1290, 1291, 1385, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 1347, 196, - 220, 364, 1409, 449, 287, 637, 606, 601, 205, 222, - 1284, 261, 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, - 1335, 1336, 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, - 1380, 1392, 1412, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 1346, 1352, 377, 280, 303, 318, 1361, 605, 496, - 226, 461, 289, 250, 1379, 1381, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 1342, 1370, 372, 568, 569, 314, 392, 0, 0, 0, - 1398, 1384, 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, - 1320, 1363, 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, - 1269, 1297, 1328, 269, 1294, 1386, 1345, 1400, 362, 266, - 1275, 1300, 425, 1316, 203, 1365, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 1407, 366, 1351, 0, 491, 396, 0, 0, 0, 1330, - 1390, 1339, 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, - 1403, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 1308, 1357, 1397, 1309, 1359, 264, 319, 271, 263, 572, - 1408, 1389, 1272, 1338, 1396, 1333, 0, 0, 228, 1399, - 1332, 0, 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, - 1410, 1394, 1303, 274, 0, 0, 0, 0, 0, 0, - 0, 1329, 1340, 1374, 1378, 1323, 0, 0, 0, 0, - 0, 0, 0, 0, 1301, 0, 1349, 0, 0, 0, - 1279, 1271, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1327, 0, 0, 0, 0, 1282, - 0, 1302, 1375, 0, 1265, 296, 1276, 397, 256, 0, - 448, 1382, 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, - 1388, 1315, 361, 1278, 328, 197, 224, 0, 1313, 407, - 456, 468, 1387, 1298, 1307, 252, 1305, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 1348, 1367, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 1277, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 1293, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 1383, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 1372, 1413, - 420, 467, 239, 596, 490, 199, 1287, 1292, 1285, 0, - 253, 254, 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, - 1405, 1406, 1391, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 1376, 1281, 0, 1290, 1291, 1385, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 1347, 196, 220, 364, - 1409, 449, 287, 637, 606, 601, 205, 222, 1284, 261, - 1296, 1304, 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, - 1337, 1355, 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, - 1412, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 1346, - 1352, 377, 280, 303, 318, 1361, 605, 496, 226, 461, - 289, 250, 1379, 1381, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 1342, 1370, - 372, 568, 569, 314, 392, 0, 0, 0, 1398, 1384, - 520, 0, 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, - 1273, 1341, 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, - 1328, 269, 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, - 425, 1316, 203, 1365, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 1407, 366, - 1351, 0, 491, 396, 0, 0, 0, 1330, 1390, 1339, - 1377, 1325, 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 1308, 1357, - 1397, 1309, 1359, 264, 319, 271, 263, 572, 1408, 1389, - 1272, 1338, 1396, 1333, 0, 0, 228, 1399, 1332, 0, - 1362, 0, 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, - 1303, 274, 0, 0, 0, 0, 0, 0, 0, 1329, - 1340, 1374, 1378, 1323, 0, 0, 0, 0, 0, 0, - 0, 0, 1301, 0, 1349, 0, 0, 0, 1279, 1271, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1327, 0, 0, 0, 0, 1282, 0, 1302, - 1375, 0, 1265, 296, 1276, 397, 256, 0, 448, 1382, - 1393, 1324, 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, - 361, 1278, 328, 197, 224, 0, 1313, 407, 456, 468, - 1387, 1298, 1307, 252, 1305, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 1348, 1367, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 1277, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 1293, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 1383, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 1372, 1413, 420, 467, - 239, 596, 490, 199, 1287, 1292, 1285, 0, 253, 254, - 1354, 567, 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, - 1391, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 1376, - 1281, 0, 1290, 1291, 1385, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 1347, 196, 220, 364, 1409, 449, - 287, 637, 606, 601, 205, 222, 1284, 261, 1296, 1304, - 0, 1310, 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, - 1356, 1358, 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 1346, 1352, 377, - 280, 303, 318, 1361, 605, 496, 226, 461, 289, 250, - 1379, 1381, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 1342, 1370, 372, 568, - 569, 314, 392, 0, 0, 0, 1398, 1384, 520, 0, - 1326, 1401, 1295, 1314, 1411, 1317, 1320, 1363, 1273, 1341, - 411, 1311, 1266, 1299, 1268, 1306, 1269, 1297, 1328, 269, - 1294, 1386, 1345, 1400, 362, 266, 1275, 1300, 425, 1316, - 203, 1365, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 1407, 366, 1351, 0, - 491, 396, 0, 0, 0, 1330, 1390, 1339, 1377, 1325, - 1364, 1283, 1350, 1402, 1312, 1360, 1403, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 941, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 1308, 1357, 1397, 1309, - 1359, 264, 319, 271, 263, 572, 1408, 1389, 1272, 1338, - 1396, 1333, 0, 0, 228, 1399, 1332, 0, 1362, 0, - 1414, 1267, 1353, 0, 1270, 1274, 1410, 1394, 1303, 274, - 0, 0, 0, 0, 0, 0, 0, 1329, 1340, 1374, - 1378, 1323, 0, 0, 0, 0, 0, 0, 0, 0, - 1301, 0, 1349, 0, 0, 0, 1279, 1271, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 392, 3417, 0, 4035, 1399, 1385, 520, 0, 1327, + 1402, 1296, 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, + 1312, 1267, 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, + 1387, 1346, 1401, 362, 266, 1276, 1301, 425, 1317, 203, + 1366, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 1408, 366, 1352, 0, 491, + 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, + 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 4009, 941, 0, + 0, 0, 0, 4010, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, + 264, 319, 271, 263, 572, 1409, 1390, 1273, 1339, 1397, + 1334, 0, 0, 228, 1400, 1333, 0, 1363, 0, 1415, + 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, 0, + 0, 0, 0, 0, 0, 0, 1330, 1341, 1375, 1379, + 1324, 0, 0, 0, 0, 0, 0, 0, 0, 1302, + 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1328, + 0, 0, 0, 0, 1283, 0, 1303, 1376, 0, 1266, + 296, 1277, 397, 256, 0, 448, 1383, 1394, 1325, 616, + 1396, 1323, 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, + 197, 224, 0, 1314, 407, 456, 468, 1388, 1299, 1308, + 252, 1306, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 1349, 1368, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 1278, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 1294, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 1384, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 1373, 1414, 420, 467, 239, 596, 490, + 199, 1288, 1293, 1286, 0, 253, 254, 1355, 567, 1289, + 1287, 1344, 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 1377, 1282, 0, 1291, + 1292, 1386, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 1348, 196, 220, 364, 1410, 449, 287, 637, 606, + 601, 205, 222, 1285, 261, 1297, 1305, 0, 1311, 1319, + 1320, 1332, 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, + 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 1347, 1353, 377, 280, 303, 318, + 1362, 605, 496, 226, 461, 289, 250, 1380, 1382, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 1343, 1371, 372, 568, 569, 314, 392, + 0, 0, 0, 1399, 1385, 520, 0, 1327, 1402, 1296, + 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, + 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, + 1401, 362, 266, 1276, 1301, 425, 1317, 203, 1366, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 1408, 366, 1352, 0, 491, 396, 0, + 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, + 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, 319, + 271, 263, 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, + 0, 228, 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, + 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, 0, + 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, 0, + 0, 0, 0, 0, 0, 3181, 0, 1302, 0, 1350, + 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1327, 0, 0, 0, 0, 1282, 0, 1302, 1375, 0, - 1265, 296, 1276, 397, 256, 0, 448, 1382, 1393, 1324, - 616, 1395, 1322, 1321, 1369, 1280, 1388, 1315, 361, 1278, - 328, 197, 224, 0, 1313, 407, 456, 468, 1387, 1298, - 1307, 252, 1305, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 1348, 1367, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 1277, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 1293, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 1383, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 1372, 1413, 420, 467, 239, 596, - 490, 199, 1287, 1292, 1285, 0, 253, 254, 1354, 567, - 1288, 1286, 1343, 1344, 1289, 1404, 1405, 1406, 1391, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 1376, 1281, 0, - 1290, 1291, 1385, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 1347, 196, 220, 364, 1409, 449, 287, 637, - 606, 601, 205, 222, 1284, 261, 1296, 1304, 0, 1310, - 1318, 1319, 1331, 1334, 1335, 1336, 1337, 1355, 1356, 1358, - 1366, 1368, 1371, 1373, 1380, 1392, 1412, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 1346, 1352, 377, 280, 303, - 318, 1361, 605, 496, 226, 461, 289, 250, 1379, 1381, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 1342, 1370, 372, 568, 569, 314, - 392, 0, 0, 0, 0, 0, 520, 0, 761, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, - 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, - 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, - 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, - 319, 271, 263, 572, 0, 0, 2177, 2178, 2179, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, - 901, 0, 745, 0, 0, 753, 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, 755, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, - 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, - 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, - 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, - 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, - 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, - 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, - 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, - 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, - 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, - 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, - 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, - 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, - 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, - 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, - 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, - 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, - 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, - 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, - 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, - 0, 0, 0, 0, 0, 2383, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, - 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, - 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, - 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, - 2384, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, - 0, 0, 901, 0, 745, 0, 0, 753, 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, - 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, - 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, - 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 805, 806, 279, - 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 888, 910, 899, 765, 766, 889, 890, 914, 891, - 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 902, 752, 751, - 0, 758, 0, 787, 788, 790, 794, 795, 796, 807, - 854, 855, 863, 865, 866, 864, 867, 868, 869, 872, - 873, 874, 875, 870, 871, 876, 770, 774, 771, 772, - 773, 785, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 786, 925, 926, 927, 928, 929, 930, 800, - 804, 803, 801, 802, 798, 799, 826, 825, 827, 828, - 829, 830, 831, 832, 834, 833, 835, 836, 837, 838, - 839, 840, 808, 809, 812, 813, 811, 810, 814, 823, - 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, - 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, - 853, 852, 750, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, - 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, - 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 931, - 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 0, 392, 372, 568, 569, 314, - 86, 520, 0, 761, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, - 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, - 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, - 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, - 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, - 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, - 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, - 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, - 753, 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, 755, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 0, 0, 0, 0, 0, 0, 0, 1328, 0, 0, + 0, 0, 1283, 0, 1303, 1376, 0, 1266, 296, 1277, + 397, 256, 0, 448, 1383, 1394, 1325, 616, 1396, 1323, + 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, 197, 224, + 0, 1314, 407, 456, 468, 1388, 1299, 1308, 252, 1306, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 1278, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 1294, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 1384, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 1373, 1414, 420, 467, 239, 596, 490, 199, 1288, + 1293, 1286, 0, 253, 254, 1355, 567, 1289, 1287, 1344, + 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 1377, 1282, 0, 1291, 1292, 1386, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 1348, + 196, 220, 364, 1410, 449, 287, 637, 606, 601, 205, + 222, 1285, 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, + 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, + 1374, 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 1347, 1353, 377, 280, 303, 318, 1362, 605, + 496, 226, 461, 289, 250, 1380, 1382, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 1343, 1371, 372, 568, 569, 314, 392, 0, 0, + 0, 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, + 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, + 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, + 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, + 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, + 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, + 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, + 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, + 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, + 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, + 0, 0, 0, 3142, 0, 1302, 0, 1350, 0, 0, + 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1328, 0, 0, 0, 0, + 1283, 0, 1303, 1376, 0, 1266, 296, 1277, 397, 256, + 0, 448, 1383, 1394, 1325, 616, 1396, 1323, 1322, 1370, + 1281, 1389, 1316, 361, 1279, 328, 197, 224, 0, 1314, + 407, 456, 468, 1388, 1299, 1308, 252, 1306, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 1349, 1368, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 1278, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 1294, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 1384, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 1373, + 1414, 420, 467, 239, 596, 490, 199, 1288, 1293, 1286, + 0, 253, 254, 1355, 567, 1289, 1287, 1344, 1345, 1290, + 1405, 1406, 1407, 1392, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 1377, 1282, 0, 1291, 1292, 1386, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 1348, 196, 220, + 364, 1410, 449, 287, 637, 606, 601, 205, 222, 1285, + 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, 1335, 1336, + 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, 1374, 1381, + 1393, 1413, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 1347, 1353, 377, 280, 303, 318, 1362, 605, 496, 226, + 461, 289, 250, 1380, 1382, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 1343, + 1371, 372, 568, 569, 314, 392, 0, 0, 0, 1399, + 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, 1318, 1321, + 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, 1307, 1270, + 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, 266, 1276, + 1301, 425, 1317, 203, 1366, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 1408, + 366, 1352, 0, 491, 396, 0, 0, 0, 1331, 1391, + 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, 1361, 1404, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 1309, + 1358, 1398, 1310, 1360, 264, 319, 271, 263, 572, 1409, + 1390, 1273, 1339, 1397, 1334, 0, 0, 228, 1400, 1333, + 0, 1363, 0, 1415, 1268, 1354, 0, 1271, 1275, 1411, + 1395, 1304, 274, 0, 0, 0, 0, 0, 0, 0, + 1330, 1341, 1375, 1379, 1324, 0, 0, 0, 0, 0, + 0, 2361, 0, 1302, 0, 1350, 0, 0, 0, 1280, + 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1328, 0, 0, 0, 0, 1283, 0, + 1303, 1376, 0, 1266, 296, 1277, 397, 256, 0, 448, + 1383, 1394, 1325, 616, 1396, 1323, 1322, 1370, 1281, 1389, + 1316, 361, 1279, 328, 197, 224, 0, 1314, 407, 456, + 468, 1388, 1299, 1308, 252, 1306, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, + 410, 581, 582, 255, 639, 227, 610, 219, 1278, 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 805, 806, 279, 305, 882, 881, 880, 304, 306, 878, - 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 1294, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 1384, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 888, 910, 899, 765, 766, 889, - 890, 914, 891, 768, 769, 911, 912, 762, 763, 767, - 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, + 631, 629, 402, 309, 489, 331, 369, 1373, 1414, 420, + 467, 239, 596, 490, 199, 1288, 1293, 1286, 0, 253, + 254, 1355, 567, 1289, 1287, 1344, 1345, 1290, 1405, 1406, + 1407, 1392, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 902, 752, 751, 0, 758, 0, 787, 788, 790, 794, - 795, 796, 807, 854, 855, 863, 865, 866, 864, 867, - 868, 869, 872, 873, 874, 875, 870, 871, 876, 770, - 774, 771, 772, 773, 785, 775, 776, 777, 778, 779, - 780, 781, 782, 783, 784, 786, 925, 926, 927, 928, - 929, 930, 800, 804, 803, 801, 802, 798, 799, 826, - 825, 827, 828, 829, 830, 831, 832, 834, 833, 835, - 836, 837, 838, 839, 840, 808, 809, 812, 813, 811, - 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, - 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, - 851, 849, 848, 853, 852, 750, 196, 220, 364, 94, - 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, - 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, - 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, + 1377, 1282, 0, 1291, 1292, 1386, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 1348, 196, 220, 364, 1410, + 449, 287, 637, 606, 601, 205, 222, 1285, 261, 1297, + 1305, 0, 1311, 1319, 1320, 1332, 1335, 1336, 1337, 1338, + 1356, 1357, 1359, 1367, 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 931, 932, 933, 934, 935, 936, 937, 938, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 1347, 1353, + 377, 280, 303, 318, 1362, 605, 496, 226, 461, 289, + 250, 1380, 1382, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, - 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, - 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, - 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, - 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, - 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 511, 512, 513, 515, 391, 265, 428, 1343, 1371, 372, + 568, 569, 314, 392, 0, 0, 0, 1399, 1385, 520, + 0, 1327, 1402, 1296, 1315, 1412, 1318, 1321, 1364, 1274, + 1342, 411, 1312, 1267, 1300, 1269, 1307, 1270, 1298, 1329, + 269, 1295, 1387, 1346, 1401, 362, 266, 1276, 1301, 425, + 1317, 203, 1366, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 1408, 366, 1352, + 0, 491, 396, 0, 0, 0, 1331, 1391, 1340, 1378, + 1326, 1365, 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 1309, 1358, 1398, + 1310, 1360, 264, 319, 271, 263, 572, 1409, 1390, 1273, + 1339, 1397, 1334, 0, 0, 228, 1400, 1333, 0, 1363, + 0, 1415, 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, + 274, 0, 0, 0, 0, 0, 0, 0, 1330, 1341, + 1375, 1379, 1324, 0, 0, 0, 0, 0, 0, 0, + 0, 1302, 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, - 0, 0, 753, 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, 755, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 3988, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, - 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, - 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, - 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, - 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, - 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, - 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, - 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, - 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, - 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, - 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, - 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, - 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, - 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, - 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, - 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, - 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1328, 0, 0, 0, 0, 1283, 0, 1303, 1376, + 0, 1266, 296, 1277, 397, 256, 0, 448, 1383, 1394, + 1325, 616, 1396, 1323, 1322, 1370, 1281, 1389, 1316, 361, + 1279, 328, 197, 224, 0, 1314, 407, 456, 468, 1388, + 1299, 1308, 252, 1306, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 1349, 1368, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 1278, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 1294, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 1384, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 1373, 1414, 420, 467, 239, + 596, 490, 199, 1288, 1293, 1286, 0, 253, 254, 1355, + 567, 1289, 1287, 1344, 1345, 1290, 1405, 1406, 1407, 1392, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 1377, 1282, + 0, 1291, 1292, 1386, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 1348, 196, 220, 364, 1410, 449, 287, + 637, 606, 601, 205, 222, 1285, 261, 1297, 1305, 0, + 1311, 1319, 1320, 1332, 1335, 1336, 1337, 1338, 1356, 1357, + 1359, 1367, 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 1347, 1353, 377, 280, + 303, 318, 1362, 605, 496, 226, 461, 289, 250, 1380, + 1382, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 1343, 1371, 372, 568, 569, + 314, 392, 0, 0, 0, 1399, 1385, 520, 0, 1327, + 1402, 1296, 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, + 1312, 1267, 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, + 1387, 1346, 1401, 362, 266, 1276, 1301, 425, 1317, 203, + 1366, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 1408, 366, 1352, 0, 491, + 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, + 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 194, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, + 264, 319, 271, 263, 572, 1409, 1390, 1273, 1339, 1397, + 1334, 0, 0, 228, 1400, 1333, 0, 1363, 0, 1415, + 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, 0, + 0, 0, 0, 0, 0, 0, 1330, 1341, 1375, 1379, + 1324, 0, 0, 0, 0, 0, 0, 0, 0, 1302, + 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1328, + 0, 0, 0, 0, 1283, 0, 1303, 1376, 0, 1266, + 296, 1277, 397, 256, 0, 448, 1383, 1394, 1325, 616, + 1396, 1323, 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, + 197, 224, 0, 1314, 407, 456, 468, 1388, 1299, 1308, + 252, 1306, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 1349, 1368, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 1278, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 1294, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 1384, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 1373, 1414, 420, 467, 239, 596, 490, + 199, 1288, 1293, 1286, 0, 253, 254, 1355, 567, 1289, + 1287, 1344, 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 1377, 1282, 0, 1291, + 1292, 1386, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 1348, 196, 220, 364, 1410, 449, 287, 637, 606, + 601, 205, 222, 1285, 261, 1297, 1305, 0, 1311, 1319, + 1320, 1332, 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, + 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 1347, 1353, 377, 280, 303, 318, + 1362, 605, 496, 226, 461, 289, 250, 1380, 1382, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 1343, 1371, 372, 568, 569, 314, 392, + 0, 0, 0, 1399, 1385, 520, 0, 1327, 1402, 1296, + 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, + 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, + 1401, 362, 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, - 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 95, 0, 1717, 957, 941, 733, 907, 945, - 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, - 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, - 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, - 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, - 0, 745, 0, 0, 753, 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, 755, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, - 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, + 423, 510, 417, 1408, 366, 1352, 0, 491, 396, 0, + 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, + 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, 319, + 271, 263, 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, + 0, 228, 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, + 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, 0, + 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, 0, + 0, 0, 0, 0, 0, 0, 0, 1302, 0, 1350, + 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1328, 0, 0, + 0, 0, 1283, 0, 1303, 1376, 0, 1266, 296, 1277, + 397, 256, 0, 448, 1383, 1394, 1325, 616, 1396, 1323, + 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, 197, 224, + 0, 1314, 407, 456, 468, 1388, 1299, 1308, 252, 1306, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 805, 806, 279, 305, 882, 881, - 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 1278, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 1294, 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 437, 446, 1384, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 888, 910, - 899, 765, 766, 889, 890, 914, 891, 768, 769, 911, - 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, + 369, 1373, 1414, 420, 467, 239, 596, 490, 199, 1288, + 1293, 1286, 0, 253, 254, 1355, 567, 1289, 1287, 1344, + 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 902, 752, 751, 0, 758, 0, - 787, 788, 790, 794, 795, 796, 807, 854, 855, 863, - 865, 866, 864, 867, 868, 869, 872, 873, 874, 875, - 870, 871, 876, 770, 774, 771, 772, 773, 785, 775, - 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, - 925, 926, 927, 928, 929, 930, 800, 804, 803, 801, - 802, 798, 799, 826, 825, 827, 828, 829, 830, 831, - 832, 834, 833, 835, 836, 837, 838, 839, 840, 808, - 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, - 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, - 845, 847, 846, 850, 851, 849, 848, 853, 852, 750, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, - 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, - 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, + 504, 505, 0, 507, 1377, 1282, 0, 1291, 1292, 1386, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 1348, + 196, 220, 364, 1410, 449, 287, 637, 606, 601, 205, + 222, 1285, 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, + 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, + 1374, 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 931, 932, 933, 934, - 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 1347, 1353, 377, 280, 303, 318, 1362, 605, + 496, 226, 461, 289, 250, 1380, 1382, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, - 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, - 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, - 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 743, 744, 1049, 0, 0, - 0, 901, 0, 745, 0, 0, 753, 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, 755, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, - 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, - 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, - 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, - 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, - 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, - 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, - 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, - 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, - 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, - 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, - 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, - 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, - 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, - 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, - 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, - 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, - 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, - 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, - 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, - 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, - 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, - 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, - 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, - 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 755, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, - 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, - 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, - 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, - 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, - 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, - 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, - 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, - 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, - 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, - 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, - 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, - 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, - 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, - 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, - 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, - 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, - 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 761, 0, 0, 0, 0, 0, 0, + 428, 1343, 1371, 372, 568, 569, 314, 392, 0, 0, + 0, 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, + 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, + 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, + 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, + 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, + 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 941, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, + 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, + 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, + 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, + 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, + 0, 0, 0, 0, 0, 1302, 0, 1350, 0, 0, + 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1328, 0, 0, 0, 0, + 1283, 0, 1303, 1376, 0, 1266, 296, 1277, 397, 256, + 0, 448, 1383, 1394, 1325, 616, 1396, 1323, 1322, 1370, + 1281, 1389, 1316, 361, 1279, 328, 197, 224, 0, 1314, + 407, 456, 468, 1388, 1299, 1308, 252, 1306, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 1349, 1368, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 1278, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 1294, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 1384, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 1373, + 1414, 420, 467, 239, 596, 490, 199, 1288, 1293, 1286, + 0, 253, 254, 1355, 567, 1289, 1287, 1344, 1345, 1290, + 1405, 1406, 1407, 1392, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 1377, 1282, 0, 1291, 1292, 1386, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 1348, 196, 220, + 364, 1410, 449, 287, 637, 606, 601, 205, 222, 1285, + 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, 1335, 1336, + 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, 1374, 1381, + 1393, 1413, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 1347, 1353, 377, 280, 303, 318, 1362, 605, 496, 226, + 461, 289, 250, 1380, 1382, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 1343, + 1371, 372, 568, 569, 314, 392, 0, 0, 0, 0, + 0, 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, @@ -3897,7 +3407,7 @@ var yyAct = [...]int{ 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 2182, 2183, 2184, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, @@ -3906,7 +3416,7 @@ var yyAct = [...]int{ 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, 3093, 0, 0, 0, 0, 0, 0, + 1003, 1004, 1005, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, @@ -3964,11 +3474,11 @@ var yyAct = [...]int{ 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 2390, 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, - 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, + 862, 789, 954, 962, 963, 2391, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, @@ -3978,372 +3488,11 @@ var yyAct = [...]int{ 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, 3089, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, - 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, - 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, - 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, - 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, - 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, - 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, - 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, - 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, - 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, - 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, - 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, - 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, - 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, - 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, - 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, - 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, - 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 95, 0, 0, 957, 941, 1070, 907, 945, - 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, - 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, - 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, - 0, 745, 0, 0, 753, 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, 755, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, - 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 805, 806, 279, 305, 882, 881, - 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 888, 910, - 899, 765, 766, 889, 890, 914, 891, 768, 769, 911, - 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 902, 752, 751, 0, 758, 0, - 787, 788, 790, 794, 795, 796, 807, 854, 855, 863, - 865, 866, 864, 867, 868, 869, 872, 873, 874, 875, - 870, 871, 876, 770, 774, 771, 772, 773, 785, 775, - 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, - 925, 926, 927, 928, 929, 930, 800, 804, 803, 801, - 802, 798, 799, 826, 825, 827, 828, 829, 830, 831, - 832, 834, 833, 835, 836, 837, 838, 839, 840, 808, - 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, - 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, - 845, 847, 846, 850, 851, 849, 848, 853, 852, 750, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, - 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, - 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 931, 932, 933, 934, - 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 95, 0, 0, 957, 941, 1070, - 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, - 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, - 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 746, 0, 759, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, - 0, 901, 0, 745, 0, 0, 753, 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, 2071, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, - 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, - 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, - 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, - 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, - 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, - 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, - 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, - 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, - 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, - 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, - 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, - 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, - 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, - 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, - 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, - 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, - 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, - 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, - 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, - 941, 1070, 907, 945, 958, 959, 960, 961, 946, 0, - 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, - 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, - 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 746, 0, 759, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, - 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 2069, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, - 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, - 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, - 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, - 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, - 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, - 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, - 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, - 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, - 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, - 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, - 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, - 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, - 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, - 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, - 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, - 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, - 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 1121, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 1120, 616, 0, 0, 0, 0, 0, 1117, - 1118, 361, 1078, 328, 197, 224, 1111, 1115, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 1679, 941, 0, 0, 1676, 0, 0, - 0, 0, 1674, 0, 237, 1675, 1673, 244, 1678, 0, - 906, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1001, 1002, 1003, 1004, 1005, 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, @@ -4351,46 +3500,768 @@ var yyAct = [...]int{ 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, + 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, + 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, + 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, + 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, + 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, + 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, + 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, + 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, + 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, + 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, + 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, + 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, + 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, + 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, + 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, + 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, + 392, 372, 568, 569, 314, 86, 520, 0, 761, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, + 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, + 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, + 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, + 901, 0, 745, 0, 0, 753, 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, 755, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, + 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, + 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, + 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, + 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, + 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, + 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, + 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, + 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, + 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, + 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, + 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, + 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, + 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, + 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, + 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, + 750, 196, 220, 364, 94, 449, 287, 637, 606, 601, + 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, + 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, + 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, + 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, + 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, + 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, + 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, + 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, + 0, 0, 901, 0, 745, 0, 0, 753, 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, + 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, + 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 3995, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, + 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 805, 806, 279, + 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 888, 910, 899, 765, 766, 889, 890, 914, 891, + 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 902, 752, 751, + 0, 758, 0, 787, 788, 790, 794, 795, 796, 807, + 854, 855, 863, 865, 866, 864, 867, 868, 869, 872, + 873, 874, 875, 870, 871, 876, 770, 774, 771, 772, + 773, 785, 775, 776, 777, 778, 779, 780, 781, 782, + 783, 784, 786, 925, 926, 927, 928, 929, 930, 800, + 804, 803, 801, 802, 798, 799, 826, 825, 827, 828, + 829, 830, 831, 832, 834, 833, 835, 836, 837, 838, + 839, 840, 808, 809, 812, 813, 811, 810, 814, 823, + 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, + 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, + 853, 852, 750, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, + 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, + 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 931, + 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, + 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, + 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 95, 0, 1718, + 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, + 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, + 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, + 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, + 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, + 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, 755, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, + 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, + 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, + 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, + 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, + 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, + 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, + 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, + 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, + 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, + 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, + 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, + 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, + 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, + 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, + 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, + 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, + 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, + 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, + 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, + 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, + 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, + 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, + 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 743, 744, 1050, 0, 0, 0, 901, 0, 745, 0, + 0, 753, 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, 755, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 805, 806, 279, 305, 882, 881, 880, 304, 306, + 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 888, 910, 899, 765, 766, + 889, 890, 914, 891, 768, 769, 911, 912, 762, 763, + 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 902, 752, 751, 0, 758, 0, 787, 788, 790, + 794, 795, 796, 807, 854, 855, 863, 865, 866, 864, + 867, 868, 869, 872, 873, 874, 875, 870, 871, 876, + 770, 774, 771, 772, 773, 785, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 784, 786, 925, 926, 927, + 928, 929, 930, 800, 804, 803, 801, 802, 798, 799, + 826, 825, 827, 828, 829, 830, 831, 832, 834, 833, + 835, 836, 837, 838, 839, 840, 808, 809, 812, 813, + 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, + 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, + 850, 851, 849, 848, 853, 852, 750, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 916, 261, + 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, + 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 931, 932, 933, 934, 935, 936, 937, + 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, + 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, + 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, + 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, + 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, + 745, 0, 0, 753, 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, 755, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 805, 806, 279, 305, 882, 881, 880, + 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 888, 910, 899, + 765, 766, 889, 890, 914, 891, 768, 769, 911, 912, + 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 902, 752, 751, 0, 758, 0, 787, + 788, 790, 794, 795, 796, 807, 854, 855, 863, 865, + 866, 864, 867, 868, 869, 872, 873, 874, 875, 870, + 871, 876, 770, 774, 771, 772, 773, 785, 775, 776, + 777, 778, 779, 780, 781, 782, 783, 784, 786, 925, + 926, 927, 928, 929, 930, 800, 804, 803, 801, 802, + 798, 799, 826, 825, 827, 828, 829, 830, 831, 832, + 834, 833, 835, 836, 837, 838, 839, 840, 808, 809, + 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, + 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, + 847, 846, 850, 851, 849, 848, 853, 852, 750, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, + 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, + 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 931, 932, 933, 934, 935, + 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, + 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, + 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, + 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, - 392, 372, 568, 569, 314, 86, 520, 0, 0, 0, + 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, + 901, 0, 745, 0, 0, 753, 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, 3100, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, + 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, + 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, + 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, + 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, + 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, + 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, + 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, + 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, + 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, + 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, + 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, + 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, + 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, + 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, + 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, + 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, + 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, + 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, + 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, + 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, + 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, + 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, + 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, + 0, 0, 901, 0, 745, 0, 0, 753, 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, + 3096, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, + 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, + 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 805, 806, 279, + 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 888, 910, 899, 765, 766, 889, 890, 914, 891, + 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 902, 752, 751, + 0, 758, 0, 787, 788, 790, 794, 795, 796, 807, + 854, 855, 863, 865, 866, 864, 867, 868, 869, 872, + 873, 874, 875, 870, 871, 876, 770, 774, 771, 772, + 773, 785, 775, 776, 777, 778, 779, 780, 781, 782, + 783, 784, 786, 925, 926, 927, 928, 929, 930, 800, + 804, 803, 801, 802, 798, 799, 826, 825, 827, 828, + 829, 830, 831, 832, 834, 833, 835, 836, 837, 838, + 839, 840, 808, 809, 812, 813, 811, 810, 814, 823, + 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, + 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, + 853, 852, 750, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, + 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, + 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 931, + 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, + 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, + 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, + 957, 941, 1071, 907, 945, 958, 959, 960, 961, 946, + 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, + 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, + 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 0, 0, 0, 0, 746, 0, 759, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, + 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, + 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, 755, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, + 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, + 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, + 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, + 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, + 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, + 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, + 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, + 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, + 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, + 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, + 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, + 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, + 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, + 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, + 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, + 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, + 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, + 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, + 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, + 0, 0, 957, 941, 1071, 907, 945, 958, 959, 960, + 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, + 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, + 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 746, 0, 759, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, + 0, 753, 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, 2076, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 805, 806, 279, 305, 882, 881, 880, 304, 306, + 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 888, 910, 899, 765, 766, + 889, 890, 914, 891, 768, 769, 911, 912, 762, 763, + 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 902, 752, 751, 0, 758, 0, 787, 788, 790, + 794, 795, 796, 807, 854, 855, 863, 865, 866, 864, + 867, 868, 869, 872, 873, 874, 875, 870, 871, 876, + 770, 774, 771, 772, 773, 785, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 784, 786, 925, 926, 927, + 928, 929, 930, 800, 804, 803, 801, 802, 798, 799, + 826, 825, 827, 828, 829, 830, 831, 832, 834, 833, + 835, 836, 837, 838, 839, 840, 808, 809, 812, 813, + 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, + 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, + 850, 851, 849, 848, 853, 852, 750, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 916, 261, + 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, + 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 931, 932, 933, 934, 935, 936, 937, + 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 95, 0, 0, 957, 941, 1071, 907, 945, 958, + 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, + 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, + 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 746, + 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, + 745, 0, 0, 753, 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, 2074, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 805, 806, 279, 305, 882, 881, 880, + 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 888, 910, 899, + 765, 766, 889, 890, 914, 891, 768, 769, 911, 912, + 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 902, 752, 751, 0, 758, 0, 787, + 788, 790, 794, 795, 796, 807, 854, 855, 863, 865, + 866, 864, 867, 868, 869, 872, 873, 874, 875, 870, + 871, 876, 770, 774, 771, 772, 773, 785, 775, 776, + 777, 778, 779, 780, 781, 782, 783, 784, 786, 925, + 926, 927, 928, 929, 930, 800, 804, 803, 801, 802, + 798, 799, 826, 825, 827, 828, 829, 830, 831, 832, + 834, 833, 835, 836, 837, 838, 839, 840, 808, 809, + 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, + 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, + 847, 846, 850, 851, 849, 848, 853, 852, 750, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, + 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, + 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 931, 932, 933, 934, 935, + 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, @@ -4398,12 +4269,12 @@ var yyAct = [...]int{ 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 0, 0, 194, 0, 0, + 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4413,9 +4284,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, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 397, 256, 0, 448, 0, 0, 1121, 616, 0, + 0, 0, 0, 0, 1118, 1119, 361, 1079, 328, 197, + 224, 1112, 1116, 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, @@ -4447,9 +4318,9 @@ var yyAct = [...]int{ 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 94, 449, 287, 637, 606, 601, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 2370, 0, 0, 2369, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, @@ -4462,21 +4333,21 @@ var yyAct = [...]int{ 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 1736, 0, 372, 568, 569, 314, 520, 0, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 1738, 0, 0, 0, 0, 269, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 1740, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 202, 408, 492, 285, 0, 0, 0, 0, 1680, 941, + 0, 0, 1677, 0, 0, 0, 0, 1675, 0, 237, + 1676, 1674, 244, 1679, 0, 906, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 1452, 0, - 1453, 1454, 0, 0, 0, 0, 0, 0, 0, 274, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4543,7 +4414,7 @@ var yyAct = [...]int{ 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, - 1717, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, @@ -4593,7 +4464,7 @@ var yyAct = [...]int{ 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, 94, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2377, 0, 0, 2376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, @@ -4606,21 +4477,21 @@ var yyAct = [...]int{ 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 511, 512, 513, 515, 391, 265, 428, 1741, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 1743, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 95, 0, 0, 0, 194, 0, 0, 0, 0, 0, + 0, 0, 0, 1745, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1453, 0, 1454, 1455, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4665,8 +4536,8 @@ var yyAct = [...]int{ 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 2370, 0, 0, - 2369, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, @@ -4678,672 +4549,744 @@ var yyAct = [...]int{ 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 2320, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, + 392, 372, 568, 569, 314, 86, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 95, 0, 1718, 0, 709, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 94, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 1919, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 95, 0, 0, 0, 194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 2318, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 1072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 0, 2377, 0, 0, 2376, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 2325, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 1924, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 1078, 328, - 197, 224, 1076, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 2320, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 1919, - 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 2323, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 1073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 1717, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 1079, 328, 197, 224, 1077, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 2325, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 1924, 194, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 3898, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 2080, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 1718, 0, 709, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 3905, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 2814, 709, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 2085, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 2799, 0, 0, 0, 0, 237, 0, - 0, 244, 2800, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 2821, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 1759, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 1758, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 2806, 0, + 0, 0, 0, 237, 0, 0, 244, 2807, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 711, 712, 713, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 1764, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 1763, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 711, 712, 713, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5351,71 +5294,71 @@ 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, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 4021, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 1919, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5423,288 +5366,288 @@ 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, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 4028, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 1924, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 3898, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 2371, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 3905, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 95, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 1740, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 2378, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 194, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5712,71 +5655,71 @@ 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, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 1745, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5784,72 +5727,72 @@ 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, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 2032, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 2023, 709, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5857,1379 +5800,1452 @@ 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, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 2037, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 1886, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 2028, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 1884, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 1891, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 1889, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 1882, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 1887, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 1880, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 1885, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 1878, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 1883, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 1874, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 1879, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 1872, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 1877, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 1870, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 1875, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 1845, 0, 0, 0, 709, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 1850, 0, 0, + 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 1744, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 1749, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, - 941, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 95, 0, 0, 0, 941, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 194, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1431, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 1430, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 0, 0, 0, 0, 1432, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 1431, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, - 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, - 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1030, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, + 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, + 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, + 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, + 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 397, 256, 0, 448, 0, 662, 0, 616, 0, 0, - 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, - 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, - 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, - 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, - 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, - 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, - 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, - 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 296, 0, 397, 256, 0, 448, 0, + 662, 0, 616, 0, 0, 0, 0, 0, 0, 0, + 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, + 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, - 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, - 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, - 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, - 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, - 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, - 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 4029, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, - 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, - 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, - 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, - 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, - 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, - 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, - 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 4036, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, - 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, - 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, - 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, - 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, - 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, - 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, - 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, - 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, - 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, - 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, - 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, - 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, - 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, - 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, - 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, - 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, - 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, - 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, - 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, - 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, - 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, - 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, - 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, - 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, - 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, - 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, - 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, - 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, - 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, - 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, - 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, - 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, - 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, - 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, - 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, - 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, - 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, - 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, - 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, - 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, + 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, + 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, + 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, + 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, + 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 941, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, + 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, + 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, + 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, + 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, + 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, + 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, + 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, + 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, + 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, + 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, + 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, + 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, + 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, + 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, + 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, - 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, - 0, 372, 568, 569, 314, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, + 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, + 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, + 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 0, 0, 372, 568, 569, 314, } var yyPact = [...]int{ - -1000, -1000, 1893, -1000, -532, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 6231, -1000, -531, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2350, 2400, -1000, -1000, -1000, -1000, 2535, -1000, 1002, + 1986, -1000, 2335, 4910, -1000, 54918, 503, -1000, 52030, -434, + 871, 236, 36146, -1000, 195, -1000, 184, 53474, 188, -1000, + -1000, -1000, -1000, -434, 21704, 2285, 57, 52, 54918, -1000, + -1000, -1000, -1000, -355, 2510, 1962, -1000, 415, -1000, -1000, + -1000, -1000, -1000, -1000, 51308, -1000, 1084, -1000, -1000, 2358, + 2349, 2259, 898, 2272, -1000, 2451, 1962, -1000, 21704, 2492, + 2407, 20982, 20982, 462, -1000, -1000, 315, -1000, -1000, 31092, + 54918, 39034, 306, -1000, 2335, -1000, -1000, -1000, 192, -1000, + 384, 1895, -1000, 1894, -1000, 892, 1017, 407, 875, 862, + 406, 395, 394, 389, 385, 381, 379, 361, 413, -1000, + 928, 928, -204, -208, 1319, 457, 449, 449, 1041, 476, + 2301, 2300, -1000, -1000, 928, 928, 928, 346, 928, 928, + 928, 928, 328, 327, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 860, 2335, 310, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2352, 2406, -1000, -1000, -1000, -1000, 2560, -1000, 1002, - 2052, -1000, 2357, 4901, -1000, 54763, 481, -1000, 51875, -434, - 853, 234, 35991, -1000, 198, -1000, 182, 53319, 191, -1000, - -1000, -1000, -1000, -434, 21549, 2291, 57, 53, 54763, -1000, - -1000, -1000, -1000, -357, 2521, 2031, -1000, 409, -1000, -1000, - -1000, -1000, -1000, -1000, 51153, -1000, 1082, -1000, -1000, 2364, - 2338, 2563, 912, 2292, -1000, 2456, 2031, -1000, 21549, 2510, - 2450, 20827, 20827, 430, -1000, -1000, 238, -1000, -1000, 30937, - 54763, 38879, 293, -1000, 2357, -1000, -1000, -1000, 219, -1000, - 336, 1947, -1000, 1943, -1000, 845, 896, 380, 478, 456, - 379, 359, 358, 356, 354, 349, 346, 344, 374, -1000, - 936, 936, -217, -218, 361, 425, 413, 413, 968, 458, - 2321, 2320, -1000, -1000, 936, 936, 936, 369, 936, 936, - 936, 936, 296, 295, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, - 936, 906, 2357, 274, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7275,67 +7291,67 @@ 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, + 54918, 181, 54918, -1000, 819, 495, -1000, -1000, -438, 1091, + 1091, 69, 1091, 1091, 1091, 1091, 186, 971, 50, -1000, + 185, 281, 173, 294, 1044, 321, -1000, -1000, 277, 1044, + 1769, -1000, 903, 286, 216, -1000, 1091, 1091, -1000, 14459, + 252, 14459, 14459, -1000, 2324, -1000, -1000, -1000, -1000, -1000, + 1341, -1000, -1000, -1000, -1000, -27, 475, -1000, -1000, -1000, + -1000, 53474, 50586, 275, -1000, -1000, 47, 1807, 1263, 21704, + 1256, 896, -1000, -1000, 1187, 873, -1000, -1000, -1000, -1000, + -1000, 522, -1000, 23870, 23870, 23870, 23870, -1000, -1000, 1897, + 49864, 1897, 1897, 23870, 1897, 23870, 1897, 1897, 1897, 21704, + 1897, 1897, 1897, 1897, -1000, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, -1000, -1000, -1000, -1000, 1897, 817, 1897, 1897, + 1897, 1897, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1897, 1897, 1897, 1897, 1897, 1897, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 54763, 181, 54763, -1000, 798, 480, -1000, -1000, -439, 1083, - 1083, 96, 1083, 1083, 1083, 1083, 186, 962, 50, -1000, - 176, 266, 171, 269, 1027, 319, -1000, -1000, 262, 1027, - 1736, -1000, 917, 264, 166, -1000, 1083, 1083, -1000, 14304, - 230, 14304, 14304, -1000, 2355, -1000, -1000, -1000, -1000, -1000, - 1361, -1000, -1000, -1000, -1000, -26, 454, -1000, -1000, -1000, - -1000, 53319, 50431, 233, -1000, -1000, 769, 1803, 1515, 21549, - 1254, 893, -1000, -1000, 1479, 858, -1000, -1000, -1000, -1000, - -1000, 508, -1000, 23715, 23715, 23715, 23715, -1000, -1000, 1788, - 49709, 1788, 1788, 23715, 1788, 23715, 1788, 1788, 1788, 21549, - 1788, 1788, 1788, 1788, -1000, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, -1000, -1000, -1000, -1000, 1788, 795, 1788, 1788, - 1788, 1788, 1788, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1788, 1788, 1788, 1788, 1788, 1788, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, -1000, + 26758, 1482, 1480, 1475, -1000, 18816, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 26603, 1518, 1512, 1506, -1000, 18661, 1788, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54918, -1000, 1897, + 217, 53474, 53474, 349, 1336, -1000, -1000, 2451, 1962, -1000, + 2510, 2462, 415, -1000, 3317, 1694, 1510, 1506, 1962, 1870, + 54918, -1000, 1913, -1000, -1000, -1000, -313, -318, 2197, 1471, + 1755, -1000, -1000, -1000, -1000, 2251, 21704, -1000, -1000, 2532, + -1000, 28203, 816, 2531, 49142, -1000, 462, 462, 1888, 428, + 33, -1000, -1000, -1000, -1000, 942, 35424, -1000, -1000, -1000, + -1000, -1000, 1766, 54918, -1000, -1000, 4141, 1347, -1000, 1985, + -1000, 1748, -1000, 1931, 21704, 1998, 493, 1347, 484, 483, + 482, -1000, -53, -1000, -1000, -1000, -1000, -1000, -1000, 928, + 928, 928, -1000, 387, 2490, 4910, 6412, -1000, -1000, -1000, + 48420, 1984, 1347, -1000, 1980, -1000, 1007, 869, 865, 865, + 1347, -1000, -1000, 54196, 1347, 1006, 1004, 1347, 1347, 53474, + 53474, -1000, 47698, -1000, 46976, 46254, 1328, 53474, 45532, 44810, + 44088, 43366, 42644, -1000, 2238, -1000, 2058, -1000, -1000, -1000, + 54196, 1347, 1347, 54196, 53474, 54196, 54918, 1347, -1000, -1000, + 338, -1000, -1000, 1320, 1308, 1305, 928, 928, 1291, 1742, + 1741, 1733, 928, 928, 1284, 1732, 37590, 1729, 269, 1283, + 1282, 1281, 1246, 1721, 193, 1712, 1245, 1229, 1279, 53474, + 1976, 54918, -1000, 262, 970, 935, 940, 2335, 2281, 1884, + 471, 492, 1347, 452, 452, 53474, -1000, 15187, 54918, 227, + -1000, 1665, 21704, -1000, 1054, 1044, 1044, -1000, -1000, -1000, + -1000, -1000, -1000, 1091, 54918, 1054, -1000, -1000, -1000, 1044, + 1091, 54918, 1091, 1091, 1091, 1091, 1044, 1044, 1044, 1091, + 54918, 54918, 54918, 54918, 54918, 54918, 54918, 54918, 54918, 14459, + 903, 1091, -440, -1000, 1663, -1000, -1000, -1000, 2117, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54763, -1000, 1788, - 216, 53319, 53319, 321, 1326, -1000, -1000, 2456, 2031, -1000, - 2521, 2488, 409, -1000, 3573, 1787, 1722, 1426, 2031, 1927, - 54763, -1000, 1966, -1000, -1000, -1000, -1000, 2204, 1507, 1734, - -1000, -1000, -1000, -1000, 1925, 21549, -1000, -1000, 2555, -1000, - 28048, 792, 2552, 48987, -1000, 430, 430, 1939, 421, 20, - -1000, -1000, -1000, -1000, 958, 35269, -1000, -1000, -1000, -1000, - -1000, 1870, 54763, -1000, -1000, 5319, 1353, -1000, 2044, -1000, - 1868, -1000, 1990, 21549, 2063, 477, 1353, 467, 465, 463, - -1000, -61, -1000, -1000, -1000, -1000, -1000, -1000, 936, 936, - 936, -1000, 343, 2505, 4901, 6077, -1000, -1000, -1000, 48265, - 2040, 1353, -1000, 2038, -1000, 1031, 859, 868, 868, 1353, - -1000, -1000, 54041, 1353, 1022, 1015, 1353, 1353, 53319, 53319, - -1000, 47543, -1000, 46821, 46099, 1319, 53319, 45377, 44655, 43933, - 43211, 42489, -1000, 2233, -1000, 2016, -1000, -1000, -1000, 54041, - 1353, 1353, 54041, 53319, 54041, 54763, 1353, -1000, -1000, 364, - -1000, -1000, 1308, 1307, 1306, 936, 936, 1292, 1731, 1728, - 1714, 936, 936, 1290, 1707, 37435, 1699, 270, 1289, 1270, - 1261, 1318, 1686, 229, 1674, 1281, 1264, 1252, 53319, 2032, - 54763, -1000, 254, 951, 435, 956, 2357, 2289, 1935, 453, - 474, 1353, 424, 424, 53319, -1000, 15032, 54763, 227, -1000, - 1670, 21549, -1000, 1043, 1027, 1027, -1000, -1000, -1000, -1000, - -1000, -1000, 1083, 54763, 1043, -1000, -1000, -1000, 1027, 1083, - 54763, 1083, 1083, 1083, 1083, 1027, 1027, 1027, 1083, 54763, - 54763, 54763, 54763, 54763, 54763, 54763, 54763, 54763, 14304, 917, - 1083, -440, -1000, 1659, -1000, -1000, -1000, 2157, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7350,328 +7366,328 @@ 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, 14459, 14459, -1000, -1000, + -1000, -1000, -1000, 1882, -1000, 174, 19, 187, -1000, 41922, + 518, 938, -1000, 518, -1000, -1000, -1000, 1875, 41200, -1000, + -441, -442, -448, -449, -1000, -1000, -1000, -451, -455, -1000, + -1000, -1000, 21704, 21704, 21704, 21704, -238, -1000, 1191, 23870, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21704, 251, 941, + 23870, 23870, 23870, 23870, 23870, 23870, 23870, 25314, 24592, 23870, + 23870, 23870, 23870, 23870, 23870, -1000, -1000, 33258, 3221, 3221, + 873, 873, 873, 873, -1000, -164, 1872, 54196, -1000, -1000, + -1000, 815, 21704, 21704, 873, -1000, 1347, 1289, 18816, 20982, + 20982, 21704, 945, 1263, 54196, 21704, -1000, 1506, -1000, -1000, + -1000, -1000, 1159, -1000, -1000, 1043, 2309, 2309, 2309, 2309, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 2309, 21704, 213, 213, 1731, 21704, 21704, 21704, 21704, 21704, + 21704, 17371, 21704, 21704, 23870, 21704, 21704, 21704, 1506, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 1506, 21704, + 1418, 21704, 21704, 21704, 21704, 21704, 21704, 20982, 16643, 20982, + 20982, 20982, 20982, 20982, -1000, -1000, -1000, -1000, -1000, -1000, + 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 1506, 21704, + 21704, 21704, 21704, 21704, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1545, 1520, 1459, 21704, -1000, 1871, + -1000, -184, 30370, 21704, 1633, 2528, 2014, 53474, -1000, -1000, + -1000, -1000, 2451, -1000, 2451, 1545, 3299, 2202, 20982, -1000, + -1000, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1740, -1000, 54918, 1870, 2402, 53474, -1000, -268, -1000, -274, + 2194, 1626, 341, -1000, 21704, 21704, 1867, -1000, 2124, 54918, + -1000, -238, -1000, 40478, -1000, -1000, 13731, 54918, 358, 54918, + -1000, 29648, 39756, 304, -1000, 33, 1854, -1000, 23, 12, + 18093, 866, -1000, -1000, -1000, 1319, 26036, 1785, 866, 116, + -1000, -1000, -1000, 1931, -1000, 1931, 1931, 1931, 1931, 341, + 341, 341, 341, -1000, -1000, -1000, -1000, -1000, 1974, 1972, + -1000, 1931, 1931, 1931, 1931, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 14304, 14304, -1000, -1000, -1000, - -1000, -1000, 1934, -1000, 184, 26, 189, -1000, 41767, 517, - 955, -1000, 517, -1000, -1000, -1000, 1933, 41045, -1000, -441, - -445, -446, -447, -1000, -1000, -1000, -450, -460, -1000, -1000, - -1000, 21549, 21549, 21549, 21549, -251, -1000, 1019, 23715, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 21549, 251, 1038, 23715, - 23715, 23715, 23715, 23715, 23715, 23715, 25159, 24437, 23715, 23715, - 23715, 23715, 23715, 23715, -1000, -1000, 33103, 6798, 6798, 858, - 858, 858, 858, -1000, -173, 1932, 54041, -1000, -1000, -1000, - 790, 21549, 21549, 858, -1000, 1353, 2945, 18661, 20827, 20827, - 21549, 963, 1515, 54041, 21549, -1000, 1426, -1000, -1000, -1000, - -1000, 1257, -1000, -1000, 1093, 2335, 2335, 2335, 2335, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 2335, - 21549, 908, 908, 1136, 21549, 21549, 21549, 21549, 21549, 21549, - 17216, 21549, 21549, 23715, 21549, 21549, 21549, 1426, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 1426, 21549, 1665, - 21549, 21549, 21549, 21549, 21549, 21549, 20827, 16488, 20827, 20827, - 20827, 20827, 20827, -1000, -1000, -1000, -1000, -1000, -1000, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 1426, 21549, 21549, - 21549, 21549, 21549, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1769, 1532, 1481, 21549, -1000, 1928, -1000, - -184, 30215, 21549, 1656, 2547, 2092, 53319, -1000, -1000, -1000, - -1000, 2456, -1000, 2456, 1769, 2727, 2207, 20827, -1000, -1000, - 2727, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1777, - -1000, 54763, 1927, 2393, 53319, 2198, 1652, 351, -1000, 21549, - 21549, 1923, -1000, 1601, 54763, -1000, -251, -1000, 40323, -1000, - -1000, 13576, 54763, 334, 54763, -1000, 29493, 39601, 268, -1000, - 20, 1878, -1000, 31, 9, 17938, 857, -1000, -1000, -1000, - 361, 25881, 1705, 857, 109, -1000, -1000, -1000, 1990, -1000, - 1990, 1990, 1990, 1990, 351, 351, 351, 351, -1000, -1000, - -1000, -1000, -1000, 2025, 2021, -1000, 1990, 1990, 1990, 1990, + -1000, -1000, 1969, 1969, 1969, 1967, 1967, 1949, 1949, 444, + -1000, 21704, 397, 39034, 2347, 1275, 1243, 262, 454, 2013, + 1347, 1347, 1347, 454, -1000, 1421, 1390, 1376, -1000, -509, + 1865, -1000, -1000, 2487, -1000, -1000, 905, 1050, 1042, 959, + 53474, 228, 348, -1000, 435, -1000, 39034, 1347, 994, 865, + 1347, -1000, 1347, -1000, -1000, -1000, -1000, -1000, 1347, -1000, + -1000, 1864, -1000, 1787, 1156, 1036, 1062, 987, 1864, -1000, + -1000, -173, 1864, -1000, 1864, -1000, 1864, -1000, 1864, -1000, + 1864, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 991, 300, -325, 53474, 228, 467, -1000, 466, 33258, -1000, + -1000, -1000, 33258, 33258, -1000, -1000, -1000, -1000, 1624, 1620, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2020, 2020, 2020, - 2019, 2019, 1995, 1995, 417, -1000, 21549, 415, 38879, 2362, - 1247, 1474, 254, 428, 2079, 1353, 1353, 1353, 428, -1000, - 1383, 1377, 1366, -1000, -518, 1919, -1000, -1000, 2504, -1000, - -1000, 940, 1048, 1047, 903, 53319, 220, 327, -1000, 408, - -1000, 38879, 1353, 1003, 868, 1353, -1000, 1353, -1000, -1000, - -1000, -1000, -1000, 1353, -1000, -1000, 1918, -1000, 1801, 1091, - 1044, 1077, 1030, 1918, -1000, -1000, -178, 1918, -1000, 1918, - -1000, 1918, -1000, 1918, -1000, 1918, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 979, 281, -325, 53319, 220, - 441, -1000, 439, 33103, -1000, -1000, -1000, 33103, 33103, -1000, - -1000, -1000, -1000, 1633, 1619, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -500, + 54918, -1000, 235, 936, 333, 318, 322, 54918, 226, 2441, + 2439, 2434, 2433, 2409, 250, 325, 54918, 54918, 452, 2074, + 54918, 2365, 54918, -1000, -1000, -1000, -1000, -1000, 1613, 1602, + -1000, 1263, 54918, -1000, -1000, 1091, 1091, -1000, -1000, 54918, + 1091, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1091, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -503, 54763, -1000, 240, 952, 283, - 306, 303, 54763, 420, 2419, 2408, 2405, 2400, 2397, 299, - 290, 54763, 54763, 424, 2130, 54763, 2376, 54763, -1000, -1000, - -1000, -1000, -1000, 1617, 1612, -1000, 1515, 54763, -1000, -1000, - 1083, 1083, -1000, -1000, 54763, 1083, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1083, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 54918, -1000, -1000, -1000, -1000, + -27, 170, -1000, -1000, 53474, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -105, -1000, 255, 16, 416, -1000, + -1000, -1000, -1000, -1000, 2421, -1000, 1263, 986, 976, -1000, + 1897, -1000, -1000, 1176, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 251, 23870, 23870, 23870, 1304, 822, 1410, 1456, + 1317, 904, 904, 1132, 23870, 1132, 23870, 877, 877, 877, + 877, 877, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1598, -1000, 1897, 54196, 1727, 16643, 1496, 2842, 1506, 890, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 54763, -1000, -1000, -1000, -1000, -26, 178, -1000, -1000, 53319, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -105, - -1000, 847, 24, 384, -1000, -1000, -1000, -1000, -1000, 2445, - -1000, 1515, 988, 976, -1000, 1788, -1000, -1000, 1135, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 251, 23715, 23715, - 23715, 1565, 485, 1224, 1315, 1155, 1133, 1133, 1097, 23715, - 1097, 23715, 862, 862, 862, 862, 862, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1605, -1000, 1788, 54041, 1826, - 16488, 1974, 2164, 1426, 870, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 4151, 1824, -1000, 1824, 1425, - 964, -1000, 21549, 1426, 4143, -1000, -1000, 1426, 1426, 21549, - -1000, -1000, 21549, 21549, 21549, 21549, 1474, 1474, 1474, 1474, - 1474, 1474, 1474, 1474, 1474, 1474, 21549, 1474, 1906, -1000, + 4252, 1711, -1000, 1711, 1805, 961, -1000, 21704, 1506, 4247, + -1000, -1000, 1506, 1506, 21704, -1000, -1000, 21704, 21704, 21704, + 21704, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 21704, 1243, 1863, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1900, 2544, 1352, - 1474, 1474, 1474, 1474, 1474, 21549, 1432, -1000, -1000, -1000, - 1434, 4139, 1116, 4135, 1474, 1474, -1000, 1474, 4126, 4116, - 1426, 1803, 2877, 2872, 1474, 1474, 1474, 1474, 1474, 2864, - 2803, 1474, 1474, 2722, 1474, 4112, 1474, 2681, 2658, 2645, - 2621, 2615, 2598, 2556, 2540, 2535, 2529, 2524, 2511, 2495, - 2491, 2468, 2453, 2449, 2429, 1474, 1474, 1474, 4093, 1474, - 3877, 1474, 3845, 1474, 1474, 3820, 2409, 2361, 1426, 1897, - -1000, 3813, 1474, 3808, 3804, 3526, 2351, 3515, 3477, 3449, - 1474, 1474, 1474, 2322, 3440, 3435, 3427, 3421, 3417, 3407, - 3403, 3378, 3370, 1474, 1481, 1481, 1481, 1481, 1481, 3361, - -267, 1474, 1426, -1000, -1000, -1000, -1000, -1000, 3347, 2316, - 3336, 3332, 3321, 3317, 1426, 1891, 1788, 761, -1000, -1000, - 1824, 1426, 1426, 1824, 1824, 3290, 3276, 3207, 3191, 3018, - 2997, 1474, 1474, -1000, 1474, 2960, 2940, 2312, 2304, 1426, - -1000, 1481, 54763, -1000, -431, -1000, 0, 933, 1788, -1000, - 37435, 1426, -1000, 4158, -1000, 1335, -1000, -1000, -1000, -1000, - -1000, 34547, 1752, 2727, -1000, -1000, 1788, 1791, -1000, -1000, - 351, 81, 33825, 852, 852, 127, 1515, 1515, 21549, -1000, - -1000, -1000, -1000, -1000, -1000, 542, 2527, 423, 1788, -1000, - 1883, 3286, -1000, -1000, -1000, 2386, 27326, -1000, -1000, 1788, - 1788, 54763, 1863, 1854, -1000, 537, -1000, 1359, 1878, 20, - 19, -1000, -1000, -1000, -1000, 1515, -1000, 1358, 337, 341, - -1000, 416, -1000, -1000, -1000, -1000, 2306, 102, -1000, -1000, - -1000, 365, 351, -1000, -1000, -1000, -1000, -1000, -1000, 1580, - 1580, -1000, -1000, -1000, -1000, -1000, 1241, -1000, -1000, -1000, - -1000, 1223, -1000, -1000, 1222, -1000, -1000, 2327, 2135, 415, - -1000, -1000, 936, 1566, -1000, -1000, 2293, 936, 936, 53319, - -1000, -1000, 1611, 2362, 240, 54763, 959, 2126, -1000, 2079, - 2079, 2079, 54763, -1000, -1000, -1000, -1000, -1000, -1000, -505, - 175, 583, -1000, -1000, -1000, 2009, 53319, 1785, -1000, 222, - -1000, 1549, -1000, 53319, -1000, 1768, 2015, 1353, 1353, -1000, - -1000, -1000, 53319, 1788, -1000, -1000, -1000, -1000, 473, 2347, - 353, -1000, -1000, -293, -1000, -1000, 220, 222, 54041, 1353, - 857, -1000, -1000, -1000, -1000, -1000, -506, 1759, 457, 217, - 563, 54763, 54763, 54763, 54763, 54763, 54763, 782, -1000, -1000, - 41, -1000, -1000, 207, -1000, -1000, -1000, -1000, 207, -1000, - -1000, -1000, -1000, 278, 432, -1000, 54763, 54763, 914, -1000, - -1000, -1000, -1000, -1000, 1027, -1000, -1000, 1027, -1000, -1000, + -1000, -1000, 1861, 2527, 1415, 1243, 1243, 1243, 1243, 1243, + 21704, 1783, -1000, -1000, -1000, 1527, 4196, 1225, 4190, 1243, + 1243, -1000, 1243, 4183, 4166, 1506, 1807, 2869, 2862, 1243, + 1243, 1243, 1243, 1243, 2812, 2741, 1243, 1243, 2685, 1243, + 4162, 1243, 2679, 2660, 2649, 2639, 2621, 2616, 2599, 2593, + 2589, 2581, 2577, 2572, 2516, 2499, 2495, 2491, 2486, 2469, + 1243, 1243, 1243, 4158, 1243, 4153, 1243, 4149, 1243, 1243, + 4143, 2456, 2452, 1506, 1858, -1000, 4133, 1243, 4124, 4119, + 4105, 2425, 4100, 3884, 3866, 1243, 1243, 1243, 2420, 3860, + 3852, 3831, 3827, 3823, 3818, 3810, 3498, 3484, 1243, 1459, + 1459, 1459, 1459, 1459, 3480, -240, 1243, 1506, -1000, -1000, + -1000, -1000, -1000, 3467, 2412, 3463, 3456, 3395, 3389, 1506, + 1855, 1897, 814, -1000, -1000, 1711, 1506, 1506, 1711, 1711, + 3385, 3376, 3356, 3303, 3255, 3185, 1243, 1243, -1000, 1243, + 3029, 3025, 2391, 2354, 1506, -1000, 1459, 54918, -1000, -431, + -1000, 4, 960, 1897, -1000, 37590, 1506, -1000, 4165, -1000, + 1157, -1000, -1000, -1000, -1000, -1000, 34702, 1782, 3299, -1000, + -1000, 1897, 1705, -1000, -1000, -1000, -1000, 341, 76, 33980, + 870, 870, 129, 1263, 1263, 21704, -1000, -1000, -1000, -1000, + -1000, -1000, 804, 2505, 400, 1897, -1000, 1788, 2093, -1000, + -1000, -1000, 2399, 27481, -1000, -1000, 1897, 1897, 54918, 1820, + 1790, -1000, 803, -1000, 1349, 1854, 33, 9, -1000, -1000, + -1000, -1000, 1263, -1000, 1358, 360, 1394, -1000, 439, -1000, + -1000, -1000, -1000, 2292, 88, -1000, -1000, -1000, 787, 341, + -1000, -1000, -1000, -1000, -1000, -1000, 1595, 1595, -1000, -1000, + -1000, -1000, -1000, 1274, -1000, -1000, -1000, -1000, 1273, -1000, + -1000, 1272, -1000, -1000, 2165, 2044, 397, -1000, -1000, 928, + 1581, -1000, -1000, 2295, 928, 928, 53474, -1000, -1000, 1662, + 2347, 235, 54918, 964, 2073, -1000, 2013, 2013, 2013, 54918, + -1000, -1000, -1000, -1000, -1000, -1000, -511, 165, 382, -1000, + -1000, -1000, 5045, 53474, 1703, -1000, 221, -1000, 1640, -1000, + 53474, -1000, 1701, 1965, 1347, 1347, -1000, -1000, -1000, 53474, + 1897, -1000, -1000, -1000, -1000, 490, 2330, 347, -1000, -1000, + -258, -1000, -1000, 228, 221, 54196, 1347, 866, -1000, -1000, + -1000, -1000, -1000, -503, 1697, 480, 222, 489, 54918, 54918, + 54918, 54918, 54918, 54918, 785, -1000, -1000, 35, -1000, -1000, + 198, -1000, -1000, -1000, -1000, 198, -1000, -1000, -1000, -1000, + 314, 458, -1000, 54918, 54918, 924, -1000, -1000, -1000, -1000, + -1000, 1044, -1000, -1000, 1044, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2315, 54918, 11, + -470, -1000, -467, 21704, -1000, -1000, -1000, -1000, 1149, 798, + 1410, 23870, 23870, 1289, 1289, 23870, -1000, -1000, -1000, 832, + 832, 33258, -1000, 23870, 21704, 20982, -1000, -1000, 21704, 21704, + 947, -1000, 21704, 1359, -1000, 21704, -1000, -1000, 1459, 1243, + 1243, 1243, 1243, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1789, -1000, 21704, 21704, 21704, 1506, 309, + -1000, -1000, -1000, -1000, -1000, 2521, -1000, 21704, -1000, 33258, + 21704, 21704, 21704, -1000, -1000, -1000, 21704, 21704, -1000, -1000, + 21704, -1000, 21704, -1000, -1000, -1000, -1000, -1000, -1000, 21704, + -1000, 21704, -1000, -1000, -1000, 21704, -1000, 21704, -1000, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, -1000, 21704, -1000, 21704, -1000, 21704, + -1000, 21704, 21704, -1000, 21704, 21704, 21704, -1000, 21704, 21704, + 21704, 21704, -1000, -1000, -1000, -1000, 21704, 21704, 21704, 21704, + 21704, 21704, 21704, 21704, 21704, 21704, -1000, -1000, -1000, -1000, + -1000, -1000, 21704, -1000, 39034, 53, -240, 1418, 53, 1418, + 23148, 823, 786, 22426, -1000, 20982, 15915, -1000, -1000, -1000, + -1000, -1000, 21704, 21704, 21704, 21704, 21704, 21704, -1000, -1000, + -1000, 21704, 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, + -1000, -1000, 960, -1000, 865, 865, 865, 53474, -1000, -1000, + -1000, -1000, 1848, -1000, 2438, -1000, 2232, 2224, 2520, 2505, + -1000, 29648, 3299, -1000, -1000, 53474, -419, -1000, 2273, 2240, + 870, 870, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13003, + 2451, 21704, 2072, 54196, 253, -1000, 28926, 53474, 54196, 29648, + 29648, 29648, 29648, 29648, -1000, 2103, 2101, -1000, 2133, 2125, + 2134, 54918, -1000, 1545, 1689, -1000, 21704, 31814, 1829, 29648, + -1000, -1000, 29648, 54918, 12275, -1000, -1000, 10, -3, -1000, + -1000, -1000, -1000, 1319, -1000, -1000, 927, 2386, 2283, -1000, + -1000, -1000, -1000, -1000, 1677, -1000, 1675, 1844, 1673, 1661, + 300, -1000, 1997, 2313, 928, 928, -1000, 1271, -1000, 1347, + 1564, 1560, -1000, -1000, -1000, 478, -1000, 2363, 54918, 2071, + 2070, 2054, -1000, -521, 1269, 1963, 1910, 21704, 1959, 2485, + 1832, 53474, -1000, -1000, 54196, -1000, 274, -1000, 397, 53474, + -1000, -1000, -1000, 348, 54918, -1000, 7141, -1000, -1000, -1000, + 221, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54918, 258, + -1000, 1955, 1195, -1000, -1000, 1990, -1000, -1000, -1000, -1000, + -1000, 223, 197, 1547, 201, 1524, 201, -1000, 54918, 921, + 2044, 54918, -1000, -1000, -1000, 1091, 1091, -1000, -1000, 2310, + -1000, 1347, 1243, 23870, 23870, -1000, 873, -1000, -1000, 419, + -216, 1931, 1931, -1000, 1931, 1949, -1000, 1931, 154, 1931, + 138, 1931, -1000, -1000, 1506, 1506, -1000, 1459, -1000, 2346, + 1114, -1000, 1263, 21704, 3020, -1000, -1000, -1000, -1000, -1000, + -60, 2979, 2963, 1243, -1000, 1929, 1927, 21704, 1243, 1506, + 2312, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1243, 2308, 2298, 2280, 2275, 2271, 2267, 2239, + 2211, 2198, 2189, 2056, 1994, 1981, 1977, 1946, 1915, 1243, + 1243, 1905, 1243, 1901, 1822, -1000, 1263, 1459, 2952, 1459, + 1243, 1243, 2915, 343, 1243, 1637, 1637, 1637, 1637, 1637, + 1459, 1459, 1459, 1459, 1243, 53474, -1000, -240, -1000, -1000, + -312, -316, -1000, 1506, -240, 1840, 23870, 1243, 23870, 23870, + 23870, 1243, 1506, -1000, 1814, 1791, 2892, 1754, 1243, 2746, + 1243, 1243, 1243, 1718, -1000, 2403, 2403, 2403, 1617, 1157, + 54918, -1000, -1000, -1000, -1000, 2505, 2459, 1834, -1000, -1000, + 76, 614, -1000, 2266, 2240, -1000, 2484, 2260, 2482, -1000, + -1000, -1000, -1000, -1000, 1263, -1000, 2339, 1804, -1000, 932, + 1812, -1000, -1000, 20260, 1631, 2210, 797, 1617, 1853, 2093, + 2007, 2048, 3006, -1000, -1000, -1000, -1000, 2092, -1000, 2068, + -1000, -1000, 1913, -1000, 2696, 358, 29648, 1851, 1851, -1000, + 537, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1063, 7141, + 2540, -1000, 1502, -1000, 1346, 205, 1250, -1000, -1000, 928, + 928, -1000, 993, 992, -1000, 54918, 1926, -1000, 341, 1498, + 341, 1234, -1000, -1000, 1233, -1000, -1000, -1000, -1000, 2055, + 2075, -1000, -1000, -1000, -1000, 54918, -1000, -1000, 54918, 54918, + 54918, 1923, 2478, -1000, 21704, 1922, 931, 2153, 53474, 53474, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2344, 54763, 15, -472, -1000, -469, 21549, -1000, -1000, -1000, - -1000, 1547, 484, 1224, 23715, 23715, 2945, 2945, 23715, -1000, - -1000, -1000, 1176, 1176, 33103, -1000, 23715, 21549, 20827, -1000, - -1000, 21549, 21549, 934, -1000, 21549, 1198, -1000, 21549, -1000, - -1000, 1481, 1474, 1474, 1474, 1474, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1858, -1000, 21549, 21549, - 21549, 1426, 304, -1000, -1000, -1000, -1000, -1000, 2543, -1000, - 21549, -1000, 33103, 21549, 21549, 21549, -1000, -1000, -1000, 21549, - 21549, -1000, -1000, 21549, -1000, 21549, -1000, -1000, -1000, -1000, - -1000, -1000, 21549, -1000, 21549, -1000, -1000, -1000, 21549, -1000, - 21549, -1000, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, -1000, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, -1000, 21549, -1000, - 21549, -1000, 21549, -1000, 21549, 21549, -1000, 21549, 21549, 21549, - -1000, 21549, 21549, 21549, 21549, -1000, -1000, -1000, -1000, 21549, - 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, 21549, -1000, - -1000, -1000, -1000, -1000, -1000, 21549, -1000, 38879, 58, -267, - 1665, 58, 1665, 22993, 805, 803, 22271, -1000, 20827, 15760, - -1000, -1000, -1000, -1000, -1000, 21549, 21549, 21549, 21549, 21549, - 21549, -1000, -1000, -1000, 21549, 21549, -1000, 21549, -1000, 21549, - -1000, -1000, -1000, -1000, -1000, 933, -1000, 868, 868, 868, - 53319, -1000, -1000, -1000, -1000, 1877, -1000, 2458, -1000, 2223, - 2219, 2539, 2527, -1000, 29493, 2727, -1000, -1000, 53319, -412, - -1000, 2258, 2253, 852, 852, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 12848, 2456, 21549, 2115, 54041, 249, -1000, 28771, - 53319, 54041, 29493, 29493, 29493, 29493, 29493, -1000, 2173, 2163, - -1000, 2190, 2154, 2216, 54763, -1000, 1769, 1741, -1000, 21549, - 31659, 1724, 29493, -1000, -1000, 29493, 54763, 12120, -1000, -1000, - 8, -11, -1000, -1000, -1000, -1000, 361, -1000, -1000, 1173, - 2383, 2297, -1000, -1000, -1000, -1000, -1000, 1721, -1000, 1712, - 1865, 1704, 1697, 281, -1000, 2060, 2339, 936, 936, -1000, - 1218, -1000, 1353, 1545, 1538, -1000, -1000, -1000, 436, -1000, - 2375, 54763, 2110, 2109, 2107, -1000, -515, 1213, 2011, 2014, - 21549, 2005, 2503, 1846, 53319, -1000, -1000, 54041, -1000, 294, - -1000, 415, 53319, -1000, -1000, -1000, 327, 54763, -1000, 8692, - -1000, -1000, -1000, 222, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 54763, 237, -1000, 2003, 1340, -1000, -1000, 2069, -1000, - -1000, -1000, -1000, -1000, 215, 213, 1536, 205, 1534, 205, - -1000, 54763, 907, 2135, 54763, -1000, -1000, -1000, 1083, 1083, - -1000, -1000, 2318, -1000, 1353, 1474, 23715, 23715, -1000, 858, - -1000, -1000, 520, -228, 1990, 1990, -1000, 1990, 1995, -1000, - 1990, 161, 1990, 159, 1990, -1000, -1000, 1426, 1426, -1000, - 1481, -1000, 2288, 1329, -1000, 1515, 21549, 2909, -1000, -1000, - -1000, -1000, -1000, -69, 2903, 2890, 1474, -1000, 1988, 1987, - 21549, 1474, 1426, 2280, 1474, 1474, 1474, 1474, 1474, 1474, - 1474, 1474, 1474, 1474, 1474, 1474, 2275, 2211, 2206, 2202, - 2185, 2175, 2111, 2105, 2093, 2089, 2085, 2076, 2062, 2055, - 2006, 1998, 1474, 1474, 1941, 1474, 1936, 1920, -1000, 1515, - 1481, 2843, 1481, 1474, 1474, 2834, 310, 1474, 1692, 1692, - 1692, 1692, 1692, 1481, 1481, 1481, 1481, 1474, 53319, -1000, - -267, -1000, -1000, -315, -316, -1000, 1426, -267, 1860, 23715, - 1474, 23715, 23715, 23715, 1474, 1426, -1000, 1894, 1861, 2689, - 1847, 1474, 2517, 1474, 1474, 1474, 1812, -1000, 2425, 2425, - 2425, 1640, 1335, 54763, -1000, -1000, -1000, -1000, 2527, 2519, - 1855, -1000, -1000, 81, 625, -1000, 2255, 2253, -1000, 2499, - 2272, 2496, -1000, -1000, -1000, -1000, -1000, 1515, -1000, 2353, - 1904, -1000, 950, 1819, -1000, -1000, 20105, 1683, 2210, 524, - 1640, 1881, 3286, 2084, 2106, 3001, -1000, -1000, -1000, -1000, - 2155, -1000, 2153, -1000, -1000, 1966, -1000, 2346, 334, 29493, - 1879, 1879, -1000, 518, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 1057, 8692, 2542, -1000, 1525, -1000, 1334, 209, 1199, - -1000, -1000, 936, 936, -1000, 997, 995, -1000, 54763, 1986, - -1000, 351, 1523, 351, 1181, -1000, -1000, 1180, -1000, -1000, - -1000, -1000, 1973, 2217, -1000, -1000, -1000, -1000, 54763, -1000, - -1000, 54763, 54763, 54763, 1984, 2494, -1000, 21549, 1982, 938, - 2181, 53319, 53319, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 429, 936, -486, 285, 284, 936, - 936, 936, -526, -1000, -1000, 1638, 1610, -1000, -182, -1000, - 21549, -1000, -1000, -1000, -1000, -1000, 1238, 1238, 1518, 1512, - 1506, -1000, 1966, -1000, -1000, -1000, 1544, -1000, -1000, -187, - 53319, 53319, 53319, 53319, -1000, -1000, -1000, 1148, -1000, -1000, + -1000, 456, 928, -484, 320, 311, 928, 928, 928, -525, + -1000, -1000, 1610, 1577, -1000, -190, -1000, 21704, -1000, -1000, + -1000, -1000, -1000, 1241, 1241, 1482, 1480, 1475, -1000, 1913, + -1000, -1000, -1000, 1632, -1000, -1000, -180, 53474, 53474, 53474, + 53474, -1000, -1000, -1000, 1100, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 873, 1506, 345, + -189, 1506, -1000, -1000, 341, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 21704, -1000, 21704, -1000, 1263, + 21704, 2451, 1469, 21704, 21704, -1000, 1230, 1213, 1243, -1000, + -1000, -1000, 21704, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, + 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, 21704, + -1000, -1000, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, + -1000, 21704, 234, 832, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1506, 351, -1000, -1000, -1000, + -1000, 2515, -1000, 1506, 21704, 1289, -1000, 1289, 1289, 1289, + -1000, -1000, -1000, 21704, -1000, 21704, 21704, -1000, 21704, -1000, + 21704, -1000, -1000, -1000, -1000, 21704, 1897, 2294, 1897, 1897, + 31814, -1000, -1000, 2459, 2501, 2473, 2237, 2245, 2245, 2266, + -1000, 2467, 2458, -1000, 1466, 2457, 1452, 975, -1000, 54196, + 21704, 253, -1000, 404, 53474, 253, 53474, -1000, 2498, -1000, + -1000, 21704, 1921, -1000, 21704, -1000, -1000, -1000, -1000, 3221, + 2505, 1851, -1000, -1000, 884, -1000, 21704, -1000, 9991, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1441, 1436, -1000, + -1000, 1920, 21704, -1000, -1000, -1000, 1611, 1578, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1913, -1000, -1000, -1000, + -1000, 348, -516, 2118, 53474, 1190, -1000, 1575, 1832, 337, + 253, 1434, 928, 928, 928, 1122, 1105, 37590, 1571, -1000, + 53474, 429, -1000, 348, -1000, -209, -213, 1243, -1000, -1000, + 2378, -1000, -1000, 15915, -1000, -1000, 1908, 2003, -1000, -1000, + -1000, -1000, 2167, -167, -198, -1000, -1000, 1243, 1243, 2161, + 1506, -1000, 1243, 1243, 1572, 1553, -1000, 1243, 1243, 1243, + 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1459, 1685, -1000, + 234, 1506, 2041, -1000, -1000, 3221, -1000, -1000, 2498, 2455, + 53, -1000, -1000, 240, 53, 1263, 968, 1506, 1506, 968, + 1639, 1243, 1629, 1569, 1243, 1243, 32536, -1000, 2454, 2442, + 38312, 38312, 960, 2501, -248, 21704, 21704, 2214, 1214, -1000, + -1000, -1000, -1000, 1426, 1407, -1000, 1404, -1000, 2538, -1000, + 1263, -1000, 253, -1000, 526, 1812, -1000, 2451, 1263, 53474, + 1263, 73, 2498, -1000, 1243, -1000, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, + 1897, 1897, 1897, 1897, 1897, -1000, -1000, 53474, 1987, -1000, + -1000, 2377, 1552, 163, -1000, 1511, 1832, -1000, -1000, 220, + -1000, 21704, -1000, 37590, 1378, 1363, -1000, -1000, -1000, -1000, + -525, -1000, -1000, -1000, -1000, -1000, -1000, 415, 1830, -1000, + 918, 53474, 54918, -1000, 2128, -1000, -1000, -1000, 21704, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 858, 1426, 345, -195, 1426, -1000, -1000, 351, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, -1000, - 21549, -1000, 1515, 21549, 2456, 1470, 21549, 21549, -1000, 1162, - 1144, 1474, -1000, -1000, -1000, 21549, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, -1000, 21549, -1000, -1000, -1000, 21549, -1000, 21549, -1000, - 21549, -1000, -1000, -1000, 21549, 204, 1176, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1426, 333, - -1000, -1000, -1000, -1000, 2538, -1000, 1426, 21549, 2945, -1000, - 2945, 2945, 2945, -1000, -1000, -1000, 21549, -1000, 21549, 21549, - -1000, 21549, -1000, 21549, -1000, -1000, -1000, -1000, 21549, 1788, - 2313, 1788, 1788, 31659, -1000, -1000, 2519, 2516, 2493, 2234, - 2240, 2240, 2255, -1000, 2486, 2482, -1000, 1458, 2472, 1456, - 991, -1000, 54041, 21549, 249, -1000, 419, 53319, 249, 53319, - -1000, 2459, -1000, -1000, 21549, 1977, -1000, 21549, -1000, -1000, - -1000, -1000, 6798, 2527, 1879, -1000, -1000, 869, -1000, 21549, - -1000, 10160, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1453, 1445, -1000, -1000, 1968, 21549, -1000, -1000, -1000, 1533, - 1511, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1966, - -1000, -1000, -1000, -1000, 327, -510, 2048, 53319, 1129, -1000, - 1578, 1846, 307, 249, 1406, 936, 936, 936, 1128, 1120, - 37435, 1576, -1000, 53319, 399, -1000, 327, -1000, -219, -220, - 1474, -1000, -1000, 2382, -1000, -1000, 15760, -1000, -1000, 1964, - 2074, -1000, -1000, -1000, -1000, 2183, -176, -208, -1000, -1000, - 1474, 1474, 1623, 1426, -1000, 1474, 1474, 1482, 1475, -1000, - 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, - 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, - 1481, 1750, -1000, 204, 1426, 2103, -1000, -1000, 6798, -1000, - -1000, 2459, 2470, 58, -1000, -1000, 236, 58, 1515, 987, - 1426, 1426, 987, 1685, 1474, 1680, 1608, 1474, 1474, 32381, - -1000, 2465, 2463, 38157, 38157, 933, 2516, -281, 21549, 21549, - 2227, 1142, -1000, -1000, -1000, -1000, 1403, 1401, -1000, 1387, - -1000, 2537, -1000, 1515, -1000, 249, -1000, 516, 1819, -1000, - 2456, 1515, 53319, 1515, 77, 2459, -1000, 1474, -1000, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, - 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, -1000, -1000, - 53319, 1907, -1000, -1000, 2381, 1574, 165, -1000, 1469, 1846, - -1000, -1000, 247, -1000, 21549, -1000, 37435, 1385, 1380, -1000, - -1000, -1000, -1000, -526, -1000, -1000, -1000, -1000, -1000, -1000, - 409, 1837, -1000, 931, 53319, 54763, -1000, 2161, -1000, -1000, - -1000, 21549, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21549, - -1000, 1426, 2099, -1000, -358, -1000, -490, 21549, -267, -1000, - -1000, -267, -1000, -1000, -1000, -1000, -1000, 21549, -1000, -1000, - 21549, -1000, 21549, -1000, -1000, 1571, -1000, -1000, -1000, -1000, - -1000, 1571, 1571, -1000, -281, -1000, 1832, -1000, 53319, 1515, - 1803, -1000, 1140, -1000, -1000, -1000, -1000, -1000, 54041, 1819, - 53319, -1000, 1548, 1426, 1788, 2456, -1000, 1543, -1000, 409, - -1000, 1952, 2014, -1000, -1000, -1000, 19383, -1000, -1000, -1000, - -1000, -1000, 267, -186, 15760, 11392, 1510, -1000, -180, 1474, - 1481, -1000, -462, -1000, -1000, -1000, -1000, 291, -1000, -1000, - 1803, -1000, -1000, 1461, 1419, 1357, 36713, -1000, -1000, -1000, - -1000, -281, -1000, -1000, 2380, -1000, -1000, 1766, -1000, -1000, - 31659, 52597, -1000, -171, 338, -186, 21549, 1951, 1426, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -34, -1000, -1000, - 501, -1000, -1000, -1000, 2069, -199, -1000, -1000, -1000, 318, - -475, -287, -292, 23715, -1000, 21549, -1000, 21549, -1000, 21549, - -1000, -1000, -1000, 53319, 1788, -1000, 1468, -1000, 4863, -326, - 2098, -1000, -92, -1000, -1000, -1000, 1051, 1336, -1000, -1000, - -1000, -1000, -1000, -1000, 1902, 53319, -1000, 366, -1000, -1000, - 15032, -187, -209, 972, -1000, -1000, -1000, -1000, -1000, 2945, - 1312, 1295, 1474, -1000, 53319, -1000, 52597, -321, 857, 6798, - -1000, 2086, 2026, 2532, -1000, -1000, -1000, -1000, -1000, -1000, - -529, 1442, 239, -1000, -1000, -1000, 318, -298, -1000, 21549, - -1000, 21549, -1000, 1426, -1000, -1000, 2369, 77, -1000, 2534, - -1000, 2497, 1021, 1021, -1000, 1089, -529, -1000, -1000, -1000, - -1000, 1474, 1474, -1000, -327, -1000, -1000, -1000, -1000, -1000, - 405, 1175, -1000, -1000, -1000, -1000, -1000, 6798, -1000, -1000, - -1000, 263, 263, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 21704, -1000, 1506, 2034, + -1000, -344, -1000, -488, 21704, -240, -1000, -1000, -240, -1000, + -1000, -1000, -1000, -1000, 21704, -1000, -1000, 21704, -1000, 21704, + -1000, -1000, 1529, -1000, -1000, -1000, -1000, -1000, 1529, 1529, + -1000, -248, -1000, 1824, -1000, 53474, 1263, 1807, -1000, 1153, + -1000, -1000, -1000, -1000, -1000, 54196, 1812, 53474, -1000, 1519, + 1506, 1897, 2451, -1000, 1479, -1000, 415, -1000, 1900, 1910, + -1000, -1000, -1000, 19538, -1000, -1000, -1000, -1000, -1000, 276, + -176, 15915, 11547, 1474, -1000, -174, 1243, 1459, -1000, -460, + -1000, -1000, -1000, -1000, 289, -1000, -1000, 1807, -1000, -1000, + 1509, 1505, 1461, 36868, -1000, -1000, -1000, -1000, -248, -1000, + -1000, 2373, -1000, -1000, 1803, -1000, -1000, 31814, 52752, -1000, + -162, 352, -176, 21704, 1899, 1506, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -34, -1000, -1000, 506, -1000, -1000, + -1000, 1990, -195, -1000, -1000, -1000, 296, -473, -264, -294, + 23870, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, + 53474, 1897, -1000, 1450, -1000, 1883, -336, 2033, -1000, -103, + -1000, -1000, -1000, 1052, 1360, -1000, -1000, -1000, -1000, -1000, + -1000, 1513, 53474, -1000, 441, -1000, -1000, 15187, -180, -200, + 967, -1000, -1000, -1000, -1000, -1000, 1289, 1447, 1285, 1243, + -1000, 53474, -1000, 52752, -340, 866, 3221, -1000, 2018, 2017, + 2511, -1000, -1000, -1000, -1000, -1000, -1000, -527, 1431, 260, + -1000, -1000, -1000, 296, -296, -1000, 21704, -1000, 21704, -1000, + 1506, -1000, -1000, 2362, 73, -1000, 2537, -1000, 2512, 1022, + 1022, -1000, 1092, -527, -1000, -1000, -1000, -1000, 1243, 1243, + -1000, -337, -1000, -1000, -1000, -1000, -1000, 436, 1155, -1000, + -1000, -1000, -1000, -1000, 3221, -1000, -1000, -1000, 264, 264, + -1000, -1000, } var yyPgo = [...]int{ - 0, 3155, 3154, 28, 6, 41, 35, 3152, 3138, 3136, - 177, 3135, 3131, 3130, 3128, 3127, 3126, 2601, 2585, 2578, - 3123, 3121, 3109, 3108, 3105, 3104, 3101, 3098, 3097, 39, - 106, 68, 99, 204, 213, 3096, 176, 166, 198, 3093, - 3092, 3091, 116, 192, 83, 82, 195, 3089, 3088, 74, - 3087, 3084, 3081, 185, 184, 183, 1030, 3077, 182, 112, - 48, 3076, 3073, 3066, 3064, 3062, 3061, 3055, 3054, 3053, - 3047, 3044, 3042, 3041, 3040, 3037, 3036, 3034, 3031, 296, - 3029, 3027, 21, 3026, 76, 3025, 3024, 3023, 3018, 3013, - 11, 3010, 3009, 26, 44, 3008, 3005, 47, 2999, 2998, - 2995, 2984, 2980, 69, 2979, 22, 2975, 40, 2972, 2967, - 121, 2963, 2962, 2958, 43, 2957, 2956, 2955, 29, 167, - 2954, 2951, 139, 2950, 2949, 2948, 165, 206, 2947, 2255, - 215, 108, 111, 2928, 2925, 103, 188, 2916, 123, 2915, - 2914, 2910, 150, 2908, 3192, 2900, 2899, 64, 70, 199, - 2897, 2896, 163, 66, 8, 16, 17, 2895, 2893, 63, - 73, 2890, 101, 2886, 2885, 104, 84, 2884, 90, 98, - 2883, 2882, 5, 7, 2880, 1, 4, 2, 80, 2879, - 2878, 115, 2877, 2874, 2872, 95, 2869, 2866, 4205, 2863, - 85, 128, 102, 62, 2861, 171, 131, 2859, 2858, 2857, - 2855, 2851, 49, 2850, 2849, 2848, 138, 251, 162, 2846, - 144, 337, 52, 143, 2845, 189, 77, 197, 190, 2826, - 2825, 135, 133, 2822, 2819, 55, 164, 191, 2818, 94, - 127, 117, 168, 91, 130, 2816, 2813, 56, 60, 2809, - 2806, 2804, 2803, 174, 2802, 2796, 59, 2790, 54, 2789, - 186, 2784, 136, 79, 2783, 170, 169, 2782, 61, 2781, - 2780, 65, 96, 100, 38, 2779, 158, 161, 125, 172, - 2776, 2775, 53, 2774, 2773, 2772, 196, 292, 2771, 2768, - 294, 178, 141, 147, 89, 2767, 299, 2765, 2762, 13, - 4392, 7332, 2760, 37, 160, 2759, 2756, 7030, 20, 45, - 24, 2754, 205, 2749, 2745, 2744, 2742, 238, 202, 110, - 159, 57, 2737, 2736, 2735, 36, 2732, 2731, 2724, 2723, - 2722, 2708, 72, 34, 33, 32, 212, 58, 19, 97, - 153, 152, 67, 2707, 2706, 2705, 124, 87, 2702, 157, - 155, 120, 129, 2701, 180, 142, 119, 2697, 93, 31, - 2694, 2692, 2689, 2684, 92, 2681, 2679, 2676, 2674, 151, - 146, 118, 78, 2670, 81, 114, 149, 145, 51, 2665, - 46, 2663, 2661, 30, 193, 23, 2658, 15, 105, 109, - 2656, 6221, 181, 2655, 9, 298, 148, 2650, 2647, 10, - 12, 18, 2646, 2640, 2639, 2636, 132, 2632, 2630, 2626, - 2622, 27, 50, 25, 14, 113, 75, 2621, 2616, 140, - 2615, 2614, 2594, 0, 1005, 126, 2586, 207, + 0, 3091, 3090, 28, 6, 41, 35, 3089, 3088, 3087, + 177, 3086, 3085, 3082, 3081, 3078, 3071, 2619, 2615, 2586, + 3069, 3064, 3061, 3060, 3054, 3053, 3052, 3050, 3049, 40, + 108, 62, 97, 209, 197, 3048, 179, 165, 200, 3047, + 3045, 3043, 118, 192, 80, 85, 193, 3042, 3039, 73, + 3038, 3037, 3036, 191, 186, 184, 1048, 3031, 183, 112, + 48, 3030, 3027, 3026, 3025, 3022, 3021, 3020, 3019, 3017, + 3016, 3015, 3014, 3013, 3010, 3000, 2992, 2991, 2990, 284, + 2989, 2986, 21, 2981, 76, 2979, 2976, 2973, 2971, 2970, + 8, 2969, 2968, 26, 42, 2966, 2964, 47, 2963, 2962, + 2960, 2959, 2933, 69, 2932, 22, 2929, 39, 2928, 2926, + 120, 2924, 2923, 2921, 44, 2918, 2917, 2914, 29, 163, + 2913, 2912, 134, 2910, 2908, 2907, 167, 206, 2898, 2232, + 180, 105, 103, 2897, 2892, 98, 194, 2890, 117, 2885, + 2880, 2879, 147, 2876, 3197, 2875, 2872, 60, 66, 199, + 2869, 2868, 287, 64, 11, 16, 17, 2865, 2861, 61, + 72, 2859, 104, 2858, 2857, 100, 75, 2856, 96, 99, + 2855, 2854, 5, 7, 2853, 1, 4, 2, 83, 2852, + 2833, 113, 2831, 2826, 2823, 91, 2817, 2815, 4988, 2813, + 89, 127, 101, 82, 2811, 172, 155, 2810, 2809, 2808, + 2807, 2805, 49, 2801, 2798, 2797, 132, 250, 162, 2796, + 145, 335, 52, 143, 2795, 189, 77, 198, 170, 2794, + 2790, 130, 128, 2788, 2787, 56, 166, 190, 2786, 95, + 126, 115, 168, 90, 131, 2783, 2780, 54, 71, 2778, + 2777, 2776, 2775, 176, 2772, 2771, 59, 2770, 55, 2769, + 164, 2766, 136, 68, 2765, 171, 175, 2762, 135, 2754, + 2753, 67, 93, 110, 38, 2752, 158, 161, 124, 173, + 2751, 2747, 53, 2744, 2743, 2740, 195, 289, 2734, 2730, + 294, 178, 139, 146, 81, 2725, 337, 2722, 2718, 13, + 4343, 7480, 2716, 37, 160, 2713, 2711, 6837, 20, 45, + 24, 2708, 205, 2707, 2706, 2703, 2702, 212, 202, 106, + 159, 57, 2701, 2697, 2696, 36, 2694, 2693, 2690, 2686, + 2685, 2684, 70, 34, 33, 32, 211, 58, 19, 94, + 153, 152, 63, 2680, 2679, 2676, 121, 84, 2675, 157, + 154, 123, 151, 2673, 181, 142, 116, 2672, 92, 31, + 2671, 2668, 2667, 2663, 87, 2662, 2655, 2652, 2651, 149, + 140, 119, 78, 2650, 79, 114, 144, 141, 51, 2649, + 46, 2646, 2645, 30, 188, 23, 2640, 15, 102, 109, + 2636, 5948, 187, 2632, 9, 317, 156, 2630, 2627, 10, + 12, 18, 2624, 2623, 2621, 2617, 129, 2608, 2607, 2606, + 2600, 27, 50, 25, 14, 111, 74, 2590, 2578, 137, + 2577, 2570, 2561, 0, 1005, 125, 2559, 207, } -//line sql.y:8579 +//line sql.y:8599 type yySymType struct { union any empty struct{} @@ -8508,16 +8524,17 @@ var yyR1 = [...]int{ 233, 49, 49, 49, 49, 49, 44, 44, 44, 44, 45, 45, 45, 45, 136, 136, 136, 136, 138, 138, 137, 137, 82, 82, 83, 83, 83, 142, 142, 143, - 143, 143, 140, 140, 141, 141, 250, 250, 234, 234, - 234, 241, 241, 241, 237, 237, 239, 239, 239, 240, - 240, 240, 238, 247, 247, 249, 249, 248, 248, 244, - 244, 245, 245, 246, 246, 246, 242, 242, 199, 199, - 199, 199, 199, 251, 251, 251, 251, 263, 263, 210, - 210, 212, 212, 211, 211, 161, 264, 264, 272, 269, - 269, 270, 270, 296, 296, 296, 273, 273, 286, 286, - 282, 282, 283, 283, 276, 276, 288, 288, 288, 77, - 208, 208, 365, 365, 362, 291, 291, 293, 293, 297, - 297, 301, 301, 298, 298, 8, 410, 410, 410, 289, + 143, 143, 140, 140, 141, 141, 250, 250, 250, 250, + 250, 250, 250, 234, 234, 234, 241, 241, 241, 237, + 237, 239, 239, 239, 240, 240, 240, 238, 247, 247, + 249, 249, 248, 248, 244, 244, 245, 245, 246, 246, + 246, 242, 242, 199, 199, 199, 199, 199, 251, 251, + 251, 251, 263, 263, 210, 210, 212, 212, 211, 211, + 161, 264, 264, 272, 269, 269, 270, 270, 296, 296, + 296, 273, 273, 286, 286, 282, 282, 283, 283, 276, + 276, 288, 288, 288, 77, 208, 208, 365, 365, 362, + 291, 291, 293, 293, 297, 297, 301, 301, 298, 298, + 8, 410, 410, 410, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, @@ -8532,8 +8549,7 @@ var yyR1 = [...]int{ 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, + 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, @@ -8579,7 +8595,8 @@ var yyR1 = [...]int{ 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 290, 413, 414, 307, 308, 308, 308, + 290, 290, 290, 290, 290, 290, 290, 290, 413, 414, + 307, 308, 308, 308, } var yyR2 = [...]int{ @@ -8735,16 +8752,17 @@ var yyR2 = [...]int{ 4, 0, 2, 2, 1, 1, 3, 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, 1, 0, 1, 2, 4, 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, 4, 1, 1, 3, 3, 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, 3, 0, 1, 1, 1, + 3, 2, 1, 1, 0, 1, 2, 3, 4, 2, + 3, 4, 4, 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, 4, + 1, 1, 3, 3, 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, + 3, 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, @@ -8806,7 +8824,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, 1, 0, 0, 1, 1, + 0, 0, 1, 1, } var yyChk = [...]int{ @@ -8913,56 +8931,56 @@ var yyChk = [...]int{ 216, 217, 218, 219, 220, 221, 45, 398, 398, -188, -79, -79, -79, -79, -410, 703, 579, -227, -127, -229, -33, -31, -413, 9, -79, -31, -32, -30, -36, -38, - 605, -37, -297, 100, -234, -250, 13, 163, 43, 51, - -232, -233, -34, -31, -144, 20, 24, 25, -132, 170, - -144, -297, -132, -276, 244, -79, -79, -265, -310, 317, - -267, 413, 686, 412, -257, -270, 91, -256, -269, 411, - 92, -351, 160, -337, -341, -291, 255, -367, 251, -188, - -360, -359, -291, -413, -128, -286, 241, 249, 248, 137, - -385, 140, 297, 425, 239, -53, -54, -55, -269, 178, - 706, -110, 272, 276, 88, 88, -341, -340, -339, -386, - 276, 255, -366, -358, 247, 256, -347, 248, 249, -342, - 241, 138, -386, -342, 246, 256, 251, 255, 276, 276, - 127, 276, 127, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 271, -348, 152, -348, 582, 582, -354, -386, - 251, 241, -386, -386, 247, -288, -342, 243, 26, 243, - 36, 36, -348, -348, -348, -269, 178, -348, -348, -348, - -348, 284, 284, -348, -348, -348, -348, -348, -348, -348, + 605, -37, -297, 100, -234, -250, 13, 62, 163, 43, + 51, -232, -233, -34, -31, -144, 20, 24, 25, -132, + 170, -144, -297, -132, -276, 244, -79, -79, -265, -310, + 317, -267, 413, 686, 412, -257, -270, 91, -256, -269, + 411, 92, -351, 160, -337, -341, -291, 255, -367, 251, + -188, -360, -359, -291, -413, -128, -286, 241, 249, 248, + 137, -385, 140, 297, 425, 239, -53, -54, -55, -269, + 178, 706, -110, 272, 276, 88, 88, -341, -340, -339, + -386, 276, 255, -366, -358, 247, 256, -347, 248, 249, + -342, 241, 138, -386, -342, 246, 256, 251, 255, 276, + 276, 127, 276, 127, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 271, -348, 152, -348, 582, 582, -354, + -386, 251, 241, -386, -386, 247, -288, -342, 243, 26, + 243, 36, 36, -348, -348, -348, -269, 178, -348, -348, + -348, -348, 284, 284, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, - 240, -385, -136, 409, 304, 82, -56, 286, -39, -188, - -286, 241, 242, -385, 273, -188, 223, 240, 689, -280, - 160, 16, -280, -277, 398, 396, 383, 388, -280, -280, - -280, -280, 287, 381, -343, 241, 36, 252, 398, 287, - 381, 287, 288, 287, 288, 391, 401, 287, -302, 15, - 163, 425, 386, 390, 280, 240, 281, 242, 400, 288, - -302, 90, -281, 160, 287, 398, 392, 283, -280, -280, - -308, -413, -293, -291, -289, 232, 24, 143, 26, 28, - 146, 179, 130, 20, 147, 38, 234, 347, 251, 178, - 247, 470, 227, 73, 586, 426, 433, 424, 432, 436, - 472, 473, 425, 384, 32, 14, 588, 29, 261, 25, - 39, 172, 229, 150, 589, 264, 27, 262, 118, 121, - 591, 23, 76, 256, 15, 249, 41, 17, 592, 593, - 18, 245, 244, 163, 241, 71, 12, 222, 30, 159, - 67, 594, 138, 133, 595, 596, 597, 598, 131, 69, - 160, 21, 726, 434, 435, 34, 687, 574, 275, 174, - 74, 60, 688, 144, 430, 599, 600, 119, 601, 122, - 77, 693, 140, 19, 72, 43, 602, 276, 603, 246, - 727, 604, 416, 605, 161, 230, 469, 70, 162, 700, - 606, 701, 239, 397, 9, 474, 33, 260, 248, 129, - 68, 440, 607, 240, 149, 243, 132, 120, 8, 137, - 35, 13, 75, 78, 437, 438, 439, 58, 128, 578, - 148, 16, 608, 417, 142, -381, 689, -308, -308, 33, - 92, -407, -408, -409, 578, 416, 243, -291, -188, -85, - 679, 231, -86, 685, 24, 238, -134, 398, -122, 179, - 707, 690, 691, 692, 689, 395, 697, 695, 693, 287, - 694, 88, 140, 142, 143, 4, -144, 159, -198, 152, - 153, 154, 155, 156, 157, 158, 164, 163, 144, 146, - 160, -243, 141, 165, 166, 167, 168, 169, 170, 171, - 173, 172, 174, 175, 161, 162, 178, 225, 226, -152, - -152, -152, -152, -213, -219, -218, -413, -215, -381, -290, - -297, -413, -413, -152, -275, -413, -149, -413, -413, -413, - -413, -222, -144, -413, -413, -417, -413, -417, -417, -417, - -326, -413, -326, -326, -413, -413, -413, -413, -413, -413, + -348, 240, -385, -136, 409, 304, 82, -56, 286, -39, + -188, -286, 241, 242, -385, 273, -188, 223, 240, 689, + -280, 160, 16, -280, -277, 398, 396, 383, 388, -280, + -280, -280, -280, 287, 381, -343, 241, 36, 252, 398, + 287, 381, 287, 288, 287, 288, 391, 401, 287, -302, + 15, 163, 425, 386, 390, 280, 240, 281, 242, 400, + 288, -302, 90, -281, 160, 287, 398, 392, 283, -280, + -280, -308, -413, -293, -291, -289, 232, 24, 143, 26, + 28, 146, 179, 130, 20, 147, 38, 234, 347, 251, + 178, 247, 470, 227, 73, 586, 426, 433, 424, 432, + 436, 472, 473, 425, 384, 32, 14, 588, 29, 261, + 25, 39, 172, 229, 150, 589, 264, 27, 262, 118, + 121, 591, 23, 76, 256, 15, 249, 41, 17, 592, + 593, 18, 245, 244, 163, 241, 71, 12, 222, 30, + 159, 67, 594, 138, 133, 595, 596, 597, 598, 131, + 69, 160, 21, 726, 434, 435, 34, 687, 574, 275, + 174, 74, 60, 688, 144, 430, 599, 600, 119, 601, + 122, 77, 693, 140, 19, 72, 43, 602, 276, 603, + 246, 727, 604, 416, 605, 161, 230, 469, 70, 162, + 700, 606, 701, 239, 397, 9, 474, 33, 260, 248, + 129, 68, 440, 607, 240, 149, 243, 132, 120, 8, + 137, 35, 13, 75, 78, 437, 438, 439, 58, 128, + 578, 148, 16, 608, 417, 142, -381, 689, -308, -308, + 33, 92, -407, -408, -409, 578, 416, 243, -291, -188, + -85, 679, 231, -86, 685, 24, 238, -134, 398, -122, + 179, 707, 690, 691, 692, 689, 395, 697, 695, 693, + 287, 694, 88, 140, 142, 143, 4, -144, 159, -198, + 152, 153, 154, 155, 156, 157, 158, 164, 163, 144, + 146, 160, -243, 141, 165, 166, 167, 168, 169, 170, + 171, 173, 172, 174, 175, 161, 162, 178, 225, 226, + -152, -152, -152, -152, -213, -219, -218, -413, -215, -381, + -290, -297, -413, -413, -152, -275, -413, -149, -413, -413, + -413, -413, -222, -144, -413, -413, -417, -413, -417, -417, + -417, -326, -413, -326, -326, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, @@ -8974,256 +8992,257 @@ var yyChk = [...]int{ -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, - -413, -413, -413, -413, -413, -413, -413, 223, -413, -413, - -413, -413, -413, -326, -326, -326, -326, -326, -326, -413, + -413, -413, -413, -413, -413, -413, -413, -413, 223, -413, + -413, -413, -413, -413, -326, -326, -326, -326, -326, -326, -413, -413, -413, -413, -413, -413, -413, -413, -413, -413, - -413, -413, -413, 103, 99, 102, 94, -217, 105, 90, - 90, 90, 90, -31, -32, -207, -413, -307, -395, -396, - -191, -188, -413, 304, -291, -291, 273, 96, -232, -34, - -31, -227, -233, -229, -31, -79, -120, -133, 64, 65, - -135, 25, 39, 68, 66, 24, -414, 89, -414, -250, - -414, 88, -38, -253, 87, 62, 44, 90, 90, 88, - 22, -228, -230, -144, 15, -295, 4, -294, 26, -291, - 90, 223, 15, -189, 30, -188, -276, -276, 88, 91, - 317, -266, -268, 414, 416, 152, -296, -291, 90, 32, - 89, 88, -188, -315, -318, -320, -319, -321, -316, -317, - 344, 345, 179, 348, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 361, 33, 263, 340, 341, 342, 343, - 362, 363, 364, 365, 367, 368, 369, 370, 325, 346, - 576, 326, 327, 328, 329, 330, 331, 333, 334, 337, - 335, 336, 338, 339, -382, -381, 87, 89, 88, -322, - 87, -144, -136, 240, -381, 241, 241, 241, -79, 469, - -348, -348, -348, 271, 20, -46, -43, -374, 19, -42, - -43, 232, 123, 124, 229, 87, -337, 87, -346, -382, - -381, 87, 138, 246, 137, -345, -342, -345, -346, -381, - -215, -381, 138, 138, -381, -381, -262, -291, -262, -262, - 24, -262, 24, -262, 24, 96, -291, -262, 24, -262, - 24, -262, 24, -262, 24, -262, 24, 32, 79, 80, - 81, 32, 83, 84, 85, -215, -381, -381, -215, -337, - -215, -188, -381, -269, 96, 96, 96, -348, -348, 96, - 90, 90, 90, -348, -348, 96, 90, -299, -297, 90, - 90, -387, 257, 301, 303, 96, 96, 96, 96, 32, - 90, -388, 32, 714, 713, 715, 716, 717, 90, 96, - 32, 96, 32, 96, -291, 87, -188, -142, 291, 227, - 229, 232, 77, 90, 307, 308, 305, 310, 311, 152, - 45, 88, 243, 240, -381, -282, 245, -282, -291, -298, - -297, -289, -188, 243, 380, 90, -144, -344, 15, 163, - -302, -302, -280, -188, -344, -302, -280, -188, -280, -280, - -280, -280, -302, -302, -302, -280, -297, -297, -188, -188, - -188, -188, -188, -188, -188, -308, -281, -280, 689, 90, - -274, 15, 77, -308, -308, 88, 323, 417, 418, -306, - 320, -81, -291, 90, -10, -29, -18, -17, -19, 152, - -10, 88, 578, -181, -188, 689, 689, 689, 689, 689, - 689, -144, -144, -144, -144, 601, -205, 119, 144, 120, - 121, -160, -144, -206, -211, -213, 106, 163, 146, 160, - -243, -149, -152, -149, -149, -149, -149, -149, -149, 222, - -149, 222, -149, -149, -149, -149, -149, -149, -309, -291, - 90, 179, -156, -155, 105, -404, -156, 575, 88, -218, - 223, -144, -144, -381, -118, 442, 443, 444, 445, 447, - 448, 449, 452, 453, 457, 458, 441, 459, 446, 451, - 454, 455, 456, 450, 343, -144, -130, -132, -130, -144, - -220, -221, 148, -215, -144, -414, -414, 96, 170, -126, - 25, 39, -126, -126, -126, -126, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -126, -144, -119, 441, - 459, 446, 451, 454, 455, 456, 450, 343, 460, 461, - 462, 463, 464, 465, 466, 467, 468, -119, -118, -144, - -144, -144, -144, -144, -144, -87, -144, 130, 131, 132, - -207, -144, -149, -144, -144, -144, -414, -144, -144, -144, - -208, -207, -144, -144, -144, -144, -144, -144, -144, -144, + -413, -413, -413, -413, 103, 99, 102, 94, -217, 105, + 90, 90, 90, 90, -31, -32, -207, -413, -307, -395, + -396, -191, -188, -413, 304, -291, -291, 273, 96, -232, + -34, -31, -227, -233, -229, -31, -79, -120, -133, 64, + 65, -135, 25, 39, 68, 66, 24, -414, 89, -414, + -250, -414, 88, -38, -253, 87, 633, 663, 633, 663, + 62, 44, 90, 90, 88, 22, -228, -230, -144, 15, + -295, 4, -294, 26, -291, 90, 223, 15, -189, 30, + -188, -276, -276, 88, 91, 317, -266, -268, 414, 416, + 152, -296, -291, 90, 32, 89, 88, -188, -315, -318, + -320, -319, -321, -316, -317, 344, 345, 179, 348, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 361, 33, + 263, 340, 341, 342, 343, 362, 363, 364, 365, 367, + 368, 369, 370, 325, 346, 576, 326, 327, 328, 329, + 330, 331, 333, 334, 337, 335, 336, 338, 339, -382, + -381, 87, 89, 88, -322, 87, -144, -136, 240, -381, + 241, 241, 241, -79, 469, -348, -348, -348, 271, 20, + -46, -43, -374, 19, -42, -43, 232, 123, 124, 229, + 87, -337, 87, -346, -382, -381, 87, 138, 246, 137, + -345, -342, -345, -346, -381, -215, -381, 138, 138, -381, + -381, -262, -291, -262, -262, 24, -262, 24, -262, 24, + 96, -291, -262, 24, -262, 24, -262, 24, -262, 24, + -262, 24, 32, 79, 80, 81, 32, 83, 84, 85, + -215, -381, -381, -215, -337, -215, -188, -381, -269, 96, + 96, 96, -348, -348, 96, 90, 90, 90, -348, -348, + 96, 90, -299, -297, 90, 90, -387, 257, 301, 303, + 96, 96, 96, 96, 32, 90, -388, 32, 714, 713, + 715, 716, 717, 90, 96, 32, 96, 32, 96, -291, + 87, -188, -142, 291, 227, 229, 232, 77, 90, 307, + 308, 305, 310, 311, 152, 45, 88, 243, 240, -381, + -282, 245, -282, -291, -298, -297, -289, -188, 243, 380, + 90, -144, -344, 15, 163, -302, -302, -280, -188, -344, + -302, -280, -188, -280, -280, -280, -280, -302, -302, -302, + -280, -297, -297, -188, -188, -188, -188, -188, -188, -188, + -308, -281, -280, 689, 90, -274, 15, 77, -308, -308, + 88, 323, 417, 418, -306, 320, -81, -291, 90, -10, + -29, -18, -17, -19, 152, -10, 88, 578, -181, -188, + 689, 689, 689, 689, 689, 689, -144, -144, -144, -144, + 601, -205, 119, 144, 120, 121, -160, -144, -206, -211, + -213, 106, 163, 146, 160, -243, -149, -152, -149, -149, + -149, -149, -149, -149, 222, -149, 222, -149, -149, -149, + -149, -149, -149, -309, -291, 90, 179, -156, -155, 105, + -404, -156, 575, 88, -218, 223, -144, -144, -381, -118, + 442, 443, 444, 445, 447, 448, 449, 452, 453, 457, + 458, 441, 459, 446, 451, 454, 455, 456, 450, 343, + -144, -130, -132, -130, -144, -220, -221, 148, -215, -144, + -414, -414, 96, 170, -126, 25, 39, -126, -126, -126, + -126, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -126, -144, -119, 441, 459, 446, 451, 454, 455, + 456, 450, 343, 460, 461, 462, 463, 464, 465, 466, + 467, 468, -119, -118, -144, -144, -144, -144, -144, -144, + -87, -144, 130, 131, 132, -207, -144, -149, -144, -144, + -144, -414, -144, -144, -144, -208, -207, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -144, -380, -379, - -378, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -207, -207, -207, -207, -207, -144, - -414, -144, -162, -147, 96, -258, 105, 92, -144, -144, - -144, -144, -144, -144, -131, -130, -293, -298, -289, -290, - -130, -131, -131, -130, -130, -144, -144, -144, -144, -144, - -144, -144, -144, -414, -144, -144, -144, -144, -144, -250, - -414, -207, 88, -397, 416, 417, 687, -300, 276, -299, - 26, -208, 90, 15, -260, 78, -291, -232, -232, 64, - 65, 60, -130, -135, -414, -37, 26, -252, -291, 63, - 90, -327, -269, 371, 372, 179, -144, -144, 88, -231, - 28, 29, -188, -294, 170, -298, -188, -261, 276, -188, - -166, -168, -169, -170, -191, -214, -413, -171, -31, 597, - 594, 15, -181, -182, -190, -297, -267, -310, -266, 88, - 415, 417, 418, 77, 122, -144, -328, 178, -356, -355, - -354, -337, -339, -340, -341, 89, -328, -333, 377, 376, - -322, -322, -322, -322, -322, -327, -327, -327, -327, 87, - 87, -322, -322, -322, -322, -330, 87, -330, -330, -331, - -330, 87, -331, -332, 87, -332, -367, -144, -364, -363, - -361, -362, 250, 101, 669, 625, 578, 618, 659, 78, - -359, -231, 96, -414, -142, -283, 245, -365, -362, -381, - -381, -381, -283, 91, 90, 91, 90, 91, 90, -111, - -60, -1, 726, 727, 728, 88, 20, -338, -337, -59, - 301, -370, -371, 276, -366, -360, -346, 138, -345, -346, - -346, -381, 88, 30, 127, 127, 127, 127, 578, 229, - 33, -284, 617, 144, 669, 625, -337, -59, 243, 243, - -309, -309, -309, 90, 90, -279, 722, -181, -138, 293, - 152, 282, 282, 240, 295, 240, 295, -188, 306, 309, - 307, 308, 305, 310, 311, 24, 24, 24, 24, 24, - 294, 296, 298, 284, -188, -188, -282, 77, -183, -188, - 27, -297, 90, 90, -188, -280, -280, -188, -280, -280, - -188, -409, 324, -291, 358, 680, 681, 683, 682, -122, - 416, 88, 578, 23, -123, 23, -413, 119, 120, 121, - -206, -149, -152, -149, 143, 264, -149, -149, -413, -215, - -414, -293, 26, 88, 78, -414, 168, 88, 88, -414, - -414, 88, 15, -223, -221, 150, -144, -414, 88, -414, - -414, -207, -144, -144, -144, -144, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -207, -414, 88, 88, - 15, -313, 26, -414, -414, -414, -414, -414, -222, -414, - 15, -414, 78, 88, 163, 88, -414, -414, -414, 88, - 88, -414, -414, 88, -414, 88, -414, -414, -414, -414, - -414, -414, 88, -414, 88, -414, -414, -414, 88, -414, - 88, -414, -414, 88, -414, 88, -414, 88, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, -414, - -414, 88, -414, 88, -414, 88, -414, -414, 88, -414, - 88, -414, 88, -414, 88, 88, -414, 88, 88, 88, - -414, 88, 88, 88, 88, -414, -414, -414, -414, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, -414, - -414, -414, -414, -414, -414, 88, -94, 602, -414, -414, - 88, -414, 88, 88, 88, 88, 88, -414, -413, 223, - -414, -414, -414, -414, -414, 88, 88, 88, 88, 88, - 88, -414, -414, -414, 88, 88, -414, 88, -414, 88, - -414, -396, 686, 417, -195, -194, -192, 75, 244, 76, - -413, -299, -414, -156, -258, -259, -258, -200, -291, 96, - 105, -234, -165, -167, 15, -135, -213, 89, 88, -327, - -238, -244, -277, -291, 90, 179, -329, 179, -329, 371, - 372, -230, 223, -196, 16, -199, 33, 58, -29, -413, - -413, 33, 88, -184, -186, -185, -187, 67, 71, 73, - 68, 69, 70, 74, -304, 26, -31, -166, -31, -413, - -188, -181, -415, 15, 78, -415, 88, 223, -268, -271, - 419, 416, 422, -381, 90, -110, 88, -354, -341, -235, - -139, 41, -334, 378, -327, 585, -327, -336, 90, -336, - 96, 96, 96, 89, -49, -44, -45, 34, 82, -361, - -348, 90, 40, -348, -348, -291, 89, -231, -138, -188, - 144, 77, -365, -365, -365, -297, -2, 725, 731, 138, - 87, 383, 19, -252, 88, 89, -216, 302, 89, -112, - -291, 89, 87, -346, -346, -291, -413, 240, 32, 32, - 669, 625, 617, -59, -216, -215, -381, -328, 724, 723, - 89, 242, 300, -143, 436, -140, 90, 91, -188, -188, - -188, -188, -188, -188, 232, 229, 406, -405, 312, -405, - 285, 243, -181, -188, 88, -84, 259, 254, -302, -302, - 34, -188, 416, 698, 696, -144, 143, 264, -160, -152, - -118, -118, -149, -311, 179, 344, 263, 342, 338, 358, - 349, 376, 340, 377, 335, 334, 333, -311, -309, -149, - -207, -132, -144, -144, 151, -144, 149, -144, -414, -414, - -414, -414, -414, -227, -144, -144, -144, -414, 179, 344, - 15, -144, -309, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -380, -379, -378, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -144, -144, -207, + -207, -207, -207, -207, -144, -414, -144, -162, -147, 96, + -258, 105, 92, -144, -144, -144, -144, -144, -144, -131, + -130, -293, -298, -289, -290, -130, -131, -131, -130, -130, + -144, -144, -144, -144, -144, -144, -144, -144, -414, -144, + -144, -144, -144, -144, -250, -414, -207, 88, -397, 416, + 417, 687, -300, 276, -299, 26, -208, 90, 15, -260, + 78, -291, -232, -232, 64, 65, 60, -130, -135, -414, + -37, 26, -252, -291, 626, 626, 63, 90, -327, -269, + 371, 372, 179, -144, -144, 88, -231, 28, 29, -188, + -294, 170, -298, -188, -261, 276, -188, -166, -168, -169, + -170, -191, -214, -413, -171, -31, 597, 594, 15, -181, + -182, -190, -297, -267, -310, -266, 88, 415, 417, 418, + 77, 122, -144, -328, 178, -356, -355, -354, -337, -339, + -340, -341, 89, -328, -333, 377, 376, -322, -322, -322, + -322, -322, -327, -327, -327, -327, 87, 87, -322, -322, + -322, -322, -330, 87, -330, -330, -331, -330, 87, -331, + -332, 87, -332, -367, -144, -364, -363, -361, -362, 250, + 101, 669, 625, 578, 618, 659, 78, -359, -231, 96, + -414, -142, -283, 245, -365, -362, -381, -381, -381, -283, + 91, 90, 91, 90, 91, 90, -111, -60, -1, 726, + 727, 728, 88, 20, -338, -337, -59, 301, -370, -371, + 276, -366, -360, -346, 138, -345, -346, -346, -381, 88, + 30, 127, 127, 127, 127, 578, 229, 33, -284, 617, + 144, 669, 625, -337, -59, 243, 243, -309, -309, -309, + 90, 90, -279, 722, -181, -138, 293, 152, 282, 282, + 240, 295, 240, 295, -188, 306, 309, 307, 308, 305, + 310, 311, 24, 24, 24, 24, 24, 294, 296, 298, + 284, -188, -188, -282, 77, -183, -188, 27, -297, 90, + 90, -188, -280, -280, -188, -280, -280, -188, -409, 324, + -291, 358, 680, 681, 683, 682, -122, 416, 88, 578, + 23, -123, 23, -413, 119, 120, 121, -206, -149, -152, + -149, 143, 264, -149, -149, -413, -215, -414, -293, 26, + 88, 78, -414, 168, 88, 88, -414, -414, 88, 15, + -223, -221, 150, -144, -414, 88, -414, -414, -207, -144, + -144, -144, -144, -414, -414, -414, -414, -414, -414, -414, + -414, -414, -414, -207, -414, 88, 88, 15, -313, 26, + -414, -414, -414, -414, -414, -222, -414, 15, -414, 78, + 88, 163, 88, -414, -414, -414, 88, 88, -414, -414, + 88, -414, 88, -414, -414, -414, -414, -414, -414, 88, + -414, 88, -414, -414, -414, 88, -414, 88, -414, -414, + 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, -414, -414, 88, -414, + 88, -414, 88, -414, -414, 88, -414, 88, -414, 88, + -414, 88, 88, -414, 88, 88, 88, -414, 88, 88, + 88, 88, -414, -414, -414, -414, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, -414, -414, -414, -414, + -414, -414, 88, -94, 602, -414, -414, 88, -414, 88, + 88, 88, 88, 88, -414, -413, 223, -414, -414, -414, + -414, -414, 88, 88, 88, 88, 88, 88, -414, -414, + -414, 88, 88, -414, 88, -414, 88, -414, -396, 686, + 417, -195, -194, -192, 75, 244, 76, -413, -299, -414, + -156, -258, -259, -258, -200, -291, 96, 105, -234, -165, + -167, 15, -135, -213, 89, 88, -327, -238, -244, -277, + -291, 90, 179, -329, 179, -329, 371, 372, -230, 223, + -196, 16, -199, 33, 58, -29, -413, -413, 33, 88, + -184, -186, -185, -187, 67, 71, 73, 68, 69, 70, + 74, -304, 26, -31, -166, -31, -413, -188, -181, -415, + 15, 78, -415, 88, 223, -268, -271, 419, 416, 422, + -381, 90, -110, 88, -354, -341, -235, -139, 41, -334, + 378, -327, 585, -327, -336, 90, -336, 96, 96, 96, + 89, -49, -44, -45, 34, 82, -361, -348, 90, 40, + -348, -348, -291, 89, -231, -138, -188, 144, 77, -365, + -365, -365, -297, -2, 725, 731, 138, 87, 383, 19, + -252, 88, 89, -216, 302, 89, -112, -291, 89, 87, + -346, -346, -291, -413, 240, 32, 32, 669, 625, 617, + -59, -216, -215, -381, -328, 724, 723, 89, 242, 300, + -143, 436, -140, 90, 91, -188, -188, -188, -188, -188, + -188, 232, 229, 406, -405, 312, -405, 285, 243, -181, + -188, 88, -84, 259, 254, -302, -302, 34, -188, 416, + 698, 696, -144, 143, 264, -160, -152, -118, -118, -149, + -311, 179, 344, 263, 342, 338, 358, 349, 376, 340, + 377, 335, 334, 333, -311, -309, -149, -207, -132, -144, + -144, 151, -144, 149, -144, -414, -414, -414, -414, -414, + -227, -144, -144, -144, -414, 179, 344, 15, -144, -309, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -144, -378, -144, - -207, -144, -207, -144, -144, -144, -144, -144, -379, -379, - -379, -379, -379, -207, -207, -207, -207, -144, -413, -291, - -97, -96, -95, 652, 244, -94, -162, -97, -162, 222, - -144, 222, 222, 222, -144, -131, -293, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -192, -342, -342, - -342, -262, 88, -273, 23, 15, 58, 58, -165, -196, - -166, -135, -291, -241, 679, -247, 47, -245, -246, 48, - -242, 49, 57, -329, -329, 170, -232, -144, -263, 77, - -264, -272, -215, -210, -212, -211, -413, -251, -414, -291, - -262, -264, -168, -169, -169, -168, -169, 67, 67, 67, - 72, 67, 72, 67, -185, -297, -414, -144, -300, 78, - -166, -166, -190, -297, 170, 416, 420, 421, -354, -403, - 119, 144, 32, 77, 374, 101, -401, 178, 614, 664, - 669, 625, 618, 659, -402, 246, 137, 138, 258, 26, - 42, 89, 88, 89, 88, 89, 89, 88, -285, -284, - -45, -44, -348, -348, 96, -381, 90, 90, 242, 27, - -188, 77, 77, 77, -113, 729, 96, 87, -3, 82, - -144, 87, 20, -337, -215, -372, -323, -373, -324, -325, - -5, -6, -349, -116, 58, 101, -63, 45, 241, 709, - 710, 127, -413, 722, -364, -252, -368, -370, -188, -148, - -413, -159, -146, -145, -147, -153, 168, 169, 263, 340, - 341, -216, -188, -137, 291, 299, 87, -141, 92, -384, - 78, 282, 374, 282, 374, 90, -406, 313, 90, -406, - -188, -84, -49, -188, -280, -280, 34, -381, -414, -160, - -152, -125, 163, 578, -314, 584, -322, -322, -322, -332, - -322, 330, -322, 330, -322, -414, -414, -414, 88, -414, - 23, -414, -144, 88, -121, 474, 88, 88, -414, 87, - 87, -144, -414, -414, -414, 88, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, - -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, - -414, -414, 88, -414, -414, -414, 88, -414, 88, -414, - 88, -414, -414, -414, 88, -312, 670, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -414, -93, -292, - -291, -94, 634, 634, -414, -94, -224, 88, -149, -414, - -149, -149, -149, -414, -414, -414, 88, -414, 88, 88, - -414, 88, -414, 88, -414, -414, -414, -414, 88, -193, - 23, -193, -193, -414, -258, -188, -196, -225, 17, -238, - 52, 350, -249, -248, 56, 48, -246, 20, 50, 20, - 31, -263, 88, 152, 88, -414, -414, 88, 58, 223, - -414, -196, -179, -178, 77, 78, -180, 77, -178, 67, - 67, -253, 88, -261, -166, -196, -196, 223, 119, -413, - -148, 13, 90, 90, -381, -400, 713, 714, 32, 96, - -348, -348, 138, 138, -188, 87, -327, 90, -327, 96, - 96, 32, 83, 84, 85, 32, 79, 80, 81, -188, - -188, -188, -188, -369, 87, 20, -144, 87, 152, 89, - -252, -252, 278, 163, -348, 707, 284, 284, -348, -348, - -348, -115, -114, 729, 89, -414, 88, -335, 578, 581, - -144, -154, -154, -253, 89, -377, 578, -383, -291, -291, - -291, -291, 96, 98, -414, 576, 74, 579, -414, -327, - -144, -144, -144, -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -207, -144, -414, -176, -175, -177, 690, 119, 32, -311, - -414, -209, 276, -100, -99, -98, 15, -414, -144, -118, - -118, -118, -118, -144, -144, -144, -144, -144, -144, -413, - 67, 19, 17, -413, -413, -300, -225, -226, 18, 20, - -239, 54, -237, 53, -237, -248, 20, 20, 90, 20, - 90, 138, -272, -144, -212, 58, -29, -291, -210, -291, - -227, -144, 87, -144, -156, -196, -196, -144, -202, 498, - 500, 501, 502, 499, 504, 505, 506, 507, 508, 509, - 510, 511, 512, 513, 503, 514, 475, 476, 477, 108, - 110, 109, 478, 479, 480, 344, 526, 527, 521, 524, - 525, 523, 522, 359, 360, 481, 544, 545, 549, 548, - 546, 547, 550, 553, 554, 555, 556, 557, 558, 560, - 559, 551, 552, 529, 528, 530, 531, 532, 533, 534, - 535, 537, 536, 538, 539, 540, 541, 542, 543, 561, - 562, 563, 564, 565, 567, 566, 571, 570, 568, 569, - 573, 572, 482, 483, 111, 112, 113, 114, 115, 116, - 117, 484, 487, 485, 488, 489, 490, 495, 496, 491, - 492, 493, 494, 497, 370, 368, 369, 365, 364, 363, - 423, 428, 429, 431, 515, 516, 517, 518, 519, 520, - 671, 672, 673, 674, 675, 676, 677, 678, 90, 90, - 87, -144, 89, 89, -253, -368, -60, 89, -254, -252, - 96, 89, 279, -211, -413, 90, -348, -348, -348, 96, - 96, -299, -414, 88, -291, -402, -370, 582, 582, -414, - 26, -376, -375, -293, 87, 78, 63, 577, 580, -414, - -414, 88, -414, -414, -414, 89, 89, -414, -414, -414, + -144, -144, -144, -144, -144, -378, -144, -207, -144, -207, + -144, -144, -144, -144, -144, -379, -379, -379, -379, -379, + -207, -207, -207, -207, -144, -413, -291, -97, -96, -95, + 652, 244, -94, -162, -97, -162, 222, -144, 222, 222, + 222, -144, -131, -293, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -144, -192, -342, -342, -342, -262, 88, + -273, 23, 15, 58, 58, -165, -196, -166, -135, -291, + -241, 679, -247, 47, -245, -246, 48, -242, 49, 57, + -329, -329, 170, -232, -144, -263, 77, -264, -272, -215, + -210, -212, -211, -413, -251, -414, -291, -262, -264, -168, + -169, -169, -168, -169, 67, 67, 67, 72, 67, 72, + 67, -185, -297, -414, -144, -300, 78, -166, -166, -190, + -297, 170, 416, 420, 421, -354, -403, 119, 144, 32, + 77, 374, 101, -401, 178, 614, 664, 669, 625, 618, + 659, -402, 246, 137, 138, 258, 26, 42, 89, 88, + 89, 88, 89, 89, 88, -285, -284, -45, -44, -348, + -348, 96, -381, 90, 90, 242, 27, -188, 77, 77, + 77, -113, 729, 96, 87, -3, 82, -144, 87, 20, + -337, -215, -372, -323, -373, -324, -325, -5, -6, -349, + -116, 58, 101, -63, 45, 241, 709, 710, 127, -413, + 722, -364, -252, -368, -370, -188, -148, -413, -159, -146, + -145, -147, -153, 168, 169, 263, 340, 341, -216, -188, + -137, 291, 299, 87, -141, 92, -384, 78, 282, 374, + 282, 374, 90, -406, 313, 90, -406, -188, -84, -49, + -188, -280, -280, 34, -381, -414, -160, -152, -125, 163, + 578, -314, 584, -322, -322, -322, -332, -322, 330, -322, + 330, -322, -414, -414, -414, 88, -414, 23, -414, -144, + 88, -121, 474, 88, 88, -414, 87, 87, -144, -414, + -414, -414, 88, -414, -414, -414, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, + 88, -414, 88, -414, 88, -414, 88, -414, -414, 88, + -414, -414, -414, 88, -414, 88, -414, 88, -414, -414, + -414, 88, -312, 670, -414, -414, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -93, -292, -291, -94, 634, + 634, -414, -94, -224, 88, -149, -414, -149, -149, -149, + -414, -414, -414, 88, -414, 88, 88, -414, 88, -414, + 88, -414, -414, -414, -414, 88, -193, 23, -193, -193, + -414, -258, -188, -196, -225, 17, -238, 52, 350, -249, + -248, 56, 48, -246, 20, 50, 20, 31, -263, 88, + 152, 88, -414, -414, 88, 58, 223, -414, -196, -179, + -178, 77, 78, -180, 77, -178, 67, 67, -253, 88, + -261, -166, -196, -196, 223, 119, -413, -148, 13, 90, + 90, -381, -400, 713, 714, 32, 96, -348, -348, 138, + 138, -188, 87, -327, 90, -327, 96, 96, 32, 83, + 84, 85, 32, 79, 80, 81, -188, -188, -188, -188, + -369, 87, 20, -144, 87, 152, 89, -252, -252, 278, + 163, -348, 707, 284, 284, -348, -348, -348, -115, -114, + 729, 89, -414, 88, -335, 578, 581, -144, -154, -154, + -253, 89, -377, 578, -383, -291, -291, -291, -291, 96, + 98, -414, 576, 74, 579, -414, -327, -144, -144, -144, + -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -207, -144, -414, + -176, -175, -177, 690, 119, 32, -311, -414, -209, 276, + -100, -99, -98, 15, -414, -144, -118, -118, -118, -118, + -144, -144, -144, -144, -144, -144, -413, 67, 19, 17, + -413, -413, -300, -225, -226, 18, 20, -239, 54, -237, + 53, -237, -248, 20, 20, 90, 20, 90, 138, -272, + -144, -212, 58, -29, -291, -210, -291, -227, -144, 87, + -144, -156, -196, -196, -144, -202, 498, 500, 501, 502, + 499, 504, 505, 506, 507, 508, 509, 510, 511, 512, + 513, 503, 514, 475, 476, 477, 108, 110, 109, 478, + 479, 480, 344, 526, 527, 521, 524, 525, 523, 522, + 359, 360, 481, 544, 545, 549, 548, 546, 547, 550, + 553, 554, 555, 556, 557, 558, 560, 559, 551, 552, + 529, 528, 530, 531, 532, 533, 534, 535, 537, 536, + 538, 539, 540, 541, 542, 543, 561, 562, 563, 564, + 565, 567, 566, 571, 570, 568, 569, 573, 572, 482, + 483, 111, 112, 113, 114, 115, 116, 117, 484, 487, + 485, 488, 489, 490, 495, 496, 491, 492, 493, 494, + 497, 370, 368, 369, 365, 364, 363, 423, 428, 429, + 431, 515, 516, 517, 518, 519, 520, 671, 672, 673, + 674, 675, 676, 677, 678, 90, 90, 87, -144, 89, + 89, -253, -368, -60, 89, -254, -252, 96, 89, 279, + -211, -413, 90, -348, -348, -348, 96, 96, -299, -414, + 88, -291, -402, -370, 582, 582, -414, 26, -376, -375, + -293, 87, 78, 63, 577, 580, -414, -414, 88, -414, + -414, -414, 89, 89, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, - -414, -175, -177, -414, 77, -156, -227, 20, -97, 301, - 303, -97, -414, -414, -414, -414, -414, 88, -414, -414, - 88, -414, 88, -414, -414, -255, -414, -291, 246, 20, - 20, -255, -255, -195, -226, -107, -106, -105, 608, -144, - -207, -240, 55, 77, 122, 90, 90, 90, 13, -210, - 223, -232, -252, -173, 383, -227, -414, -252, 89, 26, - 89, 731, 138, 89, -211, -124, -413, 275, -299, 90, - 90, -114, -117, -29, 88, 152, -252, -188, 63, -144, - -207, -414, 77, 589, 690, -92, -91, -88, 701, 727, - -207, -94, -94, -144, -144, -144, 88, -414, -414, -414, - -107, 88, -104, -103, -291, 77, 122, -264, -291, 89, - -414, -413, -232, 89, -236, -29, 87, -3, 275, -323, - -373, -324, -325, -5, -6, -349, -82, 578, -375, -353, - -297, -293, 90, 96, 89, 578, -414, -414, -90, 146, - 699, 667, -154, 222, -414, 88, -414, 88, -414, 88, - -291, 246, -105, 88, 26, -300, -174, -172, -291, 631, - -393, -392, 574, -403, -399, 119, 144, 101, -401, 669, - 625, 128, 129, -82, -144, 87, -414, -83, 290, 686, - 223, -384, 579, -90, 700, 645, 620, 645, 620, -149, - -144, -144, -144, -103, -413, -414, 88, 23, -315, -62, - 642, -390, -391, 77, -394, 389, 641, 662, 119, 90, - 89, -252, 251, -298, -377, 580, 143, -118, -414, 88, - -414, 88, -414, -93, -172, 638, -328, -156, -391, 77, - -390, 77, 14, 13, -4, 730, 89, 292, -90, 645, - 620, -144, -144, -414, -61, 27, -173, -389, 259, 254, - 257, 33, -389, 96, -4, -414, -414, 642, 253, 32, - 119, -156, -176, -175, -175, + -414, -414, -414, -414, -414, -414, 88, -414, -175, -177, + -414, 77, -156, -227, 20, -97, 301, 303, -97, -414, + -414, -414, -414, -414, 88, -414, -414, 88, -414, 88, + -414, -414, -255, -414, -291, 246, 20, 20, -255, -255, + -195, -226, -107, -106, -105, 608, -144, -207, -240, 55, + 77, 122, 90, 90, 90, 13, -210, 223, -232, -252, + -173, 383, -227, -414, -252, 89, 26, 89, 731, 138, + 89, -211, -124, -413, 275, -299, 90, 90, -114, -117, + -29, 88, 152, -252, -188, 63, -144, -207, -414, 77, + 589, 690, -92, -91, -88, 701, 727, -207, -94, -94, + -144, -144, -144, 88, -414, -414, -414, -107, 88, -104, + -103, -291, 77, 122, -264, -291, 89, -414, -413, -232, + 89, -236, -29, 87, -3, 275, -323, -373, -324, -325, + -5, -6, -349, -82, 578, -375, -353, -297, -293, 90, + 96, 89, 578, -414, -414, -90, 146, 699, 667, -154, + 222, -414, 88, -414, 88, -414, 88, -291, 246, -105, + 88, 26, -300, -174, -172, -291, 631, -393, -392, 574, + -403, -399, 119, 144, 101, -401, 669, 625, 128, 129, + -82, -144, 87, -414, -83, 290, 686, 223, -384, 579, + -90, 700, 645, 620, 645, 620, -149, -144, -144, -144, + -103, -413, -414, 88, 23, -315, -62, 642, -390, -391, + 77, -394, 389, 641, 662, 119, 90, 89, -252, 251, + -298, -377, 580, 143, -118, -414, 88, -414, 88, -414, + -93, -172, 638, -328, -156, -391, 77, -390, 77, 14, + 13, -4, 730, 89, 292, -90, 645, 620, -144, -144, + -414, -61, 27, -173, -389, 259, 254, 257, 33, -389, + 96, -4, -414, -414, 642, 253, 32, 119, -156, -176, + -175, -175, } var yyDef = [...]int{ @@ -9232,415 +9251,416 @@ var yyDef = [...]int{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 72, 74, 75, 880, 880, 880, 0, 880, 0, - 0, 880, -2, -2, 880, 1611, 0, 880, 0, 875, + 0, 880, -2, -2, 880, 1616, 0, 880, 0, 875, 0, -2, 795, 801, 0, 810, -2, 0, 0, 880, - 880, 2235, 2235, 875, 0, 0, 0, 0, 0, 880, - 880, 880, 880, 1616, 1477, 52, 880, 0, 87, 88, - 830, 831, 832, 67, 0, 2233, 881, 1, 3, 73, + 880, 2240, 2240, 875, 0, 0, 0, 0, 0, 880, + 880, 880, 880, 1621, 1477, 52, 880, 0, 87, 88, + 830, 831, 832, 67, 0, 2238, 881, 1, 3, 73, 77, 0, 0, 0, 60, 1486, 0, 80, 0, 0, - 884, 0, 0, 1594, 880, 880, 0, 128, 129, 0, + 884, 0, 0, 1599, 880, 880, 0, 128, 129, 0, 0, 0, -2, 132, -2, 161, 162, 163, 0, 168, 605, 526, 578, 524, 563, -2, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, - 401, 401, 0, 0, -2, 512, 512, 512, 1596, 0, + 401, 401, 0, 0, -2, 512, 512, 512, 1601, 0, 0, 0, 560, 463, 401, 401, 401, 0, 401, 401, 401, 401, 0, 0, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 1504, 167, 1612, 1609, 1610, 1769, 1770, 1771, 1772, - 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, - 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, - 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, - 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, - 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, - 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, - 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, - 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, - 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, - 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, - 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, - 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, - 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, - 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, - 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, - 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, - 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, - 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, - 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, - 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, - 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, - 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, - 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, - 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, - 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, - 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, - 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, - 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, - 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, - 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, - 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, - 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, - 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, - 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, - 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, - 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, - 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, - 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, - 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, - 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, - 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, - 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, - 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, - 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, - 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, - 0, 1588, 0, 718, 983, 0, 876, 877, 0, 784, + 401, 1504, 167, 1617, 1614, 1615, 1774, 1775, 1776, 1777, + 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, + 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, + 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, + 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, + 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, + 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, + 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, + 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, + 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, + 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, + 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, + 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, + 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, + 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, + 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, + 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, + 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, + 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, + 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, + 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, + 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, + 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, + 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, + 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, + 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, + 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, + 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, + 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, + 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, + 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, + 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, + 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, + 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, + 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, + 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, + 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, + 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, + 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, + 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, + 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, + 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, + 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, + 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, + 0, 1593, 0, 718, 983, 0, 876, 877, 0, 784, 784, 0, 784, 784, 784, 784, 0, 0, 0, 732, 0, 0, 0, 0, 781, 0, 748, 749, 0, 781, - 0, 755, 787, 0, 0, 762, 784, 784, 765, 2236, - 0, 2236, 2236, 1579, 0, 778, 776, 790, 791, 42, - 794, 797, 798, 799, 800, 803, 0, 814, 817, 1605, - 1606, 0, 819, 826, 843, 844, 0, 47, 1133, 0, + 0, 755, 787, 0, 0, 762, 784, 784, 765, 2241, + 0, 2241, 2241, 1584, 0, 778, 776, 790, 791, 42, + 794, 797, 798, 799, 800, 803, 0, 814, 817, 1610, + 1611, 0, 819, 826, 843, 844, 0, 47, 1133, 0, 1005, 0, 1011, -2, 1022, 1039, 1040, 1041, 1042, 1043, 1045, 1046, 1047, 0, 0, 0, 0, 1052, 1053, 0, 0, 0, 0, 0, 1114, 0, 0, 0, 0, 1450, 0, 0, 1412, 1412, 1148, 1412, 1412, 1414, 1414, 1414, - 1821, 1959, 1967, 2143, 1782, 1788, 1789, 1790, 2089, 2090, - 2091, 2092, 2180, 2181, 2185, 1883, 1777, 2156, 2157, 0, - 2232, 1920, 1928, 1929, 1953, 2053, 2166, 1800, 1948, 2017, - 1880, 1902, 1903, 2035, 2036, 1924, 1925, 1906, 2095, 2097, - 2113, 2114, 2099, 2101, 2110, 2116, 2121, 2100, 2112, 2117, - 2130, 2134, 2137, 2138, 2139, 2107, 2105, 2118, 2122, 2124, - 2126, 2132, 2135, 2108, 2106, 2119, 2123, 2125, 2127, 2133, - 2136, 2094, 2098, 2102, 2111, 2129, 2109, 2128, 2103, 2115, - 2120, 2131, 2104, 2096, 1918, 1921, 1909, 1910, 1912, 1914, - 1919, 1926, 1932, 1911, 1931, 1930, 0, 1907, 1908, 1913, - 1923, 1927, 1915, 1916, 1917, 1922, 1933, 1973, 1972, 1971, - 2016, 1944, 2015, 0, 0, 0, 0, 0, 1772, 1826, - 1827, 2140, 1334, 1335, 1336, 1337, 0, 0, 0, 0, - 0, 0, 0, 293, 294, 1463, 1464, 46, 1132, 1575, + 1826, 1964, 1972, 2148, 1787, 1793, 1794, 1795, 2094, 2095, + 2096, 2097, 2185, 2186, 2190, 1888, 1782, 2161, 2162, 0, + 2237, 1925, 1933, 1934, 1958, 2058, 2171, 1805, 1953, 2022, + 1885, 1907, 1908, 2040, 2041, 1929, 1930, 1911, 2100, 2102, + 2118, 2119, 2104, 2106, 2115, 2121, 2126, 2105, 2117, 2122, + 2135, 2139, 2142, 2143, 2144, 2112, 2110, 2123, 2127, 2129, + 2131, 2137, 2140, 2113, 2111, 2124, 2128, 2130, 2132, 2138, + 2141, 2099, 2103, 2107, 2116, 2134, 2114, 2133, 2108, 2120, + 2125, 2136, 2109, 2101, 1923, 1926, 1914, 1915, 1917, 1919, + 1924, 1931, 1937, 1916, 1936, 1935, 0, 1912, 1913, 1918, + 1928, 1932, 1920, 1921, 1922, 1927, 1938, 1978, 1977, 1976, + 2021, 1949, 2020, 0, 0, 0, 0, 0, 1777, 1831, + 1832, 2145, 1334, 1335, 1336, 1337, 0, 0, 0, 0, + 0, 0, 0, 293, 294, 1463, 1464, 46, 1132, 1580, 1414, 1414, 1414, 1414, 1414, 1414, 1074, 1075, 1076, 1077, - 1078, 1102, 1103, 1109, 1110, 2030, 2031, 2032, 2033, 1864, - 2175, 1872, 1873, 2012, 2013, 1885, 1886, 2206, 2207, -2, + 1078, 1102, 1103, 1109, 1110, 2035, 2036, 2037, 2038, 1869, + 2180, 1877, 1878, 2017, 2018, 1890, 1891, 2211, 2212, -2, -2, -2, 234, 235, 236, 237, 238, 239, 240, 241, - 0, 1825, 2154, 2155, 230, 0, 0, 298, 299, 295, + 0, 1830, 2159, 2160, 230, 0, 0, 298, 299, 295, 296, 297, 1116, 1117, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 2235, 0, 853, 0, - 0, 0, 0, 0, 0, 1617, 1618, 1486, 0, 1478, + 287, 288, 289, 290, 291, 292, 2240, 0, 853, 0, + 0, 0, 0, 0, 0, 1622, 1623, 1486, 0, 1478, 1477, 65, 0, 880, -2, 0, 0, 0, 0, 49, - 0, 54, 940, 883, 79, 78, 1526, 0, 0, 0, - 61, 1487, 69, 71, 1488, 0, 885, 886, 0, 916, - 920, 0, 0, 0, 1595, 1594, 1594, 104, 0, 0, - 105, 125, 126, 127, 0, 0, 111, 112, 1581, 1582, - 45, 0, 0, 179, 180, 0, 43, 428, 0, 175, - 0, 421, 360, 0, 1504, 0, 0, 0, 0, 0, - 880, 0, 1589, 156, 157, 164, 165, 166, 401, 401, - 401, 575, 0, 0, 167, 167, 533, 534, 535, 0, - 0, -2, 426, 0, 513, 0, 0, 415, 415, 419, - 417, 418, 0, 0, 0, 0, 0, 0, 0, 0, - 552, 0, 553, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 666, 0, 402, 0, 573, 574, 464, 0, - 0, 0, 0, 0, 0, 0, 0, 1597, 1598, 0, - 550, 551, 0, 0, 0, 401, 401, 0, 0, 0, - 0, 401, 401, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 155, 1517, 0, 0, 0, -2, 0, 710, 0, - 0, 0, 1590, 1590, 0, 717, 0, 0, 0, 722, - 0, 0, 723, 0, 781, 781, 779, 780, 725, 726, - 727, 728, 784, 0, 0, 410, 411, 412, 781, 784, - 0, 784, 784, 784, 784, 781, 781, 781, 784, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2236, 787, - 784, 0, 756, 0, 757, 758, 759, 760, 763, 764, - 766, 2237, 2238, 1607, 1608, 1619, 1620, 1621, 1622, 1623, - 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, - 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, - 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, - 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, - 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, - 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, - 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, - 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, - 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, - 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, - 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, - 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, - 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, - 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, - 1764, 1765, 1766, 1767, 1768, 2236, 2236, 770, 774, 1580, - 796, 802, 804, 805, 0, 0, 815, 818, 837, 51, - 1871, 825, 51, 827, 828, 829, 855, 856, 861, 0, - 0, 0, 0, 867, 868, 869, 0, 0, 872, 873, - 874, 0, 0, 0, 0, 0, 1003, 0, 0, 1122, - 1123, 1124, 1125, 1126, 1127, 1128, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1023, 1024, 0, 0, 0, 1048, - 1049, 1050, 1051, 1054, 0, 1065, 0, 1067, 1459, -2, - 0, 0, 0, 1059, 1060, 0, 0, 0, 0, 0, - 0, 0, 1451, 0, 0, 1146, 0, 1147, 1149, 1150, - 1151, 0, 1152, 1153, 890, 890, 890, 890, 890, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 890, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1600, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 900, 0, 0, 900, - 900, 0, 0, 222, 223, 224, 225, 226, 227, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 242, 243, 244, 245, 246, 247, 300, - 248, 249, 250, 1132, 0, 0, 0, 48, 845, 846, - 0, 966, 1600, 0, 0, 896, 0, 1615, 59, 68, - 70, 1486, 63, 1486, 0, 902, 0, 0, -2, -2, - 903, 909, 910, 911, 912, 913, 56, 2234, 57, 0, - 76, 0, 50, 0, 0, 0, 0, 374, 1529, 0, - 0, 1479, 1480, 1483, 0, 917, 1965, 921, 0, 923, - 924, 0, 0, 102, 0, 982, 0, 0, 0, 113, - 0, 115, 116, 0, 0, 0, 385, 1583, 1584, 1585, - -2, 408, 0, 385, 369, 308, 309, 310, 360, 312, - 360, 360, 360, 360, 374, 374, 374, 374, 343, 344, - 345, 346, 347, 0, 0, 329, 360, 360, 360, 360, - 350, 351, 352, 353, 354, 355, 356, 357, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 362, 362, 362, - 362, 362, 366, 366, 0, 44, 0, 389, 0, 1483, - 0, 0, 1517, 1592, 1602, 0, 0, 0, 1592, 134, - 0, 0, 0, 576, 616, 527, 564, 577, 0, 530, - 531, -2, 0, 0, 512, 0, 514, 0, 409, 0, - -2, 0, 419, 0, 415, 419, 416, 419, 407, 420, - 554, 555, 556, 0, 558, 559, 646, 952, 0, 0, - 0, 0, 0, 652, 653, 654, 0, 656, 657, 658, - 659, 660, 661, 662, 663, 664, 665, 565, 566, 567, - 568, 569, 570, 571, 572, 0, 0, 0, 0, 514, - 0, 561, 0, 0, 465, 466, 467, 0, 0, 470, - 471, 472, 473, 0, 0, 476, 477, 478, 969, 970, - 479, 480, 505, 506, 507, 481, 482, 483, 484, 485, - 486, 487, 499, 500, 501, 502, 503, 504, 488, 489, - 490, 491, 492, 493, 496, 0, 149, 1508, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1590, 0, 0, 0, 0, 899, 984, - 1613, 1614, 719, 0, 0, 785, 786, 0, 413, 414, - 784, 784, 729, 771, 0, 784, 733, 772, 734, 736, - 735, 737, 750, 751, 784, 740, 782, 783, 741, 742, - 743, 744, 745, 746, 747, 767, 752, 753, 754, 788, - 0, 792, 793, 768, 769, 0, 0, 808, 809, 0, - 816, 840, 838, 839, 841, 833, 834, 835, 836, 0, - 842, 0, 0, 858, 98, 863, 864, 865, 866, 878, - 871, 1134, 1000, 1001, 1002, 0, 1004, 1008, 0, 1118, - 1120, 1010, 1006, 1012, 1129, 1130, 1131, 0, 0, 0, - 0, 0, 1016, 1020, 1025, 1026, 1027, 1028, 1029, 0, - 1030, 0, 1033, 1034, 1035, 1036, 1037, 1038, 1044, 1427, - 1428, 1429, 1063, 301, 302, 0, 1064, 0, 0, 0, - 0, 0, 0, 0, 0, 1374, 1375, 1376, 1377, 1378, - 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, - 1389, 1390, 1391, 1392, 1393, 1133, 0, 914, 0, 0, - 1457, 1454, 0, 0, 0, 1413, 1415, 0, 0, 0, - 891, 892, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1394, - 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, - 1405, 1406, 1407, 1408, 1409, 1410, 1411, 0, 0, 1430, - 0, 0, 0, 0, 0, 1450, 0, 1069, 1070, 1071, - 0, 0, 0, 0, 0, 0, 1192, 0, 0, 0, - 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, - 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, 0, 0, 1338, 1339, 1340, 1341, 41, 0, 0, - 0, 0, 0, 0, 0, 901, 1461, 0, -2, -2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1363, 0, 0, 0, 0, 0, 0, - 1573, 0, 0, 848, 849, 851, 0, 986, 0, 967, - 0, 0, 854, 0, 895, 0, 898, 62, 64, 907, - 908, 0, 925, 904, 58, 53, 0, 0, 944, 1527, - 374, 1549, 0, 383, 383, 380, 1489, 1490, 0, 1482, - 1484, 1485, 81, 922, 918, 0, 998, 0, 0, 981, - 0, 928, 930, 931, 932, 964, 0, 935, 936, 0, - 0, 0, 0, 0, 100, 983, 106, 0, 114, 0, - 0, 119, 120, 107, 108, 109, 110, 0, 605, -2, - 460, 181, 183, 184, 185, 176, -2, 372, 370, 371, - 311, 374, 374, 337, 338, 339, 340, 341, 342, 0, - 0, 330, 331, 332, 333, 322, 0, 323, 324, 325, - 364, 0, 326, 327, 0, 328, 427, 0, 1491, 390, - 391, 393, 401, 0, 396, 397, 0, 401, 401, 0, - 422, 423, 0, 1483, 1508, 0, 0, 0, 1603, 1602, - 1602, 1602, 0, 169, 170, 171, 172, 173, 174, 641, - 0, 0, 617, 639, 640, 167, 0, 0, 177, 516, - 515, 0, 673, 0, 425, 0, 0, 419, 419, 404, - 405, 557, 0, 0, 648, 649, 650, 651, 0, 0, - 0, 543, 454, 0, 544, 545, 514, 516, 0, 0, - 385, 468, 469, 474, 475, 494, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 592, 593, - 594, 597, 599, 518, 603, 596, 598, 600, 518, 604, - 1505, 1506, 1507, 0, 0, 711, 0, 0, 451, 96, - 1591, 716, 720, 721, 781, 739, 773, 781, 731, 738, - 761, 806, 807, 812, 820, 821, 822, 823, 824, 862, - 0, 0, 0, 0, 870, 0, 0, 1009, 1119, 1121, - 1013, 0, 1017, 1021, 0, 0, 0, 0, 0, 1068, - 1066, 1461, 0, 0, 0, 1115, 0, 0, 0, 1137, - 1138, 0, 0, 0, 1455, 0, 0, 1144, 0, 1416, - 1154, 0, 0, 0, 0, 0, 1160, 1161, 1162, 1163, - 1164, 1165, 1166, 1167, 1168, 1169, 1477, 1171, 0, 0, - 0, 0, 0, 1176, 1177, 1178, 1179, 1180, 0, 1182, - 0, 1183, 0, 0, 0, 0, 1190, 1191, 1193, 0, - 0, 1196, 1197, 0, 1199, 0, 1201, 1202, 1203, 1204, - 1205, 1206, 0, 1208, 0, 1210, 1211, 1212, 0, 1214, - 0, 1216, 1217, 0, 1219, 0, 1221, 0, 1224, 0, - 1227, 0, 1230, 0, 1233, 0, 1236, 0, 1239, 0, - 1242, 0, 1245, 0, 1248, 0, 1251, 0, 1254, 0, - 1257, 0, 1260, 0, 1263, 0, 1266, 0, 1269, 1270, - 1271, 0, 1273, 0, 1275, 0, 1278, 1279, 0, 1281, - 0, 1284, 0, 1287, 0, 0, 1288, 0, 0, 0, - 1292, 0, 0, 0, 0, 1301, 1302, 1303, 1304, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1315, - 1316, 1317, 1318, 1319, 1320, 0, 1322, 0, 1097, 0, - 0, 1097, 0, 0, 0, 0, 0, 1135, 900, 0, - 1417, 1418, 1419, 1420, 1421, 0, 0, 0, 0, 0, - 0, 1361, 1362, 1364, 0, 0, 1367, 0, 1369, 0, - 1574, 847, 850, 852, 938, 987, 988, 0, 0, 0, - 0, 968, 1599, 893, 894, 897, 946, 0, 1465, 0, - 0, 925, 998, 926, 0, 905, 55, 941, 0, 1531, - 1530, 1543, 1556, 383, 383, 377, 378, 384, 379, 381, - 382, 1481, 0, 1486, 0, 1567, 0, 0, 1559, 0, - 0, 0, 0, 0, 0, 0, 0, 971, 0, 0, - 974, 0, 0, 0, 0, 965, 936, 0, 937, 0, - -2, 0, 0, 94, 95, 0, 0, 0, 117, 118, - 0, 0, 124, 386, 387, 158, 167, 462, 182, 435, - 0, 0, 307, 373, 334, 335, 336, 0, 358, 0, - 0, 0, 0, 456, 130, 1495, 1494, 401, 401, 392, - 0, 395, 0, 0, 0, 1604, 361, 424, 0, 148, - 0, 0, 0, 0, 0, 154, 611, 0, 0, 618, - 0, 0, 0, 525, 0, 536, 537, 0, 645, -2, - 707, 389, 0, 403, 406, 953, 0, 0, 538, 0, - 541, 542, 455, 516, 547, 548, 562, 549, 497, 498, - 495, 0, 0, 1518, 1519, 1524, 1522, 1523, 135, 583, - 585, 589, 584, 588, 0, 0, 0, 520, 0, 520, - 581, 0, 451, 1491, 0, 715, 452, 453, 784, 784, - 857, 99, 0, 860, 0, 0, 0, 0, 1014, 1018, - 1031, 1032, 1422, 1448, 360, 360, 1435, 360, 366, 1438, - 360, 1440, 360, 1443, 360, 1446, 1447, 0, 0, 1061, - 0, 915, 0, 0, 1143, 1458, 0, 0, 1155, 1156, - 1157, 1158, 1159, 1452, 0, 0, 0, 1175, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 146, 147, - 0, 0, 0, 0, 0, 0, 1372, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1092, 1096, - 0, 1098, 1099, 0, 0, 1324, 0, 0, 1342, 0, - 0, 0, 0, 0, 0, 0, 1462, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 989, 994, 994, - 994, 0, 0, 0, 1586, 1587, 1466, 1467, 998, 1468, - 927, 906, 945, 1549, 0, 1542, 0, -2, 1551, 0, - 0, 0, 1557, 375, 376, 919, 82, 999, 85, 0, - 1567, 1576, 0, 1558, 1569, 1571, 0, 0, 0, 1563, - 0, 998, 929, 960, 962, 0, 957, 972, 973, 975, - 0, 977, 0, 979, 980, 940, 934, 0, 102, 0, - 998, 998, 101, 0, 985, 121, 122, 123, 461, 186, - 191, 0, 0, 0, 196, 0, 198, 0, 0, 0, - 203, 204, 401, 401, 436, 0, 304, 306, 0, 0, - 189, 374, 0, 374, 0, 365, 367, 0, 437, 457, - 1492, 1493, 0, 0, 394, 398, 399, 400, 0, 1593, - 150, 0, 0, 0, 614, 0, 642, 0, 0, 0, - 0, 0, 0, 178, 517, 674, 675, 676, 677, 678, - 679, 680, 681, 682, 0, 401, 0, 0, 0, 401, - 401, 401, 0, 699, 388, 0, 0, 670, 667, 539, - 0, 220, 221, 228, 229, 231, 0, 0, 0, 0, - 0, 546, 940, 1509, 1510, 1511, 0, 1521, 1525, 138, - 0, 0, 0, 0, 591, 595, 601, 0, 519, 602, - 712, 713, 714, 97, 724, 730, 859, 879, 1007, 1015, - 1019, 0, 0, 0, 0, 1449, 1433, 374, 1436, 1437, - 1439, 1441, 1442, 1444, 1445, 1057, 1058, 1062, 0, 1140, - 0, 1142, 1456, 0, 1486, 0, 0, 0, 1174, 0, - 0, 0, 1185, 1184, 1186, 0, 1188, 1189, 1194, 1195, - 1198, 1200, 1207, 1209, 1213, 1215, 1218, 1220, 1222, 0, - 1225, 0, 1228, 0, 1231, 0, 1234, 0, 1237, 0, - 1240, 0, 1243, 0, 1246, 0, 1249, 0, 1252, 0, - 1255, 0, 1258, 0, 1261, 0, 1264, 0, 1267, 0, - 1272, 1274, 0, 1277, 1280, 1282, 0, 1285, 0, 1289, - 0, 1291, 1293, 1294, 0, 0, 0, 1305, 1306, 1307, - 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1321, 0, 1090, - 1093, 1323, 1100, 1101, 1106, 1326, 0, 0, 0, 1329, - 0, 0, 0, 1333, 1136, 1344, 0, 1349, 0, 0, - 1355, 0, 1359, 0, 1365, 1366, 1368, 1370, 0, 0, - 0, 0, 0, 966, 947, 66, 1468, 1470, 0, 1536, - 1534, 1534, 1544, 1545, 0, 0, 1552, 0, 0, 0, - 0, 86, 0, 0, 0, 1572, 0, 0, 0, 0, - 103, 1477, 954, 961, 0, 0, 955, 0, 956, 976, - 978, 933, 0, 998, 998, 92, 93, 0, 192, 0, - 194, 0, 197, 199, 200, 201, 207, 208, 209, 202, - 0, 0, 303, 305, 0, 0, 348, 359, 349, 0, - 0, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 940, - 151, 152, 153, 606, 0, 616, 0, 942, 0, 609, - 0, 528, 0, 0, 0, 401, 401, 401, 0, 0, - 0, 0, 684, 0, 0, 647, 0, 655, 0, 0, - 0, 232, 233, 0, 1520, 582, 0, 136, 137, 0, - 0, 587, 521, 522, 1055, 0, 0, 0, 1056, 1434, - 0, 0, 0, 0, 1453, 0, 0, 0, 0, 1181, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1297, 0, 0, 0, 636, 637, 0, 1373, - 1095, 1477, 0, 1097, 1107, 1108, 0, 1097, 1343, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 995, 0, 0, 0, 0, 986, 1470, 1475, 0, 0, - 1539, 0, 1532, 1535, 1533, 1546, 0, 0, 1553, 0, - 1555, 0, 1577, 1578, 1570, 0, 1562, 1565, 1561, 1564, - 1486, 958, 0, 963, 0, 1477, 91, 0, 195, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 205, 206, - 0, 0, 363, 368, 0, 0, 0, 607, 0, 943, - 619, 610, 0, 697, 0, 701, 0, 0, 0, 704, - 705, 706, 683, 0, 687, 429, 671, 668, 669, 540, - 0, 139, 140, 0, 0, 0, 1423, 0, 1426, 1139, - 1141, 0, 1170, 1172, 1173, 1431, 1432, 1187, 1223, 1226, - 1229, 1232, 1235, 1238, 1241, 1244, 1247, 1250, 1253, 1256, - 1259, 1262, 1265, 1268, 1276, 1283, 1286, 1290, 1295, 0, - 1298, 0, 0, 1299, 0, 638, 1086, 0, 0, 1104, - 1105, 0, 1328, 1330, 1331, 1332, 1345, 0, 1350, 1351, - 0, 1356, 0, 1360, 1371, 0, 991, 948, 949, 996, - 997, 0, 0, 939, 1475, 84, 1476, 1473, 0, 1471, - 1469, 1528, 0, 1537, 1538, 1547, 1548, 1554, 0, 1560, - 0, 89, 0, 0, 0, 1486, 193, 0, 212, 0, - 615, 0, 618, 608, 695, 696, 0, 708, 700, 702, - 703, 685, -2, 1512, 0, 0, 0, 590, 1424, 0, - 0, 1300, 0, 634, 635, 1094, 1087, 0, 1072, 1073, - 1091, 1325, 1327, 0, 0, 0, 0, 990, 992, 993, - 83, 0, 1472, 1112, 0, 1540, 1541, 1568, 1566, 959, - 966, 0, 90, 442, 435, 1512, 0, 0, 0, 688, - 689, 690, 691, 692, 693, 694, 579, 1514, 141, 142, - 0, 509, 510, 511, 135, 0, 1145, 1296, 1088, 0, - 0, 0, 0, 0, 1346, 0, 1352, 0, 1357, 0, - 950, 951, 1474, 0, 0, 620, 0, 622, 0, -2, - 430, 443, 0, 187, 213, 214, 0, 0, 217, 218, - 219, 210, 211, 131, 0, 0, 709, 0, 1515, 1516, - 0, 138, 0, 0, 1079, 1080, 1081, 1082, 1084, 0, - 0, 0, 0, 1113, 1092, 621, 0, 0, 385, 0, - 631, 431, 432, 0, 438, 439, 440, 441, 215, 216, - 643, 0, 0, 508, 586, 1425, 0, 0, 1347, 0, - 1353, 0, 1358, 0, 623, 624, 632, 0, 433, 0, - 434, 0, 0, 0, 612, 0, 643, 1513, 1089, 1083, - 1085, 0, 0, 1111, 0, 633, 629, 444, 446, 447, - 0, 0, 445, 644, 613, 1348, 1354, 0, 448, 449, - 450, 625, 626, 627, 628, + 0, 54, 940, 883, 79, 78, 1526, 1529, 0, 0, + 0, 61, 1487, 69, 71, 1488, 0, 885, 886, 0, + 916, 920, 0, 0, 0, 1600, 1599, 1599, 104, 0, + 0, 105, 125, 126, 127, 0, 0, 111, 112, 1586, + 1587, 45, 0, 0, 179, 180, 0, 43, 428, 0, + 175, 0, 421, 360, 0, 1504, 0, 0, 0, 0, + 0, 880, 0, 1594, 156, 157, 164, 165, 166, 401, + 401, 401, 575, 0, 0, 167, 167, 533, 534, 535, + 0, 0, -2, 426, 0, 513, 0, 0, 415, 415, + 419, 417, 418, 0, 0, 0, 0, 0, 0, 0, + 0, 552, 0, 553, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 666, 0, 402, 0, 573, 574, 464, + 0, 0, 0, 0, 0, 0, 0, 0, 1602, 1603, + 0, 550, 551, 0, 0, 0, 401, 401, 0, 0, + 0, 0, 401, 401, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 155, 1517, 0, 0, 0, -2, 0, 710, + 0, 0, 0, 1595, 1595, 0, 717, 0, 0, 0, + 722, 0, 0, 723, 0, 781, 781, 779, 780, 725, + 726, 727, 728, 784, 0, 0, 410, 411, 412, 781, + 784, 0, 784, 784, 784, 784, 781, 781, 781, 784, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2241, + 787, 784, 0, 756, 0, 757, 758, 759, 760, 763, + 764, 766, 2242, 2243, 1612, 1613, 1624, 1625, 1626, 1627, + 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, + 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, + 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, + 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, + 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, + 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, + 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, + 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, + 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, + 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, + 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, + 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, + 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, + 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, + 1768, 1769, 1770, 1771, 1772, 1773, 2241, 2241, 770, 774, + 1585, 796, 802, 804, 805, 0, 0, 815, 818, 837, + 51, 1876, 825, 51, 827, 828, 829, 855, 856, 861, + 0, 0, 0, 0, 867, 868, 869, 0, 0, 872, + 873, 874, 0, 0, 0, 0, 0, 1003, 0, 0, + 1122, 1123, 1124, 1125, 1126, 1127, 1128, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1023, 1024, 0, 0, 0, + 1048, 1049, 1050, 1051, 1054, 0, 1065, 0, 1067, 1459, + -2, 0, 0, 0, 1059, 1060, 0, 0, 0, 0, + 0, 0, 0, 1451, 0, 0, 1146, 0, 1147, 1149, + 1150, 1151, 0, 1152, 1153, 890, 890, 890, 890, 890, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 890, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1605, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 900, 0, 0, + 900, 900, 0, 0, 222, 223, 224, 225, 226, 227, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 242, 243, 244, 245, 246, 247, + 300, 248, 249, 250, 1132, 0, 0, 0, 48, 845, + 846, 0, 966, 1605, 0, 0, 896, 0, 1620, 59, + 68, 70, 1486, 63, 1486, 0, 902, 0, 0, -2, + -2, 903, 909, 910, 911, 912, 913, 56, 2239, 57, + 0, 76, 0, 50, 0, 0, 1527, 0, 1530, 0, + 0, 0, 374, 1534, 0, 0, 1479, 1480, 1483, 0, + 917, 1970, 921, 0, 923, 924, 0, 0, 102, 0, + 982, 0, 0, 0, 113, 0, 115, 116, 0, 0, + 0, 385, 1588, 1589, 1590, -2, 408, 0, 385, 369, + 308, 309, 310, 360, 312, 360, 360, 360, 360, 374, + 374, 374, 374, 343, 344, 345, 346, 347, 0, 0, + 329, 360, 360, 360, 360, 350, 351, 352, 353, 354, + 355, 356, 357, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 362, 362, 362, 362, 362, 366, 366, 0, + 44, 0, 389, 0, 1483, 0, 0, 1517, 1597, 1607, + 0, 0, 0, 1597, 134, 0, 0, 0, 576, 616, + 527, 564, 577, 0, 530, 531, -2, 0, 0, 512, + 0, 514, 0, 409, 0, -2, 0, 419, 0, 415, + 419, 416, 419, 407, 420, 554, 555, 556, 0, 558, + 559, 646, 952, 0, 0, 0, 0, 0, 652, 653, + 654, 0, 656, 657, 658, 659, 660, 661, 662, 663, + 664, 665, 565, 566, 567, 568, 569, 570, 571, 572, + 0, 0, 0, 0, 514, 0, 561, 0, 0, 465, + 466, 467, 0, 0, 470, 471, 472, 473, 0, 0, + 476, 477, 478, 969, 970, 479, 480, 505, 506, 507, + 481, 482, 483, 484, 485, 486, 487, 499, 500, 501, + 502, 503, 504, 488, 489, 490, 491, 492, 493, 496, + 0, 149, 1508, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1595, 0, + 0, 0, 0, 899, 984, 1618, 1619, 719, 0, 0, + 785, 786, 0, 413, 414, 784, 784, 729, 771, 0, + 784, 733, 772, 734, 736, 735, 737, 750, 751, 784, + 740, 782, 783, 741, 742, 743, 744, 745, 746, 747, + 767, 752, 753, 754, 788, 0, 792, 793, 768, 769, + 0, 0, 808, 809, 0, 816, 840, 838, 839, 841, + 833, 834, 835, 836, 0, 842, 0, 0, 858, 98, + 863, 864, 865, 866, 878, 871, 1134, 1000, 1001, 1002, + 0, 1004, 1008, 0, 1118, 1120, 1010, 1006, 1012, 1129, + 1130, 1131, 0, 0, 0, 0, 0, 1016, 1020, 1025, + 1026, 1027, 1028, 1029, 0, 1030, 0, 1033, 1034, 1035, + 1036, 1037, 1038, 1044, 1427, 1428, 1429, 1063, 301, 302, + 0, 1064, 0, 0, 0, 0, 0, 0, 0, 0, + 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, + 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, + 1133, 0, 914, 0, 0, 1457, 1454, 0, 0, 0, + 1413, 1415, 0, 0, 0, 891, 892, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1394, 1395, 1396, 1397, 1398, 1399, + 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, + 1410, 1411, 0, 0, 1430, 0, 0, 0, 0, 0, + 1450, 0, 1069, 1070, 1071, 0, 0, 0, 0, 0, + 0, 1192, 0, 0, 0, 0, 1606, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 144, 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, 0, 0, 1338, 1339, + 1340, 1341, 41, 0, 0, 0, 0, 0, 0, 0, + 901, 1461, 0, -2, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1363, 0, + 0, 0, 0, 0, 0, 1578, 0, 0, 848, 849, + 851, 0, 986, 0, 967, 0, 0, 854, 0, 895, + 0, 898, 62, 64, 907, 908, 0, 925, 904, 58, + 53, 0, 0, 944, 1528, 1531, 1532, 374, 1554, 0, + 383, 383, 380, 1489, 1490, 0, 1482, 1484, 1485, 81, + 922, 918, 0, 998, 0, 0, 981, 0, 928, 930, + 931, 932, 964, 0, 935, 936, 0, 0, 0, 0, + 0, 100, 983, 106, 0, 114, 0, 0, 119, 120, + 107, 108, 109, 110, 0, 605, -2, 460, 181, 183, + 184, 185, 176, -2, 372, 370, 371, 311, 374, 374, + 337, 338, 339, 340, 341, 342, 0, 0, 330, 331, + 332, 333, 322, 0, 323, 324, 325, 364, 0, 326, + 327, 0, 328, 427, 0, 1491, 390, 391, 393, 401, + 0, 396, 397, 0, 401, 401, 0, 422, 423, 0, + 1483, 1508, 0, 0, 0, 1608, 1607, 1607, 1607, 0, + 169, 170, 171, 172, 173, 174, 641, 0, 0, 617, + 639, 640, 167, 0, 0, 177, 516, 515, 0, 673, + 0, 425, 0, 0, 419, 419, 404, 405, 557, 0, + 0, 648, 649, 650, 651, 0, 0, 0, 543, 454, + 0, 544, 545, 514, 516, 0, 0, 385, 468, 469, + 474, 475, 494, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 592, 593, 594, 597, 599, + 518, 603, 596, 598, 600, 518, 604, 1505, 1506, 1507, + 0, 0, 711, 0, 0, 451, 96, 1596, 716, 720, + 721, 781, 739, 773, 781, 731, 738, 761, 806, 807, + 812, 820, 821, 822, 823, 824, 862, 0, 0, 0, + 0, 870, 0, 0, 1009, 1119, 1121, 1013, 0, 1017, + 1021, 0, 0, 0, 0, 0, 1068, 1066, 1461, 0, + 0, 0, 1115, 0, 0, 0, 1137, 1138, 0, 0, + 0, 1455, 0, 0, 1144, 0, 1416, 1154, 0, 0, + 0, 0, 0, 1160, 1161, 1162, 1163, 1164, 1165, 1166, + 1167, 1168, 1169, 1477, 1171, 0, 0, 0, 0, 0, + 1176, 1177, 1178, 1179, 1180, 0, 1182, 0, 1183, 0, + 0, 0, 0, 1190, 1191, 1193, 0, 0, 1196, 1197, + 0, 1199, 0, 1201, 1202, 1203, 1204, 1205, 1206, 0, + 1208, 0, 1210, 1211, 1212, 0, 1214, 0, 1216, 1217, + 0, 1219, 0, 1221, 0, 1224, 0, 1227, 0, 1230, + 0, 1233, 0, 1236, 0, 1239, 0, 1242, 0, 1245, + 0, 1248, 0, 1251, 0, 1254, 0, 1257, 0, 1260, + 0, 1263, 0, 1266, 0, 1269, 1270, 1271, 0, 1273, + 0, 1275, 0, 1278, 1279, 0, 1281, 0, 1284, 0, + 1287, 0, 0, 1288, 0, 0, 0, 1292, 0, 0, + 0, 0, 1301, 1302, 1303, 1304, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1315, 1316, 1317, 1318, + 1319, 1320, 0, 1322, 0, 1097, 0, 0, 1097, 0, + 0, 0, 0, 0, 1135, 900, 0, 1417, 1418, 1419, + 1420, 1421, 0, 0, 0, 0, 0, 0, 1361, 1362, + 1364, 0, 0, 1367, 0, 1369, 0, 1579, 847, 850, + 852, 938, 987, 988, 0, 0, 0, 0, 968, 1604, + 893, 894, 897, 946, 0, 1465, 0, 0, 925, 998, + 926, 0, 905, 55, 941, 0, 1536, 1535, 1548, 1561, + 383, 383, 377, 378, 384, 379, 381, 382, 1481, 0, + 1486, 0, 1572, 0, 0, 1564, 0, 0, 0, 0, + 0, 0, 0, 0, 971, 0, 0, 974, 0, 0, + 0, 0, 965, 936, 0, 937, 0, -2, 0, 0, + 94, 95, 0, 0, 0, 117, 118, 0, 0, 124, + 386, 387, 158, 167, 462, 182, 435, 0, 0, 307, + 373, 334, 335, 336, 0, 358, 0, 0, 0, 0, + 456, 130, 1495, 1494, 401, 401, 392, 0, 395, 0, + 0, 0, 1609, 361, 424, 0, 148, 0, 0, 0, + 0, 0, 154, 611, 0, 0, 618, 0, 0, 0, + 525, 0, 536, 537, 0, 645, -2, 707, 389, 0, + 403, 406, 953, 0, 0, 538, 0, 541, 542, 455, + 516, 547, 548, 562, 549, 497, 498, 495, 0, 0, + 1518, 1519, 1524, 1522, 1523, 135, 583, 585, 589, 584, + 588, 0, 0, 0, 520, 0, 520, 581, 0, 451, + 1491, 0, 715, 452, 453, 784, 784, 857, 99, 0, + 860, 0, 0, 0, 0, 1014, 1018, 1031, 1032, 1422, + 1448, 360, 360, 1435, 360, 366, 1438, 360, 1440, 360, + 1443, 360, 1446, 1447, 0, 0, 1061, 0, 915, 0, + 0, 1143, 1458, 0, 0, 1155, 1156, 1157, 1158, 1159, + 1452, 0, 0, 0, 1175, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 146, 147, 0, 0, 0, + 0, 0, 0, 1372, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1092, 1096, 0, 1098, 1099, + 0, 0, 1324, 0, 0, 1342, 0, 0, 0, 0, + 0, 0, 0, 1462, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 989, 994, 994, 994, 0, 0, + 0, 1591, 1592, 1466, 1467, 998, 1468, 927, 906, 945, + 1554, 0, 1547, 0, -2, 1556, 0, 0, 0, 1562, + 375, 376, 919, 82, 999, 85, 0, 1572, 1581, 0, + 1563, 1574, 1576, 0, 0, 0, 1568, 0, 998, 929, + 960, 962, 0, 957, 972, 973, 975, 0, 977, 0, + 979, 980, 940, 934, 0, 102, 0, 998, 998, 101, + 0, 985, 121, 122, 123, 461, 186, 191, 0, 0, + 0, 196, 0, 198, 0, 0, 0, 203, 204, 401, + 401, 436, 0, 304, 306, 0, 0, 189, 374, 0, + 374, 0, 365, 367, 0, 437, 457, 1492, 1493, 0, + 0, 394, 398, 399, 400, 0, 1598, 150, 0, 0, + 0, 614, 0, 642, 0, 0, 0, 0, 0, 0, + 178, 517, 674, 675, 676, 677, 678, 679, 680, 681, + 682, 0, 401, 0, 0, 0, 401, 401, 401, 0, + 699, 388, 0, 0, 670, 667, 539, 0, 220, 221, + 228, 229, 231, 0, 0, 0, 0, 0, 546, 940, + 1509, 1510, 1511, 0, 1521, 1525, 138, 0, 0, 0, + 0, 591, 595, 601, 0, 519, 602, 712, 713, 714, + 97, 724, 730, 859, 879, 1007, 1015, 1019, 0, 0, + 0, 0, 1449, 1433, 374, 1436, 1437, 1439, 1441, 1442, + 1444, 1445, 1057, 1058, 1062, 0, 1140, 0, 1142, 1456, + 0, 1486, 0, 0, 0, 1174, 0, 0, 0, 1185, + 1184, 1186, 0, 1188, 1189, 1194, 1195, 1198, 1200, 1207, + 1209, 1213, 1215, 1218, 1220, 1222, 0, 1225, 0, 1228, + 0, 1231, 0, 1234, 0, 1237, 0, 1240, 0, 1243, + 0, 1246, 0, 1249, 0, 1252, 0, 1255, 0, 1258, + 0, 1261, 0, 1264, 0, 1267, 0, 1272, 1274, 0, + 1277, 1280, 1282, 0, 1285, 0, 1289, 0, 1291, 1293, + 1294, 0, 0, 0, 1305, 1306, 1307, 1308, 1309, 1310, + 1311, 1312, 1313, 1314, 1321, 0, 1090, 1093, 1323, 1100, + 1101, 1106, 1326, 0, 0, 0, 1329, 0, 0, 0, + 1333, 1136, 1344, 0, 1349, 0, 0, 1355, 0, 1359, + 0, 1365, 1366, 1368, 1370, 0, 0, 0, 0, 0, + 966, 947, 66, 1468, 1470, 0, 1541, 1539, 1539, 1549, + 1550, 0, 0, 1557, 0, 0, 0, 0, 86, 0, + 0, 0, 1577, 0, 0, 0, 0, 103, 1477, 954, + 961, 0, 0, 955, 0, 956, 976, 978, 933, 0, + 998, 998, 92, 93, 0, 192, 0, 194, 0, 197, + 199, 200, 201, 207, 208, 209, 202, 0, 0, 303, + 305, 0, 0, 348, 359, 349, 0, 0, 1496, 1497, + 1498, 1499, 1500, 1501, 1502, 1503, 940, 151, 152, 153, + 606, 0, 616, 0, 942, 0, 609, 0, 528, 0, + 0, 0, 401, 401, 401, 0, 0, 0, 0, 684, + 0, 0, 647, 0, 655, 0, 0, 0, 232, 233, + 0, 1520, 582, 0, 136, 137, 0, 0, 587, 521, + 522, 1055, 0, 0, 0, 1056, 1434, 0, 0, 0, + 0, 1453, 0, 0, 0, 0, 1181, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1297, + 0, 0, 0, 636, 637, 0, 1373, 1095, 1477, 0, + 1097, 1107, 1108, 0, 1097, 1343, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 995, 0, 0, + 0, 0, 986, 1470, 1475, 0, 0, 1544, 0, 1537, + 1540, 1538, 1551, 0, 0, 1558, 0, 1560, 0, 1582, + 1583, 1575, 0, 1567, 1570, 1566, 1569, 1486, 958, 0, + 963, 0, 1477, 91, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 205, 206, 0, 0, 363, + 368, 0, 0, 0, 607, 0, 943, 619, 610, 0, + 697, 0, 701, 0, 0, 0, 704, 705, 706, 683, + 0, 687, 429, 671, 668, 669, 540, 0, 139, 140, + 0, 0, 0, 1423, 0, 1426, 1139, 1141, 0, 1170, + 1172, 1173, 1431, 1432, 1187, 1223, 1226, 1229, 1232, 1235, + 1238, 1241, 1244, 1247, 1250, 1253, 1256, 1259, 1262, 1265, + 1268, 1276, 1283, 1286, 1290, 1295, 0, 1298, 0, 0, + 1299, 0, 638, 1086, 0, 0, 1104, 1105, 0, 1328, + 1330, 1331, 1332, 1345, 0, 1350, 1351, 0, 1356, 0, + 1360, 1371, 0, 991, 948, 949, 996, 997, 0, 0, + 939, 1475, 84, 1476, 1473, 0, 1471, 1469, 1533, 0, + 1542, 1543, 1552, 1553, 1559, 0, 1565, 0, 89, 0, + 0, 0, 1486, 193, 0, 212, 0, 615, 0, 618, + 608, 695, 696, 0, 708, 700, 702, 703, 685, -2, + 1512, 0, 0, 0, 590, 1424, 0, 0, 1300, 0, + 634, 635, 1094, 1087, 0, 1072, 1073, 1091, 1325, 1327, + 0, 0, 0, 0, 990, 992, 993, 83, 0, 1472, + 1112, 0, 1545, 1546, 1573, 1571, 959, 966, 0, 90, + 442, 435, 1512, 0, 0, 0, 688, 689, 690, 691, + 692, 693, 694, 579, 1514, 141, 142, 0, 509, 510, + 511, 135, 0, 1145, 1296, 1088, 0, 0, 0, 0, + 0, 1346, 0, 1352, 0, 1357, 0, 950, 951, 1474, + 0, 0, 620, 0, 622, 0, -2, 430, 443, 0, + 187, 213, 214, 0, 0, 217, 218, 219, 210, 211, + 131, 0, 0, 709, 0, 1515, 1516, 0, 138, 0, + 0, 1079, 1080, 1081, 1082, 1084, 0, 0, 0, 0, + 1113, 1092, 621, 0, 0, 385, 0, 631, 431, 432, + 0, 438, 439, 440, 441, 215, 216, 643, 0, 0, + 508, 586, 1425, 0, 0, 1347, 0, 1353, 0, 1358, + 0, 623, 624, 632, 0, 433, 0, 434, 0, 0, + 0, 612, 0, 643, 1513, 1089, 1083, 1085, 0, 0, + 1111, 0, 633, 629, 444, 446, 447, 0, 0, 445, + 644, 613, 1348, 1354, 0, 448, 449, 450, 625, 626, + 627, 628, } var yyTok1 = [...]int{ @@ -21510,336 +21530,376 @@ yydefault: } yyVAL.union = yyLOCAL case 1527: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock //line sql.y:7515 { - yyLOCAL = ShareModeLock + yyLOCAL = ForUpdateLockNoWait } yyVAL.union = yyLOCAL case 1528: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Lock +//line sql.y:7519 + { + yyLOCAL = ForUpdateLockSkipLocked + } + yyVAL.union = yyLOCAL + case 1529: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL Lock +//line sql.y:7523 + { + yyLOCAL = ForShareLock + } + yyVAL.union = yyLOCAL + case 1530: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL Lock +//line sql.y:7527 + { + yyLOCAL = ForShareLockNoWait + } + yyVAL.union = yyLOCAL + case 1531: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Lock +//line sql.y:7531 + { + yyLOCAL = ForShareLockSkipLocked + } + yyVAL.union = yyLOCAL + case 1532: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Lock +//line sql.y:7535 + { + yyLOCAL = ShareModeLock + } + yyVAL.union = yyLOCAL + case 1533: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7521 +//line sql.y:7541 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 1529: + case 1534: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7525 +//line sql.y:7545 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1530: + case 1535: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7529 +//line sql.y:7549 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1531: + case 1536: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7534 +//line sql.y:7554 { yyVAL.str = "" } - case 1532: + case 1537: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7538 +//line sql.y:7558 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1533: + case 1538: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7542 +//line sql.y:7562 { yyVAL.str = " format text" + yyDollar[3].str } - case 1534: + case 1539: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7547 +//line sql.y:7567 { yyVAL.str = "" } - case 1535: + case 1540: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7551 +//line sql.y:7571 { yyVAL.str = " header" } - case 1536: + case 1541: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7556 +//line sql.y:7576 { yyVAL.str = "" } - case 1537: + case 1542: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7560 +//line sql.y:7580 { yyVAL.str = " manifest on" } - case 1538: + case 1543: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7564 +//line sql.y:7584 { yyVAL.str = " manifest off" } - case 1539: + case 1544: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7569 +//line sql.y:7589 { yyVAL.str = "" } - case 1540: + case 1545: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7573 +//line sql.y:7593 { yyVAL.str = " overwrite on" } - case 1541: + case 1546: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7577 +//line sql.y:7597 { yyVAL.str = " overwrite off" } - case 1542: + case 1547: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7583 +//line sql.y:7603 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1543: + case 1548: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7588 +//line sql.y:7608 { yyVAL.str = "" } - case 1544: + case 1549: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7592 +//line sql.y:7612 { yyVAL.str = " lines" + yyDollar[2].str } - case 1545: + case 1550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7598 +//line sql.y:7618 { yyVAL.str = yyDollar[1].str } - case 1546: + case 1551: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7602 +//line sql.y:7622 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1547: + case 1552: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7608 +//line sql.y:7628 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1548: + case 1553: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7612 +//line sql.y:7632 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1549: + case 1554: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7617 +//line sql.y:7637 { yyVAL.str = "" } - case 1550: + case 1555: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7621 +//line sql.y:7641 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1551: + case 1556: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7627 +//line sql.y:7647 { yyVAL.str = yyDollar[1].str } - case 1552: + case 1557: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7631 +//line sql.y:7651 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1553: + case 1558: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7637 +//line sql.y:7657 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1554: + case 1559: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7641 +//line sql.y:7661 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1555: + case 1560: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7645 +//line sql.y:7665 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1556: + case 1561: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7650 +//line sql.y:7670 { yyVAL.str = "" } - case 1557: + case 1562: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7654 +//line sql.y:7674 { yyVAL.str = " optionally" } - case 1558: + case 1563: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Insert -//line sql.y:7667 +//line sql.y:7687 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion()} } yyVAL.union = yyLOCAL - case 1559: + case 1564: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:7671 +//line sql.y:7691 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1560: + case 1565: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:7675 +//line sql.y:7695 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion()} } yyVAL.union = yyLOCAL - case 1561: + case 1566: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7679 +//line sql.y:7699 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion()} } yyVAL.union = yyLOCAL - case 1562: + case 1567: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7683 +//line sql.y:7703 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1563: + case 1568: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:7689 +//line sql.y:7709 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1564: + case 1569: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:7693 +//line sql.y:7713 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1565: + case 1570: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7697 +//line sql.y:7717 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1566: + case 1571: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:7701 +//line sql.y:7721 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1567: + case 1572: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7706 +//line sql.y:7726 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1568: + case 1573: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7710 +//line sql.y:7730 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1569: + case 1574: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:7716 +//line sql.y:7736 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1570: + case 1575: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7720 +//line sql.y:7740 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1571: + case 1576: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7726 +//line sql.y:7746 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1572: + case 1577: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7730 +//line sql.y:7750 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1573: + case 1578: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7736 +//line sql.y:7756 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1574: + case 1579: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7740 +//line sql.y:7760 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1575: + case 1580: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7745 +//line sql.y:7765 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -21848,300 +21908,300 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1576: + case 1581: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7755 +//line sql.y:7775 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1577: + case 1582: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7759 +//line sql.y:7779 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1578: + case 1583: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:7765 +//line sql.y:7785 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1580: + case 1585: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7772 +//line sql.y:7792 { yyVAL.str = "charset" } - case 1583: + case 1588: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7782 +//line sql.y:7802 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1584: + case 1589: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7786 +//line sql.y:7806 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1585: + case 1590: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7790 +//line sql.y:7810 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1588: + case 1593: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7799 +//line sql.y:7819 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1589: + case 1594: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7801 +//line sql.y:7821 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1590: + case 1595: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7804 +//line sql.y:7824 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1591: + case 1596: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7806 +//line sql.y:7826 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1592: + case 1597: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7809 +//line sql.y:7829 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1593: + case 1598: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:7811 +//line sql.y:7831 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1594: + case 1599: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:7814 +//line sql.y:7834 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1595: + case 1600: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:7816 +//line sql.y:7836 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1596: + case 1601: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7819 +//line sql.y:7839 { yyVAL.empty = struct{}{} } - case 1597: + case 1602: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7821 +//line sql.y:7841 { yyVAL.empty = struct{}{} } - case 1598: + case 1603: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7823 +//line sql.y:7843 { yyVAL.empty = struct{}{} } - case 1599: + case 1604: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:7827 +//line sql.y:7847 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1600: + case 1605: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7832 +//line sql.y:7852 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1601: + case 1606: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:7836 +//line sql.y:7856 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1602: + case 1607: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7841 +//line sql.y:7861 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1603: + case 1608: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7843 +//line sql.y:7863 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1604: + case 1609: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:7847 +//line sql.y:7867 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1605: + case 1610: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7853 +//line sql.y:7873 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1606: + case 1611: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7857 +//line sql.y:7877 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1608: + case 1613: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7864 +//line sql.y:7884 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1609: + case 1614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7870 +//line sql.y:7890 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1610: + case 1615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7874 +//line sql.y:7894 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1611: + case 1616: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7880 +//line sql.y:7900 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1612: + case 1617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7884 +//line sql.y:7904 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1614: + case 1619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7891 +//line sql.y:7911 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1615: + case 1620: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:7897 +//line sql.y:7917 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1616: + case 1621: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:7903 +//line sql.y:7923 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1617: + case 1622: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7907 +//line sql.y:7927 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1618: + case 1623: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7911 +//line sql.y:7931 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2233: + case 2238: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8554 +//line sql.y:8574 { } - case 2234: + case 2239: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8559 +//line sql.y:8579 { } - case 2235: + case 2240: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8563 +//line sql.y:8583 { skipToEnd(yylex) } - case 2236: + case 2241: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8568 +//line sql.y:8588 { skipToEnd(yylex) } - case 2237: + case 2242: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8572 +//line sql.y:8592 { skipToEnd(yylex) } - case 2238: + case 2243: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8576 +//line sql.y:8596 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 4ed613718fd..a71e8e6ac4c 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -7511,6 +7511,26 @@ FOR UPDATE { $$ = ForUpdateLock } +| FOR UPDATE NOWAIT + { + $$ = ForUpdateLockNoWait + } +| FOR UPDATE SKIP LOCKED + { + $$ = ForUpdateLockSkipLocked + } +| FOR SHARE + { + $$ = ForShareLock + } +| FOR SHARE NOWAIT + { + $$ = ForShareLockNoWait + } +| FOR SHARE SKIP LOCKED + { + $$ = ForShareLockSkipLocked + } | LOCK IN SHARE MODE { $$ = ShareModeLock diff --git a/go/vt/sqlparser/testdata/union_cases.txt b/go/vt/sqlparser/testdata/union_cases.txt index 8e2def0e04e..d5b620cb246 100644 --- a/go/vt/sqlparser/testdata/union_cases.txt +++ b/go/vt/sqlparser/testdata/union_cases.txt @@ -1004,7 +1004,7 @@ INPUT SELECT 1 FOR SHARE UNION SELECT 2; END ERROR -syntax error at position 19 near 'SHARE' +syntax error at position 25 near 'UNION' END INPUT SELECT ST_AsText(ST_Union(shore, boundary)) FROM lakes, named_places WHERE lakes.name = 'Blue Lake' AND named_places.name = 'Goose Island'; diff --git a/go/vt/vtgate/planbuilder/testdata/lock_cases.json b/go/vt/vtgate/planbuilder/testdata/lock_cases.json index c14ba026869..568b066fa22 100644 --- a/go/vt/vtgate/planbuilder/testdata/lock_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/lock_cases.json @@ -124,5 +124,95 @@ "main.dual" ] } + }, + { + "comment": "select nowait", + "query": "select u.col, u.bar from user u join music m on u.foo = m.foo for update nowait", + "plan": { + "QueryType": "SELECT", + "Original": "select u.col, u.bar from user u join music m on u.foo = m.foo for update nowait", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0,L:1", + "JoinVars": { + "u_foo": 2 + }, + "TableName": "`user`_music", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select u.col, u.bar, u.foo from `user` as u where 1 != 1", + "Query": "select u.col, u.bar, u.foo from `user` as u for update nowait", + "Table": "`user`" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music as m where 1 != 1", + "Query": "select 1 from music as m where m.foo = :u_foo for update nowait", + "Table": "music" + } + ] + }, + "TablesUsed": [ + "user.music", + "user.user" + ] + } + }, + { + "comment": "select skip locked", + "query": "select u.col, u.bar from user u join music m on u.foo = m.foo for share skip locked", + "plan": { + "QueryType": "SELECT", + "Original": "select u.col, u.bar from user u join music m on u.foo = m.foo for share skip locked", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0,L:1", + "JoinVars": { + "u_foo": 2 + }, + "TableName": "`user`_music", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select u.col, u.bar, u.foo from `user` as u where 1 != 1", + "Query": "select u.col, u.bar, u.foo from `user` as u for share skip locked", + "Table": "`user`" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from music as m where 1 != 1", + "Query": "select 1 from music as m where m.foo = :u_foo for share skip locked", + "Table": "music" + } + ] + }, + "TablesUsed": [ + "user.music", + "user.user" + ] + } } ] From 59d3d23938c2113e5128bde837c1886affc60f92 Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Fri, 17 Nov 2023 10:13:54 -0800 Subject: [PATCH 027/119] Replace usages of bytes.Buffer with strings.Builder (#14539) Signed-off-by: Matt Robenolt --- go/bytes2/buffer.go | 2 +- .../collations/integration/collations_test.go | 6 +-- go/mysql/sqlerror/sql_error.go | 7 ++- go/sqltypes/bind_variables.go | 4 +- go/sqltypes/testing.go | 7 ++- go/sqltypes/value_test.go | 8 ++-- go/stats/opentsdb/collector.go | 3 +- go/tools/release-notes/release_notes.go | 25 +++++------ go/vt/binlog/binlog_streamer.go | 8 ++-- go/vt/hook/hook.go | 7 ++- go/vt/key/destination.go | 9 ++-- go/vt/logutil/logger.go | 17 ++++---- go/vt/mysqlctl/mycnf_gen.go | 10 ++--- go/vt/mysqlctl/mysqld.go | 4 +- go/vt/schemadiff/schema.go | 3 +- go/vt/servenv/status.go | 7 ++- go/vt/sqlparser/normalizer_test.go | 4 +- go/vt/sqlparser/parse_next_test.go | 3 +- go/vt/sqlparser/parse_test.go | 7 ++- go/vt/throttler/result.go | 4 +- go/vt/vtctl/workflow/server.go | 24 +++++------ go/vt/vtexplain/vtexplain.go | 14 +++--- go/vt/vtgate/engine/set.go | 9 +--- go/vt/vtgate/vindexes/consistent_lookup.go | 11 ++--- go/vt/vtgate/vindexes/lookup_internal.go | 18 ++++---- go/vt/vtorc/inst/instance_dao.go | 43 ++++++++++--------- go/vt/vttablet/sysloglogger/sysloglogger.go | 6 ++- .../tabletserver/tabletenv/logstats_test.go | 4 +- go/vt/vttest/local_cluster.go | 10 ++--- go/vt/wrangler/schema.go | 6 +-- go/vt/zkctl/zkconf.go | 17 ++++---- 31 files changed, 143 insertions(+), 164 deletions(-) diff --git a/go/bytes2/buffer.go b/go/bytes2/buffer.go index 1725274c43c..48561c5e493 100644 --- a/go/bytes2/buffer.go +++ b/go/bytes2/buffer.go @@ -65,7 +65,7 @@ func (buf *Buffer) String() string { // is _not_ allocated, so modifying this buffer after calling StringUnsafe will lead // to undefined behavior. func (buf *Buffer) StringUnsafe() string { - return *(*string)(unsafe.Pointer(&buf.bytes)) + return unsafe.String(unsafe.SliceData(buf.bytes), len(buf.bytes)) } // Reset is equivalent to bytes.Buffer.Reset. diff --git a/go/mysql/collations/integration/collations_test.go b/go/mysql/collations/integration/collations_test.go index c8f53eeb242..e5362608e75 100644 --- a/go/mysql/collations/integration/collations_test.go +++ b/go/mysql/collations/integration/collations_test.go @@ -59,7 +59,7 @@ func getSQLQueries(t *testing.T, testfile string) []string { defer tf.Close() var chunks []string - var curchunk bytes.Buffer + var curchunk strings.Builder addchunk := func() { if curchunk.Len() > 0 { @@ -219,8 +219,8 @@ func TestCollationsOnMysqld(t *testing.T) { } func TestRemoteKanaSensitivity(t *testing.T) { - var Kana1 = []byte("の東京ノ") - var Kana2 = []byte("ノ東京の") + Kana1 := []byte("の東京ノ") + Kana2 := []byte("ノ東京の") testRemoteComparison(t, nil, []testcmp{ {"utf8mb4_0900_as_cs", Kana1, Kana2}, diff --git a/go/mysql/sqlerror/sql_error.go b/go/mysql/sqlerror/sql_error.go index 30ce99d681a..7a71070a70c 100644 --- a/go/mysql/sqlerror/sql_error.go +++ b/go/mysql/sqlerror/sql_error.go @@ -17,7 +17,6 @@ limitations under the License. package sqlerror import ( - "bytes" "fmt" "regexp" "strconv" @@ -53,17 +52,17 @@ func NewSQLError(number ErrorCode, sqlState string, format string, args ...any) // Error implements the error interface func (se *SQLError) Error() string { - buf := &bytes.Buffer{} + var buf strings.Builder buf.WriteString(se.Message) // Add MySQL errno and SQLSTATE in a format that we can later parse. // There's no avoiding string parsing because all errors // are converted to strings anyway at RPC boundaries. // See NewSQLErrorFromError. - fmt.Fprintf(buf, " (errno %v) (sqlstate %v)", se.Num, se.State) + fmt.Fprintf(&buf, " (errno %v) (sqlstate %v)", se.Num, se.State) if se.Query != "" { - fmt.Fprintf(buf, " during query: %s", sqlparser.TruncateForLog(se.Query)) + fmt.Fprintf(&buf, " during query: %s", sqlparser.TruncateForLog(se.Query)) } return buf.String() diff --git a/go/sqltypes/bind_variables.go b/go/sqltypes/bind_variables.go index 18beda37702..9b8969bc814 100644 --- a/go/sqltypes/bind_variables.go +++ b/go/sqltypes/bind_variables.go @@ -17,10 +17,10 @@ limitations under the License. package sqltypes import ( - "bytes" "errors" "fmt" "strconv" + "strings" "google.golang.org/protobuf/proto" @@ -418,7 +418,7 @@ func FormatBindVariables(bindVariables map[string]*querypb.BindVariable, full, a } if asJSON { - var buf bytes.Buffer + var buf strings.Builder buf.WriteString("{") first := true for k, v := range out { diff --git a/go/sqltypes/testing.go b/go/sqltypes/testing.go index 3894635eae0..1c191b8c5e7 100644 --- a/go/sqltypes/testing.go +++ b/go/sqltypes/testing.go @@ -17,7 +17,6 @@ limitations under the License. package sqltypes import ( - "bytes" crand "crypto/rand" "encoding/base64" "encoding/hex" @@ -155,13 +154,13 @@ func TestTuple(vals ...Value) Value { // PrintResults prints []*Results into a string. // This function should only be used for testing. func PrintResults(results []*Result) string { - b := new(bytes.Buffer) + var b strings.Builder for i, r := range results { if i == 0 { - fmt.Fprintf(b, "%v", r) + fmt.Fprintf(&b, "%v", r) continue } - fmt.Fprintf(b, ", %v", r) + fmt.Fprintf(&b, ", %v", r) } return b.String() } diff --git a/go/sqltypes/value_test.go b/go/sqltypes/value_test.go index 86c751f3d0d..10a46e09a9e 100644 --- a/go/sqltypes/value_test.go +++ b/go/sqltypes/value_test.go @@ -463,13 +463,13 @@ func TestEncode(t *testing.T) { outASCII: "'YQ=='", }} for _, tcase := range testcases { - buf := &bytes.Buffer{} - tcase.in.EncodeSQL(buf) + var buf strings.Builder + tcase.in.EncodeSQL(&buf) if tcase.outSQL != buf.String() { t.Errorf("%v.EncodeSQL = %q, want %q", tcase.in, buf.String(), tcase.outSQL) } - buf = &bytes.Buffer{} - tcase.in.EncodeASCII(buf) + buf.Reset() + tcase.in.EncodeASCII(&buf) if tcase.outASCII != buf.String() { t.Errorf("%v.EncodeASCII = %q, want %q", tcase.in, buf.String(), tcase.outASCII) } diff --git a/go/stats/opentsdb/collector.go b/go/stats/opentsdb/collector.go index 9b870815067..d2c40432e7f 100644 --- a/go/stats/opentsdb/collector.go +++ b/go/stats/opentsdb/collector.go @@ -17,7 +17,6 @@ limitations under the License. package opentsdb import ( - "bytes" "encoding/json" "expvar" "strings" @@ -65,7 +64,7 @@ func (dc *collector) addFloat(metric string, val float64, tags map[string]string // Also make everything lowercase, since opentsdb is case sensitive and lowercase // simplifies the convention. sanitize := func(text string) string { - var b bytes.Buffer + var b strings.Builder for _, r := range text { if unicode.IsDigit(r) || unicode.IsLetter(r) || r == '-' || r == '_' || r == '/' || r == '.' { b.WriteRune(r) diff --git a/go/tools/release-notes/release_notes.go b/go/tools/release-notes/release_notes.go index 1673d6a5160..1a8105a6f38 100644 --- a/go/tools/release-notes/release_notes.go +++ b/go/tools/release-notes/release_notes.go @@ -17,7 +17,6 @@ limitations under the License. package main import ( - "bytes" "encoding/json" "fmt" "log" @@ -79,9 +78,7 @@ type ( } ) -var ( - releaseNotesPath = `changelog/` -) +var releaseNotesPath = `changelog/` const ( releaseNotesPathGitHub = `https://github.com/vitessio/vitess/blob/main/` @@ -141,7 +138,7 @@ func (rn *releaseNote) generate(rnFile, changelogFile *os.File) error { // Generate the release notes rn.PathToChangeLogFileOnGH = releaseNotesPathGitHub + path.Join(rn.SubDirPath, "changelog.md") if rnFile == nil { - rnFile, err = os.OpenFile(path.Join(rn.SubDirPath, "release_notes.md"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + rnFile, err = os.OpenFile(path.Join(rn.SubDirPath, "release_notes.md"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666) if err != nil { return err } @@ -155,7 +152,7 @@ func (rn *releaseNote) generate(rnFile, changelogFile *os.File) error { // Generate the changelog if changelogFile == nil { - changelogFile, err = os.OpenFile(path.Join(rn.SubDirPath, "changelog.md"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + changelogFile, err = os.OpenFile(path.Join(rn.SubDirPath, "changelog.md"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666) if err != nil { return err } @@ -304,11 +301,11 @@ func getStringForPullRequestInfos(prPerType prsByType) (string, error) { data := createSortedPrTypeSlice(prPerType) t := template.Must(template.New("markdownTemplatePR").Parse(markdownTemplatePR)) - buff := bytes.Buffer{} - if err := t.ExecuteTemplate(&buff, "markdownTemplatePR", data); err != nil { + var buf strings.Builder + if err := t.ExecuteTemplate(&buf, "markdownTemplatePR", data); err != nil { return "", err } - return buff.String(), nil + return buf.String(), nil } func getStringForKnownIssues(issues []knownIssue) (string, error) { @@ -316,11 +313,11 @@ func getStringForKnownIssues(issues []knownIssue) (string, error) { return "", nil } t := template.Must(template.New("markdownTemplateKnownIssues").Parse(markdownTemplateKnownIssues)) - buff := bytes.Buffer{} - if err := t.ExecuteTemplate(&buff, "markdownTemplateKnownIssues", issues); err != nil { + var buf strings.Builder + if err := t.ExecuteTemplate(&buf, "markdownTemplateKnownIssues", issues); err != nil { return "", err } - return buff.String(), nil + return buf.String(), nil } func groupAndStringifyPullRequest(pris []pullRequestInformation) (string, error) { @@ -336,9 +333,7 @@ func groupAndStringifyPullRequest(pris []pullRequestInformation) (string, error) } func main() { - var ( - versionName, summaryFile string - ) + var versionName, summaryFile string pflag.StringVarP(&versionName, "version", "v", "", "name of the version (has to be the following format: v11.0.0)") pflag.StringVarP(&summaryFile, "summary", "s", "", "readme file on which there is a summary of the release") pflag.Parse() diff --git a/go/vt/binlog/binlog_streamer.go b/go/vt/binlog/binlog_streamer.go index abbf73ba506..d62fcc3a915 100644 --- a/go/vt/binlog/binlog_streamer.go +++ b/go/vt/binlog/binlog_streamer.go @@ -251,8 +251,8 @@ func (bls *Streamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog var statements []FullBinlogStatement var format mysql.BinlogFormat var gtid replication.GTID - var pos = bls.startPos - var autocommit = true + pos := bls.startPos + autocommit := true var err error // Remember the RBR state. @@ -723,7 +723,7 @@ func (bls *Streamer) appendDeletes(statements []FullBinlogStatement, tce *tableC } // writeValuesAsSQL is a helper method to print the values as SQL in the -// provided bytes.Buffer. It also returns the value for the keyspaceIDColumn, +// provided strings.Builder. It also returns the value for the keyspaceIDColumn, // and the array of values for the PK, if necessary. func writeValuesAsSQL(sql *sqlparser.TrackedBuffer, tce *tableCacheEntry, rs *mysql.Rows, rowIndex int, getPK bool) (sqltypes.Value, []sqltypes.Value, error) { valueIndex := 0 @@ -794,7 +794,7 @@ func writeValuesAsSQL(sql *sqlparser.TrackedBuffer, tce *tableCacheEntry, rs *my } // writeIdentifiersAsSQL is a helper method to print the identifies as SQL in the -// provided bytes.Buffer. It also returns the value for the keyspaceIDColumn, +// provided strings.Builder. It also returns the value for the keyspaceIDColumn, // and the array of values for the PK, if necessary. func writeIdentifiersAsSQL(sql *sqlparser.TrackedBuffer, tce *tableCacheEntry, rs *mysql.Rows, rowIndex int, getPK bool) (sqltypes.Value, []sqltypes.Value, error) { valueIndex := 0 diff --git a/go/vt/hook/hook.go b/go/vt/hook/hook.go index 6cee35e4241..4f402cdcb44 100644 --- a/go/vt/hook/hook.go +++ b/go/vt/hook/hook.go @@ -17,7 +17,6 @@ limitations under the License. package hook import ( - "bytes" "context" "errors" "fmt" @@ -147,7 +146,7 @@ func (hook *Hook) ExecuteContext(ctx context.Context) (result *HookResult) { } // Run it. - var stdout, stderr bytes.Buffer + var stdout, stderr strings.Builder cmd.Stdout = &stdout cmd.Stderr = &stderr @@ -234,7 +233,7 @@ func (hook *Hook) ExecuteAsWritePipe(out io.Writer) (io.WriteCloser, WaitFunc, i return nil, nil, HOOK_GENERIC_ERROR, fmt.Errorf("failed to configure stdin: %v", err) } cmd.Stdout = out - var stderr bytes.Buffer + var stderr strings.Builder cmd.Stderr = &stderr // Start the process. @@ -273,7 +272,7 @@ func (hook *Hook) ExecuteAsReadPipe(in io.Reader) (io.Reader, WaitFunc, int, err return nil, nil, HOOK_GENERIC_ERROR, fmt.Errorf("failed to configure stdout: %v", err) } cmd.Stdin = in - var stderr bytes.Buffer + var stderr strings.Builder cmd.Stderr = &stderr // Start the process. diff --git a/go/vt/key/destination.go b/go/vt/key/destination.go index 437e980f480..be95406cca7 100644 --- a/go/vt/key/destination.go +++ b/go/vt/key/destination.go @@ -17,7 +17,6 @@ limitations under the License. package key import ( - "bytes" "encoding/hex" "math/rand" "sort" @@ -48,7 +47,7 @@ type Destination interface { // DestinationsString returns a printed version of the destination array. func DestinationsString(destinations []Destination) string { - var buffer bytes.Buffer + var buffer strings.Builder buffer.WriteString("Destinations:") for i, d := range destinations { if i > 0 { @@ -177,7 +176,7 @@ func (d DestinationExactKeyRanges) Resolve(allShards []*topodatapb.ShardReferenc // String is part of the Destination interface. func (d DestinationExactKeyRanges) String() string { - var buffer bytes.Buffer + var buffer strings.Builder buffer.WriteString("DestinationExactKeyRanges(") for i, kr := range d { if i > 0 { @@ -246,7 +245,7 @@ func (d DestinationKeyRanges) Resolve(allShards []*topodatapb.ShardReference, ad // String is part of the Destination interface. func (d DestinationKeyRanges) String() string { - var buffer bytes.Buffer + var buffer strings.Builder buffer.WriteString("DestinationKeyRanges(") for i, kr := range d { if i > 0 { @@ -318,7 +317,7 @@ func (d DestinationKeyspaceIDs) Resolve(allShards []*topodatapb.ShardReference, // String is part of the Destination interface. func (d DestinationKeyspaceIDs) String() string { - var buffer bytes.Buffer + var buffer strings.Builder buffer.WriteString("DestinationKeyspaceIDs(") for i, ksid := range d { if i > 0 { diff --git a/go/vt/logutil/logger.go b/go/vt/logutil/logger.go index 524ca4db4d7..087c310011c 100644 --- a/go/vt/logutil/logger.go +++ b/go/vt/logutil/logger.go @@ -17,7 +17,6 @@ limitations under the License. package logutil import ( - "bytes" "fmt" "io" "runtime" @@ -57,7 +56,7 @@ type Logger interface { // EventToBuffer formats an individual Event into a buffer, without the // final '\n' -func EventToBuffer(event *logutilpb.Event, buf *bytes.Buffer) { +func EventToBuffer(event *logutilpb.Event, buf *strings.Builder) { // Avoid Fprintf, for speed. The format is so simple that we // can do it quickly by hand. It's worth about 3X. Fprintf is hard. @@ -98,8 +97,8 @@ func EventToBuffer(event *logutilpb.Event, buf *bytes.Buffer) { // EventString returns the line in one string func EventString(event *logutilpb.Event) string { - buf := new(bytes.Buffer) - EventToBuffer(event, buf) + var buf strings.Builder + EventToBuffer(event, &buf) return buf.String() } @@ -251,11 +250,11 @@ func NewMemoryLogger() *MemoryLogger { // String returns all the lines in one String, separated by '\n' func (ml *MemoryLogger) String() string { - buf := new(bytes.Buffer) + var buf strings.Builder ml.mu.Lock() defer ml.mu.Unlock() for _, event := range ml.Events { - EventToBuffer(event, buf) + EventToBuffer(event, &buf) buf.WriteByte('\n') } return buf.String() @@ -355,7 +354,7 @@ func (tl *TeeLogger) Printf(format string, v ...any) { const digits = "0123456789" // twoDigits adds a zero-prefixed two-digit integer to buf -func twoDigits(buf *bytes.Buffer, value int) { +func twoDigits(buf *strings.Builder, value int) { buf.WriteByte(digits[value/10]) buf.WriteByte(digits[value%10]) } @@ -363,7 +362,7 @@ func twoDigits(buf *bytes.Buffer, value int) { // nDigits adds an n-digit integer d to buf // padding with pad on the left. // It assumes d >= 0. -func nDigits(buf *bytes.Buffer, n, d int, pad byte) { +func nDigits(buf *strings.Builder, n, d int, pad byte) { tmp := make([]byte, n) j := n - 1 for ; j >= 0 && d > 0; j-- { @@ -377,7 +376,7 @@ func nDigits(buf *bytes.Buffer, n, d int, pad byte) { } // someDigits adds a zero-prefixed variable-width integer to buf -func someDigits(buf *bytes.Buffer, d int64) { +func someDigits(buf *strings.Builder, d int64) { // Print into the top, then copy down. tmp := make([]byte, 10) j := 10 diff --git a/go/vt/mysqlctl/mycnf_gen.go b/go/vt/mysqlctl/mycnf_gen.go index b29d152707f..dd0d6c81c81 100644 --- a/go/vt/mysqlctl/mycnf_gen.go +++ b/go/vt/mysqlctl/mycnf_gen.go @@ -19,11 +19,11 @@ limitations under the License. package mysqlctl import ( - "bytes" "crypto/rand" "fmt" "math/big" "path" + "strings" "text/template" "github.com/spf13/pflag" @@ -54,9 +54,7 @@ const ( innodbLogSubdir = "innodb/logs" ) -var ( - tabletDir string -) +var tabletDir string func init() { for _, cmd := range []string{"mysqlctl", "mysqlctld", "vtcombo", "vttablet", "vttestserver", "vtctld", "vtctldclient"} { @@ -149,8 +147,8 @@ func (cnf *Mycnf) fillMycnfTemplate(tmplSrc string) (string, error) { if err != nil { return "", err } - mycnfData := new(bytes.Buffer) - err = myTemplate.Execute(mycnfData, cnf) + var mycnfData strings.Builder + err = myTemplate.Execute(&mycnfData, cnf) if err != nil { return "", err } diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index ee872c214f4..b6a743cc120 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -780,7 +780,7 @@ func (mysqld *Mysqld) initConfig(cnf *Mycnf, outFile string) error { return err } - return os.WriteFile(outFile, []byte(configData), 0664) + return os.WriteFile(outFile, []byte(configData), 0o664) } func (mysqld *Mysqld) getMycnfTemplate() string { @@ -791,7 +791,7 @@ func (mysqld *Mysqld) getMycnfTemplate() string { } return string(data) // use only specified template } - myTemplateSource := new(bytes.Buffer) + var myTemplateSource strings.Builder myTemplateSource.WriteString("[mysqld]\n") myTemplateSource.WriteString(config.MycnfDefault) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 9180012676f..40848a96536 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -17,7 +17,6 @@ limitations under the License. package schemadiff import ( - "bytes" "errors" "fmt" "io" @@ -613,7 +612,7 @@ func (s *Schema) ToQueries() []string { // ToSQL returns a SQL blob with ordered sequence of queries which can be applied to create the schema func (s *Schema) ToSQL() string { - var buf bytes.Buffer + var buf strings.Builder for _, query := range s.ToQueries() { buf.WriteString(query) buf.WriteString(";\n") diff --git a/go/vt/servenv/status.go b/go/vt/servenv/status.go index ac912fd881e..7a8df5d5568 100644 --- a/go/vt/servenv/status.go +++ b/go/vt/servenv/status.go @@ -17,7 +17,6 @@ limitations under the License. package servenv import ( - "bytes" "fmt" "io" "net" @@ -256,7 +255,7 @@ func (sp *statusPage) statusHandler(w http.ResponseWriter, r *http.Request) { } func (sp *statusPage) reparse(sections []section) (*template.Template, error) { - var buf bytes.Buffer + var buf strings.Builder io.WriteString(&buf, `{{define "status"}}`) io.WriteString(&buf, statusHTML) @@ -301,7 +300,7 @@ func registerDebugBlockProfileRate() { runtime.SetBlockProfileRate(rate) log.Infof("Set block profile rate to: %d", rate) w.Header().Set("Content-Type", "text/plain") - w.Write([]byte(message)) + io.WriteString(w, message) }) } @@ -329,7 +328,7 @@ func registerDebugMutexProfileFraction() { runtime.SetMutexProfileFraction(fraction) log.Infof("Set mutex profiling fraction to: %d", fraction) w.Header().Set("Content-Type", "text/plain") - w.Write([]byte(message)) + io.WriteString(w, message) }) } diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go index 7c8c5e7a963..9a92064d9b3 100644 --- a/go/vt/sqlparser/normalizer_test.go +++ b/go/vt/sqlparser/normalizer_test.go @@ -17,12 +17,12 @@ limitations under the License. package sqlparser import ( - "bytes" "fmt" "math/rand" "reflect" "regexp" "strconv" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -625,7 +625,7 @@ values func BenchmarkNormalizeTPCCInsert(b *testing.B) { generateInsert := func(rows int) string { - var query bytes.Buffer + var query strings.Builder query.WriteString("INSERT IGNORE INTO customer0 (c_id, c_d_id, c_w_id, c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_since, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_payment_cnt, c_delivery_cnt, c_data) values ") for i := 0; i < rows; i++ { fmt.Fprintf(&query, "(%d, %d, %d, '%s','OE','%s','%s', '%s', '%s', '%s', '%s','%s',NOW(),'%s',50000,%f,-10,10,1,0,'%s' )", diff --git a/go/vt/sqlparser/parse_next_test.go b/go/vt/sqlparser/parse_next_test.go index 2e55fbb8a9a..756bf4fb3d0 100644 --- a/go/vt/sqlparser/parse_next_test.go +++ b/go/vt/sqlparser/parse_next_test.go @@ -17,7 +17,6 @@ limitations under the License. package sqlparser import ( - "bytes" "io" "strings" "testing" @@ -29,7 +28,7 @@ import ( // TestParseNextValid concatenates all the valid SQL test cases and check it can read // them as one long string. func TestParseNextValid(t *testing.T) { - var sql bytes.Buffer + var sql strings.Builder for _, tcase := range validSQL { sql.WriteString(strings.TrimSuffix(tcase.input, ";")) sql.WriteRune(';') diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index a6c9d9ccf88..4fe2cd8f247 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -18,7 +18,6 @@ package sqlparser import ( "bufio" - "bytes" "compress/gzip" "fmt" "io" @@ -6130,7 +6129,7 @@ func BenchmarkParseStress(b *testing.B) { for i, sql := range []string{sql1, sql2} { b.Run(fmt.Sprintf("sql%d", i), func(b *testing.B) { - var buf bytes.Buffer + var buf strings.Builder buf.WriteString(sql) querySQL := buf.String() b.ReportAllocs() @@ -6155,7 +6154,7 @@ func BenchmarkParse3(b *testing.B) { // Size of value is 1/10 size of query. Then we add // 10 such values to the where clause. - var baseval bytes.Buffer + var baseval strings.Builder for i := 0; i < benchQuerySize/100; i++ { // Add an escape character: This will force the upcoming // tokenizer improvement to still create a copy of the string. @@ -6167,7 +6166,7 @@ func BenchmarkParse3(b *testing.B) { } } - var buf bytes.Buffer + var buf strings.Builder buf.WriteString("select a from t1 where v = 1") for i := 0; i < 10; i++ { fmt.Fprintf(&buf, " and v%d = \"%d%s\"", i, i, baseval.String()) diff --git a/go/vt/throttler/result.go b/go/vt/throttler/result.go index 179711116a3..0976a180877 100644 --- a/go/vt/throttler/result.go +++ b/go/vt/throttler/result.go @@ -17,8 +17,8 @@ limitations under the License. package throttler import ( - "bytes" "fmt" + "strings" "sync" "text/template" "time" @@ -81,7 +81,7 @@ type result struct { } func (r result) String() string { - var b bytes.Buffer + var b strings.Builder if err := resultStringTemplate.Execute(&b, r); err != nil { panic(fmt.Sprintf("failed to Execute() template: %v", err)) } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 6927b56b89d..21723504019 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -17,7 +17,6 @@ limitations under the License. package workflow import ( - "bytes" "context" "errors" "fmt" @@ -929,7 +928,6 @@ ORDER BY func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowName string) (*trafficSwitcher, *State, error) { ts, err := s.buildTrafficSwitcher(ctx, targetKeyspace, workflowName) - if err != nil { log.Errorf("buildTrafficSwitcher failed: %v", err) return nil, nil, err @@ -973,7 +971,6 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN // We assume a consistent state, so only choose routing rule for one table. if len(ts.Tables()) == 0 { return nil, nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "no tables in workflow %s.%s", targetKeyspace, workflowName) - } table := ts.Tables()[0] @@ -1263,8 +1260,8 @@ func (s *Server) MoveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl } func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTablesCreateRequest, - workflowType binlogdatapb.VReplicationWorkflowType) (res *vtctldatapb.WorkflowStatusResponse, err error) { - + workflowType binlogdatapb.VReplicationWorkflowType, +) (res *vtctldatapb.WorkflowStatusResponse, err error) { span, ctx := trace.NewSpan(ctx, "workflow.Server.MoveTablesCreate") defer span.Finish() @@ -1276,7 +1273,7 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl sourceKeyspace := req.SourceKeyspace targetKeyspace := req.TargetKeyspace - //FIXME validate tableSpecs, allTables, excludeTables + // FIXME validate tableSpecs, allTables, excludeTables var ( tables = req.IncludeTables externalTopo *topo.Server @@ -2028,7 +2025,7 @@ func (s *Server) GetCopyProgress(ctx context.Context, ts *trafficSwitcher, state sourceTableSizes[table] = 0 } - var getTableMetrics = func(tablet *topodatapb.Tablet, query string, rowCounts *map[string]int64, tableSizes *map[string]int64) error { + getTableMetrics := func(tablet *topodatapb.Tablet, query string, rowCounts *map[string]int64, tableSizes *map[string]int64) error { p3qr, err := s.tmc.ExecuteFetchAsDba(ctx, tablet, true, &tabletmanagerdatapb.ExecuteFetchAsDbaRequest{ Query: []byte(query), MaxRows: uint64(len(tables)), @@ -2762,7 +2759,8 @@ func (s *Server) DeleteShard(ctx context.Context, keyspace, shard string, recurs // updateShardRecords updates the shard records based on 'from' or 'to' direction. func (s *Server) updateShardRecords(ctx context.Context, keyspace string, shards []*topo.ShardInfo, cells []string, - servedType topodatapb.TabletType, isFrom bool, clearSourceShards bool, logger logutil.Logger) (err error) { + servedType topodatapb.TabletType, isFrom bool, clearSourceShards bool, logger logutil.Logger, +) (err error) { return topotools.UpdateShardRecords(ctx, s.ts, s.tmc, keyspace, shards, cells, servedType, isFrom, clearSourceShards, logger) } @@ -2977,7 +2975,7 @@ func (s *Server) switchReads(ctx context.Context, req *vtctldatapb.WorkflowSwitc return handleError("invalid request", vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "requesting reversal of SwitchReads for RDONLYs but RDONLY reads have not been switched")) } } - var cells = req.Cells + cells := req.Cells // If no cells were provided in the command then use the value from the workflow. if len(cells) == 0 && ts.optCells != "" { cells = strings.Split(strings.TrimSpace(ts.optCells), ",") @@ -3048,8 +3046,8 @@ func (s *Server) switchReads(ctx context.Context, req *vtctldatapb.WorkflowSwitc // switchWrites is a generic way of migrating write traffic for a workflow. func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwitchTrafficRequest, ts *trafficSwitcher, timeout time.Duration, - cancel bool) (journalID int64, dryRunResults *[]string, err error) { - + cancel bool, +) (journalID int64, dryRunResults *[]string, err error) { var sw iswitcher if req.DryRun { sw = &switcherDryRun{ts: ts, drLog: NewLogRecorder()} @@ -3402,8 +3400,8 @@ func (s *Server) applySQLShard(ctx context.Context, tabletInfo *topo.TabletInfo, // fillStringTemplate returns the string template filled. func fillStringTemplate(tmpl string, vars any) (string, error) { myTemplate := template.Must(template.New("").Parse(tmpl)) - data := new(bytes.Buffer) - if err := myTemplate.Execute(data, vars); err != nil { + var data strings.Builder + if err := myTemplate.Execute(&data, vars); err != nil { return "", err } return data.String(), nil diff --git a/go/vt/vtexplain/vtexplain.go b/go/vt/vtexplain/vtexplain.go index 55e76606e08..b15d5d2af3a 100644 --- a/go/vt/vtexplain/vtexplain.go +++ b/go/vt/vtexplain/vtexplain.go @@ -20,7 +20,6 @@ limitations under the License. package vtexplain import ( - "bytes" "context" "fmt" "sort" @@ -43,9 +42,7 @@ import ( vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" ) -var ( - batchInterval = 10 * time.Millisecond -) +var batchInterval = 10 * time.Millisecond func init() { servenv.OnParseFor("vtexplain", func(fs *pflag.FlagSet) { @@ -154,10 +151,11 @@ type ( func (tq *TabletQuery) MarshalJSON() ([]byte, error) { // Convert Bindvars to strings for nicer output bindVars := make(map[string]string) + var buf strings.Builder for k, v := range tq.BindVars { - var b strings.Builder - sqlparser.EncodeValue(&b, v) - bindVars[k] = b.String() + buf.Reset() + sqlparser.EncodeValue(&buf, v) + bindVars[k] = buf.String() } return jsonutil.MarshalNoEscape(&struct { @@ -337,7 +335,7 @@ func (vte *VTExplain) explain(sql string) (*Explain, error) { // ExplainsAsText returns a text representation of the explains in logical time // order func (vte *VTExplain) ExplainsAsText(explains []*Explain) (string, error) { - var b bytes.Buffer + var b strings.Builder for _, explain := range explains { fmt.Fprintf(&b, "----------------------------------------------------------------------\n") fmt.Fprintf(&b, "%s\n\n", explain.SQL) diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index df56fc04ed2..9e9500d1ca8 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -17,7 +17,6 @@ limitations under the License. package engine import ( - "bytes" "context" "encoding/json" "fmt" @@ -181,7 +180,6 @@ func (u *UserDefinedVariable) MarshalJSON() ([]byte, error) { Name: u.Name, Expr: sqlparser.String(u.Expr), }) - } // VariableName implements the SetOp interface method. @@ -209,7 +207,6 @@ func (svi *SysVarIgnore) MarshalJSON() ([]byte, error) { Type: "SysVarIgnore", SysVarIgnore: *svi, }) - } // VariableName implements the SetOp interface method. @@ -234,7 +231,6 @@ func (svci *SysVarCheckAndIgnore) MarshalJSON() ([]byte, error) { Type: "SysVarCheckAndIgnore", SysVarCheckAndIgnore: *svci, }) - } // VariableName implements the SetOp interface method @@ -278,7 +274,6 @@ func (svs *SysVarReservedConn) MarshalJSON() ([]byte, error) { Type: "SysVarSet", SysVarReservedConn: *svs, }) - } // VariableName implements the SetOp interface method @@ -363,8 +358,8 @@ func (svs *SysVarReservedConn) checkAndUpdateSysVar(ctx context.Context, vcursor } else { value = qr.Rows[0][0] } - buf := new(bytes.Buffer) - value.EncodeSQL(buf) + var buf strings.Builder + value.EncodeSQL(&buf) s := buf.String() vcursor.Session().SetSysVar(svs.Name, s) diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go index d73631cc6ca..fb5eb5dfb0a 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup.go +++ b/go/vt/vtgate/vindexes/consistent_lookup.go @@ -21,6 +21,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" @@ -433,7 +434,7 @@ func (lu *clCommon) MarshalJSON() ([]byte, error) { } func (lu *clCommon) generateLockLookup() string { - var buf bytes.Buffer + var buf strings.Builder fmt.Fprintf(&buf, "select %s from %s", lu.lkp.To, lu.lkp.Table) lu.addWhere(&buf, lu.lkp.FromColumns) fmt.Fprintf(&buf, " for update") @@ -441,7 +442,7 @@ func (lu *clCommon) generateLockLookup() string { } func (lu *clCommon) generateLockOwner() string { - var buf bytes.Buffer + var buf strings.Builder fmt.Fprintf(&buf, "select %s from %s", lu.ownerColumns[0], lu.ownerTable) lu.addWhere(&buf, lu.ownerColumns) // We can lock in share mode because we only want to check @@ -452,7 +453,7 @@ func (lu *clCommon) generateLockOwner() string { } func (lu *clCommon) generateInsertLookup() string { - var buf bytes.Buffer + var buf strings.Builder fmt.Fprintf(&buf, "insert into %s(", lu.lkp.Table) for _, col := range lu.lkp.FromColumns { fmt.Fprintf(&buf, "%s, ", col) @@ -466,13 +467,13 @@ func (lu *clCommon) generateInsertLookup() string { } func (lu *clCommon) generateUpdateLookup() string { - var buf bytes.Buffer + var buf strings.Builder fmt.Fprintf(&buf, "update %s set %s=:%s", lu.lkp.Table, lu.lkp.To, lu.lkp.To) lu.addWhere(&buf, lu.lkp.FromColumns) return buf.String() } -func (lu *clCommon) addWhere(buf *bytes.Buffer, cols []string) { +func (lu *clCommon) addWhere(buf *strings.Builder, cols []string) { buf.WriteString(" where ") for colIdx, column := range cols { if colIdx != 0 { diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index 673b3fcb64b..dac6ea8c27a 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -312,16 +312,16 @@ nextRow: if lkp.MultiShardAutocommit { insStmt = "insert /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */" } - buf := new(bytes.Buffer) + var buf strings.Builder if ignoreMode { - fmt.Fprintf(buf, "%s ignore into %s(", insStmt, lkp.Table) + fmt.Fprintf(&buf, "%s ignore into %s(", insStmt, lkp.Table) } else { - fmt.Fprintf(buf, "%s into %s(", insStmt, lkp.Table) + fmt.Fprintf(&buf, "%s into %s(", insStmt, lkp.Table) } for _, col := range lkp.FromColumns { - fmt.Fprintf(buf, "%s, ", col) + fmt.Fprintf(&buf, "%s, ", col) } - fmt.Fprintf(buf, "%s) values(", lkp.To) + fmt.Fprintf(&buf, "%s) values(", lkp.To) bindVars := make(map[string]*querypb.BindVariable, 2*len(trimmedRowsCols)) for rowIdx := range trimmedToValues { @@ -340,11 +340,11 @@ nextRow: } if lkp.Upsert { - fmt.Fprintf(buf, " on duplicate key update ") + fmt.Fprintf(&buf, " on duplicate key update ") for _, col := range lkp.FromColumns { - fmt.Fprintf(buf, "%s=values(%s), ", col, col) + fmt.Fprintf(&buf, "%s=values(%s), ", col, col) } - fmt.Fprintf(buf, "%s=values(%s)", lkp.To, lkp.To) + fmt.Fprintf(&buf, "%s=values(%s)", lkp.To, lkp.To) } if _, err := vcursor.Execute(ctx, "VindexCreate", buf.String(), bindVars, true /* rollbackOnError */, co); err != nil { @@ -405,7 +405,7 @@ func (lkp *lookupInternal) Update(ctx context.Context, vcursor VCursor, oldValue } func (lkp *lookupInternal) initDelStmt() string { - var delBuffer bytes.Buffer + var delBuffer strings.Builder fmt.Fprintf(&delBuffer, "delete from %s where ", lkp.Table) for colIdx, column := range lkp.FromColumns { if colIdx != 0 { diff --git a/go/vt/vtorc/inst/instance_dao.go b/go/vt/vtorc/inst/instance_dao.go index 211ddce69b1..01b8a750f57 100644 --- a/go/vt/vtorc/inst/instance_dao.go +++ b/go/vt/vtorc/inst/instance_dao.go @@ -17,7 +17,6 @@ package inst import ( - "bytes" "errors" "fmt" "regexp" @@ -52,20 +51,26 @@ const ( backendDBConcurrency = 20 ) -var instanceReadChan = make(chan bool, backendDBConcurrency) -var instanceWriteChan = make(chan bool, backendDBConcurrency) +var ( + instanceReadChan = make(chan bool, backendDBConcurrency) + instanceWriteChan = make(chan bool, backendDBConcurrency) +) var forgetAliases *cache.Cache -var accessDeniedCounter = metrics.NewCounter() -var readTopologyInstanceCounter = metrics.NewCounter() -var readInstanceCounter = metrics.NewCounter() -var writeInstanceCounter = metrics.NewCounter() -var backendWrites = collection.CreateOrReturnCollection("BACKEND_WRITES") -var writeBufferLatency = stopwatch.NewNamedStopwatch() +var ( + accessDeniedCounter = metrics.NewCounter() + readTopologyInstanceCounter = metrics.NewCounter() + readInstanceCounter = metrics.NewCounter() + writeInstanceCounter = metrics.NewCounter() + backendWrites = collection.CreateOrReturnCollection("BACKEND_WRITES") + writeBufferLatency = stopwatch.NewNamedStopwatch() +) -var emptyQuotesRegexp = regexp.MustCompile(`^""$`) -var cacheInitializationCompleted atomic.Bool +var ( + emptyQuotesRegexp = regexp.MustCompile(`^""$`) + cacheInitializationCompleted atomic.Bool +) func init() { _ = metrics.Register("instance.access_denied", accessDeniedCounter) @@ -749,12 +754,10 @@ func ReadOutdatedInstanceKeys() ([]string, error) { // We don;t return an error because we want to keep filling the outdated instances list. return nil }) - if err != nil { log.Error(err) } return res, err - } func mkInsertOdku(table string, columns []string, values []string, nrRows int, insertIgnore bool) (string, error) { @@ -768,21 +771,21 @@ func mkInsertOdku(table string, columns []string, values []string, nrRows int, i return "", errors.New("number of values must be equal to number of columns") } - var q bytes.Buffer + var q strings.Builder var ignore string if insertIgnore { ignore = "ignore" } - var valRow = fmt.Sprintf("(%s)", strings.Join(values, ", ")) - var val bytes.Buffer + valRow := fmt.Sprintf("(%s)", strings.Join(values, ", ")) + var val strings.Builder val.WriteString(valRow) for i := 1; i < nrRows; i++ { val.WriteString(",\n ") // indent VALUES, see below val.WriteString(valRow) } - var col = strings.Join(columns, ", ") - var odku bytes.Buffer + col := strings.Join(columns, ", ") + var odku strings.Builder odku.WriteString(fmt.Sprintf("%s=VALUES(%s)", columns[0], columns[0])) for _, c := range columns[1:] { odku.WriteString(", ") @@ -810,7 +813,7 @@ func mkInsertOdkuForInstances(instances []*Instance, instanceWasActuallyFound bo if !instanceWasActuallyFound { insertIgnore = true } - var columns = []string{ + columns := []string{ "alias", "hostname", "port", @@ -876,7 +879,7 @@ func mkInsertOdkuForInstances(instances []*Instance, instanceWasActuallyFound bo "last_discovery_latency", } - var values = make([]string, len(columns)) + values := make([]string, len(columns)) for i := range columns { values[i] = "?" } diff --git a/go/vt/vttablet/sysloglogger/sysloglogger.go b/go/vt/vttablet/sysloglogger/sysloglogger.go index e56d47bd902..87601884d5c 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger.go @@ -18,8 +18,8 @@ limitations under the License. package sysloglogger import ( - "bytes" "log/syslog" + "strings" "github.com/spf13/pflag" @@ -76,8 +76,10 @@ func run() { } formatParams := map[string][]string{"full": {}} + + var b strings.Builder for stats := range ch { - var b bytes.Buffer + b.Reset() if err := stats.Logf(&b, formatParams); err != nil { log.Errorf("Error formatting logStats: %v", err) continue diff --git a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go index 84de50aae74..51e056687b5 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go +++ b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go @@ -17,7 +17,6 @@ limitations under the License. package tabletenv import ( - "bytes" "context" "encoding/json" "errors" @@ -54,7 +53,7 @@ func TestLogStats(t *testing.T) { } func testFormat(stats *LogStats, params url.Values) string { - var b bytes.Buffer + var b strings.Builder stats.Logf(&b, params) return b.String() } @@ -183,7 +182,6 @@ func TestLogStatsFilter(t *testing.T) { if got != want { t.Errorf("logstats format: got:\n%q\nwant:\n%q\n", got, want) } - } func TestLogStatsFormatQuerySources(t *testing.T) { diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 9d84cb7fceb..6138508aea6 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -18,7 +18,6 @@ package vttest import ( "bufio" - "bytes" "context" "encoding/json" "fmt" @@ -173,12 +172,12 @@ func (cfg *Config) InitSchemas(keyspace, schema string, vschema *vschemapb.Keysp // Write the schema if set. if schema != "" { ksDir := path.Join(schemaDir, keyspace) - err := os.Mkdir(ksDir, os.ModeDir|0775) + err := os.Mkdir(ksDir, os.ModeDir|0o775) if err != nil { return err } fileName := path.Join(ksDir, "schema.sql") - err = os.WriteFile(fileName, []byte(schema), 0666) + err = os.WriteFile(fileName, []byte(schema), 0o666) if err != nil { return err } @@ -191,7 +190,7 @@ func (cfg *Config) InitSchemas(keyspace, schema string, vschema *vschemapb.Keysp if err != nil { return err } - if err := os.WriteFile(vschemaFilePath, vschemaJSON, 0644); err != nil { + if err := os.WriteFile(vschemaFilePath, vschemaJSON, 0o644); err != nil { return err } } @@ -554,6 +553,7 @@ func (db *LocalCluster) createVTSchema() error { } return nil } + func (db *LocalCluster) createDatabases() error { log.Info("Creating databases in cluster...") @@ -697,7 +697,7 @@ func dirExist(dir string) bool { // statements in the SQL file. func LoadSQLFile(filename, sourceroot string) ([]string, error) { var ( - cmd bytes.Buffer + cmd strings.Builder sql []string inSQ bool inDQ bool diff --git a/go/vt/wrangler/schema.go b/go/vt/wrangler/schema.go index 84bc078f240..e6c1fbc25d9 100644 --- a/go/vt/wrangler/schema.go +++ b/go/vt/wrangler/schema.go @@ -17,9 +17,9 @@ limitations under the License. package wrangler import ( - "bytes" "context" "fmt" + "strings" "sync" "text/template" "time" @@ -307,8 +307,8 @@ func (wr *Wrangler) applySQLShard(ctx context.Context, tabletInfo *topo.TabletIn // fillStringTemplate returns the string template filled func fillStringTemplate(tmpl string, vars any) (string, error) { myTemplate := template.Must(template.New("").Parse(tmpl)) - data := new(bytes.Buffer) - if err := myTemplate.Execute(data, vars); err != nil { + var data strings.Builder + if err := myTemplate.Execute(&data, vars); err != nil { return "", err } return data.String(), nil diff --git a/go/vt/zkctl/zkconf.go b/go/vt/zkctl/zkconf.go index 15a912231ff..7361408c3fc 100644 --- a/go/vt/zkctl/zkconf.go +++ b/go/vt/zkctl/zkconf.go @@ -24,7 +24,6 @@ limitations under the License. package zkctl import ( - "bytes" "fmt" "os" "path" @@ -94,16 +93,16 @@ func (cnf *ZkConfig) MyidFile() string { } func (cnf *ZkConfig) WriteMyid() error { - return os.WriteFile(cnf.MyidFile(), []byte(fmt.Sprintf("%v", cnf.ServerId)), 0664) + return os.WriteFile(cnf.MyidFile(), []byte(fmt.Sprintf("%v", cnf.ServerId)), 0o664) } /* Search for first existing file in cnfFiles and subsitute in the right values. */ func MakeZooCfg(cnfFiles []string, cnf *ZkConfig, header string) (string, error) { - myTemplateSource := new(bytes.Buffer) + var myTemplateSource strings.Builder for _, line := range strings.Split(header, "\n") { - fmt.Fprintf(myTemplateSource, "## %v\n", strings.TrimSpace(line)) + fmt.Fprintf(&myTemplateSource, "## %v\n", strings.TrimSpace(line)) } var dataErr error for _, path := range cnfFiles { @@ -127,8 +126,8 @@ func MakeZooCfg(cnfFiles []string, cnf *ZkConfig, header string) (string, error) if err != nil { return "", err } - cnfData := new(bytes.Buffer) - err = myTemplate.Execute(cnfData, cnf) + var cnfData strings.Builder + err = myTemplate.Execute(&cnfData, cnf) if err != nil { return "", err } @@ -161,8 +160,10 @@ func MakeZkConfigFromString(cmdLine string, myID uint32) *ZkConfig { } myID = myID % 1000 - zkServer := zkServerAddr{ServerId: uint32(serverID), ClientPort: 2181, - LeaderPort: 2888, ElectionPort: 3888} + zkServer := zkServerAddr{ + ServerId: uint32(serverID), ClientPort: 2181, + LeaderPort: 2888, ElectionPort: 3888, + } switch len(zkAddrParts) { case 4: zkServer.ClientPort, _ = strconv.Atoi(zkAddrParts[3]) From bda4f9a508240051047bd9f117a2831921ea5fa9 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:05:17 +0530 Subject: [PATCH 028/119] Make `Foreign_key_checks` a Vitess Aware variable (#14484) Signed-off-by: Manan Gupta --- .../vtgate/foreignkey/fk_fuzz_test.go | 138 +- go/test/endtoend/vtgate/foreignkey/fk_test.go | 22 + go/test/vschemawrapper/vschema_wrapper.go | 21 +- go/vt/schemadiff/semantics.go | 4 + go/vt/sqlparser/ast_funcs.go | 14 + go/vt/sqlparser/ast_rewriting.go | 30 +- go/vt/sqlparser/ast_rewriting_test.go | 22 +- go/vt/sqlparser/comments.go | 226 ++ go/vt/sqlparser/comments_test.go | 118 + go/vt/sqlparser/normalizer_test.go | 2 + go/vt/sysvars/sysvars.go | 3 +- go/vt/vtgate/engine/fake_vcursor_test.go | 8 + go/vt/vtgate/engine/primitive.go | 1 + go/vt/vtgate/engine/set.go | 2 + go/vt/vtgate/executor.go | 2 + go/vt/vtgate/executor_set_test.go | 5 +- go/vt/vtgate/planbuilder/builder.go | 16 +- go/vt/vtgate/planbuilder/operators/delete.go | 4 +- go/vt/vtgate/planbuilder/operators/update.go | 39 +- go/vt/vtgate/planbuilder/plan_test.go | 32 + .../vtgate/planbuilder/plancontext/vschema.go | 2 + go/vt/vtgate/planbuilder/simplifier_test.go | 8 +- .../testdata/foreignkey_cases.json | 119 +- .../testdata/foreignkey_checks_off_cases.json | 491 ++++ .../testdata/foreignkey_checks_on_cases.json | 2148 +++++++++++++++++ go/vt/vtgate/planbuilder/update.go | 3 +- go/vt/vtgate/semantics/FakeSI.go | 4 + go/vt/vtgate/semantics/analyzer.go | 11 +- go/vt/vtgate/semantics/analyzer_fk_test.go | 3 +- go/vt/vtgate/semantics/early_rewriter.go | 5 + go/vt/vtgate/semantics/info_schema.go | 4 + go/vt/vtgate/semantics/semantic_state.go | 3 +- go/vt/vtgate/vcursor_impl.go | 45 + go/vt/vtgate/vcursor_impl_test.go | 8 + 34 files changed, 3440 insertions(+), 123 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json create mode 100644 go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json diff --git a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go index 4c84eae2f42..2005b12a8fd 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/utils" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/sqlparser" ) type QueryFormat string @@ -52,6 +53,7 @@ type fuzzer struct { updateShare int concurrency int queryFormat QueryFormat + fkState *bool // shouldStop is an internal state variable, that tells the fuzzer // whether it should stop or not. @@ -71,7 +73,7 @@ type debugInfo struct { } // newFuzzer creates a new fuzzer struct. -func newFuzzer(concurrency int, maxValForId int, maxValForCol int, insertShare int, deleteShare int, updateShare int, queryFormat QueryFormat) *fuzzer { +func newFuzzer(concurrency int, maxValForId int, maxValForCol int, insertShare int, deleteShare int, updateShare int, queryFormat QueryFormat, fkState *bool) *fuzzer { fz := &fuzzer{ concurrency: concurrency, maxValForId: maxValForId, @@ -80,6 +82,7 @@ func newFuzzer(concurrency int, maxValForId int, maxValForCol int, insertShare i deleteShare: deleteShare, updateShare: updateShare, queryFormat: queryFormat, + fkState: fkState, wg: sync.WaitGroup{}, } // Initially the fuzzer thread is stopped. @@ -131,17 +134,18 @@ func (fz *fuzzer) generateInsertDMLQuery(insertType string) string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] + setVarFkChecksVal := fz.getSetVarFkChecksVal() if tableName == "fk_t20" { colValue := rand.Intn(1 + fz.maxValForCol) col2Value := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("%s into %v (id, col, col2) values (%v, %v, %v)", insertType, tableName, idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)) + return fmt.Sprintf("%s %vinto %v (id, col, col2) values (%v, %v, %v)", insertType, setVarFkChecksVal, tableName, idValue, convertIntValueToString(colValue), convertIntValueToString(col2Value)) } else if isMultiColFkTable(tableName) { colaValue := rand.Intn(1 + fz.maxValForCol) colbValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("%s into %v (id, cola, colb) values (%v, %v, %v)", insertType, tableName, idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)) + return fmt.Sprintf("%s %vinto %v (id, cola, colb) values (%v, %v, %v)", insertType, setVarFkChecksVal, tableName, idValue, convertIntValueToString(colaValue), convertIntValueToString(colbValue)) } else { colValue := rand.Intn(1 + fz.maxValForCol) - return fmt.Sprintf("%s into %v (id, col) values (%v, %v)", insertType, tableName, idValue, convertIntValueToString(colValue)) + return fmt.Sprintf("%s %vinto %v (id, col) values (%v, %v)", insertType, setVarFkChecksVal, tableName, idValue, convertIntValueToString(colValue)) } } @@ -150,10 +154,11 @@ func (fz *fuzzer) generateUpdateDMLQuery() string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) tableName := fkTables[tableId] + setVarFkChecksVal := fz.getSetVarFkChecksVal() if tableName == "fk_t20" { colValue := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) col2Value := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) - return fmt.Sprintf("update %v set col = %v, col2 = %v where id = %v", tableName, colValue, col2Value, idValue) + return fmt.Sprintf("update %v%v set col = %v, col2 = %v where id = %v", setVarFkChecksVal, tableName, colValue, col2Value, idValue) } else if isMultiColFkTable(tableName) { if rand.Intn(2) == 0 { colaValue := convertIntValueToString(rand.Intn(1 + fz.maxValForCol)) @@ -162,7 +167,7 @@ func (fz *fuzzer) generateUpdateDMLQuery() string { colaValue = fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") colbValue = fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") } - return fmt.Sprintf("update %v set cola = %v, colb = %v where id = %v", tableName, colaValue, colbValue, idValue) + return fmt.Sprintf("update %v%v set cola = %v, colb = %v where id = %v", setVarFkChecksVal, tableName, colaValue, colbValue, idValue) } else { colValue := fz.generateExpression(rand.Intn(4)+1, "cola", "colb", "id") colToUpdate := []string{"cola", "colb"}[rand.Intn(2)] @@ -170,7 +175,7 @@ func (fz *fuzzer) generateUpdateDMLQuery() string { } } else { colValue := fz.generateExpression(rand.Intn(4)+1, "col", "id") - return fmt.Sprintf("update %v set col = %v where id = %v", tableName, colValue, idValue) + return fmt.Sprintf("update %v%v set col = %v where id = %v", setVarFkChecksVal, tableName, colValue, idValue) } } @@ -178,7 +183,8 @@ func (fz *fuzzer) generateUpdateDMLQuery() string { func (fz *fuzzer) generateDeleteDMLQuery() string { tableId := rand.Intn(len(fkTables)) idValue := 1 + rand.Intn(fz.maxValForId) - query := fmt.Sprintf("delete from %v where id = %v", fkTables[tableId], idValue) + setVarFkChecksVal := fz.getSetVarFkChecksVal() + query := fmt.Sprintf("delete %vfrom %v where id = %v", setVarFkChecksVal, fkTables[tableId], idValue) return query } @@ -204,6 +210,9 @@ func (fz *fuzzer) runFuzzerThread(t *testing.T, sharded bool, fuzzerThreadId int // Create a MySQL Compare that connects to both Vitess and MySQL and runs the queries against both. mcmp, err := utils.NewMySQLCompare(t, vtParams, mysqlParams) require.NoError(t, err) + if fz.fkState != nil { + mcmp.Exec(fmt.Sprintf("SET FOREIGN_KEY_CHECKS=%v", sqlparser.FkChecksStateString(fz.fkState))) + } var vitessDb, mysqlDb *sql.DB if fz.queryFormat == PreparedStatementPacket { // Open another connection to Vitess using the go-sql-driver so that we can send prepared statements as COM_STMT_PREPARE packets. @@ -464,6 +473,21 @@ func (fz *fuzzer) generateParameterizedDeleteQuery() (query string, params []any return fmt.Sprintf("delete from %v where id = ?", fkTables[tableId]), []any{idValue} } +// getSetVarFkChecksVal generates an optimizer hint to randomly set the foreign key checks to on or off or leave them unaltered. +func (fz *fuzzer) getSetVarFkChecksVal() string { + if fz.concurrency != 1 { + return "" + } + val := rand.Intn(3) + if val == 0 { + return "" + } + if val == 1 { + return "/*+ SET_VAR(foreign_key_checks=On) */ " + } + return "/*+ SET_VAR(foreign_key_checks=Off) */ " +} + // TestFkFuzzTest is a fuzzer test that works by querying the database concurrently. // We have a pre-written set of query templates that we will use, but the data in the queries will // be randomly generated. The intent is that we hammer the database as a real-world application would @@ -615,57 +639,65 @@ func TestFkFuzzTest(t *testing.T) { updateShare: 50, }} - for _, tt := range testcases { - for _, testSharded := range []bool{false, true} { - for _, queryFormat := range []QueryFormat{OlapSQLQueries, SQLQueries, PreparedStatmentQueries, PreparedStatementPacket} { - t.Run(getTestName(tt.name, testSharded)+fmt.Sprintf(" QueryFormat - %v", queryFormat), func(t *testing.T) { - mcmp, closer := start(t) - defer closer() - // Set the correct keyspace to use from VtGates. - if testSharded { - t.Skip("Skip test since we don't have sharded foreign key support yet") - _ = utils.Exec(t, mcmp.VtConn, "use `ks`") - } else { - _ = utils.Exec(t, mcmp.VtConn, "use `uks`") + valTrue := true + valFalse := false + for _, fkState := range []*bool{nil, &valTrue, &valFalse} { + for _, tt := range testcases { + for _, testSharded := range []bool{false, true} { + for _, queryFormat := range []QueryFormat{OlapSQLQueries, SQLQueries, PreparedStatmentQueries, PreparedStatementPacket} { + if fkState != nil && (queryFormat != SQLQueries || tt.concurrency != 1) { + continue } - // Ensure that the Vitess database is originally empty - ensureDatabaseState(t, mcmp.VtConn, true) - ensureDatabaseState(t, mcmp.MySQLConn, true) - - // Create the fuzzer. - fz := newFuzzer(tt.concurrency, tt.maxValForId, tt.maxValForCol, tt.insertShare, tt.deleteShare, tt.updateShare, queryFormat) - - // Start the fuzzer. - fz.start(t, testSharded) - - // Wait for the timeForTesting so that the threads continue to run. - totalTime := time.After(tt.timeForTesting) - done := false - for !done { - select { - case <-totalTime: - done = true - case <-time.After(10 * time.Millisecond): - validateReplication(t) + t.Run(getTestName(tt.name, testSharded)+fmt.Sprintf(" FkState - %v QueryFormat - %v", sqlparser.FkChecksStateString(fkState), queryFormat), func(t *testing.T) { + mcmp, closer := start(t) + defer closer() + // Set the correct keyspace to use from VtGates. + if testSharded { + t.Skip("Skip test since we don't have sharded foreign key support yet") + _ = utils.Exec(t, mcmp.VtConn, "use `ks`") + } else { + _ = utils.Exec(t, mcmp.VtConn, "use `uks`") + } + + // Ensure that the Vitess database is originally empty + ensureDatabaseState(t, mcmp.VtConn, true) + ensureDatabaseState(t, mcmp.MySQLConn, true) + + // Create the fuzzer. + fz := newFuzzer(tt.concurrency, tt.maxValForId, tt.maxValForCol, tt.insertShare, tt.deleteShare, tt.updateShare, queryFormat, fkState) + + // Start the fuzzer. + fz.start(t, testSharded) + + // Wait for the timeForTesting so that the threads continue to run. + totalTime := time.After(tt.timeForTesting) + done := false + for !done { + select { + case <-totalTime: + done = true + case <-time.After(10 * time.Millisecond): + validateReplication(t) + } } - } - fz.stop() + fz.stop() - // We encountered an error while running the fuzzer. Let's print out the information! - if fz.firstFailureInfo != nil { - log.Errorf("Failing query - %v", fz.firstFailureInfo.queryToFail) - for idx, table := range fkTables { - log.Errorf("MySQL data for %v -\n%v", table, fz.firstFailureInfo.mysqlState[idx].Rows) - log.Errorf("Vitess data for %v -\n%v", table, fz.firstFailureInfo.vitessState[idx].Rows) + // We encountered an error while running the fuzzer. Let's print out the information! + if fz.firstFailureInfo != nil { + log.Errorf("Failing query - %v", fz.firstFailureInfo.queryToFail) + for idx, table := range fkTables { + log.Errorf("MySQL data for %v -\n%v", table, fz.firstFailureInfo.mysqlState[idx].Rows) + log.Errorf("Vitess data for %v -\n%v", table, fz.firstFailureInfo.vitessState[idx].Rows) + } } - } - // ensure Vitess database has some data. This ensures not all the commands failed. - ensureDatabaseState(t, mcmp.VtConn, false) - // Verify the consistency of the data. - verifyDataIsCorrect(t, mcmp, tt.concurrency) - }) + // ensure Vitess database has some data. This ensures not all the commands failed. + ensureDatabaseState(t, mcmp.VtConn, false) + // Verify the consistency of the data. + verifyDataIsCorrect(t, mcmp, tt.concurrency) + }) + } } } } diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index 7a29136e915..67e23c1cfd1 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "io" + "strings" "testing" "time" @@ -888,6 +889,22 @@ func TestFkQueries(t *testing.T) { "update fk_t15 set col = col * (col - (col))", }, }, + { + name: "Update a child table which doesn't cause an update, but parent doesn't have that value", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2)", + "insert /*+ SET_VAR(foreign_key_checks=0) */ into fk_t11 (id, col) values (1,1),(2,2),(5,5)", + "update fk_t11 set col = id where id in (1, 5)", + }, + }, + { + name: "Update a child table from a null to a value that parent doesn't have", + queries: []string{ + "insert into fk_t10 (id, col) values (1,1),(2,2)", + "insert into fk_t11 (id, col) values (1,1),(2,2),(5,NULL)", + "update fk_t11 set col = id where id in (1, 5)", + }, + }, } for _, testcase := range testcases { @@ -954,6 +971,11 @@ func TestFkOneCase(t *testing.T) { ensureDatabaseState(t, mcmp.MySQLConn, true) for _, query := range queries { + if strings.HasPrefix(query, "vexplain") { + res := utils.Exec(t, mcmp.VtConn, query) + log.Errorf("Query %v, Result - %v", query, res.Rows) + continue + } _, _ = mcmp.ExecAllowAndCompareError(query) if t.Failed() { log.Errorf("Query failed - %v", query) diff --git a/go/test/vschemawrapper/vschema_wrapper.go b/go/test/vschemawrapper/vschema_wrapper.go index 78cf0f8d41c..85d9840c3f7 100644 --- a/go/test/vschemawrapper/vschema_wrapper.go +++ b/go/test/vschemawrapper/vschema_wrapper.go @@ -40,14 +40,15 @@ import ( var _ plancontext.VSchema = (*VSchemaWrapper)(nil) type VSchemaWrapper struct { - V *vindexes.VSchema - Keyspace *vindexes.Keyspace - TabletType_ topodatapb.TabletType - Dest key.Destination - SysVarEnabled bool - Version plancontext.PlannerVersion - EnableViews bool - TestBuilder func(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error) + V *vindexes.VSchema + Keyspace *vindexes.Keyspace + TabletType_ topodatapb.TabletType + Dest key.Destination + SysVarEnabled bool + ForeignKeyChecksState *bool + Version plancontext.PlannerVersion + EnableViews bool + TestBuilder func(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error) } func (vw *VSchemaWrapper) GetPrepareData(stmtName string) *vtgatepb.PrepareData { @@ -140,6 +141,10 @@ func (vw *VSchemaWrapper) KeyspaceError(keyspace string) error { return nil } +func (vw *VSchemaWrapper) GetForeignKeyChecksState() *bool { + return vw.ForeignKeyChecksState +} + func (vw *VSchemaWrapper) AllKeyspace() ([]*vindexes.Keyspace, error) { if vw.Keyspace == nil { return nil, vterrors.VT13001("keyspace not available") diff --git a/go/vt/schemadiff/semantics.go b/go/vt/schemadiff/semantics.go index da9c6b1e2a9..7cfe127cf57 100644 --- a/go/vt/schemadiff/semantics.go +++ b/go/vt/schemadiff/semantics.go @@ -64,6 +64,10 @@ func (si *declarativeSchemaInformation) KeyspaceError(keyspace string) error { return nil } +func (si *declarativeSchemaInformation) GetForeignKeyChecksState() *bool { + return nil +} + // addTable adds a fake table with an empty column list func (si *declarativeSchemaInformation) addTable(tableName string) { tbl := &vindexes.Table{ diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 5ab4e0ba98c..3e8b54f7e08 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -357,6 +357,20 @@ func (node *ParsedComments) AddQueryHint(queryHint string) (Comments, error) { return newComments, nil } +// FkChecksStateString prints the foreign key checks state. +func FkChecksStateString(state *bool) string { + if state == nil { + return "" + } + switch *state { + case false: + return "Off" + case true: + return "On" + } + return "" +} + // ParseParams parses the vindex parameter list, pulling out the special-case // "owner" parameter func (node *VindexSpec) ParseParams() (string, map[string]string) { diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index f3255143dbb..e20a5b80f70 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -51,6 +51,7 @@ func PrepareAST( selectLimit int, setVarComment string, sysVars map[string]string, + fkChecksState *bool, views VSchemaViews, ) (*RewriteASTResult, error) { if parameterize { @@ -59,7 +60,7 @@ func PrepareAST( return nil, err } } - return RewriteAST(in, keyspace, selectLimit, setVarComment, sysVars, views) + return RewriteAST(in, keyspace, selectLimit, setVarComment, sysVars, fkChecksState, views) } // RewriteAST rewrites the whole AST, replacing function calls and adding column aliases to queries. @@ -70,9 +71,10 @@ func RewriteAST( selectLimit int, setVarComment string, sysVars map[string]string, + fkChecksState *bool, views VSchemaViews, ) (*RewriteASTResult, error) { - er := newASTRewriter(keyspace, selectLimit, setVarComment, sysVars, views) + er := newASTRewriter(keyspace, selectLimit, setVarComment, sysVars, fkChecksState, views) er.shouldRewriteDatabaseFunc = shouldRewriteDatabaseFunc(in) result := SafeRewrite(in, er.rewriteDown, er.rewriteUp) if er.err != nil { @@ -121,16 +123,18 @@ type astRewriter struct { keyspace string selectLimit int setVarComment string + fkChecksState *bool sysVars map[string]string views VSchemaViews } -func newASTRewriter(keyspace string, selectLimit int, setVarComment string, sysVars map[string]string, views VSchemaViews) *astRewriter { +func newASTRewriter(keyspace string, selectLimit int, setVarComment string, sysVars map[string]string, fkChecksState *bool, views VSchemaViews) *astRewriter { return &astRewriter{ bindVars: &BindVarNeeds{}, keyspace: keyspace, selectLimit: selectLimit, setVarComment: setVarComment, + fkChecksState: fkChecksState, sysVars: sysVars, views: views, } @@ -154,7 +158,7 @@ const ( ) func (er *astRewriter) rewriteAliasedExpr(node *AliasedExpr) (*BindVarNeeds, error) { - inner := newASTRewriter(er.keyspace, er.selectLimit, er.setVarComment, er.sysVars, er.views) + inner := newASTRewriter(er.keyspace, er.selectLimit, er.setVarComment, er.sysVars, nil, er.views) inner.shouldRewriteDatabaseFunc = er.shouldRewriteDatabaseFunc tmp := SafeRewrite(node.Expr, inner.rewriteDown, inner.rewriteUp) newExpr, ok := tmp.(Expr) @@ -177,13 +181,19 @@ func (er *astRewriter) rewriteDown(node SQLNode, _ SQLNode) bool { func (er *astRewriter) rewriteUp(cursor *Cursor) bool { // Add SET_VAR comment to this node if it supports it and is needed - if supportOptimizerHint, supportsOptimizerHint := cursor.Node().(SupportOptimizerHint); supportsOptimizerHint && er.setVarComment != "" { - newComments, err := supportOptimizerHint.GetParsedComments().AddQueryHint(er.setVarComment) - if err != nil { - er.err = err - return false + if supportOptimizerHint, supportsOptimizerHint := cursor.Node().(SupportOptimizerHint); supportsOptimizerHint { + if er.setVarComment != "" { + newComments, err := supportOptimizerHint.GetParsedComments().AddQueryHint(er.setVarComment) + if err != nil { + er.err = err + return false + } + supportOptimizerHint.SetComments(newComments) + } + if er.fkChecksState != nil { + newComments := supportOptimizerHint.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, FkChecksStateString(er.fkChecksState)) + supportOptimizerHint.SetComments(newComments) } - supportOptimizerHint.SetComments(newComments) } switch node := cursor.Node().(type) { diff --git a/go/vt/sqlparser/ast_rewriting_test.go b/go/vt/sqlparser/ast_rewriting_test.go index 2ed92201296..c8bc0fdbef9 100644 --- a/go/vt/sqlparser/ast_rewriting_test.go +++ b/go/vt/sqlparser/ast_rewriting_test.go @@ -37,12 +37,12 @@ type testCaseSysVar struct { } type myTestCase struct { - in, expected string - liid, db, foundRows, rowCount, rawGTID, rawTimeout, sessTrackGTID bool - ddlStrategy, migrationContext, sessionUUID, sessionEnableSystemSettings bool - udv int - autocommit, clientFoundRows, skipQueryPlanCache, socket, queryTimeout bool - sqlSelectLimit, transactionMode, workload, version, versionComment bool + in, expected string + liid, db, foundRows, rowCount, rawGTID, rawTimeout, sessTrackGTID bool + ddlStrategy, migrationContext, sessionUUID, sessionEnableSystemSettings bool + udv int + autocommit, foreignKeyChecks, clientFoundRows, skipQueryPlanCache, socket, queryTimeout bool + sqlSelectLimit, transactionMode, workload, version, versionComment bool } func TestRewrites(in *testing.T) { @@ -296,6 +296,7 @@ func TestRewrites(in *testing.T) { in: "SHOW VARIABLES", expected: "SHOW VARIABLES", autocommit: true, + foreignKeyChecks: true, clientFoundRows: true, skipQueryPlanCache: true, sqlSelectLimit: true, @@ -316,6 +317,7 @@ func TestRewrites(in *testing.T) { in: "SHOW GLOBAL VARIABLES", expected: "SHOW GLOBAL VARIABLES", autocommit: true, + foreignKeyChecks: true, clientFoundRows: true, skipQueryPlanCache: true, sqlSelectLimit: true, @@ -346,6 +348,7 @@ func TestRewrites(in *testing.T) { SQLSelectLimitUnset, "", nil, + nil, &fakeViews{}, ) require.NoError(err) @@ -362,6 +365,7 @@ func TestRewrites(in *testing.T) { assert.Equal(tc.rowCount, result.NeedsFuncResult(RowCountName), "should need row count") assert.Equal(tc.udv, len(result.NeedUserDefinedVariables), "count of user defined variables") assert.Equal(tc.autocommit, result.NeedsSysVar(sysvars.Autocommit.Name), "should need :__vtautocommit") + assert.Equal(tc.foreignKeyChecks, result.NeedsSysVar(sysvars.ForeignKeyChecks.Name), "should need :__vtforeignKeyChecks") assert.Equal(tc.clientFoundRows, result.NeedsSysVar(sysvars.ClientFoundRows.Name), "should need :__vtclientFoundRows") assert.Equal(tc.skipQueryPlanCache, result.NeedsSysVar(sysvars.SkipQueryPlanCache.Name), "should need :__vtskipQueryPlanCache") assert.Equal(tc.sqlSelectLimit, result.NeedsSysVar(sysvars.SQLSelectLimit.Name), "should need :__vtsqlSelectLimit") @@ -436,7 +440,7 @@ func TestRewritesWithSetVarComment(in *testing.T) { stmt, err := Parse(tc.in) require.NoError(err) - result, err := RewriteAST(stmt, "ks", SQLSelectLimitUnset, tc.setVarComment, nil, &fakeViews{}) + result, err := RewriteAST(stmt, "ks", SQLSelectLimitUnset, tc.setVarComment, nil, nil, &fakeViews{}) require.NoError(err) expected, err := Parse(tc.expected) @@ -484,7 +488,7 @@ func TestRewritesSysVar(in *testing.T) { stmt, err := Parse(tc.in) require.NoError(err) - result, err := RewriteAST(stmt, "ks", SQLSelectLimitUnset, "", tc.sysVar, &fakeViews{}) + result, err := RewriteAST(stmt, "ks", SQLSelectLimitUnset, "", tc.sysVar, nil, &fakeViews{}) require.NoError(err) expected, err := Parse(tc.expected) @@ -534,7 +538,7 @@ func TestRewritesWithDefaultKeyspace(in *testing.T) { stmt, err := Parse(tc.in) require.NoError(err) - result, err := RewriteAST(stmt, "sys", SQLSelectLimitUnset, "", nil, &fakeViews{}) + result, err := RewriteAST(stmt, "sys", SQLSelectLimitUnset, "", nil, nil, &fakeViews{}) require.NoError(err) expected, err := Parse(tc.expected) diff --git a/go/vt/sqlparser/comments.go b/go/vt/sqlparser/comments.go index 84b73f8e81c..fbc1e17ba2f 100644 --- a/go/vt/sqlparser/comments.go +++ b/go/vt/sqlparser/comments.go @@ -17,11 +17,13 @@ limitations under the License. package sqlparser import ( + "fmt" "strconv" "strings" "unicode" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" querypb "vitess.io/vitess/go/vt/proto/query" @@ -60,6 +62,9 @@ const ( // MaxPriorityValue specifies the maximum value allowed for the priority query directive. Valid priority values are // between zero and MaxPriorityValue. MaxPriorityValue = 100 + + // OptimizerHintSetVar is the optimizer hint used in MySQL to set the value of a specific session variable for a query. + OptimizerHintSetVar = "SET_VAR" ) var ErrInvalidPriority = vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Invalid priority value specified in query") @@ -266,6 +271,206 @@ func (c *ParsedComments) Directives() *CommentDirectives { return c._directives } +// GetMySQLSetVarValue gets the value of the given variable if it is part of a /*+ SET_VAR() */ MySQL optimizer hint. +func (c *ParsedComments) GetMySQLSetVarValue(key string) string { + if c == nil { + // If we have no parsed comments, then we return an empty string. + return "" + } + for _, commentStr := range c.comments { + // Skip all the comments that don't start with the query optimizer prefix. + if commentStr[0:3] != queryOptimizerPrefix { + continue + } + + pos := 4 + for pos < len(commentStr) { + // Go over the entire comment and extract an optimizer hint. + // We get back the final position of the cursor, along with the start and end of + // the optimizer hint name and content. + finalPos, ohNameStart, ohNameEnd, ohContentStart, ohContentEnd := getOptimizerHint(pos, commentStr) + pos = finalPos + 1 + // If we didn't find an optimizer hint or if it was malformed, we skip it. + if ohContentEnd == -1 { + break + } + // Construct the name and the content from the starts and ends. + ohName := commentStr[ohNameStart:ohNameEnd] + ohContent := commentStr[ohContentStart:ohContentEnd] + // Check if the optimizer hint name matches `SET_VAR`. + if strings.EqualFold(strings.TrimSpace(ohName), OptimizerHintSetVar) { + // If it does, then we cut the string at the first occurrence of "=". + // That gives us the name of the variable, and the value that it is being set to. + // If the variable matches what we are looking for, we return its value. + setVarName, setVarValue, isValid := strings.Cut(ohContent, "=") + if !isValid { + continue + } + if strings.EqualFold(strings.TrimSpace(setVarName), key) { + return strings.TrimSpace(setVarValue) + } + } + } + + // MySQL only parses the first comment that has the optimizer hint prefix. The following ones are ignored. + return "" + } + return "" +} + +// SetMySQLSetVarValue updates or sets the value of the given variable as part of a /*+ SET_VAR() */ MySQL optimizer hint. +func (c *ParsedComments) SetMySQLSetVarValue(key string, value string) (newComments Comments) { + if c == nil { + // If we have no parsed comments, then we create a new one with the required optimizer hint and return it. + newComments = append(newComments, fmt.Sprintf("/*+ %v(%v=%v) */", OptimizerHintSetVar, key, value)) + return + } + seenFirstOhComment := false + for _, commentStr := range c.comments { + // Skip all the comments that don't start with the query optimizer prefix. + // Also, since MySQL only parses the first comment that has the optimizer hint prefix and ignores the following ones, + // we skip over all the comments that come after we have seen the first comment with the optimizer hint. + if seenFirstOhComment || commentStr[0:3] != queryOptimizerPrefix { + newComments = append(newComments, commentStr) + continue + } + + seenFirstOhComment = true + finalComment := "/*+" + keyPresent := false + pos := 4 + for pos < len(commentStr) { + // Go over the entire comment and extract an optimizer hint. + // We get back the final position of the cursor, along with the start and end of + // the optimizer hint name and content. + finalPos, ohNameStart, ohNameEnd, ohContentStart, ohContentEnd := getOptimizerHint(pos, commentStr) + pos = finalPos + 1 + // If we didn't find an optimizer hint or if it was malformed, we skip it. + if ohContentEnd == -1 { + break + } + // Construct the name and the content from the starts and ends. + ohName := commentStr[ohNameStart:ohNameEnd] + ohContent := commentStr[ohContentStart:ohContentEnd] + // Check if the optimizer hint name matches `SET_VAR`. + if strings.EqualFold(strings.TrimSpace(ohName), OptimizerHintSetVar) { + // If it does, then we cut the string at the first occurrence of "=". + // That gives us the name of the variable, and the value that it is being set to. + // If the variable matches what we are looking for, we can change its value. + // Otherwise we add the comment as is to our final comments and move on. + setVarName, _, isValid := strings.Cut(ohContent, "=") + if !isValid || !strings.EqualFold(strings.TrimSpace(setVarName), key) { + finalComment += fmt.Sprintf(" %v(%v)", ohName, ohContent) + continue + } + if strings.EqualFold(strings.TrimSpace(setVarName), key) { + keyPresent = true + finalComment += fmt.Sprintf(" %v(%v=%v)", ohName, strings.TrimSpace(setVarName), value) + } + } else { + // If it doesn't match, we add it to our final comment and move on. + finalComment += fmt.Sprintf(" %v(%v)", ohName, ohContent) + } + } + // If we haven't found any SET_VAR optimizer hint with the matching variable, + // then we add a new optimizer hint to introduce this variable. + if !keyPresent { + finalComment += fmt.Sprintf(" %v(%v=%v)", OptimizerHintSetVar, key, value) + } + + finalComment += " */" + newComments = append(newComments, finalComment) + } + // If we have not seen even a single comment that has the optimizer hint prefix, + // then we add a new optimizer hint to introduce this variable. + if !seenFirstOhComment { + newComments = append(newComments, fmt.Sprintf("/*+ %v(%v=%v) */", OptimizerHintSetVar, key, value)) + } + return newComments +} + +// getOptimizerHint goes over the comment string from the given initial position. +// It returns back the final position of the cursor, along with the start and end of +// the optimizer hint name and content. +func getOptimizerHint(initialPos int, commentStr string) (pos int, ohNameStart int, ohNameEnd int, ohContentStart int, ohContentEnd int) { + ohContentEnd = -1 + // skip spaces as they aren't interesting. + pos = skipBlanks(initialPos, commentStr) + ohNameStart = pos + pos++ + // All characters until we get a space of a opening bracket are part of the optimizer hint name. + for pos < len(commentStr) { + if commentStr[pos] == ' ' || commentStr[pos] == '(' { + break + } + pos++ + } + // Mark the end of the optimizer hint name and skip spaces. + ohNameEnd = pos + pos = skipBlanks(pos, commentStr) + // Verify that the comment is not malformed. If it doesn't contain an opening bracket + // at the current position, then something is wrong. + if pos >= len(commentStr) || commentStr[pos] != '(' { + return + } + // Seeing the opening bracket, marks the start of the optimizer hint content. + // We skip over the comment until we see the end of the parenthesis. + pos++ + ohContentStart = pos + pos = skipUntilParenthesisEnd(pos, commentStr) + ohContentEnd = pos + return +} + +// skipUntilParenthesisEnd reads the comment string given the initial position and skips over until +// it has seen the end of opening bracket. +func skipUntilParenthesisEnd(pos int, commentStr string) int { + for pos < len(commentStr) { + switch commentStr[pos] { + case ')': + // If we see a closing bracket, we have found the ending of our parenthesis. + return pos + case '\'': + // If we see a single quote character, then it signifies the start of a new string. + // We wait until we see the end of this string. + pos++ + pos = skipUntilCharacter(pos, commentStr, '\'') + case '"': + // If we see a double quote character, then it signifies the start of a new string. + // We wait until we see the end of this string. + pos++ + pos = skipUntilCharacter(pos, commentStr, '"') + } + pos++ + } + + return pos +} + +// skipUntilCharacter skips until the given character has been seen in the comment string, given the starting position. +func skipUntilCharacter(pos int, commentStr string, ch byte) int { + for pos < len(commentStr) { + if commentStr[pos] != ch { + pos++ + continue + } + break + } + return pos +} + +// skipBlanks skips over space characters from the comment string, given the starting position. +func skipBlanks(pos int, commentStr string) int { + for pos < len(commentStr) { + if commentStr[pos] == ' ' { + pos++ + continue + } + break + } + return pos +} + func (c *ParsedComments) Length() int { if c == nil { return 0 @@ -349,6 +554,27 @@ func AllowScatterDirective(stmt Statement) bool { return checkDirective(stmt, DirectiveAllowScatter) } +// ForeignKeyChecksState returns the state of foreign_key_checks variable if it is part of a SET_VAR optimizer hint in the comments. +func ForeignKeyChecksState(stmt Statement) *bool { + cmt, ok := stmt.(Commented) + if ok { + fkChecksVal := cmt.GetParsedComments().GetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name) + // If the value of the `foreign_key_checks` optimizer hint is something that doesn't make sense, + // then MySQL just ignores it and treats it like the case, where it is unspecified. We are choosing + // to have the same behaviour here. If the value doesn't match any of the acceptable values, we return nil, + // that signifies that no value was specified. + switch strings.ToLower(fkChecksVal) { + case "on", "1": + fkState := true + return &fkState + case "off", "0": + fkState := false + return &fkState + } + } + return nil +} + func checkDirective(stmt Statement, key string) bool { cmt, ok := stmt.(Commented) if ok { diff --git a/go/vt/sqlparser/comments_test.go b/go/vt/sqlparser/comments_test.go index b3c1bf9fec8..6312acb5994 100644 --- a/go/vt/sqlparser/comments_test.go +++ b/go/vt/sqlparser/comments_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/sysvars" ) func TestSplitComments(t *testing.T) { @@ -551,3 +552,120 @@ func TestGetPriorityFromStatement(t *testing.T) { }) } } + +// TestGetMySQLSetVarValue tests the functionality of GetMySQLSetVarValue +func TestGetMySQLSetVarValue(t *testing.T) { + tests := []struct { + name string + comments []string + valToFind string + want string + }{ + { + name: "SET_VAR clause in the middle", + comments: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=OFF) NO_ICP(t1, t2) */"}, + valToFind: sysvars.ForeignKeyChecks.Name, + want: "OFF", + }, + { + name: "Single SET_VAR clause", + comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */"}, + valToFind: "sort_buffer_size", + want: "16M", + }, + { + name: "No comments", + comments: nil, + valToFind: "sort_buffer_size", + want: "", + }, + { + name: "Multiple SET_VAR clauses", + comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, + valToFind: sysvars.ForeignKeyChecks.Name, + want: "", + }, + { + name: "Verify casing", + comments: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR( foReiGn_key_checks = On) */"}, + valToFind: sysvars.ForeignKeyChecks.Name, + want: "On", + }, + { + name: "Leading comment is a normal comment", + comments: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR( foreign_key_checks = 1) */"}, + valToFind: sysvars.ForeignKeyChecks.Name, + want: "1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ParsedComments{ + comments: tt.comments, + } + assert.Equal(t, tt.want, c.GetMySQLSetVarValue(tt.valToFind)) + }) + } +} + +func TestSetMySQLSetVarValue(t *testing.T) { + tests := []struct { + name string + comments []string + key string + value string + commentsWanted Comments + }{ + { + name: "SET_VAR clause in the middle", + comments: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=OFF) NO_ICP(t1, t2) */"}, + key: sysvars.ForeignKeyChecks.Name, + value: "On", + commentsWanted: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=On) NO_ICP(t1, t2) */"}, + }, + { + name: "Single SET_VAR clause", + comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */"}, + key: "sort_buffer_size", + value: "1Mb", + commentsWanted: []string{"/*+ SET_VAR(sort_buffer_size=1Mb) */"}, + }, + { + name: "No comments", + comments: nil, + key: "sort_buffer_size", + value: "13M", + commentsWanted: []string{"/*+ SET_VAR(sort_buffer_size=13M) */"}, + }, + { + name: "Multiple SET_VAR clauses", + comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, + key: sysvars.ForeignKeyChecks.Name, + value: "1", + commentsWanted: []string{"/*+ SET_VAR(sort_buffer_size = 16M) SET_VAR(foreign_key_checks=1) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, + }, + { + name: "Verify casing", + comments: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR( foReiGn_key_checks = On) */"}, + key: sysvars.ForeignKeyChecks.Name, + value: "off", + commentsWanted: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR(foReiGn_key_checks=off) */"}, + }, + { + name: "Leading comment is a normal comment", + comments: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR( foreign_key_checks = 1) */"}, + key: sysvars.ForeignKeyChecks.Name, + value: "Off", + commentsWanted: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR(foreign_key_checks=Off) */"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ParsedComments{ + comments: tt.comments, + } + newComments := c.SetMySQLSetVarValue(tt.key, tt.value) + require.EqualValues(t, tt.commentsWanted, newComments) + }) + } +} diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go index 9a92064d9b3..f6545b44388 100644 --- a/go/vt/sqlparser/normalizer_test.go +++ b/go/vt/sqlparser/normalizer_test.go @@ -573,6 +573,7 @@ func BenchmarkNormalizeVTGate(b *testing.B) { SQLSelectLimitUnset, "", nil, /*sysvars*/ + nil, nil, /*views*/ ) if err != nil { @@ -864,6 +865,7 @@ func benchmarkNormalization(b *testing.B, sqls []string) { "", nil, nil, + nil, ) if err != nil { b.Fatal(err) diff --git a/go/vt/sysvars/sysvars.go b/go/vt/sysvars/sysvars.go index 98da8ff07b7..945a60ae965 100644 --- a/go/vt/sysvars/sysvars.go +++ b/go/vt/sysvars/sysvars.go @@ -71,6 +71,7 @@ var ( TxReadOnly = SystemVariable{Name: "tx_read_only", IsBoolean: true, Default: off} Workload = SystemVariable{Name: "workload", IdentifierAsString: true} QueryTimeout = SystemVariable{Name: "query_timeout"} + ForeignKeyChecks = SystemVariable{Name: "foreign_key_checks", IsBoolean: true, SupportSetVar: true} // Online DDL DDLStrategy = SystemVariable{Name: "ddl_strategy", IdentifierAsString: true} @@ -104,6 +105,7 @@ var ( ReadAfterWriteTimeOut, SessionTrackGTIDs, QueryTimeout, + ForeignKeyChecks, } ReadOnly = []SystemVariable{ @@ -186,7 +188,6 @@ var ( {Name: "end_markers_in_json", IsBoolean: true, SupportSetVar: true}, {Name: "eq_range_index_dive_limit", SupportSetVar: true}, {Name: "explicit_defaults_for_timestamp"}, - {Name: "foreign_key_checks", IsBoolean: true, SupportSetVar: true}, {Name: "group_concat_max_len", SupportSetVar: true}, {Name: "information_schema_stats_expiry"}, {Name: "max_heap_table_size", SupportSetVar: true}, diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 9776572f1a5..0ee95a72e60 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -270,6 +270,10 @@ func (t *noopVCursor) SetAutocommit(context.Context, bool) error { panic("implement me") } +func (t *noopVCursor) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { + panic("implement me") +} + func (t *noopVCursor) SetClientFoundRows(context.Context, bool) error { panic("implement me") } @@ -738,6 +742,10 @@ func (f *loggingVCursor) SetAutocommit(context.Context, bool) error { panic("implement me") } +func (f *loggingVCursor) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { + panic("implement me") +} + func (f *loggingVCursor) SetClientFoundRows(context.Context, bool) error { panic("implement me") } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index a3a37f97fe4..dc1259e2267 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -153,6 +153,7 @@ type ( SetAutocommit(ctx context.Context, autocommit bool) error SetClientFoundRows(context.Context, bool) error + SetSessionForeignKeyChecks(ctx context.Context, autocommit bool) error SetSkipQueryPlanCache(context.Context, bool) error SetSQLSelectLimit(int64) error SetTransactionMode(vtgatepb.TransactionMode) diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index 9e9500d1ca8..a0d4987d85a 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -445,6 +445,8 @@ func (svss *SysVarSetAware) Execute(ctx context.Context, vcursor VCursor, env *e switch svss.Name { case sysvars.Autocommit.Name: err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetAutocommit) + case sysvars.ForeignKeyChecks.Name: + err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetSessionForeignKeyChecks) case sysvars.ClientFoundRows.Name: err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetClientFoundRows) case sysvars.SkipQueryPlanCache.Name: diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 152533f2c0d..40c50420586 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1042,6 +1042,7 @@ func (e *Executor) getPlan( vcursor.SetIgnoreMaxMemoryRows(sqlparser.IgnoreMaxMaxMemoryRowsDirective(stmt)) vcursor.SetConsolidator(sqlparser.Consolidator(stmt)) vcursor.SetWorkloadName(sqlparser.GetWorkloadNameFromStatement(stmt)) + vcursor.UpdateForeignKeyChecksState(sqlparser.ForeignKeyChecksState(stmt)) priority, err := sqlparser.GetPriorityFromStatement(stmt) if err != nil { return nil, err @@ -1066,6 +1067,7 @@ func (e *Executor) getPlan( vcursor.safeSession.getSelectLimit(), setVarComment, vcursor.safeSession.SystemVariables, + vcursor.GetForeignKeyChecksState(), vcursor, ) if err != nil { diff --git a/go/vt/vtgate/executor_set_test.go b/go/vt/vtgate/executor_set_test.go index e71a41eeb7f..68898b7ea45 100644 --- a/go/vt/vtgate/executor_set_test.go +++ b/go/vt/vtgate/executor_set_test.go @@ -319,8 +319,9 @@ func TestExecutorSetOp(t *testing.T) { sysVars: map[string]string{"sql_quote_show_create": "0"}, result: returnResult("sql_quote_show_create", "int64", "0"), }, { - in: "set foreign_key_checks = 1", - result: returnNoResult("foreign_key_checks", "int64"), + in: "set foreign_key_checks = 1", + sysVars: map[string]string{"foreign_key_checks": "1"}, + result: returnNoResult("foreign_key_checks", "int64"), }, { in: "set unique_checks = 0", sysVars: map[string]string{"unique_checks": "0"}, diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 2777181907d..f715c230db9 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -22,6 +22,7 @@ import ( "sort" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/vschemawrapper" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" @@ -74,7 +75,20 @@ func TestBuilder(query string, vschema plancontext.VSchema, keyspace string) (*e if err != nil { return nil, err } - result, err := sqlparser.RewriteAST(stmt, keyspace, sqlparser.SQLSelectLimitUnset, "", nil, vschema) + // Store the foreign key mode like we do for vcursor. + vw, isVw := vschema.(*vschemawrapper.VSchemaWrapper) + if isVw { + fkState := sqlparser.ForeignKeyChecksState(stmt) + if fkState != nil { + // Restore the old volue of ForeignKeyChecksState to not interfere with the next test cases. + oldVal := vw.ForeignKeyChecksState + vw.ForeignKeyChecksState = fkState + defer func() { + vw.ForeignKeyChecksState = oldVal + }() + } + } + result, err := sqlparser.RewriteAST(stmt, keyspace, sqlparser.SQLSelectLimitUnset, "", nil, vschema.GetForeignKeyChecksState(), vschema) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index dd37ed5db01..bd38b849e7c 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -204,7 +204,7 @@ func createFkCascadeOpForDelete(ctx *plancontext.PlanningContext, parentOp ops.O func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, cols []int) (*FkChild, error) { bvName := ctx.ReservedVars.ReserveVariable(foreignKeyConstraintValues) - + parsedComments := getParsedCommentsForFkChecks(ctx) var childStmt sqlparser.Statement switch fk.OnDelete { case sqlparser.Cascade: @@ -216,6 +216,7 @@ func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildF } compExpr := sqlparser.NewComparisonExpr(sqlparser.InOp, valTuple, sqlparser.NewListArg(bvName), nil) childStmt = &sqlparser.Delete{ + Comments: parsedComments, TableExprs: []sqlparser.TableExpr{sqlparser.NewAliasedTableExpr(fk.Table.GetTableName(), "")}, Where: &sqlparser.Where{Type: sqlparser.WhereClause, Expr: compExpr}, } @@ -234,6 +235,7 @@ func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildF compExpr := sqlparser.NewComparisonExpr(sqlparser.InOp, valTuple, sqlparser.NewListArg(bvName), nil) childStmt = &sqlparser.Update{ Exprs: updExprs, + Comments: parsedComments, TableExprs: []sqlparser.TableExpr{sqlparser.NewAliasedTableExpr(fk.Table.GetTableName(), "")}, Where: &sqlparser.Where{Type: sqlparser.WhereClause, Expr: compExpr}, } diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 9d39b2f4fc7..1f122a950d4 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -23,6 +23,7 @@ import ( "strings" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" @@ -437,9 +438,7 @@ func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.Chi // Because we could be updating the child to a non-null value, // We have to run with foreign key checks OFF because the parent isn't guaranteed to have // the data being updated to. - parsedComments := sqlparser.Comments{ - "/*+ SET_VAR(foreign_key_checks=OFF) */", - }.Parsed() + parsedComments := (&sqlparser.ParsedComments{}).SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "OFF").Parsed() childUpdStmt := &sqlparser.Update{ Comments: parsedComments, Exprs: childUpdateExprs, @@ -490,14 +489,30 @@ func buildChildUpdOpForSetNull( Right: compExpr, } } + parsedComments := getParsedCommentsForFkChecks(ctx) childUpdStmt := &sqlparser.Update{ Exprs: childUpdateExprs, + Comments: parsedComments, TableExprs: []sqlparser.TableExpr{sqlparser.NewAliasedTableExpr(fk.Table.GetTableName(), "")}, Where: &sqlparser.Where{Type: sqlparser.WhereClause, Expr: childWhereExpr}, } return createOpFromStmt(ctx, childUpdStmt, false, "") } +// getParsedCommentsForFkChecks gets the parsed comments to be set on a child query related to foreign_key_checks session variable. +// We only use this function if foreign key checks are either unspecified or on. +// If foreign key checks are explicity turned on, then we should add the set_var parsed comment too +// since underlying MySQL might have foreign_key_checks as off. +// We run with foreign key checks on because the DML might still fail on MySQL due to a child table +// with RESTRICT constraints. +func getParsedCommentsForFkChecks(ctx *plancontext.PlanningContext) (parsedComments *sqlparser.ParsedComments) { + fkState := ctx.VSchema.GetForeignKeyChecksState() + if fkState != nil && *fkState { + parsedComments = parsedComments.SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "ON").Parsed() + } + return parsedComments +} + // createFKVerifyOp creates the verify operator for the parent foreign key constraints. func createFKVerifyOp( ctx *plancontext.PlanningContext, @@ -542,14 +557,14 @@ func createFKVerifyOp( // Each parent foreign key constraint is verified by an anti join query of the form: // select 1 from child_tbl left join parent_tbl on -// where and and and limit 1 +// where and and and and limit 1 // E.g: // Child (c1, c2) references Parent (p1, p2) // update Child set c1 = c2 + 1 where id = 1 // verify query: // select 1 from Child left join Parent on Parent.p1 = Child.c2 + 1 and Parent.p2 = Child.c2 // where Parent.p1 is null and Parent.p2 is null and Child.id = 1 and Child.c2 + 1 is not null -// and Child.c2 is not null +// and Child.c2 is not null and not ((Child.c1) <=> (Child.c2 + 1)) // limit 1 func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) (ops.Operator, error) { childTblExpr := updStmt.TableExprs[0].(*sqlparser.AliasedTableExpr) @@ -560,6 +575,8 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS parentTbl := pFK.Table.GetTableName() var whereCond sqlparser.Expr var joinCond sqlparser.Expr + var notEqualColNames sqlparser.ValTuple + var notEqualExprs sqlparser.ValTuple for idx, column := range pFK.ChildColumns { var matchedExpr *sqlparser.UpdateExpr for _, updateExpr := range updStmt.Exprs { @@ -588,7 +605,9 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS Right: sqlparser.NewColNameWithQualifier(pFK.ChildColumns[idx].String(), childTbl), } } else { + notEqualColNames = append(notEqualColNames, prefixColNames(childTbl, matchedExpr.Name)) prefixedMatchExpr := prefixColNames(childTbl, matchedExpr.Expr) + notEqualExprs = append(notEqualExprs, prefixedMatchExpr) joinExpr = &sqlparser.ComparisonExpr{ Operator: sqlparser.EqualOp, Left: sqlparser.NewColNameWithQualifier(pFK.ParentColumns[idx].String(), parentTbl), @@ -610,6 +629,16 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS joinCond = &sqlparser.AndExpr{Left: joinCond, Right: joinExpr} whereCond = &sqlparser.AndExpr{Left: whereCond, Right: predicate} } + whereCond = &sqlparser.AndExpr{ + Left: whereCond, + Right: &sqlparser.NotExpr{ + Expr: &sqlparser.ComparisonExpr{ + Operator: sqlparser.NullSafeEqualOp, + Left: notEqualColNames, + Right: notEqualExprs, + }, + }, + } // add existing where condition on the update statement if updStmt.Where != nil { whereCond = &sqlparser.AndExpr{Left: whereCond, Right: prefixColNames(childTbl, updStmt.Where.Expr)} diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 9c1592fdf81..c04c5cd9ddc 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -113,6 +113,38 @@ func TestForeignKeyPlanning(t *testing.T) { testFile(t, "foreignkey_cases.json", testOutputTempDir, vschemaWrapper, false) } +// TestForeignKeyChecksOn tests the planning when the session variable for foreign_key_checks is set to ON. +func TestForeignKeyChecksOn(t *testing.T) { + vschema := loadSchema(t, "vschemas/schema.json", true) + setFks(t, vschema) + fkChecksState := true + vschemaWrapper := &vschemawrapper.VSchemaWrapper{ + V: vschema, + TestBuilder: TestBuilder, + ForeignKeyChecksState: &fkChecksState, + } + + testOutputTempDir := makeTestOutput(t) + + testFile(t, "foreignkey_checks_on_cases.json", testOutputTempDir, vschemaWrapper, false) +} + +// TestForeignKeyChecksOff tests the planning when the session variable for foreign_key_checks is set to OFF. +func TestForeignKeyChecksOff(t *testing.T) { + vschema := loadSchema(t, "vschemas/schema.json", true) + setFks(t, vschema) + fkChecksState := false + vschemaWrapper := &vschemawrapper.VSchemaWrapper{ + V: vschema, + TestBuilder: TestBuilder, + ForeignKeyChecksState: &fkChecksState, + } + + testOutputTempDir := makeTestOutput(t) + + testFile(t, "foreignkey_checks_off_cases.json", testOutputTempDir, vschemaWrapper, false) +} + func setFks(t *testing.T, vschema *vindexes.VSchema) { if vschema.Keyspaces["sharded_fk_allow"] != nil { // FK from multicol_tbl2 referencing multicol_tbl1 that is shard scoped. diff --git a/go/vt/vtgate/planbuilder/plancontext/vschema.go b/go/vt/vtgate/planbuilder/plancontext/vschema.go index 9dde6dee31c..286e8d30b67 100644 --- a/go/vt/vtgate/planbuilder/plancontext/vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/vschema.go @@ -60,6 +60,8 @@ type VSchema interface { // KeyspaceError returns any error in the keyspace vschema. KeyspaceError(keyspace string) error + GetForeignKeyChecksState() *bool + // GetVSchema returns the latest cached vindexes.VSchema GetVSchema() *vindexes.VSchema diff --git a/go/vt/vtgate/planbuilder/simplifier_test.go b/go/vt/vtgate/planbuilder/simplifier_test.go index 1e106adacc0..4c83af77933 100644 --- a/go/vt/vtgate/planbuilder/simplifier_test.go +++ b/go/vt/vtgate/planbuilder/simplifier_test.go @@ -48,7 +48,7 @@ func TestSimplifyBuggyQuery(t *testing.T) { } stmt, reserved, err := sqlparser.Parse2(query) require.NoError(t, err) - rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil) + rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( @@ -70,7 +70,7 @@ func TestSimplifyPanic(t *testing.T) { } stmt, reserved, err := sqlparser.Parse2(query) require.NoError(t, err) - rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil) + rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( @@ -100,7 +100,7 @@ func TestUnsupportedFile(t *testing.T) { t.Skip() return } - rewritten, err := sqlparser.RewriteAST(stmt, vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil) + rewritten, err := sqlparser.RewriteAST(stmt, vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) if err != nil { t.Skip() } @@ -134,7 +134,7 @@ func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema * if err != nil { panic(err) } - rewritten, _ := sqlparser.RewriteAST(stmt, vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil) + rewritten, _ := sqlparser.RewriteAST(stmt, vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) ast := rewritten.AST _, expected := BuildFromStmt(context.Background(), query, ast, reservedVars, vschema, rewritten.BindVarNeeds, true, true) if expected == nil { diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index f77cb4aeac3..99679d698a2 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -527,7 +527,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl10 where 1 != 1", - "Query": "select 1 from tbl10 lock in share mode", + "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') lock in share mode", "Table": "tbl10" }, { @@ -558,7 +558,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update tbl10 set col = 'foo'", + "Query": "update tbl10 set tbl10.col = 'foo'", "Table": "tbl10" } ] @@ -806,7 +806,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", - "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", "Table": "u_tbl1, u_tbl2" }, { @@ -821,8 +821,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col2, col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", - "Query": "select col2, col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", + "FieldQuery": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", + "Query": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", "Table": "u_tbl2" }, { @@ -858,7 +858,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, u_tbl2.col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", "Table": "u_tbl2" } ] @@ -1284,7 +1284,7 @@ "Sharded": true }, "FieldQuery": "select tbl3.colx from tbl3 where 1 != 1", - "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and tbl3.coly = 10 lock in share mode", + "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 lock in share mode", "Table": "tbl3" }, { @@ -1315,7 +1315,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set coly = tbl3.colx + 10 where tbl3.coly = 10", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set tbl3.coly = tbl3.colx + 10 where tbl3.coly = 10", "Table": "tbl3" } ] @@ -1364,7 +1364,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl3 where 1 != 1", - "Query": "select 1 from tbl3 where tbl3.coly = 10 lock in share mode", + "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 lock in share mode", "Table": "tbl3" }, { @@ -1395,7 +1395,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update tbl3 set coly = 20 where tbl3.coly = 10", + "Query": "update tbl3 set tbl3.coly = 20 where tbl3.coly = 10", "Table": "tbl3" } ] @@ -1444,7 +1444,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 lock in share mode", "Table": "u_tbl8, u_tbl9" }, { @@ -1456,7 +1456,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set col8 = 'foo' where (u_tbl8.col8) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set u_tbl8.col8 = 'foo' where (u_tbl8.col8) in ::fkc_vals", "Table": "u_tbl8" } ] @@ -1520,7 +1520,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", "Table": "u_tbl3, u_tbl4" }, { @@ -1544,7 +1544,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = 'foo' where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = 'foo' where (u_tbl4.col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -1609,7 +1609,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", "Table": "u_tbl3, u_tbl4" }, { @@ -1633,7 +1633,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :v1 where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :v1 where (u_tbl4.col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -2121,7 +2121,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where not (u_tbl4.col4) <=> (:fkc_upd) and (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 lock in share mode", "Table": "u_tbl3, u_tbl4" }, { @@ -2145,7 +2145,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -2297,7 +2297,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where 1 != 1", - "Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 lock in share mode", + "Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and not (u_multicol_tbl2.cola, u_multicol_tbl2.colb) <=> (2, u_multicol_tbl2.colc - 2) and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 lock in share mode", "Table": "u_multicol_tbl1, u_multicol_tbl2" }, { @@ -2312,8 +2312,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select cola, colb, cola <=> 2, 2, colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb, cola <=> 2, 2, colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where u_multicol_tbl2.id = 7 for update", + "FieldQuery": "select cola, colb, u_multicol_tbl2.cola <=> 2, 2, u_multicol_tbl2.colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb, u_multicol_tbl2.cola <=> 2, 2, u_multicol_tbl2.colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where u_multicol_tbl2.id = 7 for update", "Table": "u_multicol_tbl2" }, { @@ -2356,7 +2356,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl2 set cola = 2, colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.id = 7", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl2 set u_multicol_tbl2.cola = 2, u_multicol_tbl2.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.id = 7", "Table": "u_multicol_tbl2" } ] @@ -2443,5 +2443,80 @@ "unsharded_fk_allow.u_tbl9" ] } + }, + { + "comment": "Delete with foreign key checks off", + "query": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "plan": { + "QueryType": "DELETE", + "Original": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Instructions": { + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl1" + ] + } + }, + { + "comment": "Update with foreign key checks off", + "query": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "plan": { + "QueryType": "UPDATE", + "Original": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=Off) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Table": "u_multicol_tbl1" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1" + ] + } + }, + { + "comment": "Insert with cross shard foreign keys and foreign key checks off", + "query": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into tbl3(col3, coly) values (:_col3_0, 3)", + "TableName": "tbl3", + "VindexValues": { + "hash_vin": "1" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl3" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json new file mode 100644 index 00000000000..968fb8679fb --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json @@ -0,0 +1,491 @@ +[ + { + "comment": "Insertion in a table with cross-shard foreign keys works with foreign_key_checks off", + "query": "insert into tbl3 (col3, coly) values (1, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into tbl3 (col3, coly) values (1, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into tbl3(col3, coly) values (:_col3_0, 3)", + "TableName": "tbl3", + "VindexValues": { + "hash_vin": "1" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl3" + ] + } + }, + { + "comment": "Insertion in a table with shard-scoped multiple column foreign key is allowed", + "query": "insert into multicol_tbl2 (cola, colb, colc) values (1, 2, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into multicol_tbl2 (cola, colb, colc) values (1, 2, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into multicol_tbl2(cola, colb, colc) values (:_cola_0, :_colb_0, :_colc_0)", + "TableName": "multicol_tbl2", + "VindexValues": { + "multicolIdx": "1, 2, 3" + } + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl2" + ] + } + }, + { + "comment": "Delete in a table with cross-shard foreign key works with foreign_key_checks off ", + "query": "delete from tbl1", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl1", + "Instructions": { + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from tbl1", + "Table": "tbl1" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1" + ] + } + }, + { + "comment": "Delete in a table with not all column shard-scoped foreign keys works with foreign_key_checks off", + "query": "delete from tbl7", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl7", + "Instructions": { + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from tbl7", + "Table": "tbl7" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl7" + ] + } + }, + { + "comment": "Delete in a table with shard-scoped multiple column foreign key with cascade with foreign key checks on", + "query": "delete /*+ SET_VAR(foreign_key_checks=1) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "plan": { + "QueryType": "DELETE", + "Original": "delete /*+ SET_VAR(foreign_key_checks=1) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select colb, cola, y, colc, x from multicol_tbl1 where 1 != 1", + "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1, + 2, + 3, + 4 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from multicol_tbl2 where (colb, cola, x, colc, y) in ::fkc_vals", + "Table": "multicol_tbl2" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl1", + "sharded_fk_allow.multicol_tbl2" + ] + } + }, + { + "comment": "Delete in a table with shard-scoped foreign keys with SET NULL", + "query": "delete from tbl8 where col8 = 1", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl8 where col8 = 1", + "Instructions": { + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from tbl8 where col8 = 1", + "Table": "tbl8", + "Values": [ + "1" + ], + "Vindex": "hash_vin" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl8" + ] + } + }, + { + "comment": "Update in a table with cross-shard foreign keys works with foreign_key_checks off", + "query": "update tbl1 set t1col1 = 'foo' where col1 = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl1 set t1col1 = 'foo' where col1 = 1", + "Instructions": { + "OperatorType": "Update", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=Off) */ tbl1 set t1col1 = 'foo' where col1 = 1", + "Table": "tbl1", + "Values": [ + "1" + ], + "Vindex": "hash_vin" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1" + ] + } + }, + { + "comment": "Update in a table with column modified not shard-scoped foreign key whereas other column referencing same table is works with foreign_key_checks off", + "query": "update tbl7 set t7col7 = 'foo', t7col72 = 42", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl7 set t7col7 = 'foo', t7col72 = 42", + "Instructions": { + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=Off) */ tbl7 set t7col7 = 'foo', t7col72 = 42", + "Table": "tbl7" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl7" + ] + } + }, + { + "comment": "Update in a table with shard-scoped foreign keys with cascade", + "query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl5 set t5col5 = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl5 set t5col5 = 'foo'", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select t5col5 from tbl5 where 1 != 1", + "Query": "select t5col5 from tbl5 for update", + "Table": "tbl5" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (tbl4.t4col4) not in (('foo'))", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl5 set t5col5 = 'foo'", + "Table": "tbl5" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl5" + ] + } + }, + { + "comment": "Insertion in a table with 2 foreign keys constraint with same table on different columns - both are not shard scoped - works with foreign_key_checks off", + "query": "insert into tbl6 (col6, t6col6) values (100, 'foo')", + "plan": { + "QueryType": "INSERT", + "Original": "insert into tbl6 (col6, t6col6) values (100, 'foo')", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into tbl6(col6, t6col6) values (:_col6_0, 'foo')", + "TableName": "tbl6", + "VindexValues": { + "hash_vin": "100" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl6" + ] + } + }, + { + "comment": "delete table with shard scoped foreign key set default works with foreign_key_checks off", + "query": "delete from tbl20 where col = 'bar'", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl20 where col = 'bar'", + "Instructions": { + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from tbl20 where col = 'bar'", + "Table": "tbl20", + "Values": [ + "'bar'" + ], + "Vindex": "hash_vin" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl20" + ] + } + }, + { + "comment": "Delete table with cross-shard foreign key with set null - should be eventually allowed", + "query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl9 where col9 = 34", + "plan": { + "QueryType": "DELETE", + "Original": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl9 where col9 = 34", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select col9 from tbl9 where 1 != 1", + "Query": "select col9 from tbl9 where col9 = 34 for update", + "Table": "tbl9", + "Values": [ + "34" + ], + "Vindex": "hash_vin" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set col_ref = null where (col_ref) in ::fkc_vals", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl9 where col9 = 34", + "Table": "tbl9", + "Values": [ + "34" + ], + "Vindex": "hash_vin" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl9" + ] + } + }, + { + "comment": "Delete with foreign key checks off", + "query": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "plan": { + "QueryType": "DELETE", + "Original": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Instructions": { + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl1" + ] + } + }, + { + "comment": "Update with foreign key checks off", + "query": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "plan": { + "QueryType": "UPDATE", + "Original": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=Off) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Table": "u_multicol_tbl1" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1" + ] + } + }, + { + "comment": "Insert with cross shard foreign keys and foreign key checks off", + "query": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into tbl3(col3, coly) values (:_col3_0, 3)", + "TableName": "tbl3", + "VindexValues": { + "hash_vin": "1" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl3" + ] + } + } +] diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json new file mode 100644 index 00000000000..862c18b068d --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json @@ -0,0 +1,2148 @@ +[ + { + "comment": "Insertion in a table with cross-shard foreign keys disallowed", + "query": "insert into tbl3 (col3, coly) values (1, 3)", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Insertion in a table with shard-scoped foreign keys is allowed", + "query": "insert into tbl2 (col2, coly) values (1, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into tbl2 (col2, coly) values (1, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=On) */ into tbl2(col2, coly) values (:_col2_0, 3)", + "TableName": "tbl2", + "VindexValues": { + "hash_vin": "1" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl2" + ] + } + }, + { + "comment": "Insertion in a table with shard-scoped multiple column foreign key is allowed", + "query": "insert into multicol_tbl2 (cola, colb, colc) values (1, 2, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into multicol_tbl2 (cola, colb, colc) values (1, 2, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=On) */ into multicol_tbl2(cola, colb, colc) values (:_cola_0, :_colb_0, :_colc_0)", + "TableName": "multicol_tbl2", + "VindexValues": { + "multicolIdx": "1, 2, 3" + } + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl2" + ] + } + }, + { + "comment": "Delete in a table with cross-shard foreign keys disallowed", + "query": "delete from tbl1", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Delete in a table with not all column shard-scoped foreign keys - disallowed", + "query": "delete from tbl7", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Delete in a table with shard-scoped multiple column foreign key with cascade", + "query": "delete from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "plan": { + "QueryType": "DELETE", + "Original": "delete from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select colb, cola, y, colc, x from multicol_tbl1 where 1 != 1", + "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1, + 2, + 3, + 4 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from multicol_tbl2 where (colb, cola, x, colc, y) in ::fkc_vals", + "Table": "multicol_tbl2" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl1", + "sharded_fk_allow.multicol_tbl2" + ] + } + }, + { + "comment": "Delete in a table with shard-scoped foreign keys with cascade", + "query": "delete from tbl5", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl5", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", + "Query": "select col5, t5col5 from tbl5 for update", + "Table": "tbl5" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from tbl4 where (col4) in ::fkc_vals", + "Table": "tbl4" + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 1 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from tbl4 where (t4col4) in ::fkc_vals1", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl5", + "Table": "tbl5" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl5" + ] + } + }, + { + "comment": "Delete in a table with shard-scoped foreign keys with SET NULL", + "query": "delete from tbl8 where col8 = 1", + "plan": "VT12001: unsupported: you cannot UPDATE primary vindex columns; invalid update on vindex: hash_vin" + }, + { + "comment": "Delete in a table with unsharded foreign key with SET NULL", + "query": "delete from u_tbl9 where col9 = 5", + "plan": { + "QueryType": "DELETE", + "Original": "delete from u_tbl9 where col9 = 5", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where col9 = 5 for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl8 set col8 = null where (col8) in ::fkc_vals", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from u_tbl9 where col9 = 5", + "Table": "u_tbl9" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "update in unsharded table with restrict", + "query": "update u_tbl5 set col5 = 'foo' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl5 set col5 = 'foo' where id = 1", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl5 set col5 = 'foo' where id = 1", + "Table": "u_tbl5" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl5" + ] + } + }, + { + "comment": "update in unsharded table with cascade", + "query": "update u_tbl2 set col2 = 'bar' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl2 set col2 = 'bar' where id = 1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where id = 1 for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in (('bar'))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl2 set col2 = 'bar' where id = 1", + "Table": "u_tbl2" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } + }, + { + "comment": "update in unsharded table with cascade - on non-referenced column", + "query": "update u_tbl2 set col_no_ref = 'baz' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl2 set col_no_ref = 'baz' where id = 1", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl2 set col_no_ref = 'baz' where id = 1", + "Table": "u_tbl2" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl2" + ] + } + }, + { + "comment": "Update in a table with cross-shard foreign keys disallowed", + "query": "update tbl1 set t1col1 = 'foo' where col1 = 1", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Update in a table with cross-shard foreign keys, column not in update expression - allowed", + "query": "update tbl1 set not_ref_col = 'foo' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl1 set not_ref_col = 'foo' where id = 1", + "Instructions": { + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl1 set not_ref_col = 'foo' where id = 1", + "Table": "tbl1" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1" + ] + } + }, + { + "comment": "Update in a table with column modified not shard-scoped foreign key whereas other column referencing same table is - disallowed", + "query": "update tbl7 set t7col7 = 'foo', t7col72 = 42", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Update in a table with shard-scoped foreign keys with cascade", + "query": "update tbl5 set t5col5 = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl5 set t5col5 = 'foo'", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select t5col5 from tbl5 where 1 != 1", + "Query": "select t5col5 from tbl5 for update", + "Table": "tbl5" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (tbl4.t4col4) not in (('foo'))", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl5 set t5col5 = 'foo'", + "Table": "tbl5" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl5" + ] + } + }, + { + "comment": "Insertion in a table with 2 foreign keys constraint with same table on different columns - both are not shard scoped - disallowed", + "query": "insert into tbl6 (col6, t6col6) values (100, 'foo')", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "Update a table with parent and child foreign keys - shard scoped", + "query": "update tbl2 set col = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl2 set col = 'foo'", + "Instructions": { + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl2 set col = 'foo'", + "Table": "tbl2" + }, + "TablesUsed": [ + "sharded_fk_allow.tbl2" + ] + } + }, + { + "comment": "update table with column's parent foreign key cross shard", + "query": "update tbl10 set col = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl10 set col = 'foo'", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Limit", + "Count": "1", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "1 as 1" + ], + "Inputs": [ + { + "OperatorType": "Filter", + "Predicate": "tbl3.col is null", + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "R:0,R:0", + "TableName": "tbl10_tbl3", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select 1 from tbl10 where 1 != 1", + "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') lock in share mode", + "Table": "tbl10" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl3.col from tbl3 where 1 != 1", + "Query": "select tbl3.col from tbl3 where tbl3.col = 'foo' lock in share mode", + "Table": "tbl3" + } + ] + } + ] + } + ] + } + ] + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl10 set tbl10.col = 'foo'", + "Table": "tbl10" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl10", + "sharded_fk_allow.tbl3" + ] + } + }, + { + "comment": "delete table with shard scoped foreign key set default - disallowed", + "query": "delete from tbl20 where col = 'bar'", + "plan": "VT09016: Cannot delete or update a parent row: a foreign key constraint fails" + }, + { + "comment": "Delete table with cross-shard foreign key with set null - should be eventually allowed", + "query": "delete from tbl9 where col9 = 34", + "plan": { + "QueryType": "DELETE", + "Original": "delete from tbl9 where col9 = 34", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select col9 from tbl9 where 1 != 1", + "Query": "select col9 from tbl9 where col9 = 34 for update", + "Table": "tbl9", + "Values": [ + "34" + ], + "Vindex": "hash_vin" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set col_ref = null where (col_ref) in ::fkc_vals", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl9 where col9 = 34", + "Table": "tbl9", + "Values": [ + "34" + ], + "Vindex": "hash_vin" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl9" + ] + } + }, + { + "comment": "update table with same column having reference to different tables, one with on update cascade other with on update set null - child table have further reference", + "query": "update u_tbl1 set col1 = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl1 set col1 = 'foo'", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in (('foo'))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = 'foo' where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo')) for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo'))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl1 set col1 = 'foo'", + "Table": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "update in a table with limit - disallowed", + "query": "update u_tbl2 set col2 = 'bar' limit 2", + "plan": "VT12001: unsupported: update with limit with foreign key constraints" + }, + { + "comment": "update in a table with non-literal value - set null fail due to child update where condition", + "query": "update u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", + "Table": "u_tbl1, u_tbl2" + }, + { + "InputName": "PostVerify", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", + "Query": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "ExprCol": 0, + "CompExprCol": 1, + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd" + } + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, u_tbl2.col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", + "Table": "u_tbl2" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } + }, + { + "comment": "update in a table with non-literal value - with cascade fail as the cascade value is not known", + "query": "update u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where id = 1 for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "ExprCol": 0, + "CompExprCol": 1, + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd" + } + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = :fkc_upd where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "NonLiteralUpdateInfo": [ + { + "ExprCol": 0, + "CompExprCol": 1, + "UpdateExprCol": 2, + "UpdateExprBvName": "fkc_upd1" + } + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1))) for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1)))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = u_tbl1.x + 'bar' where id = 1", + "Table": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "update in a table with set null, non-literal value on non-foreign key column - allowed", + "query": "update u_tbl2 set m = col1 + 'bar', col2 = 2 where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl2 set m = col1 + 'bar', col2 = 2 where id = 1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where id = 1 for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in ((2))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl2 set m = col1 + 'bar', col2 = 2 where id = 1", + "Table": "u_tbl2" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } + }, + { + "comment": "update in a table with cascade, non-literal value on non-foreign key column - allowed", + "query": "update u_tbl1 set m = x + 'bar', col1 = 2 where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl1 set m = x + 'bar', col1 = 2 where id = 1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where id = 1 for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in ((2))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = 2 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2)) for update", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl1 set m = x + 'bar', col1 = 2 where id = 1", + "Table": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "update in a table with a child table having SET DEFAULT constraint - disallowed", + "query": "update tbl20 set col2 = 'bar'", + "plan": "VT09016: Cannot delete or update a parent row: a foreign key constraint fails" + }, + { + "comment": "delete in a table with limit - disallowed", + "query": "delete from u_tbl2 limit 2", + "plan": "VT12001: unsupported: foreign keys management at vitess with limit" + }, + { + "comment": "update with fk on cross-shard with a where condition on non-literal value - disallowed", + "query": "update tbl3 set coly = colx + 10 where coly = 10", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl3 set coly = colx + 10 where coly = 10", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Limit", + "Count": "1", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "1 as 1" + ], + "Inputs": [ + { + "OperatorType": "Filter", + "Predicate": "tbl1.t1col1 is null", + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "R:0,R:0", + "JoinVars": { + "tbl3_colx": 0 + }, + "TableName": "tbl3_tbl1", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl3.colx from tbl3 where 1 != 1", + "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 lock in share mode", + "Table": "tbl3" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 lock in share mode", + "Table": "tbl1" + } + ] + } + ] + } + ] + } + ] + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set tbl3.coly = tbl3.colx + 10 where tbl3.coly = 10", + "Table": "tbl3" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1", + "sharded_fk_allow.tbl3" + ] + } + }, + { + "comment": "update with fk on cross-shard with a where condition", + "query": "update tbl3 set coly = 20 where coly = 10", + "plan": { + "QueryType": "UPDATE", + "Original": "update tbl3 set coly = 20 where coly = 10", + "Instructions": { + "OperatorType": "FKVerify", + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Limit", + "Count": "1", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "1 as 1" + ], + "Inputs": [ + { + "OperatorType": "Filter", + "Predicate": "tbl1.t1col1 is null", + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "R:0,R:0", + "TableName": "tbl3_tbl1", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select 1 from tbl3 where 1 != 1", + "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 lock in share mode", + "Table": "tbl3" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = 20 lock in share mode", + "Table": "tbl1" + } + ] + } + ] + } + ] + } + ] + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl3 set tbl3.coly = 20 where tbl3.coly = 10", + "Table": "tbl3" + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl1", + "sharded_fk_allow.tbl3" + ] + } + }, + { + "comment": "Update in a table with shard-scoped foreign keys with cascade that requires a validation of a different parent foreign key", + "query": "update u_tbl6 set col6 = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl6 set col6 = 'foo'", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col6 from u_tbl6 where 1 != 1", + "Query": "select col6 from u_tbl6 for update", + "Table": "u_tbl6" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FKVerify", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 lock in share mode", + "Table": "u_tbl8, u_tbl9" + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set u_tbl8.col8 = 'foo' where (u_tbl8.col8) in ::fkc_vals", + "Table": "u_tbl8" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl6 set col6 = 'foo'", + "Table": "u_tbl6" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl6", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "Update that cascades and requires parent fk and restrict child fk verification", + "query": "update u_tbl7 set col7 = 'foo'", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl7 set col7 = 'foo'", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col7 from u_tbl7 where 1 != 1", + "Query": "select col7 from u_tbl7 for update", + "Table": "u_tbl7" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FKVerify", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", + "Table": "u_tbl3, u_tbl4" + }, + { + "InputName": "VerifyChild-2", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Table": "u_tbl4, u_tbl9" + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = 'foo' where (u_tbl4.col4) in ::fkc_vals", + "Table": "u_tbl4" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl7 set col7 = 'foo'", + "Table": "u_tbl7" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl4", + "unsharded_fk_allow.u_tbl7", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "Update that cascades and requires parent fk and restrict child fk verification - bindVariable", + "query": "update u_tbl7 set col7 = :v1", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_tbl7 set col7 = :v1", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col7 from u_tbl7 where 1 != 1", + "Query": "select col7 from u_tbl7 for update", + "Table": "u_tbl7" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FKVerify", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "VerifyParent-1", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Table": "u_tbl3, u_tbl4" + }, + { + "InputName": "VerifyChild-2", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Table": "u_tbl4, u_tbl9" + }, + { + "InputName": "PostVerify", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :v1 where (u_tbl4.col4) in ::fkc_vals", + "Table": "u_tbl4" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl7 set col7 = :v1", + "Table": "u_tbl7" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl4", + "unsharded_fk_allow.u_tbl7", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "Insert with on duplicate key update - foreign keys disallowed", + "query": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = 5", + "plan": "VT12001: unsupported: ON DUPLICATE KEY UPDATE with foreign keys" + }, + { + "comment": "Insert with on duplicate key update - foreign keys not on update column - allowed", + "query": "insert into u_tbl1 (id, col1, foo) values (1, 3, 'bar') on duplicate key update foo = 'baz'", + "plan": { + "QueryType": "INSERT", + "Original": "insert into u_tbl1 (id, col1, foo) values (1, 3, 'bar') on duplicate key update foo = 'baz'", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=On) */ into u_tbl1(id, col1, foo) values (1, 3, 'bar') on duplicate key update foo = 'baz'", + "TableName": "u_tbl1" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1" + ] + } + }, + { + "comment": "Insert with unsharded table having fk reference in sharded table", + "query": "insert into u_tbl (id, col) values (1, 2)", + "plan": "VT12002: unsupported: cross-shard foreign keys" + }, + { + "comment": "replace with fk reference unsupported", + "query": "replace into u_tbl1 (id, col1) values (1, 2)", + "plan": { + "QueryType": "INSERT", + "Original": "replace into u_tbl1 (id, col1) values (1, 2)", + "Instructions": { + "OperatorType": "Sequential", + "Inputs": [ + { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where (id) in ((1)) for update", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from u_tbl2 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from u_tbl1 where (id) in ((1))", + "Table": "u_tbl1" + } + ] + }, + { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert /*+ SET_VAR(foreign_key_checks=On) */ into u_tbl1(id, col1) values (1, 2)", + "TableName": "u_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } + }, + { + "comment": "update on a multicol foreign key that set nulls and then cascades", + "query": "update u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "plan": { + "QueryType": "UPDATE", + "Original": "update u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", + "Query": "select cola, colb from u_multicol_tbl1 where id = 3 for update", + "Table": "u_multicol_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2)) for update", + "Table": "u_multicol_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0, + 1 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl3 set cola = null, colb = null where (cola, colb) in ::fkc_vals1", + "Table": "u_multicol_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2))", + "Table": "u_multicol_tbl2" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Table": "u_multicol_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1", + "unsharded_fk_allow.u_multicol_tbl2", + "unsharded_fk_allow.u_multicol_tbl3" + ] + } + }, + { + "comment": "update on a multicol foreign key that set nulls and then cascades - bindVariables", + "query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_multicol_tbl1 set cola = :v1, colb = :v2 where id = :v3", + "plan": { + "QueryType": "UPDATE", + "Original": "update /*+ SET_VAR(foreign_key_checks=On) */ u_multicol_tbl1 set cola = :v1, colb = :v2 where id = :v3", + "Instructions": { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", + "Query": "select cola, colb from u_multicol_tbl1 where id = :v3 for update", + "Table": "u_multicol_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0, + 1 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2)))) for update", + "Table": "u_multicol_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0, + 1 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl3 set cola = null, colb = null where (cola, colb) in ::fkc_vals1", + "Table": "u_multicol_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2))))", + "Table": "u_multicol_tbl2" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_multicol_tbl1 set cola = :v1, colb = :v2 where id = :v3", + "Table": "u_multicol_tbl1" + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1", + "unsharded_fk_allow.u_multicol_tbl2", + "unsharded_fk_allow.u_multicol_tbl3" + ] + } + }, + { + "comment": "Cascaded delete run from prepared statement", + "query": "execute prep_delete using @foo", + "plan": { + "QueryType": "EXECUTE", + "Original": "execute prep_delete using @foo", + "Instructions": { + "OperatorType": "EXECUTE", + "Parameters": [ + "foo" + ], + "Inputs": [ + { + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", + "Query": "select col5, t5col5 from tbl5 where id = :v1 for update", + "Table": "tbl5" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from tbl4 where (col4) in ::fkc_vals", + "Table": "tbl4" + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 1 + ], + "Query": "delete /*+ SET_VAR(foreign_key_checks=ON) */ from tbl4 where (t4col4) in ::fkc_vals1", + "Table": "tbl4" + }, + { + "InputName": "Parent", + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from tbl5 where id = :v1", + "Table": "tbl5" + } + ] + } + ] + }, + "TablesUsed": [ + "sharded_fk_allow.tbl4", + "sharded_fk_allow.tbl5" + ] + } + }, + { + "comment": "Delete with foreign key checks off", + "query": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "plan": { + "QueryType": "DELETE", + "Original": "delete /*+ SET_VAR(foreign_key_checks=off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Instructions": { + "OperatorType": "Delete", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "delete /*+ SET_VAR(foreign_key_checks=Off) */ from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3", + "Table": "multicol_tbl1", + "Values": [ + "1", + "2", + "3" + ], + "Vindex": "multicolIdx" + }, + "TablesUsed": [ + "sharded_fk_allow.multicol_tbl1" + ] + } + }, + { + "comment": "Update with foreign key checks off", + "query": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "plan": { + "QueryType": "UPDATE", + "Original": "update /*+ SET_VAR(foreign_key_checks=0) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=Off) */ u_multicol_tbl1 set cola = 1, colb = 2 where id = 3", + "Table": "u_multicol_tbl1" + }, + "TablesUsed": [ + "unsharded_fk_allow.u_multicol_tbl1" + ] + } + }, + { + "comment": "Insert with cross shard foreign keys and foreign key checks off", + "query": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "plan": { + "QueryType": "INSERT", + "Original": "insert /*+ SET_VAR(foreign_key_checks=0) */ into tbl3 (col3, coly) values (1, 3)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "sharded_fk_allow", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "Query": "insert /*+ SET_VAR(foreign_key_checks=Off) */ into tbl3(col3, coly) values (:_col3_0, 3)", + "TableName": "tbl3", + "VindexValues": { + "hash_vin": "1" + } + }, + "TablesUsed": [ + "sharded_fk_allow.tbl3" + ] + } + } +] diff --git a/go/vt/vtgate/planbuilder/update.go b/go/vt/vtgate/planbuilder/update.go index dfb841a4d11..9bcc8691f8e 100644 --- a/go/vt/vtgate/planbuilder/update.go +++ b/go/vt/vtgate/planbuilder/update.go @@ -19,6 +19,7 @@ package planbuilder import ( querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" @@ -50,7 +51,7 @@ func gen4UpdateStmtPlanner( if ctx.SemTable.HasNonLiteralForeignKeyUpdate(updStmt.Exprs) { // Since we are running the query with foreign key checks off, we have to verify all the foreign keys validity on vtgate. ctx.VerifyAllFKs = true - updStmt.Comments = updStmt.Comments.Prepend("/*+ SET_VAR(foreign_key_checks=OFF) */").Parsed() + updStmt.SetComments(updStmt.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "OFF")) } // Remove all the foreign keys that don't require any handling. diff --git a/go/vt/vtgate/semantics/FakeSI.go b/go/vt/vtgate/semantics/FakeSI.go index b7043b42980..5a91ece816d 100644 --- a/go/vt/vtgate/semantics/FakeSI.go +++ b/go/vt/vtgate/semantics/FakeSI.go @@ -61,6 +61,10 @@ func (s *FakeSI) ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyM return vschemapb.Keyspace_unmanaged, nil } +func (s *FakeSI) GetForeignKeyChecksState() *bool { + return nil +} + func (s *FakeSI) KeyspaceError(keyspace string) error { if s.KsError != nil { fkErr, isPresent := s.KsError[keyspace] diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index 96c604d76a1..44f2481a6b7 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -77,7 +77,7 @@ func Analyze(statement sqlparser.Statement, currentDb string, si SchemaInformati } // Creation of the semantic table - return analyzer.newSemTable(statement, si.ConnCollation()) + return analyzer.newSemTable(statement, si.ConnCollation(), si.GetForeignKeyChecksState()) } // AnalyzeStrict analyzes the parsed query, and fails the analysis for any possible errors @@ -97,7 +97,7 @@ func AnalyzeStrict(statement sqlparser.Statement, currentDb string, si SchemaInf return st, nil } -func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID) (*SemTable, error) { +func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID, fkChecksState *bool) (*SemTable, error) { var comments *sqlparser.ParsedComments commentedStmt, isCommented := statement.(sqlparser.Commented) if isCommented { @@ -108,7 +108,7 @@ func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID columns[union] = info.exprs } - childFks, parentFks, childFkToUpdExprs, err := a.getInvolvedForeignKeys(statement) + childFks, parentFks, childFkToUpdExprs, err := a.getInvolvedForeignKeys(statement, fkChecksState) if err != nil { return nil, err } @@ -318,7 +318,10 @@ func (a *analyzer) noteQuerySignature(node sqlparser.SQLNode) { } // getInvolvedForeignKeys gets the foreign keys that might require taking care off when executing the given statement. -func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, map[string]sqlparser.UpdateExprs, error) { +func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement, fkChecksState *bool) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, map[string]sqlparser.UpdateExprs, error) { + if fkChecksState != nil && !*fkChecksState { + return nil, nil, nil, nil + } // There are only the DML statements that require any foreign keys handling. switch stmt := statement.(type) { case *sqlparser.Delete: diff --git a/go/vt/vtgate/semantics/analyzer_fk_test.go b/go/vt/vtgate/semantics/analyzer_fk_test.go index 5ba6041ef5c..771a9b3ebd9 100644 --- a/go/vt/vtgate/semantics/analyzer_fk_test.go +++ b/go/vt/vtgate/semantics/analyzer_fk_test.go @@ -552,7 +552,8 @@ func TestGetInvolvedForeignKeys(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - childFks, parentFks, childFkUpdateExprs, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt) + fkState := true + childFks, parentFks, childFkUpdateExprs, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt, &fkState) if tt.expectedErr != "" { require.EqualError(t, err, tt.expectedErr) return diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index 0349ef3f79d..1a957c8ae60 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -107,6 +107,11 @@ func rewriteNotExpr(cursor *sqlparser.Cursor, node *sqlparser.NotExpr) { return } + // There is no inverse operator for NullSafeEqualOp. + // There doesn't exist a null safe non-equality. + if cmp.Operator == sqlparser.NullSafeEqualOp { + return + } cmp.Operator = sqlparser.Inverse(cmp.Operator) cursor.Replace(cmp) } diff --git a/go/vt/vtgate/semantics/info_schema.go b/go/vt/vtgate/semantics/info_schema.go index 838f6276472..b2b5d9036f2 100644 --- a/go/vt/vtgate/semantics/info_schema.go +++ b/go/vt/vtgate/semantics/info_schema.go @@ -1718,6 +1718,10 @@ func (i *infoSchemaWithColumns) ForeignKeyMode(keyspace string) (vschemapb.Keysp return i.inner.ForeignKeyMode(keyspace) } +func (i *infoSchemaWithColumns) GetForeignKeyChecksState() *bool { + return nil +} + func (i *infoSchemaWithColumns) KeyspaceError(keyspace string) error { return i.inner.KeyspaceError(keyspace) } diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 48060524dba..8292ebdf4aa 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -146,12 +146,13 @@ type ( ColumnName string } - // SchemaInformation is used tp provide table information from Vschema. + // SchemaInformation is used to provide table information from Vschema. SchemaInformation interface { FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) ConnCollation() collations.ID // ForeignKeyMode returns the foreign_key flag value ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyMode, error) + GetForeignKeyChecksState() *bool KeyspaceError(keyspace string) error } diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 0e89d6fbc95..9ec4bb0dc03 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -28,6 +28,7 @@ import ( "github.com/google/uuid" "vitess.io/vitess/go/mysql/sqlerror" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" @@ -105,6 +106,11 @@ type vcursorImpl struct { logStats *logstats.LogStats collation collations.ID + // fkChecksState stores the state of foreign key checks variable. + // This state is meant to be the final fk checks state after consulting the + // session state, and the given query's comments for `SET_VAR` optimizer hints. + // A nil value represents that no foreign_key_checks value was provided. + fkChecksState *bool ignoreMaxMemoryRows bool vschema *vindexes.VSchema vm VSchemaOperator @@ -820,6 +826,16 @@ func (vc *vcursorImpl) SetAutocommit(ctx context.Context, autocommit bool) error return nil } +// SetSessionForeignKeyChecks implements the SessionActions interface +func (vc *vcursorImpl) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { + if foreignKeyChecks { + vc.safeSession.SetSystemVariable(sysvars.ForeignKeyChecks.Name, "1") + } else { + vc.safeSession.SetSystemVariable(sysvars.ForeignKeyChecks.Name, "0") + } + return nil +} + // SetQueryTimeout implements the SessionActions interface func (vc *vcursorImpl) SetQueryTimeout(maxExecutionTime int64) { vc.safeSession.QueryTimeout = maxExecutionTime @@ -1331,3 +1347,32 @@ func (vc *vcursorImpl) CloneForReplicaWarming(ctx context.Context) engine.VCurso return v } + +// UpdateForeignKeyChecksState updates the foreign key checks state of the vcursor. +func (vc *vcursorImpl) UpdateForeignKeyChecksState(fkStateFromQuery *bool) { + // Initialize the state to unspecified. + vc.fkChecksState = nil + // If the query has a SET_VAR optimizer hint that explicitly sets the foreign key checks state, + // we should use that. + if fkStateFromQuery != nil { + vc.fkChecksState = fkStateFromQuery + return + } + // If the query doesn't have anything, then we consult the session state. + fkVal, isPresent := vc.safeSession.SystemVariables[sysvars.ForeignKeyChecks.Name] + if isPresent { + switch strings.ToLower(fkVal) { + case "on", "1": + val := true + vc.fkChecksState = &val + case "off", "0": + val := false + vc.fkChecksState = &val + } + } +} + +// GetForeignKeyChecksState gets the stored foreign key checks state in the vcursor. +func (vc *vcursorImpl) GetForeignKeyChecksState() *bool { + return vc.fkChecksState +} diff --git a/go/vt/vtgate/vcursor_impl_test.go b/go/vt/vtgate/vcursor_impl_test.go index 3160b8a9b1a..77be183eacd 100644 --- a/go/vt/vtgate/vcursor_impl_test.go +++ b/go/vt/vtgate/vcursor_impl_test.go @@ -280,6 +280,14 @@ func TestKeyForPlan(t *testing.T) { vschema: vschemaWith1KS, targetString: "ks1[deadbeef]", expectedPlanPrefixKey: "ks1@primary+Collate:utf8mb4_0900_ai_ci+KsIDsResolved:80-+Query:SELECT 1", + }, { + vschema: vschemaWith1KS, + targetString: "", + expectedPlanPrefixKey: "ks1@primary+Collate:utf8mb4_0900_ai_ci+Query:SELECT 1", + }, { + vschema: vschemaWith1KS, + targetString: "ks1@replica", + expectedPlanPrefixKey: "ks1@replica+Collate:utf8mb4_0900_ai_ci+Query:SELECT 1", }} for i, tc := range tests { From 63aadd1941795f1c81f88c885004bf3dd4c50577 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 20 Nov 2023 16:11:02 +0530 Subject: [PATCH 029/119] Enable `Replace Into` engine and Fix Foreign key locking issue (#14532) Signed-off-by: Harshit Gangal Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Co-authored-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/sqlerror/constants.go | 1 + go/test/endtoend/utils/utils.go | 55 +++---- .../vtgate/foreignkey/fk_fuzz_test.go | 2 +- go/test/endtoend/vtgate/foreignkey/fk_test.go | 36 ++++- .../foreignkey/stress/fk_stress_test.go | 5 +- go/vt/vterrors/code.go | 2 +- go/vt/vtgate/engine/sequential.go | 22 ++- go/vt/vtgate/planbuilder/operators/delete.go | 2 +- .../planbuilder/operators/query_planning.go | 8 +- go/vt/vtgate/planbuilder/operators/update.go | 32 ++-- go/vt/vtgate/planbuilder/plan_test.go | 36 +++-- .../testdata/foreignkey_cases.json | 150 +++++++++--------- .../testdata/foreignkey_checks_off_cases.json | 8 +- .../testdata/foreignkey_checks_on_cases.json | 122 +++++++------- go/vt/vtgate/semantics/analyzer_fk_test.go | 4 +- go/vt/vtgate/vschema_manager_test.go | 2 +- 16 files changed, 267 insertions(+), 220 deletions(-) diff --git a/go/mysql/sqlerror/constants.go b/go/mysql/sqlerror/constants.go index 0074e904e4a..01de1b6d45c 100644 --- a/go/mysql/sqlerror/constants.go +++ b/go/mysql/sqlerror/constants.go @@ -250,6 +250,7 @@ const ( ERJSONValueTooBig = ErrorCode(3150) ERJSONDocumentTooDeep = ErrorCode(3157) + ERLockNowait = ErrorCode(3572) ERRegexpStringNotTerminated = ErrorCode(3684) ERRegexpBufferOverflow = ErrorCode(3684) ERRegexpIllegalArgument = ErrorCode(3685) diff --git a/go/test/endtoend/utils/utils.go b/go/test/endtoend/utils/utils.go index 0231cae7baf..9cf9c767fc7 100644 --- a/go/test/endtoend/utils/utils.go +++ b/go/test/endtoend/utils/utils.go @@ -256,51 +256,46 @@ func WaitForAuthoritative(t *testing.T, ks, tbl string, readVSchema func() (*int // WaitForKsError waits for the ks error field to be populated and returns it. func WaitForKsError(t *testing.T, vtgateProcess cluster.VtgateProcess, ks string) string { + var errString string + WaitForVschemaCondition(t, vtgateProcess, ks, func(t *testing.T, keyspace map[string]interface{}) bool { + ksErr, fieldPresent := keyspace["error"] + if !fieldPresent { + return false + } + var ok bool + errString, ok = ksErr.(string) + return ok + }) + return errString +} + +// WaitForVschemaCondition waits for the condition to be true +func WaitForVschemaCondition(t *testing.T, vtgateProcess cluster.VtgateProcess, ks string, conditionMet func(t *testing.T, keyspace map[string]interface{}) bool) { timeout := time.After(60 * time.Second) for { select { case <-timeout: - t.Fatalf("schema tracking did not find error in '%s'", ks) - return "" + t.Fatalf("schema tracking did not met the condition within the time for keyspace: %s", ks) default: res, err := vtgateProcess.ReadVSchema() require.NoError(t, err, res) kss := convertToMap(*res)["keyspaces"] ksMap := convertToMap(convertToMap(kss)[ks]) - ksErr, fieldPresent := ksMap["error"] - if !fieldPresent { - time.Sleep(100 * time.Millisecond) - continue + if conditionMet(t, ksMap) { + return } - errString, isErr := ksErr.(string) - if !isErr { - time.Sleep(100 * time.Millisecond) - continue - } - return errString + time.Sleep(100 * time.Millisecond) } } } // WaitForTableDeletions waits for a table to be deleted -func WaitForTableDeletions(ctx context.Context, t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl string) error { - for { - select { - case <-ctx.Done(): - return fmt.Errorf("schema tracking still found the table '%s'", tbl) - default: - res, err := vtgateProcess.ReadVSchema() - require.NoError(t, err, res) - keyspacesMap := convertToMap(*res)["keyspaces"] - ksMap := convertToMap(keyspacesMap)[ks] - tablesMap := convertToMap(ksMap)["tables"] - _, isPresent := convertToMap(tablesMap)[tbl] - if !isPresent { - return nil - } - time.Sleep(100 * time.Millisecond) - } - } +func WaitForTableDeletions(ctx context.Context, t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl string) { + WaitForVschemaCondition(t, vtgateProcess, ks, func(t *testing.T, keyspace map[string]interface{}) bool { + tablesMap := keyspace["tables"] + _, isPresent := convertToMap(tablesMap)[tbl] + return !isPresent + }) } // WaitForColumn waits for a table's column to be present diff --git a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go index 2005b12a8fd..325bdedc5c9 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go @@ -126,7 +126,7 @@ func (fz *fuzzer) generateQuery() []string { } func getInsertType() string { - return "insert" + return []string{"insert", "replace"}[rand.Intn(2)] } // generateInsertDMLQuery generates an INSERT query from the parameters for the fuzzer. diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index 67e23c1cfd1..785310b6ade 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -1000,20 +1000,26 @@ func TestCyclicFks(t *testing.T) { // Create a cyclic foreign key constraint. utils.Exec(t, mcmp.VtConn, "alter table fk_t10 add constraint test_cyclic_fks foreign key (col) references fk_t12 (col) on delete cascade on update cascade") - defer func() { - utils.Exec(t, mcmp.VtConn, "alter table fk_t10 drop foreign key test_cyclic_fks") - }() // Wait for schema-tracking to be complete. - ksErr := utils.WaitForKsError(t, clusterInstance.VtgateProcess, unshardedKs) - // Make sure Vschema has the error for cyclic foreign keys. - assert.Contains(t, ksErr, "VT09019: uks has cyclic foreign keys") + errString := utils.WaitForKsError(t, clusterInstance.VtgateProcess, unshardedKs) + assert.Contains(t, errString, "VT09019: keyspace 'uks' has cyclic foreign keys") // Ensure that the Vitess database is originally empty ensureDatabaseState(t, mcmp.VtConn, true) _, err := utils.ExecAllowError(t, mcmp.VtConn, "insert into fk_t10(id, col) values (1, 1)") - require.ErrorContains(t, err, "VT09019: uks has cyclic foreign keys") + require.ErrorContains(t, err, "VT09019: keyspace 'uks' has cyclic foreign keys") + + // Drop the cyclic foreign key constraint. + utils.Exec(t, mcmp.VtConn, "alter table fk_t10 drop foreign key test_cyclic_fks") + + // Wait for schema-tracking to be complete. + utils.WaitForVschemaCondition(t, clusterInstance.VtgateProcess, unshardedKs, func(t *testing.T, keyspace map[string]interface{}) bool { + _, fieldPresent := keyspace["error"] + return !fieldPresent + }) + } func TestReplace(t *testing.T) { @@ -1175,4 +1181,20 @@ func TestReplaceWithFK(t *testing.T) { // replace some data. _, err := utils.ExecAllowError(t, conn, `replace into t1(id, col) values (1, 1)`) require.ErrorContains(t, err, "VT12001: unsupported: REPLACE INTO with sharded keyspace (errno 1235) (sqlstate 42000)") + + _ = utils.Exec(t, conn, `use uks`) + + _ = utils.Exec(t, conn, `replace into u_t1(id, col1) values (1, 1), (2, 1)`) + // u_t1: (1,1) (2,1) + + _ = utils.Exec(t, conn, `replace into u_t2(id, col2) values (1, 1), (2, 1)`) + // u_t1: (1,1) (2,1) + // u_t2: (1,1) (2,1) + + _ = utils.Exec(t, conn, `replace into u_t1(id, col1) values (2, 2)`) + // u_t1: (1,1) (2,2) + // u_t2: (1,null) (2,null) + + utils.AssertMatches(t, conn, `select * from u_t1`, `[[INT64(1) INT64(1)] [INT64(2) INT64(2)]]`) + utils.AssertMatches(t, conn, `select * from u_t2`, `[[INT64(1) NULL] [INT64(2) NULL]]`) } diff --git a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go index 00b7d9ca0cc..ae2b9324bb6 100644 --- a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go +++ b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go @@ -707,8 +707,7 @@ func createInitialSchema(t *testing.T, tcase *testCase) { timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() for _, tableName := range tableNames { - err := utils.WaitForTableDeletions(timeoutCtx, t, clusterInstance.VtgateProcess, keyspaceName, tableName) - require.NoError(t, err) + utils.WaitForTableDeletions(timeoutCtx, t, clusterInstance.VtgateProcess, keyspaceName, tableName) } }) t.Run("creating tables", func(t *testing.T) { @@ -922,6 +921,8 @@ func isFKError(err error) bool { return false case sqlerror.ERLockDeadlock: return false // bummer, but deadlocks can happen, it's a legit error. + case sqlerror.ERLockNowait: + return false // For some queries we use NOWAIT. Bummer, but this can happen, it's a legit error. case sqlerror.ERNoReferencedRow, sqlerror.ERRowIsReferenced, sqlerror.ERRowIsReferenced2, diff --git a/go/vt/vterrors/code.go b/go/vt/vterrors/code.go index e619c6fff59..e6cd1ca9ba0 100644 --- a/go/vt/vterrors/code.go +++ b/go/vt/vterrors/code.go @@ -84,7 +84,7 @@ var ( VT09016 = errorWithState("VT09016", vtrpcpb.Code_FAILED_PRECONDITION, RowIsReferenced2, "Cannot delete or update a parent row: a foreign key constraint fails", "SET DEFAULT is not supported by InnoDB") VT09017 = errorWithoutState("VT09017", vtrpcpb.Code_FAILED_PRECONDITION, "%s", "Invalid syntax for the statement type.") VT09018 = errorWithoutState("VT09018", vtrpcpb.Code_FAILED_PRECONDITION, "%s", "Invalid syntax for the vindex function statement.") - VT09019 = errorWithoutState("VT09019", vtrpcpb.Code_FAILED_PRECONDITION, "%s has cyclic foreign keys", "Vitess doesn't support cyclic foreign keys.") + VT09019 = errorWithoutState("VT09019", vtrpcpb.Code_FAILED_PRECONDITION, "keyspace '%s' has cyclic foreign keys", "Vitess doesn't support cyclic foreign keys.") VT10001 = errorWithoutState("VT10001", vtrpcpb.Code_ABORTED, "foreign key constraints are not allowed", "Foreign key constraints are not allowed, see https://vitess.io/blog/2021-06-15-online-ddl-why-no-fk/.") VT10002 = errorWithoutState("VT10002", vtrpcpb.Code_ABORTED, "'replace into' with foreign key constraints are not allowed", "Foreign key constraints sometimes are not written in binary logs and will cause issue with vreplication workflows like online-ddl.") diff --git a/go/vt/vtgate/engine/sequential.go b/go/vt/vtgate/engine/sequential.go index d038df4afbf..fddce333c91 100644 --- a/go/vt/vtgate/engine/sequential.go +++ b/go/vt/vtgate/engine/sequential.go @@ -67,12 +67,30 @@ func (s *Sequential) GetTableName() string { // TryExecute performs a non-streaming exec. func (s *Sequential) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantFields bool) (*sqltypes.Result, error) { - return nil, vterrors.VT10002() + finalRes := &sqltypes.Result{} + for _, source := range s.Sources { + res, err := vcursor.ExecutePrimitive(ctx, source, bindVars, wantFields) + if err != nil { + return nil, err + } + finalRes.RowsAffected += res.RowsAffected + if finalRes.InsertID == 0 { + finalRes.InsertID = res.InsertID + } + if res.Info != "" { + finalRes.Info = res.Info + } + } + return finalRes, nil } // TryStreamExecute performs a streaming exec. func (s *Sequential) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantFields bool, callback func(*sqltypes.Result) error) error { - return vterrors.VT10002() + qr, err := s.TryExecute(ctx, vcursor, bindVars, wantFields) + if err != nil { + return err + } + return callback(qr) } // GetFields fetches the field info. diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index bd38b849e7c..8b7841bdcdd 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -190,7 +190,7 @@ func createFkCascadeOpForDelete(ctx *plancontext.PlanningContext, parentOp ops.O } fkChildren = append(fkChildren, fkChild) } - selectionOp, err := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, nil, sqlparser.ForUpdateLock) + selectionOp, err := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, nil, sqlparser.ForUpdateLockNoWait) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 1f239a31973..1738d35de43 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -432,7 +432,7 @@ func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Proje } expr = semantics.RewriteDerivedTableExpression(expr, derivedTbl) - out := prefixColNames(tblName, expr) + out := prefixColNames(ctx, tblName, expr) alias := sqlparser.UnescapedString(out) predicate.LHSExprs[idx].Expr = sqlparser.NewColNameWithQualifier(alias, derivedTblName) @@ -450,14 +450,14 @@ func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Proje // prefixColNames adds qualifier prefixes to all ColName:s. // We want to be more explicit than the user was to make sure we never produce invalid SQL -func prefixColNames(tblName sqlparser.TableName, e sqlparser.Expr) sqlparser.Expr { +func prefixColNames(ctx *plancontext.PlanningContext, tblName sqlparser.TableName, e sqlparser.Expr) sqlparser.Expr { return sqlparser.CopyOnRewrite(e, nil, func(cursor *sqlparser.CopyOnWriteCursor) { col, ok := cursor.Node().(*sqlparser.ColName) if !ok { return } - col.Qualifier = tblName - }, nil).(sqlparser.Expr) + cursor.Replace(sqlparser.NewColNameWithQualifier(col.Name.String(), tblName)) + }, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) } func createProjectionWithTheseColumns( diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 1f122a950d4..71d82c64216 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -280,7 +280,7 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, fkChildren = append(fkChildren, fkChild) } - selectionOp, err := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, updStmt.OrderBy, nil, sqlparser.ForUpdateLock) + selectionOp, err := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, updStmt.OrderBy, nil, sqlparser.ForUpdateLockNoWait) if err != nil { return nil, err } @@ -482,7 +482,9 @@ func buildChildUpdOpForSetNull( // For example, if we are setting `update parent cola = :v1 and colb = :v2`, then on the child, the where condition would look something like this - // `:v1 IS NULL OR :v2 IS NULL OR (child_cola, child_colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). - compExpr := nullSafeNotInComparison(ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)), fk, updatedTable.GetTableName(), nonLiteralUpdateInfo) + updateExprs := ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)) + compExpr := nullSafeNotInComparison(ctx, + updateExprs, fk, updatedTable.GetTableName(), nonLiteralUpdateInfo, false /* appendQualifier */) if compExpr != nil { childWhereExpr = &sqlparser.AndExpr{ Left: childWhereExpr, @@ -605,8 +607,8 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS Right: sqlparser.NewColNameWithQualifier(pFK.ChildColumns[idx].String(), childTbl), } } else { - notEqualColNames = append(notEqualColNames, prefixColNames(childTbl, matchedExpr.Name)) - prefixedMatchExpr := prefixColNames(childTbl, matchedExpr.Expr) + notEqualColNames = append(notEqualColNames, prefixColNames(ctx, childTbl, matchedExpr.Name)) + prefixedMatchExpr := prefixColNames(ctx, childTbl, matchedExpr.Expr) notEqualExprs = append(notEqualExprs, prefixedMatchExpr) joinExpr = &sqlparser.ComparisonExpr{ Operator: sqlparser.EqualOp, @@ -641,7 +643,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS } // add existing where condition on the update statement if updStmt.Where != nil { - whereCond = &sqlparser.AndExpr{Left: whereCond, Right: prefixColNames(childTbl, updStmt.Where.Expr)} + whereCond = &sqlparser.AndExpr{Left: whereCond, Right: prefixColNames(ctx, childTbl, updStmt.Where.Expr)} } return createSelectionOp(ctx, sqlparser.SelectExprs{sqlparser.NewAliasedExpr(sqlparser.NewIntLiteral("1"), "")}, @@ -655,7 +657,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS sqlparser.NewWhere(sqlparser.WhereClause, whereCond), nil, sqlparser.NewLimitWithoutOffset(1), - sqlparser.ShareModeLock) + sqlparser.ForShareLockNoWait) } // Each child foreign key constraint is verified by a join query of the form: @@ -696,7 +698,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt var whereCond sqlparser.Expr // add existing where condition on the update statement if updStmt.Where != nil { - whereCond = prefixColNames(parentTbl, updStmt.Where.Expr) + whereCond = prefixColNames(ctx, parentTbl, updStmt.Where.Expr) } // We don't want to fail the RESTRICT for the case where the parent columns remains unchanged on the update. @@ -708,7 +710,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt // For example, if we are setting `update child cola = :v1 and colb = :v2`, then on the parent, the where condition would look something like this - // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). - compExpr := nullSafeNotInComparison(updStmt.Exprs, cFk, parentTbl, nil) + compExpr := nullSafeNotInComparison(ctx, updStmt.Exprs, cFk, parentTbl, nil /* nonLiteralUpdateInfo */, true /* appendQualifier */) if compExpr != nil { whereCond = sqlparser.AndExpressions(whereCond, compExpr) } @@ -725,15 +727,15 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt sqlparser.NewWhere(sqlparser.WhereClause, whereCond), nil, sqlparser.NewLimitWithoutOffset(1), - sqlparser.ShareModeLock) + sqlparser.ForShareLockNoWait) } // nullSafeNotInComparison is used to compare the child columns in the foreign key constraint aren't the same as the updateExpressions exactly. -// This comparison has to be null safe so we create an expression which looks like the following for a query like `update child cola = :v1 and colb = :v2` - +// This comparison has to be null safe, so we create an expression which looks like the following for a query like `update child cola = :v1 and colb = :v2` - // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL) // This expression is used in cascading SET NULLs and in verifying whether an update should be restricted. -func nullSafeNotInComparison(updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo, parentTbl sqlparser.TableName, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo) sqlparser.Expr { +func nullSafeNotInComparison(ctx *plancontext.PlanningContext, updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo, parentTbl sqlparser.TableName, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, appendQualifier bool) sqlparser.Expr { var valTuple sqlparser.ValTuple var updateValues sqlparser.ValTuple for idx, updateExpr := range updateExprs { @@ -742,12 +744,16 @@ func nullSafeNotInComparison(updateExprs sqlparser.UpdateExprs, cFk vindexes.Chi if sqlparser.IsNull(updateExpr.Expr) { return nil } - childUpdateExpr := prefixColNames(parentTbl, updateExpr.Expr) + childUpdateExpr := prefixColNames(ctx, parentTbl, updateExpr.Expr) if len(nonLiteralUpdateInfo) > 0 && nonLiteralUpdateInfo[idx].UpdateExprBvName != "" { childUpdateExpr = sqlparser.NewArgument(nonLiteralUpdateInfo[idx].UpdateExprBvName) } updateValues = append(updateValues, childUpdateExpr) - valTuple = append(valTuple, sqlparser.NewColNameWithQualifier(cFk.ChildColumns[colIdx].String(), cFk.Table.GetTableName())) + if appendQualifier { + valTuple = append(valTuple, sqlparser.NewColNameWithQualifier(cFk.ChildColumns[colIdx].String(), cFk.Table.GetTableName())) + } else { + valTuple = append(valTuple, sqlparser.NewColName(cFk.ChildColumns[colIdx].String())) + } } } diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index c04c5cd9ddc..a488dd1e470 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -178,6 +178,8 @@ func setFks(t *testing.T, vschema *vindexes.VSchema) { // FK from tblrefDef referencing tbl20 that is shard scoped of SET-Default types. _ = vschema.AddForeignKey("sharded_fk_allow", "tblrefDef", createFkDefinition([]string{"ref"}, "tbl20", []string{"col2"}, sqlparser.SetDefault, sqlparser.SetDefault)) + addPKs(t, vschema, "sharded_fk_allow", []string{"tbl1", "tbl2", "tbl3", "tbl4", "tbl5", "tbl6", "tbl7", "tbl9", "tbl10", + "multicol_tbl1", "multicol_tbl2", "tblrefDef", "tbl20"}) } if vschema.Keyspaces["unsharded_fk_allow"] != nil { // u_tbl2(col2) -> u_tbl1(col1) Cascade. @@ -208,22 +210,24 @@ func setFks(t *testing.T, vschema *vindexes.VSchema) { _ = vschema.AddForeignKey("unsharded_fk_allow", "u_multicol_tbl2", createFkDefinition([]string{"cola", "colb"}, "u_multicol_tbl1", []string{"cola", "colb"}, sqlparser.SetNull, sqlparser.SetNull)) _ = vschema.AddForeignKey("unsharded_fk_allow", "u_multicol_tbl3", createFkDefinition([]string{"cola", "colb"}, "u_multicol_tbl2", []string{"cola", "colb"}, sqlparser.Cascade, sqlparser.Cascade)) - _ = vschema.AddForeignKey("unsharded_fk_allow", "fk_t3", createFkDefinition([]string{"col"}, "fk_t2", []string{"col2"}, sqlparser.SetNull, sqlparser.SetNull)) - _ = vschema.AddForeignKey("unsharded_fk_allow", "fk_t4", createFkDefinition([]string{"col3"}, "fk_t3", []string{"col2"}, sqlparser.SetNull, sqlparser.SetNull)) - _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t2", []string{"id"}) - _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t3", []string{"id"}) - _ = vschema.AddPrimaryKey("unsharded_fk_allow", "fk_t4", []string{"id"}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "fk_t3", sqlparser.Exprs{sqlparser.NewColName("col")}) - } - - _ = vschema.AddPrimaryKey("unsharded_fk_allow", "u_tbl1", []string{"id"}) - _ = vschema.AddPrimaryKey("unsharded_fk_allow", "u_tbl9", []string{"id"}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9")}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{&sqlparser.BinaryExpr{Operator: sqlparser.MultOp, Left: sqlparser.NewColName("col9"), Right: sqlparser.NewColName("foo")}}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9"), sqlparser.NewColName("foo")}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("foo"), sqlparser.NewColName("bar")}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("bar"), sqlparser.NewColName("col9")}) - _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl8", sqlparser.Exprs{sqlparser.NewColName("col8")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{&sqlparser.BinaryExpr{Operator: sqlparser.MultOp, Left: sqlparser.NewColName("col9"), Right: sqlparser.NewColName("foo")}}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("col9"), sqlparser.NewColName("foo")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("foo"), sqlparser.NewColName("bar")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl9", sqlparser.Exprs{sqlparser.NewColName("bar"), sqlparser.NewColName("col9")}) + _ = vschema.AddUniqueKey("unsharded_fk_allow", "u_tbl8", sqlparser.Exprs{sqlparser.NewColName("col8")}) + + addPKs(t, vschema, "unsharded_fk_allow", []string{"u_tbl1", "u_tbl2", "u_tbl3", "u_tbl4", "u_tbl5", "u_tbl6", "u_tbl7", "u_tbl8", "u_tbl9", + "u_multicol_tbl1", "u_multicol_tbl2", "u_multicol_tbl3"}) + } + +} + +func addPKs(t *testing.T, vschema *vindexes.VSchema, ks string, tbls []string) { + for _, tbl := range tbls { + require.NoError(t, + vschema.AddPrimaryKey(ks, tbl, []string{"id"})) + } } func TestSystemTables57(t *testing.T) { diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index 99679d698a2..6757f7688e1 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -82,7 +82,7 @@ "Sharded": true }, "FieldQuery": "select colb, cola, y, colc, x from multicol_tbl1 where 1 != 1", - "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update", + "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update nowait", "Table": "multicol_tbl1", "Values": [ "1", @@ -155,7 +155,7 @@ "Sharded": true }, "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", - "Query": "select col5, t5col5 from tbl5 for update", + "Query": "select col5, t5col5 from tbl5 for update nowait", "Table": "tbl5" }, { @@ -233,7 +233,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where col9 = 5 for update", + "Query": "select col9 from u_tbl9 where col9 = 5 for update nowait", "Table": "u_tbl9" }, { @@ -312,7 +312,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where id = 1 for update", + "Query": "select col2 from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -328,7 +328,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in (('bar'))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in (('bar'))", "Table": "u_tbl3" }, { @@ -423,7 +423,7 @@ "Sharded": true }, "FieldQuery": "select t5col5 from tbl5 where 1 != 1", - "Query": "select t5col5 from tbl5 for update", + "Query": "select t5col5 from tbl5 for update nowait", "Table": "tbl5" }, { @@ -439,7 +439,7 @@ "Cols": [ 0 ], - "Query": "update tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (tbl4.t4col4) not in (('foo'))", + "Query": "update tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (t4col4) not in (('foo'))", "Table": "tbl4" }, { @@ -527,7 +527,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl10 where 1 != 1", - "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') lock in share mode", + "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') for share nowait", "Table": "tbl10" }, { @@ -538,7 +538,7 @@ "Sharded": true }, "FieldQuery": "select tbl3.col from tbl3 where 1 != 1", - "Query": "select tbl3.col from tbl3 where tbl3.col = 'foo' lock in share mode", + "Query": "select tbl3.col from tbl3 where tbl3.col = 'foo' for share nowait", "Table": "tbl3" } ] @@ -558,7 +558,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update tbl10 set tbl10.col = 'foo'", + "Query": "update tbl10 set col = 'foo'", "Table": "tbl10" } ] @@ -592,7 +592,7 @@ "Sharded": true }, "FieldQuery": "select col9 from tbl9 where 1 != 1", - "Query": "select col9 from tbl9 where col9 = 34 for update", + "Query": "select col9 from tbl9 where col9 = 34 for update nowait", "Table": "tbl9", "Values": [ "34" @@ -657,7 +657,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 for update", + "Query": "select col1 from u_tbl1 for update nowait", "Table": "u_tbl1" }, { @@ -677,7 +677,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -693,7 +693,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in (('foo'))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in (('foo'))", "Table": "u_tbl3" }, { @@ -727,7 +727,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo')) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in (('foo')) for update nowait", "Table": "u_tbl9" }, { @@ -755,7 +755,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo'))", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in (('foo'))", "Table": "u_tbl9" } ] @@ -806,7 +806,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", - "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", "Table": "u_tbl1, u_tbl2" }, { @@ -821,8 +821,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", - "Query": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", + "FieldQuery": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where 1 != 1", + "Query": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -846,7 +846,7 @@ "UpdateExprBvName": "fkc_upd" } ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", "Table": "u_tbl3" }, { @@ -858,7 +858,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, u_tbl2.col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", "Table": "u_tbl2" } ] @@ -889,8 +889,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where 1 != 1", - "Query": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where id = 1 for update", + "FieldQuery": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -918,7 +918,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -934,7 +934,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", "Table": "u_tbl3" }, { @@ -976,7 +976,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1))) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (col9) not in ((:fkc_upd1))) for update nowait", "Table": "u_tbl9" }, { @@ -1004,7 +1004,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1)))", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (col9) not in ((:fkc_upd1)))", "Table": "u_tbl9" } ] @@ -1018,7 +1018,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = u_tbl1.x + 'bar' where id = 1", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", "Table": "u_tbl1" } ] @@ -1050,7 +1050,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where id = 1 for update", + "Query": "select col2 from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -1066,7 +1066,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in ((2))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((2))", "Table": "u_tbl3" }, { @@ -1107,7 +1107,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 where id = 1 for update", + "Query": "select col1 from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -1127,7 +1127,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -1143,7 +1143,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in ((2))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((2))", "Table": "u_tbl3" }, { @@ -1177,7 +1177,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2)) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((2)) for update nowait", "Table": "u_tbl9" }, { @@ -1205,7 +1205,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2))", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((2))", "Table": "u_tbl9" } ] @@ -1284,7 +1284,7 @@ "Sharded": true }, "FieldQuery": "select tbl3.colx from tbl3 where 1 != 1", - "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 lock in share mode", + "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 for share nowait", "Table": "tbl3" }, { @@ -1295,7 +1295,7 @@ "Sharded": true }, "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", - "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 lock in share mode", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 for share nowait", "Table": "tbl1" } ] @@ -1315,7 +1315,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set tbl3.coly = tbl3.colx + 10 where tbl3.coly = 10", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set coly = colx + 10 where coly = 10", "Table": "tbl3" } ] @@ -1364,7 +1364,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl3 where 1 != 1", - "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 lock in share mode", + "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 for share nowait", "Table": "tbl3" }, { @@ -1375,7 +1375,7 @@ "Sharded": true }, "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", - "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = 20 lock in share mode", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = 20 for share nowait", "Table": "tbl1" } ] @@ -1395,7 +1395,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update tbl3 set tbl3.coly = 20 where tbl3.coly = 10", + "Query": "update tbl3 set coly = 20 where coly = 10", "Table": "tbl3" } ] @@ -1424,7 +1424,7 @@ "Sharded": false }, "FieldQuery": "select col6 from u_tbl6 where 1 != 1", - "Query": "select col6 from u_tbl6 for update", + "Query": "select col6 from u_tbl6 for update nowait", "Table": "u_tbl6" }, { @@ -1444,7 +1444,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", "Table": "u_tbl8, u_tbl9" }, { @@ -1456,7 +1456,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set u_tbl8.col8 = 'foo' where (u_tbl8.col8) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set col8 = 'foo' where (col8) in ::fkc_vals", "Table": "u_tbl8" } ] @@ -1500,7 +1500,7 @@ "Sharded": false }, "FieldQuery": "select col7 from u_tbl7 where 1 != 1", - "Query": "select col7 from u_tbl7 for update", + "Query": "select col7 from u_tbl7 for update nowait", "Table": "u_tbl7" }, { @@ -1520,7 +1520,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1532,7 +1532,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1544,7 +1544,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = 'foo' where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = 'foo' where (col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -1589,7 +1589,7 @@ "Sharded": false }, "FieldQuery": "select col7 from u_tbl7 where 1 != 1", - "Query": "select col7 from u_tbl7 for update", + "Query": "select col7 from u_tbl7 for update nowait", "Table": "u_tbl7" }, { @@ -1609,7 +1609,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1621,7 +1621,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1633,7 +1633,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :v1 where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :v1 where (col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -1713,7 +1713,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 where (id) in ((1)) for update", + "Query": "select col1 from u_tbl1 where (id) in ((1)) for update nowait", "Table": "u_tbl1" }, { @@ -1733,7 +1733,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -1819,7 +1819,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl1 where id = 3 for update", + "Query": "select cola, colb from u_multicol_tbl1 where id = 3 for update nowait", "Table": "u_multicol_tbl1" }, { @@ -1840,7 +1840,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2)) for update", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (cola, colb) not in ((1, 2)) for update nowait", "Table": "u_multicol_tbl2" }, { @@ -1869,7 +1869,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2))", + "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (cola, colb) not in ((1, 2))", "Table": "u_multicol_tbl2" } ] @@ -1913,7 +1913,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl1 where id = :v3 for update", + "Query": "select cola, colb from u_multicol_tbl1 where id = :v3 for update nowait", "Table": "u_multicol_tbl1" }, { @@ -1934,7 +1934,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2)))) for update", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (cola, colb) not in ((:v1, :v2)))) for update nowait", "Table": "u_multicol_tbl2" }, { @@ -1963,7 +1963,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2))))", + "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (cola, colb) not in ((:v1, :v2))))", "Table": "u_multicol_tbl2" } ] @@ -2013,7 +2013,7 @@ "Sharded": true }, "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", - "Query": "select col5, t5col5 from tbl5 where id = :v1 for update", + "Query": "select col5, t5col5 from tbl5 where id = :v1 for update nowait", "Table": "tbl5" }, { @@ -2093,7 +2093,7 @@ "Sharded": false }, "FieldQuery": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where 1 != 1", - "Query": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where bar = 42 for update", + "Query": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where bar = 42 for update nowait", "Table": "u_tbl7" }, { @@ -2121,7 +2121,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where not (u_tbl4.col4) <=> (:fkc_upd) and (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where not (u_tbl4.col4) <=> (:fkc_upd) and (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -2133,7 +2133,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:fkc_upd is null or (u_tbl9.col9) not in ((:fkc_upd))) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:fkc_upd is null or (u_tbl9.col9) not in ((:fkc_upd))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -2145,7 +2145,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :fkc_upd where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :fkc_upd where (col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -2189,8 +2189,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select cola, colb, cola <=> u_multicol_tbl1.cola + 3, u_multicol_tbl1.cola + 3 from u_multicol_tbl1 where 1 != 1", - "Query": "select cola, colb, cola <=> u_multicol_tbl1.cola + 3, u_multicol_tbl1.cola + 3 from u_multicol_tbl1 where id = 3 for update", + "FieldQuery": "select cola, colb, cola <=> cola + 3, cola + 3 from u_multicol_tbl1 where 1 != 1", + "Query": "select cola, colb, cola <=> cola + 3, cola + 3 from u_multicol_tbl1 where id = 3 for update nowait", "Table": "u_multicol_tbl1" }, { @@ -2219,7 +2219,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (u_multicol_tbl2.cola) not in ((:fkc_upd))) for update", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (cola) not in ((:fkc_upd))) for update nowait", "Table": "u_multicol_tbl2" }, { @@ -2248,7 +2248,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (u_multicol_tbl2.cola) not in ((:fkc_upd)))", + "Query": "update u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:fkc_upd is null or (cola) not in ((:fkc_upd)))", "Table": "u_multicol_tbl2" } ] @@ -2262,7 +2262,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl1 set cola = u_multicol_tbl1.cola + 3 where id = 3", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl1 set cola = cola + 3 where id = 3", "Table": "u_multicol_tbl1" } ] @@ -2297,7 +2297,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where 1 != 1", - "Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and not (u_multicol_tbl2.cola, u_multicol_tbl2.colb) <=> (2, u_multicol_tbl2.colc - 2) and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 lock in share mode", + "Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and not (u_multicol_tbl2.cola, u_multicol_tbl2.colb) <=> (2, u_multicol_tbl2.colc - 2) and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 for share nowait", "Table": "u_multicol_tbl1, u_multicol_tbl2" }, { @@ -2312,8 +2312,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select cola, colb, u_multicol_tbl2.cola <=> 2, 2, u_multicol_tbl2.colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb, u_multicol_tbl2.cola <=> 2, 2, u_multicol_tbl2.colb <=> u_multicol_tbl2.colc - 2, u_multicol_tbl2.colc - 2 from u_multicol_tbl2 where u_multicol_tbl2.id = 7 for update", + "FieldQuery": "select cola, colb, cola <=> 2, 2, colb <=> colc - 2, colc - 2 from u_multicol_tbl2 where 1 != 1", + "Query": "select cola, colb, cola <=> 2, 2, colb <=> colc - 2, colc - 2 from u_multicol_tbl2 where id = 7 for update nowait", "Table": "u_multicol_tbl2" }, { @@ -2356,7 +2356,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl2 set u_multicol_tbl2.cola = 2, u_multicol_tbl2.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.id = 7", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_multicol_tbl2 set cola = 2, colb = colc - 2 where id = 7", "Table": "u_multicol_tbl2" } ] @@ -2391,7 +2391,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ((10), (20), (30)) or (col9 * foo) in ((10 * null), (20 * null), (30 * null)) or (bar, col9) in ((1, 10), (1, 20), (1, 30)) or (id) in ((1), (2), (3)) for update", + "Query": "select col9 from u_tbl9 where (col9) in ((10), (20), (30)) or (col9 * foo) in ((10 * null), (20 * null), (30 * null)) or (bar, col9) in ((1, 10), (1, 20), (1, 30)) or (id) in ((1), (2), (3)) for update nowait", "Table": "u_tbl9" }, { diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json index 968fb8679fb..9fd0563f703 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_off_cases.json @@ -111,7 +111,7 @@ "Sharded": true }, "FieldQuery": "select colb, cola, y, colc, x from multicol_tbl1 where 1 != 1", - "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update", + "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update nowait", "Table": "multicol_tbl1", "Values": [ "1", @@ -258,7 +258,7 @@ "Sharded": true }, "FieldQuery": "select t5col5 from tbl5 where 1 != 1", - "Query": "select t5col5 from tbl5 for update", + "Query": "select t5col5 from tbl5 for update nowait", "Table": "tbl5" }, { @@ -274,7 +274,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (tbl4.t4col4) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (t4col4) not in (('foo'))", "Table": "tbl4" }, { @@ -366,7 +366,7 @@ "Sharded": true }, "FieldQuery": "select col9 from tbl9 where 1 != 1", - "Query": "select col9 from tbl9 where col9 = 34 for update", + "Query": "select col9 from tbl9 where col9 = 34 for update nowait", "Table": "tbl9", "Values": [ "34" diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json index 862c18b068d..1d523f3f24f 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json @@ -82,7 +82,7 @@ "Sharded": true }, "FieldQuery": "select colb, cola, y, colc, x from multicol_tbl1 where 1 != 1", - "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update", + "Query": "select colb, cola, y, colc, x from multicol_tbl1 where cola = 1 and colb = 2 and colc = 3 for update nowait", "Table": "multicol_tbl1", "Values": [ "1", @@ -155,7 +155,7 @@ "Sharded": true }, "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", - "Query": "select col5, t5col5 from tbl5 for update", + "Query": "select col5, t5col5 from tbl5 for update nowait", "Table": "tbl5" }, { @@ -233,7 +233,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where col9 = 5 for update", + "Query": "select col9 from u_tbl9 where col9 = 5 for update nowait", "Table": "u_tbl9" }, { @@ -312,7 +312,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where id = 1 for update", + "Query": "select col2 from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -328,7 +328,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in (('bar'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in (('bar'))", "Table": "u_tbl3" }, { @@ -423,7 +423,7 @@ "Sharded": true }, "FieldQuery": "select t5col5 from tbl5 where 1 != 1", - "Query": "select t5col5 from tbl5 for update", + "Query": "select t5col5 from tbl5 for update nowait", "Table": "tbl5" }, { @@ -439,7 +439,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (tbl4.t4col4) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ tbl4 set t4col4 = null where (t4col4) in ::fkc_vals and (t4col4) not in (('foo'))", "Table": "tbl4" }, { @@ -527,7 +527,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl10 where 1 != 1", - "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') lock in share mode", + "Query": "select 1 from tbl10 where not (tbl10.col) <=> ('foo') for share nowait", "Table": "tbl10" }, { @@ -538,7 +538,7 @@ "Sharded": true }, "FieldQuery": "select tbl3.col from tbl3 where 1 != 1", - "Query": "select tbl3.col from tbl3 where tbl3.col = 'foo' lock in share mode", + "Query": "select tbl3.col from tbl3 where tbl3.col = 'foo' for share nowait", "Table": "tbl3" } ] @@ -558,7 +558,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl10 set tbl10.col = 'foo'", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl10 set col = 'foo'", "Table": "tbl10" } ] @@ -592,7 +592,7 @@ "Sharded": true }, "FieldQuery": "select col9 from tbl9 where 1 != 1", - "Query": "select col9 from tbl9 where col9 = 34 for update", + "Query": "select col9 from tbl9 where col9 = 34 for update nowait", "Table": "tbl9", "Values": [ "34" @@ -657,7 +657,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 for update", + "Query": "select col1 from u_tbl1 for update nowait", "Table": "u_tbl1" }, { @@ -677,7 +677,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -693,7 +693,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in (('foo'))", "Table": "u_tbl3" }, { @@ -727,7 +727,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo')) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in (('foo')) for update nowait", "Table": "u_tbl9" }, { @@ -755,7 +755,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in (('foo'))", "Table": "u_tbl9" } ] @@ -806,7 +806,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", - "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", "Table": "u_tbl1, u_tbl2" }, { @@ -821,8 +821,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where 1 != 1", - "Query": "select col2, u_tbl2.col2 <=> u_tbl2.col1 + 'bar', u_tbl2.col1 + 'bar' from u_tbl2 where u_tbl2.id = 1 for update", + "FieldQuery": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where 1 != 1", + "Query": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -846,7 +846,7 @@ "UpdateExprBvName": "fkc_upd" } ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", "Table": "u_tbl3" }, { @@ -858,7 +858,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, u_tbl2.col2 = u_tbl2.col1 + 'bar' where u_tbl2.id = 1", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set m = 2, col2 = col1 + 'bar' where id = 1", "Table": "u_tbl2" } ] @@ -889,8 +889,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where 1 != 1", - "Query": "select col1, col1 <=> u_tbl1.x + 'bar', u_tbl1.x + 'bar' from u_tbl1 where id = 1 for update", + "FieldQuery": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -918,7 +918,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -934,7 +934,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (u_tbl3.col3) not in ((:fkc_upd)))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", "Table": "u_tbl3" }, { @@ -976,7 +976,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1))) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (col9) not in ((:fkc_upd1))) for update nowait", "Table": "u_tbl9" }, { @@ -1004,7 +1004,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (u_tbl9.col9) not in ((:fkc_upd1)))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (:fkc_upd1 is null or (col9) not in ((:fkc_upd1)))", "Table": "u_tbl9" } ] @@ -1018,7 +1018,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = u_tbl1.x + 'bar' where id = 1", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl1 set m = 2, col1 = x + 'bar' where id = 1", "Table": "u_tbl1" } ] @@ -1050,7 +1050,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where id = 1 for update", + "Query": "select col2 from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -1066,7 +1066,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (u_tbl3.col3) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((2))", "Table": "u_tbl3" }, { @@ -1107,7 +1107,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 where id = 1 for update", + "Query": "select col1 from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -1127,7 +1127,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -1143,7 +1143,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (u_tbl3.col3) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((2))", "Table": "u_tbl3" }, { @@ -1177,7 +1177,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2)) for update", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((2)) for update nowait", "Table": "u_tbl9" }, { @@ -1205,7 +1205,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (u_tbl9.col9) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((2))", "Table": "u_tbl9" } ] @@ -1284,7 +1284,7 @@ "Sharded": true }, "FieldQuery": "select tbl3.colx from tbl3 where 1 != 1", - "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 lock in share mode", + "Query": "select tbl3.colx from tbl3 where tbl3.colx + 10 is not null and not (tbl3.coly) <=> (tbl3.colx + 10) and tbl3.coly = 10 for share nowait", "Table": "tbl3" }, { @@ -1295,7 +1295,7 @@ "Sharded": true }, "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", - "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 lock in share mode", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = :tbl3_colx + 10 for share nowait", "Table": "tbl1" } ] @@ -1315,7 +1315,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set tbl3.coly = tbl3.colx + 10 where tbl3.coly = 10", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ tbl3 set coly = colx + 10 where coly = 10", "Table": "tbl3" } ] @@ -1364,7 +1364,7 @@ "Sharded": true }, "FieldQuery": "select 1 from tbl3 where 1 != 1", - "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 lock in share mode", + "Query": "select 1 from tbl3 where not (tbl3.coly) <=> (20) and tbl3.coly = 10 for share nowait", "Table": "tbl3" }, { @@ -1375,7 +1375,7 @@ "Sharded": true }, "FieldQuery": "select tbl1.t1col1 from tbl1 where 1 != 1", - "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = 20 lock in share mode", + "Query": "select tbl1.t1col1 from tbl1 where tbl1.t1col1 = 20 for share nowait", "Table": "tbl1" } ] @@ -1395,7 +1395,7 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl3 set tbl3.coly = 20 where tbl3.coly = 10", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ tbl3 set coly = 20 where coly = 10", "Table": "tbl3" } ] @@ -1424,7 +1424,7 @@ "Sharded": false }, "FieldQuery": "select col6 from u_tbl6 where 1 != 1", - "Query": "select col6 from u_tbl6 for update", + "Query": "select col6 from u_tbl6 for update nowait", "Table": "u_tbl6" }, { @@ -1444,7 +1444,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", "Table": "u_tbl8, u_tbl9" }, { @@ -1456,7 +1456,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set u_tbl8.col8 = 'foo' where (u_tbl8.col8) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl8 set col8 = 'foo' where (col8) in ::fkc_vals", "Table": "u_tbl8" } ] @@ -1500,7 +1500,7 @@ "Sharded": false }, "FieldQuery": "select col7 from u_tbl7 where 1 != 1", - "Query": "select col7 from u_tbl7 for update", + "Query": "select col7 from u_tbl7 for update nowait", "Table": "u_tbl7" }, { @@ -1520,7 +1520,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1532,7 +1532,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1544,7 +1544,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = 'foo' where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = 'foo' where (col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -1589,7 +1589,7 @@ "Sharded": false }, "FieldQuery": "select col7 from u_tbl7 where 1 != 1", - "Query": "select col7 from u_tbl7 for update", + "Query": "select col7 from u_tbl7 for update nowait", "Table": "u_tbl7" }, { @@ -1609,7 +1609,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 lock in share mode", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1621,7 +1621,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 lock in share mode", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1633,7 +1633,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set u_tbl4.col4 = :v1 where (u_tbl4.col4) in ::fkc_vals", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl4 set col4 = :v1 where (col4) in ::fkc_vals", "Table": "u_tbl4" } ] @@ -1713,7 +1713,7 @@ "Sharded": false }, "FieldQuery": "select col1 from u_tbl1 where 1 != 1", - "Query": "select col1 from u_tbl1 where (id) in ((1)) for update", + "Query": "select col1 from u_tbl1 where (id) in ((1)) for update nowait", "Table": "u_tbl1" }, { @@ -1733,7 +1733,7 @@ "Sharded": false }, "FieldQuery": "select col2 from u_tbl2 where 1 != 1", - "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", "Table": "u_tbl2" }, { @@ -1819,7 +1819,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl1 where id = 3 for update", + "Query": "select cola, colb from u_multicol_tbl1 where id = 3 for update nowait", "Table": "u_multicol_tbl1" }, { @@ -1840,7 +1840,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2)) for update", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (cola, colb) not in ((1, 2)) for update nowait", "Table": "u_multicol_tbl2" }, { @@ -1869,7 +1869,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((1, 2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (cola, colb) not in ((1, 2))", "Table": "u_multicol_tbl2" } ] @@ -1913,7 +1913,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl1 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl1 where id = :v3 for update", + "Query": "select cola, colb from u_multicol_tbl1 where id = :v3 for update nowait", "Table": "u_multicol_tbl1" }, { @@ -1934,7 +1934,7 @@ "Sharded": false }, "FieldQuery": "select cola, colb from u_multicol_tbl2 where 1 != 1", - "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2)))) for update", + "Query": "select cola, colb from u_multicol_tbl2 where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (cola, colb) not in ((:v1, :v2)))) for update nowait", "Table": "u_multicol_tbl2" }, { @@ -1963,7 +1963,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (u_multicol_tbl2.cola, u_multicol_tbl2.colb) not in ((:v1, :v2))))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_multicol_tbl2 set cola = null, colb = null where (cola, colb) in ::fkc_vals and (:v2 is null or (:v1 is null or (cola, colb) not in ((:v1, :v2))))", "Table": "u_multicol_tbl2" } ] @@ -2013,7 +2013,7 @@ "Sharded": true }, "FieldQuery": "select col5, t5col5 from tbl5 where 1 != 1", - "Query": "select col5, t5col5 from tbl5 where id = :v1 for update", + "Query": "select col5, t5col5 from tbl5 where id = :v1 for update nowait", "Table": "tbl5" }, { diff --git a/go/vt/vtgate/semantics/analyzer_fk_test.go b/go/vt/vtgate/semantics/analyzer_fk_test.go index 771a9b3ebd9..c6965b1a7cd 100644 --- a/go/vt/vtgate/semantics/analyzer_fk_test.go +++ b/go/vt/vtgate/semantics/analyzer_fk_test.go @@ -199,12 +199,12 @@ func TestGetAllManagedForeignKeys(t *testing.T) { "ks_unmanaged": vschemapb.Keyspace_unmanaged, }, KsError: map[string]error{ - "ks": fmt.Errorf("VT09019: ks has cyclic foreign keys"), + "ks": fmt.Errorf("VT09019: keyspace 'ks' has cyclic foreign keys"), }, }, }, }, - expectedErr: "VT09019: ks has cyclic foreign keys", + expectedErr: "VT09019: keyspace 'ks' has cyclic foreign keys", }, } for _, tt := range tests { diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index 38e22fee0a2..2b6eaa6161d 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -523,7 +523,7 @@ func TestMarkErrorIfCyclesInFk(t *testing.T) { _ = vschema.AddForeignKey("ks", "t1", createFkDefinition([]string{"col"}, "t3", []string{"col"}, sqlparser.Cascade, sqlparser.Cascade)) return vschema }, - errWanted: "VT09019: ks has cyclic foreign keys", + errWanted: "VT09019: keyspace 'ks' has cyclic foreign keys", }, { name: "No cycle", From 2e13b10d2535295b8aa864a7daf9465b1923b65f Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Mon, 20 Nov 2023 12:42:02 +0100 Subject: [PATCH 030/119] evalengine: Improve the typing situation for functions (#14533) Signed-off-by: Dirkjan Bussink Signed-off-by: Vicent Marti Co-authored-by: Vicent Marti --- go/vt/proto/vschema/vschema.pb.go | 142 +- go/vt/proto/vschema/vschema_vtproto.pb.go | 198 +- go/vt/vtgate/engine/aggregations.go | 13 +- go/vt/vtgate/engine/cached_size.go | 12 +- go/vt/vtgate/engine/delete_test.go | 4 +- go/vt/vtgate/engine/distinct.go | 14 +- go/vt/vtgate/engine/distinct_test.go | 9 +- go/vt/vtgate/engine/hash_join_test.go | 8 +- go/vt/vtgate/engine/limit_test.go | 10 +- go/vt/vtgate/engine/memory_sort_test.go | 18 +- go/vt/vtgate/engine/merge_sort_test.go | 2 +- go/vt/vtgate/engine/ordered_aggregate.go | 8 +- go/vt/vtgate/engine/ordered_aggregate_test.go | 6 +- go/vt/vtgate/engine/projection.go | 8 +- go/vt/vtgate/engine/route_test.go | 7 +- go/vt/vtgate/engine/set_test.go | 2 +- go/vt/vtgate/engine/update_test.go | 2 +- go/vt/vtgate/evalengine/api_coerce.go | 64 +- go/vt/vtgate/evalengine/api_compare.go | 10 +- go/vt/vtgate/evalengine/api_compare_test.go | 216 +- go/vt/vtgate/evalengine/api_literal.go | 11 +- go/vt/vtgate/evalengine/cached_size.go | 6 +- go/vt/vtgate/evalengine/compiler.go | 91 +- go/vt/vtgate/evalengine/compiler_asm.go | 3 - go/vt/vtgate/evalengine/compiler_test.go | 36 + go/vt/vtgate/evalengine/expr_arithmetic.go | 21 +- go/vt/vtgate/evalengine/expr_column.go | 15 +- go/vt/vtgate/evalengine/expr_env.go | 6 +- go/vt/vtgate/evalengine/expr_literal.go | 4 + go/vt/vtgate/evalengine/fn_time.go | 37 +- go/vt/vtgate/evalengine/translate.go | 18 +- go/vt/vtgate/planbuilder/collations_test.go | 12 +- .../planbuilder/expression_converter.go | 2 +- .../planbuilder/expression_converter_test.go | 2 +- .../planbuilder/operator_transformers.go | 4 +- .../planbuilder/operators/queryprojection.go | 4 +- .../testdata/info_schema57_cases.json | 24 +- .../testdata/info_schema80_cases.json | 20 +- .../planbuilder/testdata/union_cases.json | 24 +- go/vt/vtgate/schema/tracker.go | 39 +- go/vt/vtgate/schema/tracker_test.go | 56 +- go/vt/vtgate/semantics/analyzer_test.go | 2 +- go/vt/vtgate/semantics/binder.go | 5 +- go/vt/vtgate/semantics/dependencies.go | 4 +- go/vt/vtgate/semantics/info_schema.go | 2663 ++++++++--------- .../vtgate/semantics/info_schema_gen_test.go | 36 +- go/vt/vtgate/semantics/real_table.go | 17 +- go/vt/vtgate/semantics/semantic_state.go | 20 +- go/vt/vtgate/semantics/typer.go | 17 +- go/vt/vtgate/semantics/typer_test.go | 2 +- go/vt/vtgate/vindexes/vschema.go | 36 +- go/vt/vtgate/vschema_manager_test.go | 20 +- go/vt/vttablet/tabletmanager/vdiff/utils.go | 11 +- go/vt/wrangler/vdiff.go | 8 +- go/vt/wrangler/vdiff_test.go | 4 +- proto/vschema.proto | 6 + web/vtadmin/src/proto/vtadmin.d.ts | 33 + web/vtadmin/src/proto/vtadmin.js | 151 + 58 files changed, 2376 insertions(+), 1847 deletions(-) diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index fe185d63fcd..ff64faf4bab 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -600,10 +600,16 @@ type Column struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Type query.Type `protobuf:"varint,2,opt,name=type,proto3,enum=query.Type" json:"type,omitempty"` - Invisible bool `protobuf:"varint,3,opt,name=invisible,proto3" json:"invisible,omitempty"` - Default string `protobuf:"bytes,4,opt,name=default,proto3" json:"default,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type query.Type `protobuf:"varint,2,opt,name=type,proto3,enum=query.Type" json:"type,omitempty"` + Invisible bool `protobuf:"varint,3,opt,name=invisible,proto3" json:"invisible,omitempty"` + Default string `protobuf:"bytes,4,opt,name=default,proto3" json:"default,omitempty"` + CollationName string `protobuf:"bytes,5,opt,name=collation_name,json=collationName,proto3" json:"collation_name,omitempty"` + Size int32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` + Scale int32 `protobuf:"varint,7,opt,name=scale,proto3" json:"scale,omitempty"` + Nullable *bool `protobuf:"varint,8,opt,name=nullable,proto3,oneof" json:"nullable,omitempty"` + // values contains the list of values for an enum or set column. + Values []string `protobuf:"bytes,9,rep,name=values,proto3" json:"values,omitempty"` } func (x *Column) Reset() { @@ -666,6 +672,41 @@ func (x *Column) GetDefault() string { return "" } +func (x *Column) GetCollationName() string { + if x != nil { + return x.CollationName + } + return "" +} + +func (x *Column) GetSize() int32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *Column) GetScale() int32 { + if x != nil { + return x.Scale + } + return 0 +} + +func (x *Column) GetNullable() bool { + if x != nil && x.Nullable != nil { + return *x.Nullable + } + return false +} + +func (x *Column) GetValues() []string { + if x != nil { + return x.Values + } + return nil +} + // SrvVSchema is the roll-up of all the Keyspace schema for a cell. type SrvVSchema struct { state protoimpl.MessageState @@ -928,47 +969,57 @@ var file_vschema_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x75, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x73, 0x69, - 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x73, - 0x69, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0xa7, - 0x02, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x40, 0x0a, - 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, - 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, - 0x18, 0x02, 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, 0x4a, 0x0a, 0x13, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x4f, 0x0a, 0x0e, 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, 0x27, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6e, - 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x42, 0x26, - 0x5a, 0x24, 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, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, + 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x12, 0x1f, 0x0a, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x75, + 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x40, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 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, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, + 0x4f, 0x0a, 0x0e, 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, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x44, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, + 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x42, 0x26, 0x5a, 0x24, 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, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1167,6 +1218,7 @@ func file_vschema_proto_init() { } } } + file_vschema_proto_msgTypes[7].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/go/vt/proto/vschema/vschema_vtproto.pb.go b/go/vt/proto/vschema/vschema_vtproto.pb.go index 2235bfea496..ba55bcfa97c 100644 --- a/go/vt/proto/vschema/vschema_vtproto.pb.go +++ b/go/vt/proto/vschema/vschema_vtproto.pb.go @@ -210,10 +210,22 @@ func (m *Column) CloneVT() *Column { return (*Column)(nil) } r := &Column{ - Name: m.Name, - Type: m.Type, - Invisible: m.Invisible, - Default: m.Default, + Name: m.Name, + Type: m.Type, + Invisible: m.Invisible, + Default: m.Default, + CollationName: m.CollationName, + Size: m.Size, + Scale: m.Scale, + } + if rhs := m.Nullable; rhs != nil { + tmpVal := *rhs + r.Nullable = &tmpVal + } + if rhs := m.Values; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.Values = tmpContainer } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -788,6 +800,42 @@ func (m *Column) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.Values) > 0 { + for iNdEx := len(m.Values) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Values[iNdEx]) + copy(dAtA[i:], m.Values[iNdEx]) + i = encodeVarint(dAtA, i, uint64(len(m.Values[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if m.Nullable != nil { + i-- + if *m.Nullable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if m.Scale != 0 { + i = encodeVarint(dAtA, i, uint64(m.Scale)) + i-- + dAtA[i] = 0x38 + } + if m.Size != 0 { + i = encodeVarint(dAtA, i, uint64(m.Size)) + i-- + dAtA[i] = 0x30 + } + if len(m.CollationName) > 0 { + i -= len(m.CollationName) + copy(dAtA[i:], m.CollationName) + i = encodeVarint(dAtA, i, uint64(len(m.CollationName))) + i-- + dAtA[i] = 0x2a + } if len(m.Default) > 0 { i -= len(m.Default) copy(dAtA[i:], m.Default) @@ -1215,6 +1263,25 @@ func (m *Column) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + l = len(m.CollationName) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.Size != 0 { + n += 1 + sov(uint64(m.Size)) + } + if m.Scale != 0 { + n += 1 + sov(uint64(m.Scale)) + } + if m.Nullable != nil { + n += 2 + } + if len(m.Values) > 0 { + for _, s := range m.Values { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } n += len(m.unknownFields) return n } @@ -2769,6 +2836,129 @@ func (m *Column) UnmarshalVT(dAtA []byte) error { } m.Default = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CollationName", 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.CollationName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Size", wireType) + } + m.Size = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Size |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Scale", wireType) + } + m.Scale = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Scale |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Nullable", 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 + } + } + b := bool(v != 0) + m.Nullable = &b + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", 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.Values = append(m.Values, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vtgate/engine/aggregations.go b/go/vt/vtgate/engine/aggregations.go index dd7a259d1b6..0a72e263e21 100644 --- a/go/vt/vtgate/engine/aggregations.go +++ b/go/vt/vtgate/engine/aggregations.go @@ -57,7 +57,6 @@ func NewAggregateParam(opcode AggregateOpcode, col int, alias string) *Aggregate Col: col, Alias: alias, WCol: -1, - Type: evalengine.UnknownType(), } if opcode.NeedsComparableValues() { out.KeyCol = col @@ -74,8 +73,8 @@ func (ap *AggregateParams) String() string { if ap.WAssigned() { keyCol = fmt.Sprintf("%s|%d", keyCol, ap.WCol) } - if sqltypes.IsText(ap.Type.Type) && ap.Type.Coll != collations.Unknown { - keyCol += " COLLATE " + collations.Local().LookupName(ap.Type.Coll) + if sqltypes.IsText(ap.Type.Type()) && ap.Type.Collation() != collations.Unknown { + keyCol += " COLLATE " + collations.Local().LookupName(ap.Type.Collation()) } dispOrigOp := "" if ap.OrigOpcode != AggregateUnassigned && ap.OrigOpcode != ap.Opcode { @@ -381,7 +380,7 @@ func newAggregation(fields []*querypb.Field, aggregates []*AggregateParams) (agg from: aggr.Col, distinct: aggregatorDistinct{ column: distinct, - coll: aggr.Type.Coll, + coll: aggr.Type.Collation(), }, } @@ -399,7 +398,7 @@ func newAggregation(fields []*querypb.Field, aggregates []*AggregateParams) (agg sum: sum, distinct: aggregatorDistinct{ column: distinct, - coll: aggr.Type.Coll, + coll: aggr.Type.Collation(), }, } @@ -407,7 +406,7 @@ func newAggregation(fields []*querypb.Field, aggregates []*AggregateParams) (agg ag = &aggregatorMin{ aggregatorMinMax{ from: aggr.Col, - minmax: evalengine.NewAggregationMinMax(sourceType, aggr.Type.Coll), + minmax: evalengine.NewAggregationMinMax(sourceType, aggr.Type.Collation()), }, } @@ -415,7 +414,7 @@ func newAggregation(fields []*querypb.Field, aggregates []*AggregateParams) (agg ag = &aggregatorMax{ aggregatorMinMax{ from: aggr.Col, - minmax: evalengine.NewAggregationMinMax(sourceType, aggr.Type.Coll), + minmax: evalengine.NewAggregationMinMax(sourceType, aggr.Type.Collation()), }, } diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index a18e2108c4a..6024c66457a 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -67,7 +67,7 @@ func (cached *CheckCol) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(24) + size += int64(32) } // field WsCol *int size += hack.RuntimeAllocSize(int64(8)) @@ -199,7 +199,7 @@ func (cached *Distinct) CachedSize(alloc bool) int64 { } // field CheckCols []vitess.io/vitess/go/vt/vtgate/engine.CheckCol { - size += hack.RuntimeAllocSize(int64(cap(cached.CheckCols)) * int64(23)) + size += hack.RuntimeAllocSize(int64(cap(cached.CheckCols)) * int64(32)) for _, elem := range cached.CheckCols { size += elem.CachedSize(false) } @@ -346,7 +346,7 @@ func (cached *GroupByParams) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(48) + size += int64(64) } // field Expr vitess.io/vitess/go/vt/sqlparser.Expr if cc, ok := cached.Expr.(cachedObject); ok { @@ -588,7 +588,7 @@ func (cached *MemorySort) CachedSize(alloc bool) int64 { } // field OrderBy vitess.io/vitess/go/vt/vtgate/evalengine.Comparison { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(27)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) } // field Input vitess.io/vitess/go/vt/vtgate/engine.Primitive if cc, ok := cached.Input.(cachedObject); ok { @@ -615,7 +615,7 @@ func (cached *MergeSort) CachedSize(alloc bool) int64 { } // field OrderBy vitess.io/vitess/go/vt/vtgate/evalengine.Comparison { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(27)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) } return size } @@ -820,7 +820,7 @@ func (cached *Route) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.FieldQuery))) // field OrderBy vitess.io/vitess/go/vt/vtgate/evalengine.Comparison { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(27)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) } // field RoutingParameters *vitess.io/vitess/go/vt/vtgate/engine.RoutingParameters size += cached.RoutingParameters.CachedSize(true) diff --git a/go/vt/vtgate/engine/delete_test.go b/go/vt/vtgate/engine/delete_test.go index be67c7fc9e6..d8485765ca9 100644 --- a/go/vt/vtgate/engine/delete_test.go +++ b/go/vt/vtgate/engine/delete_test.go @@ -89,7 +89,7 @@ func TestDeleteEqual(t *testing.T) { }) // Failure case - expr := evalengine.NewBindVar("aa", evalengine.UnknownType()) + expr := evalengine.NewBindVar("aa", evalengine.Type{}) del.Values = []evalengine.Expr{expr} _, err = del.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) require.EqualError(t, err, "query arguments missing for aa") @@ -121,7 +121,7 @@ func TestDeleteEqualMultiCol(t *testing.T) { }) // Failure case - expr := evalengine.NewBindVar("aa", evalengine.UnknownType()) + expr := evalengine.NewBindVar("aa", evalengine.Type{}) del.Values = []evalengine.Expr{expr} _, err = del.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) require.EqualError(t, err, "query arguments missing for aa") diff --git a/go/vt/vtgate/engine/distinct.go b/go/vt/vtgate/engine/distinct.go index cd6b93a9f32..7e55138e27e 100644 --- a/go/vt/vtgate/engine/distinct.go +++ b/go/vt/vtgate/engine/distinct.go @@ -118,14 +118,14 @@ func (pt *probeTable) hashCodeForRow(inputRow sqltypes.Row) (evalengine.HashCode return 0, vterrors.VT13001("index out of range in row when creating the DISTINCT hash code") } col := inputRow[checkCol.Col] - hashcode, err := evalengine.NullsafeHashcode(col, checkCol.Type.Coll, col.Type()) + hashcode, err := evalengine.NullsafeHashcode(col, checkCol.Type.Collation(), col.Type()) if err != nil { if err != evalengine.UnsupportedCollationHashError || checkCol.WsCol == nil { return 0, err } checkCol = checkCol.SwitchToWeightString() pt.checkCols[i] = checkCol - hashcode, err = evalengine.NullsafeHashcode(inputRow[checkCol.Col], checkCol.Type.Coll, col.Type()) + hashcode, err = evalengine.NullsafeHashcode(inputRow[checkCol.Col], checkCol.Type.Collation(), col.Type()) if err != nil { return 0, err } @@ -137,7 +137,7 @@ func (pt *probeTable) hashCodeForRow(inputRow sqltypes.Row) (evalengine.HashCode func (pt *probeTable) equal(a, b sqltypes.Row) (bool, error) { for i, checkCol := range pt.checkCols { - cmp, err := evalengine.NullsafeCompare(a[i], b[i], checkCol.Type.Coll) + cmp, err := evalengine.NullsafeCompare(a[i], b[i], checkCol.Type.Collation()) if err != nil { _, isCollErr := err.(evalengine.UnsupportedCollationError) if !isCollErr || checkCol.WsCol == nil { @@ -145,7 +145,7 @@ func (pt *probeTable) equal(a, b sqltypes.Row) (bool, error) { } checkCol = checkCol.SwitchToWeightString() pt.checkCols[i] = checkCol - cmp, err = evalengine.NullsafeCompare(a[i], b[i], checkCol.Type.Coll) + cmp, err = evalengine.NullsafeCompare(a[i], b[i], checkCol.Type.Collation()) if err != nil { return false, err } @@ -274,14 +274,14 @@ func (cc CheckCol) SwitchToWeightString() CheckCol { return CheckCol{ Col: *cc.WsCol, WsCol: nil, - Type: evalengine.Type{Type: sqltypes.VarBinary, Coll: collations.CollationBinaryID}, + Type: evalengine.NewType(sqltypes.VarBinary, collations.CollationBinaryID), } } func (cc CheckCol) String() string { var collation string - if sqltypes.IsText(cc.Type.Type) && cc.Type.Coll != collations.Unknown { - collation = ": " + collations.Local().LookupName(cc.Type.Coll) + if sqltypes.IsText(cc.Type.Type()) && cc.Type.Collation() != collations.Unknown { + collation = ": " + collations.Local().LookupName(cc.Type.Collation()) } var column string diff --git a/go/vt/vtgate/engine/distinct_test.go b/go/vt/vtgate/engine/distinct_test.go index 65f8e5d430c..4ec3c1c0f4a 100644 --- a/go/vt/vtgate/engine/distinct_test.go +++ b/go/vt/vtgate/engine/distinct_test.go @@ -88,14 +88,9 @@ func TestDistinct(t *testing.T) { if sqltypes.IsNumber(tc.inputs.Fields[i].Type) { collID = collations.CollationBinaryID } - t := evalengine.Type{ - Type: tc.inputs.Fields[i].Type, - Coll: collID, - Nullable: false, - } checkCols = append(checkCols, CheckCol{ Col: i, - Type: t, + Type: evalengine.NewTypeEx(tc.inputs.Fields[i].Type, collID, false, 0, 0), }) } } @@ -140,7 +135,6 @@ func TestWeightStringFallBack(t *testing.T) { checkCols := []CheckCol{{ Col: 0, WsCol: &offsetOne, - Type: evalengine.UnknownType(), }} input := r("myid|weightstring(myid)", "varchar|varbinary", @@ -165,6 +159,5 @@ func TestWeightStringFallBack(t *testing.T) { utils.MustMatch(t, []CheckCol{{ Col: 0, WsCol: &offsetOne, - Type: evalengine.UnknownType(), }}, distinct.CheckCols, "checkCols should not be updated") } diff --git a/go/vt/vtgate/engine/hash_join_test.go b/go/vt/vtgate/engine/hash_join_test.go index c0a3075c6ad..7f7275a2c5c 100644 --- a/go/vt/vtgate/engine/hash_join_test.go +++ b/go/vt/vtgate/engine/hash_join_test.go @@ -140,8 +140,8 @@ func TestHashJoinVariations(t *testing.T) { Cols: []int{-1, -2, 1, 2}, LHSKey: tc.lhs, RHSKey: tc.rhs, - Collation: typ.Coll, - ComparisonType: typ.Type, + Collation: typ.Collation(), + ComparisonType: typ.Type(), } t.Run(tc.name, func(t *testing.T) { @@ -164,9 +164,9 @@ func TestHashJoinVariations(t *testing.T) { func typeForOffset(i int) evalengine.Type { switch i { case 0: - return evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID} + return evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID) case 1: - return evalengine.Type{Type: sqltypes.VarChar, Coll: collations.Default()} + return evalengine.NewType(sqltypes.VarChar, collations.Default()) default: panic(i) } diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go index d5c6602f820..15bda20ace7 100644 --- a/go/vt/vtgate/engine/limit_test.go +++ b/go/vt/vtgate/engine/limit_test.go @@ -130,7 +130,7 @@ func TestLimitExecute(t *testing.T) { results: []*sqltypes.Result{inputResult}, } l = &Limit{ - Count: evalengine.NewBindVar("l", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + Count: evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), Input: fp, } @@ -343,8 +343,8 @@ func TestLimitOffsetExecute(t *testing.T) { } l = &Limit{ - Count: evalengine.NewBindVar("l", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), - Offset: evalengine.NewBindVar("o", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + Count: evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), + Offset: evalengine.NewBindVar("o", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), Input: fp, } result, err = l.TryExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(1), "o": sqltypes.Int64BindVariable(1)}, false) @@ -396,7 +396,7 @@ func TestLimitStreamExecute(t *testing.T) { // Test with bind vars. fp.rewind() - l.Count = evalengine.NewBindVar("l", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + l.Count = evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) results = nil err = l.TryStreamExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(2)}, true, func(qr *sqltypes.Result) error { results = append(results, qr) @@ -540,7 +540,7 @@ func TestLimitInputFail(t *testing.T) { func TestLimitInvalidCount(t *testing.T) { l := &Limit{ - Count: evalengine.NewBindVar("l", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + Count: evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), } _, _, err := l.getCountAndOffset(context.Background(), &noopVCursor{}, nil) assert.EqualError(t, err, "query arguments missing for l") diff --git a/go/vt/vtgate/engine/memory_sort_test.go b/go/vt/vtgate/engine/memory_sort_test.go index bc9369c57af..4f3d39ca851 100644 --- a/go/vt/vtgate/engine/memory_sort_test.go +++ b/go/vt/vtgate/engine/memory_sort_test.go @@ -75,7 +75,7 @@ func TestMemorySortExecute(t *testing.T) { utils.MustMatch(t, wantResult, result) fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} result, err = ms.TryExecute(context.Background(), &noopVCursor{}, bv, false) @@ -136,7 +136,7 @@ func TestMemorySortStreamExecuteWeightString(t *testing.T) { t.Run("Limit test", func(t *testing.T) { fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} results = nil @@ -194,7 +194,7 @@ func TestMemorySortExecuteWeightString(t *testing.T) { utils.MustMatch(t, wantResult, result) fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} result, err = ms.TryExecute(context.Background(), &noopVCursor{}, bv, false) @@ -229,7 +229,7 @@ func TestMemorySortStreamExecuteCollation(t *testing.T) { ms := &MemorySort{ OrderBy: []evalengine.OrderByParams{{ Col: 0, - Type: evalengine.Type{Type: sqltypes.VarChar, Coll: collationID}, + Type: evalengine.NewType(sqltypes.VarChar, collationID), }}, Input: fp, } @@ -277,7 +277,7 @@ func TestMemorySortStreamExecuteCollation(t *testing.T) { t.Run("Limit test", func(t *testing.T) { fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} results = nil @@ -317,7 +317,7 @@ func TestMemorySortExecuteCollation(t *testing.T) { ms := &MemorySort{ OrderBy: []evalengine.OrderByParams{{ Col: 0, - Type: evalengine.Type{Type: sqltypes.VarChar, Coll: collationID}, + Type: evalengine.NewType(sqltypes.VarChar, collationID), }}, Input: fp, } @@ -336,7 +336,7 @@ func TestMemorySortExecuteCollation(t *testing.T) { utils.MustMatch(t, wantResult, result) fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} result, err = ms.TryExecute(context.Background(), &noopVCursor{}, bv, false) @@ -393,7 +393,7 @@ func TestMemorySortStreamExecute(t *testing.T) { utils.MustMatch(t, wantResults, results) fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} results = nil @@ -552,7 +552,7 @@ func TestMemorySortMultiColumn(t *testing.T) { utils.MustMatch(t, wantResult, result) fp.rewind() - ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}) + ms.UpperLimit = evalengine.NewBindVar("__upper_limit", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} result, err = ms.TryExecute(context.Background(), &noopVCursor{}, bv, false) diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 803c70ca463..93a443691c9 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -182,7 +182,7 @@ func TestMergeSortCollation(t *testing.T) { collationID, _ := collations.Local().LookupID("utf8mb4_hu_0900_ai_ci") orderBy := []evalengine.OrderByParams{{ Col: 0, - Type: evalengine.Type{Type: sqltypes.VarChar, Coll: collationID}, + Type: evalengine.NewType(sqltypes.VarChar, collationID), }} var results []*sqltypes.Result diff --git a/go/vt/vtgate/engine/ordered_aggregate.go b/go/vt/vtgate/engine/ordered_aggregate.go index 07ea06fa5fd..99393d8afc2 100644 --- a/go/vt/vtgate/engine/ordered_aggregate.go +++ b/go/vt/vtgate/engine/ordered_aggregate.go @@ -78,8 +78,8 @@ func (gbp GroupByParams) String() string { out = fmt.Sprintf("(%d|%d)", gbp.KeyCol, gbp.WeightStringCol) } - if sqltypes.IsText(gbp.Type.Type) && gbp.Type.Coll != collations.Unknown { - out += " COLLATE " + collations.Local().LookupName(gbp.Type.Coll) + if sqltypes.IsText(gbp.Type.Type()) && gbp.Type.Collation() != collations.Unknown { + out += " COLLATE " + collations.Local().LookupName(gbp.Type.Collation()) } return out @@ -348,14 +348,14 @@ func (oa *OrderedAggregate) nextGroupBy(currentKey, nextRow []sqltypes.Value) (n return nextRow, true, nil } - cmp, err := evalengine.NullsafeCompare(v1, v2, gb.Type.Coll) + cmp, err := evalengine.NullsafeCompare(v1, v2, gb.Type.Collation()) if err != nil { _, isCollationErr := err.(evalengine.UnsupportedCollationError) if !isCollationErr || gb.WeightStringCol == -1 { return nil, false, err } gb.KeyCol = gb.WeightStringCol - cmp, err = evalengine.NullsafeCompare(currentKey[gb.WeightStringCol], nextRow[gb.WeightStringCol], gb.Type.Coll) + cmp, err = evalengine.NullsafeCompare(currentKey[gb.WeightStringCol], nextRow[gb.WeightStringCol], gb.Type.Collation()) if err != nil { return nil, false, err } diff --git a/go/vt/vtgate/engine/ordered_aggregate_test.go b/go/vt/vtgate/engine/ordered_aggregate_test.go index 2eca4fc7ba9..f977e3b09dc 100644 --- a/go/vt/vtgate/engine/ordered_aggregate_test.go +++ b/go/vt/vtgate/engine/ordered_aggregate_test.go @@ -907,7 +907,7 @@ func TestOrderedAggregateCollate(t *testing.T) { collationID, _ := collationEnv.LookupID("utf8mb4_0900_ai_ci") oa := &OrderedAggregate{ Aggregates: []*AggregateParams{NewAggregateParam(AggregateSum, 1, "")}, - GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.Type{Coll: collationID}}}, + GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.NewType(sqltypes.Unknown, collationID)}}, Input: fp, } @@ -945,7 +945,7 @@ func TestOrderedAggregateCollateAS(t *testing.T) { collationID, _ := collationEnv.LookupID("utf8mb4_0900_as_ci") oa := &OrderedAggregate{ Aggregates: []*AggregateParams{NewAggregateParam(AggregateSum, 1, "")}, - GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.Type{Coll: collationID}}}, + GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.NewType(sqltypes.Unknown, collationID)}}, Input: fp, } @@ -985,7 +985,7 @@ func TestOrderedAggregateCollateKS(t *testing.T) { collationID, _ := collationEnv.LookupID("utf8mb4_ja_0900_as_cs_ks") oa := &OrderedAggregate{ Aggregates: []*AggregateParams{NewAggregateParam(AggregateSum, 1, "")}, - GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.Type{Coll: collationID}}}, + GroupByKeys: []*GroupByParams{{KeyCol: 0, Type: evalengine.NewType(sqltypes.Unknown, collationID)}}, Input: fp, } diff --git a/go/vt/vtgate/engine/projection.go b/go/vt/vtgate/engine/projection.go index e0055baa757..166dd88f477 100644 --- a/go/vt/vtgate/engine/projection.go +++ b/go/vt/vtgate/engine/projection.go @@ -149,14 +149,14 @@ func (p *Projection) evalFields(env *evalengine.ExpressionEnv, infields []*query if err != nil { return nil, err } - fl := mysql.FlagsForColumn(typ.Type, typ.Coll) - if !sqltypes.IsNull(typ.Type) && !typ.Nullable { + fl := mysql.FlagsForColumn(typ.Type(), typ.Collation()) + if !sqltypes.IsNull(typ.Type()) && !typ.Nullable() { fl |= uint32(querypb.MySqlFlag_NOT_NULL_FLAG) } fields = append(fields, &querypb.Field{ Name: col, - Type: typ.Type, - Charset: uint32(typ.Coll), + Type: typ.Type(), + Charset: uint32(typ.Collation()), Flags: fl, }) } diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index 54c7b5c6fb4..5a89aae8d5f 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -1077,7 +1077,7 @@ func TestRouteSortCollation(t *testing.T) { sel.OrderBy = []evalengine.OrderByParams{{ Col: 0, - Type: evalengine.Type{Type: sqltypes.VarChar, Coll: collationID}, + Type: evalengine.NewType(sqltypes.VarChar, collationID), }} vc := &loggingVCursor{ @@ -1142,8 +1142,7 @@ func TestRouteSortCollation(t *testing.T) { t.Run("Error when Unknown Collation", func(t *testing.T) { sel.OrderBy = []evalengine.OrderByParams{{ - Col: 0, - Type: evalengine.UnknownType(), + Col: 0, }} vc := &loggingVCursor{ @@ -1169,7 +1168,7 @@ func TestRouteSortCollation(t *testing.T) { t.Run("Error when Unsupported Collation", func(t *testing.T) { sel.OrderBy = []evalengine.OrderByParams{{ Col: 0, - Type: evalengine.Type{Coll: 1111}, + Type: evalengine.NewType(sqltypes.Unknown, 1111), }} vc := &loggingVCursor{ diff --git a/go/vt/vtgate/engine/set_test.go b/go/vt/vtgate/engine/set_test.go index 9245e9a618d..dbce162ff87 100644 --- a/go/vt/vtgate/engine/set_test.go +++ b/go/vt/vtgate/engine/set_test.go @@ -107,7 +107,7 @@ func TestSetTable(t *testing.T) { setOps: []SetOp{ &UserDefinedVariable{ Name: "x", - Expr: evalengine.NewColumn(0, evalengine.UnknownType(), nil), + Expr: evalengine.NewColumn(0, evalengine.Type{}, nil), }, }, qr: []*sqltypes.Result{sqltypes.MakeTestResult( diff --git a/go/vt/vtgate/engine/update_test.go b/go/vt/vtgate/engine/update_test.go index 22c2b90d60e..e2ee9d553d1 100644 --- a/go/vt/vtgate/engine/update_test.go +++ b/go/vt/vtgate/engine/update_test.go @@ -93,7 +93,7 @@ func TestUpdateEqual(t *testing.T) { }) // Failure case - upd.Values = []evalengine.Expr{evalengine.NewBindVar("aa", evalengine.UnknownType())} + upd.Values = []evalengine.Expr{evalengine.NewBindVar("aa", evalengine.Type{})} _, err = upd.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) require.EqualError(t, err, `query arguments missing for aa`) } diff --git a/go/vt/vtgate/evalengine/api_coerce.go b/go/vt/vtgate/evalengine/api_coerce.go index 5e92431e555..143d22ab78c 100644 --- a/go/vt/vtgate/evalengine/api_coerce.go +++ b/go/vt/vtgate/evalengine/api_coerce.go @@ -36,63 +36,63 @@ func CoerceTypes(v1, v2 Type) (out Type, err error) { if v1 == v2 { return v1, nil } - if sqltypes.IsNull(v1.Type) || sqltypes.IsNull(v2.Type) { - return Type{Type: sqltypes.Null, Coll: collations.CollationBinaryID, Nullable: true}, nil - } - fail := func() error { - return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "types does not support hashcode yet: %v vs %v", v1.Type, v2.Type) + if sqltypes.IsNull(v1.Type()) || sqltypes.IsNull(v2.Type()) { + return NewType(sqltypes.Null, collations.CollationBinaryID), nil } - out = Type{Nullable: v1.Nullable || v2.Nullable} + out = Type{ + init: true, + nullable: v1.Nullable() || v2.Nullable(), + } switch { - case sqltypes.IsTextOrBinary(v1.Type) && sqltypes.IsTextOrBinary(v2.Type): - out.Type = sqltypes.VarChar - mergedCollation, _, _, ferr := mergeCollations(typedCoercionCollation(v1.Type, v1.Coll), typedCoercionCollation(v2.Type, v2.Coll), v1.Type, v2.Type) + case sqltypes.IsTextOrBinary(v1.Type()) && sqltypes.IsTextOrBinary(v2.Type()): + mergedCollation, _, _, ferr := mergeCollations(typedCoercionCollation(v1.Type(), v1.Collation()), typedCoercionCollation(v2.Type(), v2.Collation()), v1.Type(), v2.Type()) if err != nil { return Type{}, ferr } - out.Coll = mergedCollation.Collation + out.collation = mergedCollation.Collation + out.typ = sqltypes.VarChar return - case sqltypes.IsDateOrTime(v1.Type): - out.Coll = collations.CollationBinaryID - out.Type = v1.Type + case sqltypes.IsDateOrTime(v1.Type()): + out.collation = collations.CollationBinaryID + out.typ = v1.Type() return - case sqltypes.IsDateOrTime(v2.Type): - out.Coll = collations.CollationBinaryID - out.Type = v2.Type + case sqltypes.IsDateOrTime(v2.Type()): + out.collation = collations.CollationBinaryID + out.typ = v2.Type() return - case sqltypes.IsNumber(v1.Type) || sqltypes.IsNumber(v2.Type): - out.Coll = collations.CollationBinaryID + case sqltypes.IsNumber(v1.Type()) || sqltypes.IsNumber(v2.Type()): + out.collation = collations.CollationBinaryID switch { - case sqltypes.IsTextOrBinary(v1.Type) || sqltypes.IsFloat(v1.Type) || sqltypes.IsDecimal(v1.Type) || - sqltypes.IsTextOrBinary(v2.Type) || sqltypes.IsFloat(v2.Type) || sqltypes.IsDecimal(v2.Type): - out.Type = sqltypes.Float64 + case sqltypes.IsTextOrBinary(v1.Type()) || sqltypes.IsFloat(v1.Type()) || sqltypes.IsDecimal(v1.Type()) || + sqltypes.IsTextOrBinary(v2.Type()) || sqltypes.IsFloat(v2.Type()) || sqltypes.IsDecimal(v2.Type()): + out.typ = sqltypes.Float64 return - case sqltypes.IsSigned(v1.Type): + case sqltypes.IsSigned(v1.Type()): switch { - case sqltypes.IsUnsigned(v2.Type): - out.Type = sqltypes.Uint64 + case sqltypes.IsUnsigned(v2.Type()): + out.typ = sqltypes.Uint64 return - case sqltypes.IsSigned(v2.Type): - out.Type = sqltypes.Int64 + case sqltypes.IsSigned(v2.Type()): + out.typ = sqltypes.Int64 return default: - return Type{}, fail() + return Type{}, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "cannot coerce SIGNED into %v", v2.Type()) } - case sqltypes.IsUnsigned(v1.Type): + case sqltypes.IsUnsigned(v1.Type()): switch { - case sqltypes.IsSigned(v2.Type) || sqltypes.IsUnsigned(v2.Type): - out.Type = sqltypes.Uint64 + case sqltypes.IsSigned(v2.Type()) || sqltypes.IsUnsigned(v2.Type()): + out.typ = sqltypes.Uint64 return default: - return Type{}, fail() + return Type{}, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "cannot coerce UNSIGNED into %v", v2.Type()) } } } - return Type{}, fail() + return Type{}, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "cannot coerce %v into %v", v1.Type(), v2.Type()) } diff --git a/go/vt/vtgate/evalengine/api_compare.go b/go/vt/vtgate/evalengine/api_compare.go index 1f30a17b9d5..b595c71a175 100644 --- a/go/vt/vtgate/evalengine/api_compare.go +++ b/go/vt/vtgate/evalengine/api_compare.go @@ -198,8 +198,8 @@ func (obp *OrderByParams) String() string { val += " ASC" } - if sqltypes.IsText(obp.Type.Type) && obp.Type.Coll != collations.Unknown { - val += " COLLATE " + collations.Local().LookupName(obp.Type.Coll) + if sqltypes.IsText(obp.Type.Type()) && obp.Type.Collation() != collations.Unknown { + val += " COLLATE " + collations.Local().LookupName(obp.Type.Collation()) } return val } @@ -211,7 +211,7 @@ func (obp *OrderByParams) Compare(r1, r2 []sqltypes.Value) int { if cmp == 0 { var err error - cmp, err = NullsafeCompare(v1, v2, obp.Type.Coll) + cmp, err = NullsafeCompare(v1, v2, obp.Type.Collation()) if err != nil { _, isCollationErr := err.(UnsupportedCollationError) if !isCollationErr || obp.WeightStringCol == -1 { @@ -220,7 +220,7 @@ func (obp *OrderByParams) Compare(r1, r2 []sqltypes.Value) int { // in case of a comparison or collation error switch to using the weight string column for ordering obp.Col = obp.WeightStringCol obp.WeightStringCol = -1 - cmp, err = NullsafeCompare(r1[obp.Col], r2[obp.Col], obp.Type.Coll) + cmp, err = NullsafeCompare(r1[obp.Col], r2[obp.Col], obp.Type.Collation()) if err != nil { panic(err) } @@ -236,7 +236,7 @@ func (obp *OrderByParams) Compare(r1, r2 []sqltypes.Value) int { func (cmp Comparison) tinyWeighters(fields []*querypb.Field) []tinyWeighter { weights := make([]tinyWeighter, 0, len(cmp)) for _, c := range cmp { - if apply := TinyWeighter(fields[c.Col], c.Type.Coll); apply != nil { + if apply := TinyWeighter(fields[c.Col], c.Type.Collation()); apply != nil { weights = append(weights, tinyWeighter{c.Col, apply}) } } diff --git a/go/vt/vtgate/evalengine/api_compare_test.go b/go/vt/vtgate/evalengine/api_compare_test.go index 3f97d9d18e9..4da234edbc4 100644 --- a/go/vt/vtgate/evalengine/api_compare_test.go +++ b/go/vt/vtgate/evalengine/api_compare_test.go @@ -110,7 +110,7 @@ func TestCompareIntegers(t *testing.T) { tests := []testCase{ { name: "integers are equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Int64, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewInt64(18)}, }, @@ -131,25 +131,25 @@ func TestCompareIntegers(t *testing.T) { }, { name: "integers are not equal (3)", - v1: newColumn(0, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Int64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewInt64(18), sqltypes.NewInt64(98)}, }, { name: "unsigned integers are equal", - v1: newColumn(0, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Uint64, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Uint64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewUint64(18)}, }, { name: "unsigned integer and integer are equal", - v1: newColumn(0, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Uint64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewUint64(18), sqltypes.NewInt64(18)}, }, { name: "unsigned integer and integer are not equal", - v1: newColumn(0, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Uint64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewUint64(18), sqltypes.NewInt64(42)}, }, @@ -207,7 +207,7 @@ func TestCompareFloats(t *testing.T) { tests := []testCase{ { name: "floats are equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(18)}, }, @@ -228,7 +228,7 @@ func TestCompareFloats(t *testing.T) { }, { name: "floats are not equal (3)", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(16516.84), sqltypes.NewFloat64(219541.01)}, }, @@ -286,37 +286,37 @@ func TestCompareDecimals(t *testing.T) { tests := []testCase{ { name: "decimals are equal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("12.9019")}, }, { name: "decimals are not equal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("12.9019"), sqltypes.NewDecimal("489.156849")}, }, { name: "decimal is greater than decimal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.129"), sqltypes.NewDecimal("192.128")}, }, { name: "decimal is not greater than decimal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.128"), sqltypes.NewDecimal("192.129")}, }, { name: "decimal is less than decimal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.128"), sqltypes.NewDecimal("192.129")}, }, { name: "decimal is not less than decimal", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &F, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.129"), sqltypes.NewDecimal("192.128")}, }, @@ -334,151 +334,151 @@ func TestCompareNumerics(t *testing.T) { tests := []testCase{ { name: "decimal and float are equal", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(189.6), sqltypes.NewDecimal("189.6")}, }, { name: "decimal and float with negative values are equal", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(-98.1839), sqltypes.NewDecimal("-98.1839")}, }, { name: "decimal and float with negative values are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(-98.9381), sqltypes.NewDecimal("-98.1839")}, }, { name: "decimal and float with negative values are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Float64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewFloat64(-98.9381), sqltypes.NewDecimal("-98.1839")}, }, { name: "decimal and integer are equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Int64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewInt64(8979), sqltypes.NewDecimal("8979")}, }, { name: "decimal and integer are equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("8979.0000"), sqltypes.NewInt64(8979)}, }, { name: "decimal and unsigned integer are equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Uint64, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Decimal, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewUint64(901), sqltypes.NewDecimal("901")}, }, { name: "decimal and unsigned integer are equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Uint64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("901.00"), sqltypes.NewUint64(901)}, }, { name: "decimal and unsigned integer are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Uint64, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.129"), sqltypes.NewUint64(192)}, }, { name: "decimal and unsigned integer are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Uint64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Uint64, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("192.129"), sqltypes.NewUint64(192)}, }, { name: "decimal is greater than integer", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("1.01"), sqltypes.NewInt64(1)}, }, { name: "decimal is greater-equal to integer", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("1.00"), sqltypes.NewInt64(1)}, }, { name: "decimal is less than integer", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDecimal(".99"), sqltypes.NewInt64(1)}, }, { name: "decimal is less-equal to integer", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("1.00"), sqltypes.NewInt64(1)}, }, { name: "decimal is greater than float", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("849.896"), sqltypes.NewFloat64(86.568)}, }, { name: "decimal is not greater than float", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("15.23"), sqltypes.NewFloat64(8689.5)}, }, { name: "decimal is greater-equal to float (1)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("65"), sqltypes.NewFloat64(65)}, }, { name: "decimal is greater-equal to float (2)", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("65"), sqltypes.NewFloat64(60)}, }, { name: "decimal is less than float", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDecimal("0.998"), sqltypes.NewFloat64(0.999)}, }, { name: "decimal is less-equal to float", - v1: newColumn(0, Type{Type: sqltypes.Decimal, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Float64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Decimal, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Float64, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDecimal("1.000101"), sqltypes.NewFloat64(1.00101)}, }, { name: "different int types are equal for 8 bit", - v1: newColumn(0, Type{Type: sqltypes.Int8, Coll: collations.CollationBinaryID}), v2: NewLiteralInt(0), + v1: newColumn(0, NewType(sqltypes.Int8, collations.CollationBinaryID)), v2: NewLiteralInt(0), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewInt8(0)}, }, { name: "different int types are equal for 32 bit", - v1: newColumn(0, Type{Type: sqltypes.Int32, Coll: collations.CollationBinaryID}), v2: NewLiteralInt(0), + v1: newColumn(0, NewType(sqltypes.Int32, collations.CollationBinaryID)), v2: NewLiteralInt(0), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewInt32(0)}, }, { name: "different int types are equal for float32 bit", - v1: newColumn(0, Type{Type: sqltypes.Float32, Coll: collations.CollationBinaryID}), v2: NewLiteralFloat(1.0), + v1: newColumn(0, NewType(sqltypes.Float32, collations.CollationBinaryID)), v2: NewLiteralFloat(1.0), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Float32, []byte("1.0"))}, }, { name: "different unsigned int types are equal for 8 bit", - v1: newColumn(0, Type{Type: sqltypes.Uint8, Coll: collations.CollationBinaryID}), v2: NewLiteralInt(0), + v1: newColumn(0, NewType(sqltypes.Uint8, collations.CollationBinaryID)), v2: NewLiteralInt(0), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Uint8, []byte("0"))}, }, { name: "different unsigned int types are equal for 32 bit", - v1: newColumn(0, Type{Type: sqltypes.Uint32, Coll: collations.CollationBinaryID}), v2: NewLiteralInt(0), + v1: newColumn(0, NewType(sqltypes.Uint32, collations.CollationBinaryID)), v2: NewLiteralInt(0), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewUint32(0)}, }, @@ -496,73 +496,73 @@ func TestCompareDatetime(t *testing.T) { tests := []testCase{ { name: "datetimes are equal", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-22 12:00:00")}, }, { name: "datetimes are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-22 12:00:00"), sqltypes.NewDatetime("2020-10-22 12:00:00")}, }, { name: "datetimes are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-22 12:00:00"), sqltypes.NewDatetime("2021-10-22 10:23:56")}, }, { name: "datetimes are not equal (3)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-01 00:00:00"), sqltypes.NewDatetime("2021-02-01 00:00:00")}, }, { name: "datetime is greater than datetime", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-30 10:42:50"), sqltypes.NewDatetime("2021-10-01 13:10:02")}, }, { name: "datetime is not greater than datetime", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-01 13:10:02"), sqltypes.NewDatetime("2021-10-30 10:42:50")}, }, { name: "datetime is less than datetime", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-01 13:10:02"), sqltypes.NewDatetime("2021-10-30 10:42:50")}, }, { name: "datetime is not less than datetime", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &F, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-30 10:42:50"), sqltypes.NewDatetime("2021-10-01 13:10:02")}, }, { name: "datetime is greater-equal to datetime (1)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-30 10:42:50"), sqltypes.NewDatetime("2021-10-30 10:42:50")}, }, { name: "datetime is greater-equal to datetime (2)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-30 10:42:50"), sqltypes.NewDatetime("2021-10-01 13:10:02")}, }, { name: "datetime is less-equal to datetime (1)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-30 10:42:50"), sqltypes.NewDatetime("2021-10-30 10:42:50")}, }, { name: "datetime is less-equal to datetime (2)", - v1: newColumn(0, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Datetime, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDatetime("2021-10-01 13:10:02"), sqltypes.NewDatetime("2021-10-30 10:42:50")}, }, @@ -580,73 +580,73 @@ func TestCompareTimestamp(t *testing.T) { tests := []testCase{ { name: "timestamps are equal", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-22 12:00:00")}, }, { name: "timestamps are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-22 12:00:00"), sqltypes.NewTimestamp("2020-10-22 12:00:00")}, }, { name: "timestamps are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-22 12:00:00"), sqltypes.NewTimestamp("2021-10-22 10:23:56")}, }, { name: "timestamps are not equal (3)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-01 00:00:00"), sqltypes.NewTimestamp("2021-02-01 00:00:00")}, }, { name: "timestamp is greater than timestamp", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-30 10:42:50"), sqltypes.NewTimestamp("2021-10-01 13:10:02")}, }, { name: "timestamp is not greater than timestamp", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-01 13:10:02"), sqltypes.NewTimestamp("2021-10-30 10:42:50")}, }, { name: "timestamp is less than timestamp", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-01 13:10:02"), sqltypes.NewTimestamp("2021-10-30 10:42:50")}, }, { name: "timestamp is not less than timestamp", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &F, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-30 10:42:50"), sqltypes.NewTimestamp("2021-10-01 13:10:02")}, }, { name: "timestamp is greater-equal to timestamp (1)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-30 10:42:50"), sqltypes.NewTimestamp("2021-10-30 10:42:50")}, }, { name: "timestamp is greater-equal to timestamp (2)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-30 10:42:50"), sqltypes.NewTimestamp("2021-10-01 13:10:02")}, }, { name: "timestamp is less-equal to timestamp (1)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-30 10:42:50"), sqltypes.NewTimestamp("2021-10-30 10:42:50")}, }, { name: "timestamp is less-equal to timestamp (2)", - v1: newColumn(0, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewTimestamp("2021-10-01 13:10:02"), sqltypes.NewTimestamp("2021-10-30 10:42:50")}, }, @@ -668,67 +668,67 @@ func TestCompareDate(t *testing.T) { tests := []testCase{ { name: "dates are equal", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22")}, }, { name: "dates are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22"), sqltypes.NewDate("2020-10-21")}, }, { name: "dates are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-01"), sqltypes.NewDate("2021-02-01")}, }, { name: "date is greater than date", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-30"), sqltypes.NewDate("2021-10-01")}, }, { name: "date is not greater than date", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-01"), sqltypes.NewDate("2021-10-30")}, }, { name: "date is less than date", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-01"), sqltypes.NewDate("2021-10-30")}, }, { name: "date is not less than date", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &F, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-30"), sqltypes.NewDate("2021-10-01")}, }, { name: "date is greater-equal to date (1)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-30"), sqltypes.NewDate("2021-10-30")}, }, { name: "date is greater-equal to date (2)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-30"), sqltypes.NewDate("2021-10-01")}, }, { name: "date is less-equal to date (1)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-30"), sqltypes.NewDate("2021-10-30")}, }, { name: "date is less-equal to date (2)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-01"), sqltypes.NewDate("2021-10-30")}, }, @@ -746,79 +746,79 @@ func TestCompareTime(t *testing.T) { tests := []testCase{ { name: "times are equal", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewTime("12:00:00")}, }, { name: "times are not equal (1)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewTime("12:00:00"), sqltypes.NewTime("10:23:56")}, }, { name: "times are not equal (2)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewTime("00:00:00"), sqltypes.NewTime("10:15:00")}, }, { name: "time is greater than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTime("18:14:35"), sqltypes.NewTime("13:01:38")}, }, { name: "time is not greater than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTime("02:46:02"), sqltypes.NewTime("10:42:50")}, }, { name: "time is greater than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTime("101:14:35"), sqltypes.NewTime("13:01:38")}, }, { name: "time is not greater than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &F, op: sqlparser.GreaterThanOp, row: []sqltypes.Value{sqltypes.NewTime("24:46:02"), sqltypes.NewTime("101:42:50")}, }, { name: "time is less than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewTime("04:30:00"), sqltypes.NewTime("09:23:48")}, }, { name: "time is not less than time", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &F, op: sqlparser.LessThanOp, row: []sqltypes.Value{sqltypes.NewTime("15:21:00"), sqltypes.NewTime("10:00:00")}, }, { name: "time is greater-equal to time (1)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewTime("10:42:50"), sqltypes.NewTime("10:42:50")}, }, { name: "time is greater-equal to time (2)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.GreaterEqualOp, row: []sqltypes.Value{sqltypes.NewTime("19:42:50"), sqltypes.NewTime("13:10:02")}, }, { name: "time is less-equal to time (1)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewTime("10:42:50"), sqltypes.NewTime("10:42:50")}, }, { name: "time is less-equal to time (2)", - v1: newColumn(0, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Time, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.LessEqualOp, row: []sqltypes.Value{sqltypes.NewTime("10:10:02"), sqltypes.NewTime("10:42:50")}, }, @@ -836,13 +836,13 @@ func TestCompareDates(t *testing.T) { tests := []testCase{ { name: "date equal datetime", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22"), sqltypes.NewDatetime("2021-10-22 00:00:00")}, }, { name: "date equal datetime through bind variables", - v1: NewBindVar("k1", Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: NewBindVar("k2", Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: NewBindVar("k1", NewType(sqltypes.Date, collations.CollationBinaryID)), v2: NewBindVar("k2", NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, bv: map[string]*querypb.BindVariable{ "k1": {Type: sqltypes.Date, Value: []byte("2021-10-22")}, @@ -851,7 +851,7 @@ func TestCompareDates(t *testing.T) { }, { name: "date not equal datetime through bind variables", - v1: NewBindVar("k1", Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: NewBindVar("k2", Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: NewBindVar("k1", NewType(sqltypes.Date, collations.CollationBinaryID)), v2: NewBindVar("k2", NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, bv: map[string]*querypb.BindVariable{ "k1": {Type: sqltypes.Date, Value: []byte("2021-02-20")}, @@ -860,73 +860,73 @@ func TestCompareDates(t *testing.T) { }, { name: "date not equal datetime", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22"), sqltypes.NewDatetime("2021-10-20 00:06:00")}, }, { name: "date equal timestamp", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22"), sqltypes.NewTimestamp("2021-10-22 00:00:00")}, }, { name: "date not equal timestamp", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-10-22"), sqltypes.NewTimestamp("2021-10-22 16:00:00")}, }, { name: "date equal time", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &F, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewDate(time.Now().Format("2006-01-02")), sqltypes.NewTime("00:00:00")}, }, { name: "date not equal time", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDate(time.Now().Format("2006-01-02")), sqltypes.NewTime("12:00:00")}, }, { name: "string equal datetime", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Datetime, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Datetime, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("2021-10-22"), sqltypes.NewDatetime("2021-10-22 00:00:00")}, }, { name: "string equal timestamp", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("2021-10-22 00:00:00"), sqltypes.NewTimestamp("2021-10-22 00:00:00")}, }, { name: "string not equal timestamp", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Timestamp, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Timestamp, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("2021-10-22 06:00:30"), sqltypes.NewTimestamp("2021-10-20 15:02:10")}, }, { name: "string equal time", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Time, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Time, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("00:05:12"), sqltypes.NewTime("00:05:12")}, }, { name: "string equal date", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("2021-02-22"), sqltypes.NewDate("2021-02-22")}, }, { name: "string not equal date (1, date on the RHS)", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), v2: newColumn(1, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), v2: newColumn(1, NewType(sqltypes.Date, collations.CollationBinaryID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("2021-02-20"), sqltypes.NewDate("2021-03-30")}, }, { name: "string not equal date (2, date on the LHS)", - v1: newColumn(0, Type{Type: sqltypes.Date, Coll: collations.CollationBinaryID}), v2: newColumn(1, Type{Type: sqltypes.VarChar, Coll: collations.CollationUtf8mb4ID}), + v1: newColumn(0, NewType(sqltypes.Date, collations.CollationBinaryID)), v2: newColumn(1, NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)), out: &T, op: sqlparser.NotEqualOp, row: []sqltypes.Value{sqltypes.NewDate("2021-03-30"), sqltypes.NewVarChar("2021-02-20")}, }, @@ -944,13 +944,13 @@ func TestCompareStrings(t *testing.T) { tests := []testCase{ { name: "string equal string", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.Default()}), v2: newColumn(1, Type{Type: sqltypes.VarChar, Coll: collations.Default()}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.Default())), v2: newColumn(1, NewType(sqltypes.VarChar, collations.Default())), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("toto"), sqltypes.NewVarChar("toto")}, }, { name: "string equal number", - v1: newColumn(0, Type{Type: sqltypes.VarChar, Coll: collations.Default()}), v2: newColumn(1, Type{Type: sqltypes.Int64, Coll: collations.CollationBinaryID}), + v1: newColumn(0, NewType(sqltypes.VarChar, collations.Default())), v2: newColumn(1, NewType(sqltypes.Int64, collations.CollationBinaryID)), out: &T, op: sqlparser.EqualOp, row: []sqltypes.Value{sqltypes.NewVarChar("1"), sqltypes.NewInt64(1)}, }, @@ -1341,30 +1341,30 @@ func TestCompareSorter(t *testing.T) { Count: 100, Limit: 10, Random: sqltypes.RandomGenerators[sqltypes.Int64], - Cmp: Comparison{{Col: 0, Desc: false, Type: Type{Type: sqltypes.Int64}}}, + Cmp: Comparison{{Col: 0, Desc: false, Type: NewType(sqltypes.Int64, collations.Unknown)}}, }, { Count: 100, Limit: 10, Random: sqltypes.RandomGenerators[sqltypes.Int64], - Cmp: Comparison{{Col: 0, Desc: true, Type: Type{Type: sqltypes.Int64}}}, + Cmp: Comparison{{Col: 0, Desc: true, Type: NewType(sqltypes.Int64, collations.Unknown)}}, }, { Count: 100, Limit: math.MaxInt, Random: sqltypes.RandomGenerators[sqltypes.Int64], - Cmp: Comparison{{Col: 0, Desc: false, Type: Type{Type: sqltypes.Int64}}}, + Cmp: Comparison{{Col: 0, Desc: false, Type: NewType(sqltypes.Int64, collations.Unknown)}}, }, { Count: 100, Limit: math.MaxInt, Random: sqltypes.RandomGenerators[sqltypes.Int64], - Cmp: Comparison{{Col: 0, Desc: true, Type: Type{Type: sqltypes.Int64}}}, + Cmp: Comparison{{Col: 0, Desc: true, Type: NewType(sqltypes.Int64, collations.Unknown)}}, }, } for _, tc := range cases { - t.Run(fmt.Sprintf("%s-%d-%d", tc.Cmp[0].Type.Type, tc.Count, tc.Limit), func(t *testing.T) { + t.Run(fmt.Sprintf("%s-%d-%d", tc.Cmp[0].Type.Type(), tc.Count, tc.Limit), func(t *testing.T) { unsorted := make([]sqltypes.Row, 0, tc.Count) for i := 0; i < tc.Count; i++ { unsorted = append(unsorted, []sqltypes.Value{tc.Random()}) diff --git a/go/vt/vtgate/evalengine/api_literal.go b/go/vt/vtgate/evalengine/api_literal.go index f12988233e8..64d0cf5c1c3 100644 --- a/go/vt/vtgate/evalengine/api_literal.go +++ b/go/vt/vtgate/evalengine/api_literal.go @@ -203,8 +203,8 @@ func NewLiteralBinaryFromBit(val []byte) (*Literal, error) { func NewBindVar(key string, typ Type) *BindVariable { return &BindVariable{ Key: key, - Type: typ.Type, - Collation: typ.Coll, + Type: typ.Type(), + Collation: typ.Collation(), dynamicTypeOffset: -1, } } @@ -222,9 +222,12 @@ func NewBindVarTuple(key string, coll collations.ID) *BindVariable { func NewColumn(offset int, typ Type, original sqlparser.Expr) *Column { return &Column{ Offset: offset, - Type: typ.Type, - Collation: typedCoercionCollation(typ.Type, typ.Coll), + Type: typ.Type(), + Size: typ.size, + Scale: typ.scale, + Collation: typedCoercionCollation(typ.Type(), typ.Collation()), Original: original, + Nullable: typ.nullable, dynamicTypeOffset: -1, } } diff --git a/go/vt/vtgate/evalengine/cached_size.go b/go/vt/vtgate/evalengine/cached_size.go index d227af1a237..b0860f0b9e3 100644 --- a/go/vt/vtgate/evalengine/cached_size.go +++ b/go/vt/vtgate/evalengine/cached_size.go @@ -157,7 +157,7 @@ func (cached *Column) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(48) + size += int64(64) } // field Original vitess.io/vitess/go/vt/sqlparser.Expr if cc, ok := cached.Original.(cachedObject); ok { @@ -187,7 +187,7 @@ func (cached *CompiledExpr) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(64) + size += int64(80) } // field code []vitess.io/vitess/go/vt/vtgate/evalengine.frame { @@ -1786,7 +1786,7 @@ func (cached *typedExpr) CachedSize(alloc bool) int64 { } // field types []vitess.io/vitess/go/vt/vtgate/evalengine.ctype { - size += hack.RuntimeAllocSize(int64(cap(cached.types)) * int64(10)) + size += hack.RuntimeAllocSize(int64(cap(cached.types)) * int64(20)) } // field compiled *vitess.io/vitess/go/vt/vtgate/evalengine.CompiledExpr size += cached.compiled.CachedSize(true) diff --git a/go/vt/vtgate/evalengine/compiler.go b/go/vt/vtgate/evalengine/compiler.go index 1c2feeb5f15..e7d0e962fab 100644 --- a/go/vt/vtgate/evalengine/compiler.go +++ b/go/vt/vtgate/evalengine/compiler.go @@ -47,19 +47,64 @@ type compiledCoercion struct { } type ctype struct { - Type sqltypes.Type - Flag typeFlag - Col collations.TypedCollation + Type sqltypes.Type + Flag typeFlag + Size, Scale int32 + Col collations.TypedCollation } type Type struct { - Type sqltypes.Type - Coll collations.ID - Nullable bool + typ sqltypes.Type + collation collations.ID + nullable bool + init bool + size, scale int32 } -func UnknownType() Type { - return Type{Type: sqltypes.Unknown, Coll: collations.Unknown} +func NewType(t sqltypes.Type, collation collations.ID) Type { + // New types default to being nullable + return NewTypeEx(t, collation, true, 0, 0) +} + +func NewTypeEx(t sqltypes.Type, collation collations.ID, nullable bool, size, scale int32) Type { + return Type{ + typ: t, + collation: collation, + nullable: nullable, + init: true, + size: size, + scale: scale, + } +} + +func (t *Type) Type() sqltypes.Type { + if t.init { + return t.typ + } + return sqltypes.Unknown +} + +func (t *Type) Collation() collations.ID { + return t.collation +} + +func (t *Type) Size() int32 { + return t.size +} + +func (t *Type) Scale() int32 { + return t.scale +} + +func (t *Type) Nullable() bool { + if t.init { + return t.nullable + } + return true // nullable by default for unknown types +} + +func (t *Type) Valid() bool { + return t.init } func (ct ctype) nullable() bool { @@ -102,36 +147,36 @@ func (c *compiler) compileToNumeric(ct ctype, offset int, fallback sqltypes.Type if ct.Type == sqltypes.VarBinary { if (ct.Flag & flagHex) != 0 { c.asm.Convert_hex(offset) - return ctype{sqltypes.Uint64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Uint64, Flag: ct.Flag, Col: collationNumeric} } if (ct.Flag & flagBit) != 0 { c.asm.Convert_bit(offset) - return ctype{sqltypes.Int64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Int64, Flag: ct.Flag, Col: collationNumeric} } } if sqltypes.IsDateOrTime(ct.Type) { if preciseDatetime { c.asm.Convert_Ti(offset) - return ctype{sqltypes.Int64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Int64, Flag: ct.Flag, Col: collationNumeric} } c.asm.Convert_Tf(offset) - return ctype{sqltypes.Float64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Float64, Flag: ct.Flag, Col: collationNumeric} } switch fallback { case sqltypes.Int64: c.asm.Convert_xi(offset) - return ctype{sqltypes.Int64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Int64, Flag: ct.Flag, Col: collationNumeric} case sqltypes.Uint64: c.asm.Convert_xu(offset) - return ctype{sqltypes.Uint64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Uint64, Flag: ct.Flag, Col: collationNumeric} case sqltypes.Decimal: c.asm.Convert_xd(offset, 0, 0) - return ctype{sqltypes.Decimal, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Decimal, Flag: ct.Flag, Col: collationNumeric} } c.asm.Convert_xf(offset) - return ctype{sqltypes.Float64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Float64, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToInt64(ct ctype, offset int) ctype { @@ -144,7 +189,7 @@ func (c *compiler) compileToInt64(ct ctype, offset int) ctype { default: c.asm.Convert_xi(offset) } - return ctype{sqltypes.Int64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Int64, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToUint64(ct ctype, offset int) ctype { @@ -157,7 +202,7 @@ func (c *compiler) compileToUint64(ct ctype, offset int) ctype { default: c.asm.Convert_xu(offset) } - return ctype{sqltypes.Uint64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Uint64, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToBitwiseUint64(ct ctype, offset int) ctype { @@ -172,7 +217,7 @@ func (c *compiler) compileToBitwiseUint64(ct ctype, offset int) ctype { default: c.asm.Convert_xu(offset) } - return ctype{sqltypes.Uint64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Uint64, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToFloat(ct ctype, offset int) ctype { @@ -189,7 +234,7 @@ func (c *compiler) compileToFloat(ct ctype, offset int) ctype { default: c.asm.Convert_xf(offset) } - return ctype{sqltypes.Float64, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Float64, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToDecimal(ct ctype, offset int) ctype { @@ -204,7 +249,7 @@ func (c *compiler) compileToDecimal(ct ctype, offset int) ctype { default: c.asm.Convert_xd(offset, 0, 0) } - return ctype{sqltypes.Decimal, ct.Flag, collationNumeric} + return ctype{Type: sqltypes.Decimal, Flag: ct.Flag, Col: collationNumeric} } func (c *compiler) compileToDate(doct ctype, offset int) ctype { @@ -225,7 +270,7 @@ func (c *compiler) compileToDateTime(doct ctype, offset, prec int) ctype { default: c.asm.Convert_xDT(offset, prec) } - return ctype{Type: sqltypes.Datetime, Col: collationBinary, Flag: flagNullable} + return ctype{Type: sqltypes.Datetime, Size: int32(prec), Col: collationBinary, Flag: flagNullable} } func (c *compiler) compileToTime(doct ctype, offset, prec int) ctype { @@ -236,7 +281,7 @@ func (c *compiler) compileToTime(doct ctype, offset, prec int) ctype { default: c.asm.Convert_xT(offset, prec) } - return ctype{Type: sqltypes.Time, Col: collationBinary, Flag: flagNullable} + return ctype{Type: sqltypes.Time, Size: int32(prec), Col: collationBinary, Flag: flagNullable} } func (c *compiler) compileNullCheck1(ct ctype) *jump { diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index 6230627c26a..4b2f0525e9d 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -3761,9 +3761,6 @@ func (asm *assembler) Fn_UNIX_TIMESTAMP0() { func (asm *assembler) Fn_UNIX_TIMESTAMP1() { asm.emit(func(env *ExpressionEnv) int { res := dateTimeUnixTimestamp(env, env.vm.stack[env.vm.sp-1]) - if _, ok := res.(*evalInt64); !ok { - env.vm.err = errDeoptimize - } env.vm.stack[env.vm.sp-1] = res return 1 }, "FN UNIX_TIMESTAMP (SP-1)") diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go index 4fba65aeb75..b2cb9553f49 100644 --- a/go/vt/vtgate/evalengine/compiler_test.go +++ b/go/vt/vtgate/evalengine/compiler_test.go @@ -496,6 +496,42 @@ func TestCompilerSingle(t *testing.T) { result: `VARCHAR("0")`, collation: collations.CollationUtf8mb4ID, }, + { + expression: `UNIX_TIMESTAMP(0.0) + 1`, + result: `DECIMAL(1.0)`, + }, + { + expression: `UNIX_TIMESTAMP(0.000) + 1`, + result: `DECIMAL(1.000)`, + }, + { + expression: `UNIX_TIMESTAMP(-1.5) + 1`, + result: `DECIMAL(1.0)`, + }, + { + expression: `UNIX_TIMESTAMP(-1.500) + 1`, + result: `DECIMAL(1.000)`, + }, + { + expression: `UNIX_TIMESTAMP(0x0) + 1`, + result: `INT64(1)`, + }, + { + expression: `UNIX_TIMESTAMP(timestamp '2000-01-01 10:34:58.123456') + 1`, + result: `DECIMAL(946719299.123456)`, + }, + { + expression: `UNIX_TIMESTAMP('200001011034581111111') + 1`, + result: `INT64(946719299)`, + }, + { + expression: `CONV(-0x1, 13e0, 13e0)`, + result: `VARCHAR("219505A9511A867B72")`, + }, + { + expression: `UNIX_TIMESTAMP('20000101103458.111111') + 1`, + result: `DECIMAL(946719299.111111)`, + }, } tz, _ := time.LoadLocation("Europe/Madrid") diff --git a/go/vt/vtgate/evalengine/expr_arithmetic.go b/go/vt/vtgate/evalengine/expr_arithmetic.go index cb80e57c365..8814d9ed6b8 100644 --- a/go/vt/vtgate/evalengine/expr_arithmetic.go +++ b/go/vt/vtgate/evalengine/expr_arithmetic.go @@ -66,19 +66,6 @@ func (b *ArithmeticExpr) eval(env *ExpressionEnv) (eval, error) { return b.Op.eval(left, right) } -func makeNumericalType(t sqltypes.Type, f typeFlag) (sqltypes.Type, typeFlag) { - if sqltypes.IsNumber(t) { - return t, f - } - if t == sqltypes.VarBinary && (f&flagHex) != 0 { - return sqltypes.Uint64, f - } - if sqltypes.IsDateOrTime(t) { - return sqltypes.Int64, f | flagAmbiguousType - } - return sqltypes.Float64, f -} - func (b *ArithmeticExpr) compile(c *compiler) (ctype, error) { return b.Op.compile(c, b.Left, b.Right) } @@ -536,5 +523,11 @@ func (expr *NegateExpr) compile(c *compiler) (ctype, error) { } c.asm.jumpDestination(skip) - return ctype{Type: neg, Col: collationNumeric}, nil + return ctype{ + Type: neg, + Flag: arg.Flag & (flagNull | flagNullable), + Size: arg.Size, + Scale: arg.Scale, + Col: collationNumeric, + }, nil } diff --git a/go/vt/vtgate/evalengine/expr_column.go b/go/vt/vtgate/evalengine/expr_column.go index 741d04c6a06..06e135c317c 100644 --- a/go/vt/vtgate/evalengine/expr_column.go +++ b/go/vt/vtgate/evalengine/expr_column.go @@ -29,8 +29,11 @@ type ( Column struct { Offset int Type sqltypes.Type + Size int32 + Scale int32 Collation collations.TypedCollation Original sqlparser.Expr + Nullable bool // dynamicTypeOffset is set when the type of this column cannot be calculated // at translation time. Since expressions with dynamic types cannot be compiled ahead of time, @@ -56,7 +59,11 @@ func (c *Column) eval(env *ExpressionEnv) (eval, error) { func (c *Column) typeof(env *ExpressionEnv) (ctype, error) { if c.typed() { - return ctype{Type: c.Type, Flag: flagNullable, Col: c.Collation}, nil + var nullable typeFlag + if c.Nullable { + nullable = flagNullable + } + return ctype{Type: c.Type, Size: c.Size, Scale: c.Scale, Flag: nullable, Col: c.Collation}, nil } if c.Offset < len(env.Fields) { field := env.Fields[c.Offset] @@ -85,7 +92,11 @@ func (column *Column) compile(c *compiler) (ctype, error) { if column.typed() { typ.Type = column.Type typ.Col = column.Collation - typ.Flag = flagNullable + if column.Nullable { + typ.Flag = flagNullable + } + typ.Size = column.Size + typ.Scale = column.Scale } else if c.dynamicTypes != nil { typ = c.dynamicTypes[column.dynamicTypeOffset] } else { diff --git a/go/vt/vtgate/evalengine/expr_env.go b/go/vt/vtgate/evalengine/expr_env.go index ffcde05d2a0..a6ca1411e74 100644 --- a/go/vt/vtgate/evalengine/expr_env.go +++ b/go/vt/vtgate/evalengine/expr_env.go @@ -99,11 +99,7 @@ func (env *ExpressionEnv) TypeOf(expr Expr) (Type, error) { if err != nil { return Type{}, err } - return Type{ - Type: ty.Type, - Coll: ty.Col.Collation, - Nullable: ty.Flag&flagNullable != 0, - }, nil + return NewTypeEx(ty.Type, ty.Col.Collation, ty.Flag&flagNullable != 0, ty.Size, ty.Scale), nil } func (env *ExpressionEnv) SetTime(now time.Time) { diff --git a/go/vt/vtgate/evalengine/expr_literal.go b/go/vt/vtgate/evalengine/expr_literal.go index 5058c157229..2291356fcc7 100644 --- a/go/vt/vtgate/evalengine/expr_literal.go +++ b/go/vt/vtgate/evalengine/expr_literal.go @@ -70,6 +70,10 @@ func (l *Literal) typeof(*ExpressionEnv) (ctype, error) { if e.u > math.MaxInt64+1 { f |= flagIntegerOvf } + case *evalTemporal: + return ctype{Type: e.t, Col: collationNumeric, Size: int32(e.prec)}, nil + case *evalDecimal: + return ctype{Type: sqltypes.Decimal, Col: collationNumeric, Size: e.length, Scale: -e.dec.Exponent()}, nil } return ctype{Type: l.inner.SQLType(), Flag: f, Col: evalCollation(l.inner)}, nil } diff --git a/go/vt/vtgate/evalengine/fn_time.go b/go/vt/vtgate/evalengine/fn_time.go index 430b975974b..b0e7366ce8f 100644 --- a/go/vt/vtgate/evalengine/fn_time.go +++ b/go/vt/vtgate/evalengine/fn_time.go @@ -29,6 +29,8 @@ import ( var SystemTime = time.Now +const maxTimePrec = 6 + type ( builtinNow struct { CallExpr @@ -564,7 +566,7 @@ func (b *builtinFromUnixtime) eval(env *ExpressionEnv) (eval, error) { sf, ff := math.Modf(ts.f) sec = int64(sf) frac = int64(ff * 1e9) - prec = 6 + prec = maxTimePrec case *evalDecimal: sd, fd := ts.dec.QuoRem(decimal.New(1, 0), 0) sec, _ = sd.Int64() @@ -589,14 +591,14 @@ func (b *builtinFromUnixtime) eval(env *ExpressionEnv) (eval, error) { sf, ff := math.Modf(f.f) sec = int64(sf) frac = int64(ff * 1e9) - prec = 6 + prec = maxTimePrec } default: f, _ := evalToFloat(ts) sf, ff := math.Modf(f.f) sec = int64(sf) frac = int64(ff * 1e9) - prec = 6 + prec = maxTimePrec } if sec < 0 || sec >= maxUnixtime { @@ -1280,9 +1282,9 @@ func dateTimeUnixTimestamp(env *ExpressionEnv, date eval) evalNumeric { if d.isHexOrBitLiteral() { return newEvalInt64(0) } - prec = 6 + prec = maxTimePrec default: - prec = 6 + prec = maxTimePrec } return newEvalDecimalWithPrec(decimal.Zero, prec) } @@ -1336,7 +1338,30 @@ func (call *builtinUnixTimestamp) compile(c *compiler) (ctype, error) { c.asm.Fn_UNIX_TIMESTAMP1() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationBinary, Flag: arg.Flag | flagAmbiguousType}, nil + switch arg.Type { + case sqltypes.Datetime, sqltypes.Time, sqltypes.Decimal: + if arg.Size == 0 { + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil + } + return ctype{Type: sqltypes.Decimal, Size: arg.Size, Col: collationNumeric, Flag: arg.Flag}, nil + case sqltypes.Date, sqltypes.Int64, sqltypes.Uint64: + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil + case sqltypes.VarChar, sqltypes.VarBinary: + if arg.isHexOrBitLiteral() { + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil + } + if lit, ok := call.Arguments[0].(*Literal); ok { + if dt := evalToDateTime(lit.inner, -1, time.Now()); dt != nil { + if dt.prec == 0 { + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil + } + return ctype{Type: sqltypes.Decimal, Size: int32(dt.prec), Col: collationNumeric, Flag: arg.Flag}, nil + } + } + fallthrough + default: + return ctype{Type: sqltypes.Decimal, Size: maxTimePrec, Col: collationNumeric, Flag: arg.Flag}, nil + } } func (b *builtinWeek) eval(env *ExpressionEnv) (eval, error) { diff --git a/go/vt/vtgate/evalengine/translate.go b/go/vt/vtgate/evalengine/translate.go index c8f6f7d1337..7993854db36 100644 --- a/go/vt/vtgate/evalengine/translate.go +++ b/go/vt/vtgate/evalengine/translate.go @@ -193,7 +193,7 @@ func (ast *astCompiler) translateIsExpr(left sqlparser.Expr, op sqlparser.IsExpr } func (ast *astCompiler) translateBindVar(arg *sqlparser.Argument) (IR, error) { - bvar := NewBindVar(arg.Name, Type{Type: arg.Type, Coll: ast.cfg.Collation}) + bvar := NewBindVar(arg.Name, NewType(arg.Type, ast.cfg.Collation)) if !bvar.typed() { bvar.dynamicTypeOffset = len(ast.untyped) @@ -203,12 +203,12 @@ func (ast *astCompiler) translateBindVar(arg *sqlparser.Argument) (IR, error) { } func (ast *astCompiler) translateColOffset(col *sqlparser.Offset) (IR, error) { - typ := UnknownType() + var typ Type if ast.cfg.ResolveType != nil { typ, _ = ast.cfg.ResolveType(col.Original) } - if typ.Coll == collations.Unknown { - typ.Coll = ast.cfg.Collation + if typ.Valid() && typ.collation == collations.Unknown { + typ.collation = ast.cfg.Collation } column := NewColumn(col.V, typ, col.Original) @@ -227,12 +227,12 @@ func (ast *astCompiler) translateColName(colname *sqlparser.ColName) (IR, error) if err != nil { return nil, err } - typ := UnknownType() + var typ Type if ast.cfg.ResolveType != nil { typ, _ = ast.cfg.ResolveType(colname) } - if typ.Coll == collations.Unknown { - typ.Coll = ast.cfg.Collation + if typ.Valid() && typ.collation == collations.Unknown { + typ.collation = ast.cfg.Collation } column := NewColumn(idx, typ, colname) @@ -734,9 +734,9 @@ func (fields FieldResolver) Type(expr sqlparser.Expr) (Type, bool) { name := expr.CompliantName() for _, f := range fields { if f.Name == name { - return Type{Type: f.Type, Coll: collations.ID(f.Charset)}, true + return NewType(f.Type, collations.ID(f.Charset)), true } } } - return UnknownType(), false + return Type{}, false } diff --git a/go/vt/vtgate/planbuilder/collations_test.go b/go/vt/vtgate/planbuilder/collations_test.go index 7eaf3968f74..01b86125921 100644 --- a/go/vt/vtgate/planbuilder/collations_test.go +++ b/go/vt/vtgate/planbuilder/collations_test.go @@ -76,7 +76,7 @@ func TestOrderedAggregateCollations(t *testing.T) { check: func(t *testing.T, colls []collationInTable, primitive engine.Primitive) { oa, isOA := primitive.(*engine.OrderedAggregate) require.True(t, isOA, "should be an OrderedAggregate") - require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Coll) + require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Collation()) }, }, { @@ -85,7 +85,7 @@ func TestOrderedAggregateCollations(t *testing.T) { check: func(t *testing.T, colls []collationInTable, primitive engine.Primitive) { distinct, isDistinct := primitive.(*engine.Distinct) require.True(t, isDistinct, "should be a distinct") - require.Equal(t, collid(colls[0].collationName), distinct.CheckCols[0].Type.Coll) + require.Equal(t, collid(colls[0].collationName), distinct.CheckCols[0].Type.Collation()) }, }, { @@ -97,8 +97,8 @@ func TestOrderedAggregateCollations(t *testing.T) { check: func(t *testing.T, colls []collationInTable, primitive engine.Primitive) { oa, isOA := primitive.(*engine.OrderedAggregate) require.True(t, isOA, "should be an OrderedAggregate") - require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Coll) - require.Equal(t, collid(colls[1].collationName), oa.GroupByKeys[1].Type.Coll) + require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Collation()) + require.Equal(t, collid(colls[1].collationName), oa.GroupByKeys[1].Type.Collation()) }, }, { @@ -109,7 +109,7 @@ func TestOrderedAggregateCollations(t *testing.T) { check: func(t *testing.T, colls []collationInTable, primitive engine.Primitive) { oa, isOA := primitive.(*engine.OrderedAggregate) require.True(t, isOA, "should be an OrderedAggregate") - require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Coll) + require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Collation()) }, }, { @@ -122,7 +122,7 @@ func TestOrderedAggregateCollations(t *testing.T) { require.True(t, isMemSort, "should be a MemorySort") oa, isOA := memSort.Input.(*engine.OrderedAggregate) require.True(t, isOA, "should be an OrderedAggregate") - require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Coll) + require.Equal(t, collid(colls[0].collationName), oa.GroupByKeys[0].Type.Collation()) }, }, } diff --git a/go/vt/vtgate/planbuilder/expression_converter.go b/go/vt/vtgate/planbuilder/expression_converter.go index 61eebbe7f99..865c515ecbd 100644 --- a/go/vt/vtgate/planbuilder/expression_converter.go +++ b/go/vt/vtgate/planbuilder/expression_converter.go @@ -86,7 +86,7 @@ func (ec *expressionConverter) convert(astExpr sqlparser.Expr, boolean, identifi if !strings.Contains(err.Error(), evalengine.ErrTranslateExprNotSupported) { return nil, err } - evalExpr = evalengine.NewColumn(len(ec.tabletExpressions), evalengine.UnknownType(), nil) + evalExpr = evalengine.NewColumn(len(ec.tabletExpressions), evalengine.Type{}, nil) ec.tabletExpressions = append(ec.tabletExpressions, astExpr) } return evalExpr, nil diff --git a/go/vt/vtgate/planbuilder/expression_converter_test.go b/go/vt/vtgate/planbuilder/expression_converter_test.go index 798ed1e1635..3c0c25b6003 100644 --- a/go/vt/vtgate/planbuilder/expression_converter_test.go +++ b/go/vt/vtgate/planbuilder/expression_converter_test.go @@ -40,7 +40,7 @@ func TestConversion(t *testing.T) { expressionsOut: e(evalengine.NewLiteralInt(1)), }, { expressionsIn: "@@foo", - expressionsOut: e(evalengine.NewColumn(0, evalengine.UnknownType(), nil)), + expressionsOut: e(evalengine.NewColumn(0, evalengine.Type{}, nil)), }} for _, tc := range queries { diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 7d3223a48e9..d6732ada87d 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -862,8 +862,8 @@ func transformHashJoin(ctx *plancontext.PlanningContext, op *operators.HashJoin) LHSKey: op.LHSKeys[0], RHSKey: op.RHSKeys[0], ASTPred: op.JoinPredicate(), - Collation: comparisonType.Coll, - ComparisonType: comparisonType.Type, + Collation: comparisonType.Collation(), + ComparisonType: comparisonType.Type(), }, }, nil } diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index e3f4d349d2a..1cef6706a9f 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -115,7 +115,7 @@ func (aggr Aggr) NeedsWeightString(ctx *plancontext.PlanningContext) bool { func (aggr Aggr) GetTypeCollation(ctx *plancontext.PlanningContext) evalengine.Type { if aggr.Func == nil { - return evalengine.UnknownType() + return evalengine.Type{} } switch aggr.OpCode { case opcode.AggregateMin, opcode.AggregateMax, opcode.AggregateSumDistinct, opcode.AggregateCountDistinct: @@ -123,7 +123,7 @@ func (aggr Aggr) GetTypeCollation(ctx *plancontext.PlanningContext) evalengine.T return typ } - return evalengine.UnknownType() + return evalengine.Type{} } // NewGroupBy creates a new group by from the given fields. diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json index 2084d1a6e91..58cfbf1e68c 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json @@ -103,7 +103,7 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -146,13 +146,13 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci", - "1: utf8mb4_0900_ai_ci", - "2: utf8mb4_0900_ai_ci", - "3: utf8mb4_0900_ai_ci", - "4: utf8mb4_0900_ai_ci", + "0: utf8mb3_general_ci", + "1: utf8mb3_general_ci", + "2: utf8mb3_general_ci", + "3: utf8mb3_general_ci", + "4: utf8mb3_general_ci", "5", - "6: utf8mb4_0900_ai_ci", + "6: utf8mb3_general_ci", "7", "8", "9", @@ -163,10 +163,10 @@ "14", "15", "16", - "17: utf8mb4_0900_ai_ci", + "17: utf8mb3_general_ci", "18", - "19: utf8mb4_0900_ai_ci", - "20: utf8mb4_0900_ai_ci" + "19: utf8mb3_general_ci", + "20: utf8mb3_general_ci" ], "Inputs": [ { @@ -1000,7 +1000,7 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -1053,7 +1053,7 @@ "InputName": "SubQuery", "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json index 66449a2cc8c..b13e2912645 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json @@ -103,7 +103,7 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -146,11 +146,11 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci", - "1: utf8mb4_0900_ai_ci", - "2: utf8mb4_0900_ai_ci", + "0: utf8mb3_general_ci", + "1: utf8mb3_general_ci", + "2: utf8mb3_general_ci", "3", - "4: utf8mb4_0900_ai_ci", + "4: utf8mb3_general_ci", "5", "6", "7", @@ -163,10 +163,10 @@ "14", "15", "16", - "17: utf8mb4_0900_ai_ci", + "17: utf8mb3_general_ci", "18", - "19: utf8mb4_0900_ai_ci", - "20: utf8mb4_0900_ai_ci" + "19: utf8mb3_general_ci", + "20: utf8mb3_general_ci" ], "Inputs": [ { @@ -1065,7 +1065,7 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -1118,7 +1118,7 @@ "InputName": "SubQuery", "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index 9c1f376b652..37113c778e3 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -322,7 +322,7 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -1138,7 +1138,7 @@ { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci" + "0: utf8mb3_general_ci" ], "Inputs": [ { @@ -1218,18 +1218,18 @@ { "OperatorType": "Distinct", "Collations": [ - "0: utf8mb4_0900_ai_ci", - "1: utf8mb4_0900_ai_ci", - "2: utf8mb4_0900_ai_ci", - "3: utf8mb4_0900_ai_ci", - "4: utf8mb4_0900_ai_ci", - "5: utf8mb4_0900_ai_ci", - "6: utf8mb4_0900_ai_ci", + "0: utf8mb3_general_ci", + "1: utf8mb3_general_ci", + "2: utf8mb3_general_ci", + "3: utf8mb3_general_ci", + "4: utf8mb3_general_ci", + "5: utf8mb3_general_ci", + "6: utf8mb3_general_ci", "7", "8", - "9: utf8mb4_0900_ai_ci", - "10: utf8mb4_0900_ai_ci", - "11: utf8mb4_0900_ai_ci" + "9: utf8mb3_general_ci", + "10: utf8mb3_general_ci", + "11: utf8mb3_general_ci" ], "Inputs": [ { diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index c4b48ce8156..a6d6cafc423 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -19,6 +19,7 @@ package schema import ( "context" "maps" + "strconv" "strings" "sync" "time" @@ -311,18 +312,46 @@ func getColumns(tblSpec *sqlparser.TableSpec) []vindexes.Column { cols := make([]vindexes.Column, 0, len(tblSpec.Columns)) for _, column := range tblSpec.Columns { colCollation := getColumnCollation(tblCollation, column) + size := getColumnNumber(column.Type.Length) + scale := getColumnNumber(column.Type.Scale) + nullable := getColumnNullable(column.Type.Options.Null) cols = append(cols, vindexes.Column{ Name: column.Name, Type: column.Type.SQLType(), CollationName: colCollation, - Invisible: column.Type.Invisible(), Default: column.Type.Options.Default, + Invisible: column.Type.Invisible(), + Size: size, + Scale: scale, + Nullable: nullable, + Values: column.Type.EnumValues, }) } return cols } +func getColumnNullable(null *bool) bool { + if null == nil { + return true + } + return *null +} + +func getColumnNumber(lit *sqlparser.Literal) int32 { + if lit == nil { + return 0 + } + if lit.Type != sqlparser.IntVal { + return 0 + } + val, err := strconv.ParseInt(lit.Val, 10, 32) + if err != nil { + return 0 + } + return int32(val) +} + func getForeignKeys(tblSpec *sqlparser.TableSpec) []*sqlparser.ForeignKeyDefinition { if tblSpec.Constraints == nil { return nil @@ -353,7 +382,13 @@ func getTableCollation(tblSpec *sqlparser.TableSpec) string { func getColumnCollation(defaultCollation string, column *sqlparser.ColumnDefinition) string { if column.Type.Options == nil || column.Type.Options.Collate == "" { - return defaultCollation + switch strings.ToLower(column.Type.Type) { + case "enum", "set", "text", "tinytext", "mediumtext", "longtext", "varchar", "char": + return defaultCollation + case "json": + return "utf8mb4_bin" + } + return "binary" } return column.Type.Options.Collate } diff --git a/go/vt/vtgate/schema/tracker_test.go b/go/vt/vtgate/schema/tracker_test.go index 88b9dfa0d50..ce2a2d79b56 100644 --- a/go/vt/vtgate/schema/tracker_test.go +++ b/go/vt/vtgate/schema/tracker_test.go @@ -173,7 +173,7 @@ func TestTableTracking(t *testing.T) { }, { // initial load of view - kept empty }, { - "t1": "create table t1(id bigint primary key, name varchar(50))", + "t1": "create table t1(id bigint primary key, name varchar(50), email varchar(50) not null default 'a@b.com')", "t2": "create table t2(id varchar(50) primary key)", }, { "t2": "create table t2(id varchar(50) primary key, name varchar(50))", @@ -185,32 +185,32 @@ func TestTableTracking(t *testing.T) { testcases := []testCases{{ testName: "initial table load", expTbl: map[string][]vindexes.Column{ - "prior": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT32}}, + "prior": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT32, CollationName: "binary", Nullable: true}}, }, }, { testName: "new tables", updTbl: []string{"t1", "t2"}, expTbl: map[string][]vindexes.Column{ - "prior": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT32}}, - "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, - "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR}}, + "prior": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT32, CollationName: "binary", Nullable: true}}, + "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: false, Default: &sqlparser.Literal{Val: "a@b.com"}}}, + "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, }, }, { testName: "delete prior, updated t2 and new t3", updTbl: []string{"prior", "t2", "t3"}, expTbl: map[string][]vindexes.Column{ - "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, - "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, - "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME}}, + "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: false, Default: &sqlparser.Literal{Val: "a@b.com"}}}, + "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, + "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME, CollationName: "binary", Size: 0, Nullable: true}}, }, }, { testName: "new t4", updTbl: []string{"t4"}, expTbl: map[string][]vindexes.Column{ - "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, - "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, - "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME}}, - "t4": {{Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR}}, + "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: false, Default: &sqlparser.Literal{Val: "a@b.com"}}}, + "t2": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, + "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME, CollationName: "binary", Size: 0, Nullable: true}}, + "t4": {{Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, }, }} @@ -292,9 +292,9 @@ func TestFKInfoRetrieval(t *testing.T) { testName: "initial table load", expTbl: map[string][]vindexes.Column{ "my_tbl": { - {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: false}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, CollationName: "latin1_swedish_ci", Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, Size: 100, CollationName: "binary", Nullable: true, Default: &sqlparser.NullVal{}}, }, }, }, { @@ -302,15 +302,15 @@ func TestFKInfoRetrieval(t *testing.T) { updTbl: []string{"my_child_tbl"}, expTbl: map[string][]vindexes.Column{ "my_tbl": { - {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: false}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, CollationName: "latin1_swedish_ci", Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, Size: 100, CollationName: "binary", Nullable: true, Default: &sqlparser.NullVal{}}, }, "my_child_tbl": { - {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("code"), Type: querypb.Type_VARCHAR, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("my_id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: false}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, CollationName: "latin1_swedish_ci", Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("code"), Type: querypb.Type_VARCHAR, Size: 6, CollationName: "utf8mb4_0900_ai_ci", Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("my_id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: true, Default: &sqlparser.NullVal{}}, }, }, expFk: map[string]string{ @@ -349,9 +349,9 @@ func TestIndexInfoRetrieval(t *testing.T) { testName: "initial table load", expTbl: map[string][]vindexes.Column{ "my_tbl": { - {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: false}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Size: 50, Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "binary", Size: 100, Nullable: true, Default: &sqlparser.NullVal{}}, }, }, expIdx: map[string][]string{ @@ -365,9 +365,9 @@ func TestIndexInfoRetrieval(t *testing.T) { updTbl: []string{"my_tbl"}, expTbl: map[string][]vindexes.Column{ "my_tbl": { - {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "utf8mb4_0900_ai_ci"}, - {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Default: &sqlparser.NullVal{}}, - {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "utf8mb4_0900_ai_ci", Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: false}, + {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, CollationName: "latin1_swedish_ci", Size: 50, Nullable: true, Default: &sqlparser.NullVal{}}, + {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARBINARY, CollationName: "binary", Size: 100, Nullable: true, Default: &sqlparser.NullVal{}}, }, }, expIdx: map[string][]string{ diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go index cb19d5deafd..d27d5a926c6 100644 --- a/go/vt/vtgate/semantics/analyzer_test.go +++ b/go/vt/vtgate/semantics/analyzer_test.go @@ -402,7 +402,7 @@ func TestUnknownColumnMap2(t *testing.T) { require.NoError(t, tbl.NotSingleRouteErr) typ, found := tbl.TypeForExpr(expr) assert.True(t, found) - assert.Equal(t, test.typ, typ.Type) + assert.Equal(t, test.typ, typ.Type()) } }) } diff --git a/go/vt/vtgate/semantics/binder.go b/go/vt/vtgate/semantics/binder.go index f7fc5d64c1a..27d059673cb 100644 --- a/go/vt/vtgate/semantics/binder.go +++ b/go/vt/vtgate/semantics/binder.go @@ -19,7 +19,6 @@ package semantics import ( "strings" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" ) @@ -88,7 +87,7 @@ func (b *binder) up(cursor *sqlparser.Cursor) error { } b.recursive[node] = deps.recursive b.direct[node] = deps.direct - if deps.typ.Type != sqltypes.Unknown { + if deps.typ.Valid() { b.typer.setTypeFor(node, deps.typ) } case *sqlparser.CountStar: @@ -103,7 +102,7 @@ func (b *binder) up(cursor *sqlparser.Cursor) error { for i, expr := range info.exprs { ae := expr.(*sqlparser.AliasedExpr) b.recursive[ae.Expr] = info.recursive[i] - if t := info.types[i]; t.Type != sqltypes.Unknown { + if t := info.types[i]; t.Valid() { b.typer.m[ae.Expr] = t } } diff --git a/go/vt/vtgate/semantics/dependencies.go b/go/vt/vtgate/semantics/dependencies.go index 89b6da7045d..e68c5100ef5 100644 --- a/go/vt/vtgate/semantics/dependencies.go +++ b/go/vt/vtgate/semantics/dependencies.go @@ -54,10 +54,9 @@ func createCertain(direct TableSet, recursive TableSet, qt evalengine.Type) *cer dependency: dependency{ direct: direct, recursive: recursive, - typ: evalengine.UnknownType(), }, } - if qt.Type != querypb.Type_NULL_TYPE { + if qt.Valid() && qt.Type() != querypb.Type_NULL_TYPE { c.typ = qt } return c @@ -68,7 +67,6 @@ func createUncertain(direct TableSet, recursive TableSet) *uncertain { dependency: dependency{ direct: direct, recursive: recursive, - typ: evalengine.UnknownType(), }, } } diff --git a/go/vt/vtgate/semantics/info_schema.go b/go/vt/vtgate/semantics/info_schema.go index b2b5d9036f2..76a383b5ac0 100644 --- a/go/vt/vtgate/semantics/info_schema.go +++ b/go/vt/vtgate/semantics/info_schema.go @@ -17,6 +17,7 @@ limitations under the License. package semantics import ( + "fmt" "strings" "vitess.io/vitess/go/mysql/collations" @@ -29,8 +30,37 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) -func createCol(name string, typ int) vindexes.Column { - return vindexes.Column{Name: sqlparser.NewIdentifierCI(name), Type: query.Type(typ)} +func createCol(name string, typ int, collation string, def string, size, scale int32, notNullable bool, values string) vindexes.Column { + var expr sqlparser.Expr + if def != "" { + var err error + expr, err = sqlparser.ParseExpr(def) + if err != nil { + panic(fmt.Sprintf("Failed to parse %q: %v", def, err)) + } + } + var vals []string + if values != "" { + quotedVals := strings.Split(values, ",") + vals = make([]string, 0, len(quotedVals)) + for _, v := range quotedVals { + u := strings.TrimFunc(v, func(r rune) bool { + return r == '\'' + }) + vals = append(vals, u) + } + } + + return vindexes.Column{ + Name: sqlparser.NewIdentifierCI(name), + Type: query.Type(typ), + CollationName: collation, + Default: expr, + Size: size, + Scale: scale, + Nullable: !notNullable, + Values: vals, + } } // getInfoSchema57 returns a map of all information_schema tables and their columns with types @@ -38,734 +68,627 @@ func createCol(name string, typ int) vindexes.Column { func getInfoSchema57() map[string][]vindexes.Column { infSchema := map[string][]vindexes.Column{} var cols []vindexes.Column - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_COLLATE_NAME", 6165)) - cols = append(cols, createCol("DESCRIPTION", 6165)) - cols = append(cols, createCol("MAXLEN", 265)) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DEFAULT_COLLATE_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DESCRIPTION", 6165, "utf8mb3_general_ci", "", 60, 0, true, "")) + cols = append(cols, createCol("MAXLEN", 265, "utf8mb3_general_ci", "0", 3, 0, true, "")) infSchema["CHARACTER_SETS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) infSchema["COLLATION_CHARACTER_SET_APPLICABILITY"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("ID", 265)) - cols = append(cols, createCol("IS_DEFAULT", 6165)) - cols = append(cols, createCol("IS_COMPILED", 6165)) - cols = append(cols, createCol("SORTLEN", 265)) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("ID", 265, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("IS_DEFAULT", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("IS_COMPILED", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("SORTLEN", 265, "utf8mb3_general_ci", "0", 3, 0, true, "")) infSchema["COLLATIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 81, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["COLUMN_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 265)) - cols = append(cols, createCol("COLUMN_DEFAULT", 6163)) - cols = append(cols, createCol("IS_NULLABLE", 6165)) - cols = append(cols, createCol("DATA_TYPE", 6165)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265)) - cols = append(cols, createCol("NUMERIC_PRECISION", 265)) - cols = append(cols, createCol("NUMERIC_SCALE", 265)) - cols = append(cols, createCol("DATETIME_PRECISION", 265)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("COLUMN_TYPE", 6163)) - cols = append(cols, createCol("COLUMN_KEY", 6165)) - cols = append(cols, createCol("EXTRA", 6165)) - cols = append(cols, createCol("PRIVILEGES", 6165)) - cols = append(cols, createCol("COLUMN_COMMENT", 6165)) - cols = append(cols, createCol("GENERATION_EXPRESSION", 6163)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("COLUMN_DEFAULT", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("IS_NULLABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("DATA_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, false, "")) + cols = append(cols, createCol("COLUMN_TYPE", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COLUMN_KEY", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("EXTRA", 6165, "utf8mb3_general_ci", "", 30, 0, true, "")) + cols = append(cols, createCol("PRIVILEGES", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("COLUMN_COMMENT", 6165, "utf8mb3_general_ci", "", 1024, 0, true, "")) + cols = append(cols, createCol("GENERATION_EXPRESSION", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["COLUMNS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("SUPPORT", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) - cols = append(cols, createCol("TRANSACTIONS", 6165)) - cols = append(cols, createCol("XA", 6165)) - cols = append(cols, createCol("SAVEPOINTS", 6165)) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SUPPORT", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("TRANSACTIONS", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("XA", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("SAVEPOINTS", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) infSchema["ENGINES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("EVENT_CATALOG", 6165)) - cols = append(cols, createCol("EVENT_SCHEMA", 6165)) - cols = append(cols, createCol("EVENT_NAME", 6165)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("TIME_ZONE", 6165)) - cols = append(cols, createCol("EVENT_BODY", 6165)) - cols = append(cols, createCol("EVENT_DEFINITION", 6163)) - cols = append(cols, createCol("EVENT_TYPE", 6165)) - cols = append(cols, createCol("EXECUTE_AT", 2064)) - cols = append(cols, createCol("INTERVAL_VALUE", 6165)) - cols = append(cols, createCol("INTERVAL_FIELD", 6165)) - cols = append(cols, createCol("SQL_MODE", 6165)) - cols = append(cols, createCol("STARTS", 2064)) - cols = append(cols, createCol("ENDS", 2064)) - cols = append(cols, createCol("STATUS", 6165)) - cols = append(cols, createCol("ON_COMPLETION", 6165)) - cols = append(cols, createCol("CREATED", 2064)) - cols = append(cols, createCol("LAST_ALTERED", 2064)) - cols = append(cols, createCol("LAST_EXECUTED", 2064)) - cols = append(cols, createCol("EVENT_COMMENT", 6165)) - cols = append(cols, createCol("ORIGINATOR", 265)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("EVENT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 93, 0, true, "")) + cols = append(cols, createCol("TIME_ZONE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_BODY", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("EVENT_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("EVENT_TYPE", 6165, "utf8mb3_general_ci", "", 9, 0, true, "")) + cols = append(cols, createCol("EXECUTE_AT", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INTERVAL_VALUE", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("INTERVAL_FIELD", 6165, "utf8mb3_general_ci", "", 18, 0, false, "")) + cols = append(cols, createCol("SQL_MODE", 6165, "utf8mb3_general_ci", "", 8192, 0, true, "")) + cols = append(cols, createCol("STARTS", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ENDS", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("STATUS", 6165, "utf8mb3_general_ci", "", 18, 0, true, "")) + cols = append(cols, createCol("ON_COMPLETION", 6165, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("CREATED", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_ALTERED", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_EXECUTED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EVENT_COMMENT", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ORIGINATOR", 265, "utf8mb3_general_ci", "0", 10, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) infSchema["EVENTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("FILE_ID", 265)) - cols = append(cols, createCol("FILE_NAME", 6165)) - cols = append(cols, createCol("FILE_TYPE", 6165)) - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165)) - cols = append(cols, createCol("LOGFILE_GROUP_NUMBER", 265)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("FULLTEXT_KEYS", 6165)) - cols = append(cols, createCol("DELETED_ROWS", 265)) - cols = append(cols, createCol("UPDATE_COUNT", 265)) - cols = append(cols, createCol("FREE_EXTENTS", 265)) - cols = append(cols, createCol("TOTAL_EXTENTS", 265)) - cols = append(cols, createCol("EXTENT_SIZE", 265)) - cols = append(cols, createCol("INITIAL_SIZE", 265)) - cols = append(cols, createCol("MAXIMUM_SIZE", 265)) - cols = append(cols, createCol("AUTOEXTEND_SIZE", 265)) - cols = append(cols, createCol("CREATION_TIME", 2064)) - cols = append(cols, createCol("LAST_UPDATE_TIME", 2064)) - cols = append(cols, createCol("LAST_ACCESS_TIME", 2064)) - cols = append(cols, createCol("RECOVER_TIME", 265)) - cols = append(cols, createCol("TRANSACTION_COUNTER", 265)) - cols = append(cols, createCol("VERSION", 265)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("TABLE_ROWS", 265)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 265)) - cols = append(cols, createCol("DATA_LENGTH", 265)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 265)) - cols = append(cols, createCol("INDEX_LENGTH", 265)) - cols = append(cols, createCol("DATA_FREE", 265)) - cols = append(cols, createCol("CREATE_TIME", 2064)) - cols = append(cols, createCol("UPDATE_TIME", 2064)) - cols = append(cols, createCol("CHECK_TIME", 2064)) - cols = append(cols, createCol("CHECKSUM", 265)) - cols = append(cols, createCol("STATUS", 6165)) - cols = append(cols, createCol("EXTRA", 6165)) + cols = append(cols, createCol("FILE_ID", 265, "utf8mb3_general_ci", "0", 4, 0, true, "")) + cols = append(cols, createCol("FILE_NAME", 6165, "utf8mb3_general_ci", "", 4000, 0, false, "")) + cols = append(cols, createCol("FILE_TYPE", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NUMBER", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("FULLTEXT_KEYS", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DELETED_ROWS", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("UPDATE_COUNT", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("FREE_EXTENTS", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("TOTAL_EXTENTS", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("EXTENT_SIZE", 265, "utf8mb3_general_ci", "0", 4, 0, true, "")) + cols = append(cols, createCol("INITIAL_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MAXIMUM_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AUTOEXTEND_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CREATION_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("LAST_UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("LAST_ACCESS_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("RECOVER_TIME", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("TRANSACTION_COUNTER", 265, "utf8mb3_general_ci", "", 4, 0, false, "")) + cols = append(cols, createCol("VERSION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("ROW_FORMAT", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("TABLE_ROWS", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATA_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATA_FREE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CREATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("STATUS", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("EXTRA", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) infSchema["FILES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("VARIABLE_NAME", 6165)) - cols = append(cols, createCol("VARIABLE_VALUE", 6165)) + cols = append(cols, createCol("VARIABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("VARIABLE_VALUE", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) infSchema["GLOBAL_STATUS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("VARIABLE_NAME", 6165)) - cols = append(cols, createCol("VARIABLE_VALUE", 6165)) + cols = append(cols, createCol("VARIABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("VARIABLE_VALUE", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) infSchema["GLOBAL_VARIABLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 265)) - cols = append(cols, createCol("BLOCK_ID", 265)) - cols = append(cols, createCol("SPACE", 265)) - cols = append(cols, createCol("PAGE_NUMBER", 265)) - cols = append(cols, createCol("PAGE_TYPE", 6165)) - cols = append(cols, createCol("FLUSH_TYPE", 265)) - cols = append(cols, createCol("FIX_COUNT", 265)) - cols = append(cols, createCol("IS_HASHED", 6165)) - cols = append(cols, createCol("NEWEST_MODIFICATION", 265)) - cols = append(cols, createCol("OLDEST_MODIFICATION", 265)) - cols = append(cols, createCol("ACCESS_TIME", 265)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("NUMBER_RECORDS", 265)) - cols = append(cols, createCol("DATA_SIZE", 265)) - cols = append(cols, createCol("COMPRESSED_SIZE", 265)) - cols = append(cols, createCol("PAGE_STATE", 6165)) - cols = append(cols, createCol("IO_FIX", 6165)) - cols = append(cols, createCol("IS_OLD", 6165)) - cols = append(cols, createCol("FREE_PAGE_CLOCK", 265)) + cols = append(cols, createCol("POOL_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("BLOCK_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("SPACE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGE_NUMBER", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("FLUSH_TYPE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("FIX_COUNT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("IS_HASHED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("NEWEST_MODIFICATION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("OLDEST_MODIFICATION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("ACCESS_TIME", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("NUMBER_RECORDS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DATA_SIZE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("COMPRESSED_SIZE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGE_STATE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IO_FIX", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IS_OLD", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("FREE_PAGE_CLOCK", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_BUFFER_PAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 265)) - cols = append(cols, createCol("LRU_POSITION", 265)) - cols = append(cols, createCol("SPACE", 265)) - cols = append(cols, createCol("PAGE_NUMBER", 265)) - cols = append(cols, createCol("PAGE_TYPE", 6165)) - cols = append(cols, createCol("FLUSH_TYPE", 265)) - cols = append(cols, createCol("FIX_COUNT", 265)) - cols = append(cols, createCol("IS_HASHED", 6165)) - cols = append(cols, createCol("NEWEST_MODIFICATION", 265)) - cols = append(cols, createCol("OLDEST_MODIFICATION", 265)) - cols = append(cols, createCol("ACCESS_TIME", 265)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("NUMBER_RECORDS", 265)) - cols = append(cols, createCol("DATA_SIZE", 265)) - cols = append(cols, createCol("COMPRESSED_SIZE", 265)) - cols = append(cols, createCol("COMPRESSED", 6165)) - cols = append(cols, createCol("IO_FIX", 6165)) - cols = append(cols, createCol("IS_OLD", 6165)) - cols = append(cols, createCol("FREE_PAGE_CLOCK", 265)) + cols = append(cols, createCol("POOL_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("LRU_POSITION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("SPACE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGE_NUMBER", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("FLUSH_TYPE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("FIX_COUNT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("IS_HASHED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("NEWEST_MODIFICATION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("OLDEST_MODIFICATION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("ACCESS_TIME", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("NUMBER_RECORDS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DATA_SIZE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("COMPRESSED_SIZE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("COMPRESSED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("IO_FIX", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IS_OLD", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("FREE_PAGE_CLOCK", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_BUFFER_PAGE_LRU"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 265)) - cols = append(cols, createCol("POOL_SIZE", 265)) - cols = append(cols, createCol("FREE_BUFFERS", 265)) - cols = append(cols, createCol("DATABASE_PAGES", 265)) - cols = append(cols, createCol("OLD_DATABASE_PAGES", 265)) - cols = append(cols, createCol("MODIFIED_DATABASE_PAGES", 265)) - cols = append(cols, createCol("PENDING_DECOMPRESS", 265)) - cols = append(cols, createCol("PENDING_READS", 265)) - cols = append(cols, createCol("PENDING_FLUSH_LRU", 265)) - cols = append(cols, createCol("PENDING_FLUSH_LIST", 265)) - cols = append(cols, createCol("PAGES_MADE_YOUNG", 265)) - cols = append(cols, createCol("PAGES_NOT_MADE_YOUNG", 265)) - cols = append(cols, createCol("PAGES_MADE_YOUNG_RATE", 1036)) - cols = append(cols, createCol("PAGES_MADE_NOT_YOUNG_RATE", 1036)) - cols = append(cols, createCol("NUMBER_PAGES_READ", 265)) - cols = append(cols, createCol("NUMBER_PAGES_CREATED", 265)) - cols = append(cols, createCol("NUMBER_PAGES_WRITTEN", 265)) - cols = append(cols, createCol("PAGES_READ_RATE", 1036)) - cols = append(cols, createCol("PAGES_CREATE_RATE", 1036)) - cols = append(cols, createCol("PAGES_WRITTEN_RATE", 1036)) - cols = append(cols, createCol("NUMBER_PAGES_GET", 265)) - cols = append(cols, createCol("HIT_RATE", 265)) - cols = append(cols, createCol("YOUNG_MAKE_PER_THOUSAND_GETS", 265)) - cols = append(cols, createCol("NOT_YOUNG_MAKE_PER_THOUSAND_GETS", 265)) - cols = append(cols, createCol("NUMBER_PAGES_READ_AHEAD", 265)) - cols = append(cols, createCol("NUMBER_READ_AHEAD_EVICTED", 265)) - cols = append(cols, createCol("READ_AHEAD_RATE", 1036)) - cols = append(cols, createCol("READ_AHEAD_EVICTED_RATE", 1036)) - cols = append(cols, createCol("LRU_IO_TOTAL", 265)) - cols = append(cols, createCol("LRU_IO_CURRENT", 265)) - cols = append(cols, createCol("UNCOMPRESS_TOTAL", 265)) - cols = append(cols, createCol("UNCOMPRESS_CURRENT", 265)) + cols = append(cols, createCol("POOL_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("POOL_SIZE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("FREE_BUFFERS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DATABASE_PAGES", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("OLD_DATABASE_PAGES", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("MODIFIED_DATABASE_PAGES", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PENDING_DECOMPRESS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PENDING_READS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PENDING_FLUSH_LRU", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PENDING_FLUSH_LIST", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_YOUNG", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGES_NOT_MADE_YOUNG", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_YOUNG_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_NOT_YOUNG_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_READ", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_CREATED", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_WRITTEN", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PAGES_READ_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_CREATE_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_WRITTEN_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_GET", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("HIT_RATE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("YOUNG_MAKE_PER_THOUSAND_GETS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NOT_YOUNG_MAKE_PER_THOUSAND_GETS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_READ_AHEAD", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NUMBER_READ_AHEAD_EVICTED", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("READ_AHEAD_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("READ_AHEAD_EVICTED_RATE", 1036, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("LRU_IO_TOTAL", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("LRU_IO_CURRENT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("UNCOMPRESS_TOTAL", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("UNCOMPRESS_CURRENT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_BUFFER_POOL_STATS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "0", 5, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMP"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("database_name", 6165)) - cols = append(cols, createCol("table_name", 6165)) - cols = append(cols, createCol("index_name", 6165)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("database_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("table_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("index_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMP_PER_INDEX"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("database_name", 6165)) - cols = append(cols, createCol("table_name", 6165)) - cols = append(cols, createCol("index_name", 6165)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("database_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("table_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("index_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMP_PER_INDEX_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "0", 5, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMP_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("buffer_pool_instance", 263)) - cols = append(cols, createCol("pages_used", 263)) - cols = append(cols, createCol("pages_free", 263)) - cols = append(cols, createCol("relocation_ops", 265)) - cols = append(cols, createCol("relocation_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "0", 5, 0, true, "")) + cols = append(cols, createCol("buffer_pool_instance", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("pages_used", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("pages_free", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("relocation_ops", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("relocation_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMPMEM"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("buffer_pool_instance", 263)) - cols = append(cols, createCol("pages_used", 263)) - cols = append(cols, createCol("pages_free", 263)) - cols = append(cols, createCol("relocation_ops", 265)) - cols = append(cols, createCol("relocation_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "0", 5, 0, true, "")) + cols = append(cols, createCol("buffer_pool_instance", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("pages_used", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("pages_free", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("relocation_ops", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("relocation_time", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) infSchema["INNODB_CMPMEM_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("DOC_ID", 265)) + cols = append(cols, createCol("DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_FT_BEING_DELETED"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("KEY", 6165)) - cols = append(cols, createCol("VALUE", 6165)) + cols = append(cols, createCol("KEY", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("VALUE", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) infSchema["INNODB_FT_CONFIG"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("value", 6165)) + cols = append(cols, createCol("value", 6165, "utf8mb3_general_ci", "", 18, 0, true, "")) infSchema["INNODB_FT_DEFAULT_STOPWORD"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("DOC_ID", 265)) + cols = append(cols, createCol("DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_FT_DELETED"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("WORD", 6165)) - cols = append(cols, createCol("FIRST_DOC_ID", 265)) - cols = append(cols, createCol("LAST_DOC_ID", 265)) - cols = append(cols, createCol("DOC_COUNT", 265)) - cols = append(cols, createCol("DOC_ID", 265)) - cols = append(cols, createCol("POSITION", 265)) + cols = append(cols, createCol("WORD", 6165, "utf8mb3_general_ci", "", 337, 0, true, "")) + cols = append(cols, createCol("FIRST_DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("LAST_DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DOC_COUNT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("POSITION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_FT_INDEX_CACHE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("WORD", 6165)) - cols = append(cols, createCol("FIRST_DOC_ID", 265)) - cols = append(cols, createCol("LAST_DOC_ID", 265)) - cols = append(cols, createCol("DOC_COUNT", 265)) - cols = append(cols, createCol("DOC_ID", 265)) - cols = append(cols, createCol("POSITION", 265)) + cols = append(cols, createCol("WORD", 6165, "utf8mb3_general_ci", "", 337, 0, true, "")) + cols = append(cols, createCol("FIRST_DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("LAST_DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DOC_COUNT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DOC_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("POSITION", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) infSchema["INNODB_FT_INDEX_TABLE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("requesting_trx_id", 6165)) - cols = append(cols, createCol("requested_lock_id", 6165)) - cols = append(cols, createCol("blocking_trx_id", 6165)) - cols = append(cols, createCol("blocking_lock_id", 6165)) - infSchema["INNODB_LOCK_WAITS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("lock_id", 6165)) - cols = append(cols, createCol("lock_trx_id", 6165)) - cols = append(cols, createCol("lock_mode", 6165)) - cols = append(cols, createCol("lock_type", 6165)) - cols = append(cols, createCol("lock_table", 6165)) - cols = append(cols, createCol("lock_index", 6165)) - cols = append(cols, createCol("lock_space", 265)) - cols = append(cols, createCol("lock_page", 265)) - cols = append(cols, createCol("lock_rec", 265)) - cols = append(cols, createCol("lock_data", 6165)) - infSchema["INNODB_LOCKS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("SUBSYSTEM", 6165)) - cols = append(cols, createCol("COUNT", 265)) - cols = append(cols, createCol("MAX_COUNT", 265)) - cols = append(cols, createCol("MIN_COUNT", 265)) - cols = append(cols, createCol("AVG_COUNT", 1036)) - cols = append(cols, createCol("COUNT_RESET", 265)) - cols = append(cols, createCol("MAX_COUNT_RESET", 265)) - cols = append(cols, createCol("MIN_COUNT_RESET", 265)) - cols = append(cols, createCol("AVG_COUNT_RESET", 1036)) - cols = append(cols, createCol("TIME_ENABLED", 2064)) - cols = append(cols, createCol("TIME_DISABLED", 2064)) - cols = append(cols, createCol("TIME_ELAPSED", 265)) - cols = append(cols, createCol("TIME_RESET", 2064)) - cols = append(cols, createCol("STATUS", 6165)) - cols = append(cols, createCol("TYPE", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("SUBSYSTEM", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("COUNT", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("MAX_COUNT", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MIN_COUNT", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AVG_COUNT", 1036, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("COUNT_RESET", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("MAX_COUNT_RESET", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MIN_COUNT_RESET", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AVG_COUNT_RESET", 1036, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_ENABLED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_DISABLED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_ELAPSED", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("TIME_RESET", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("STATUS", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("TYPE", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) infSchema["INNODB_METRICS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("POS", 265)) - cols = append(cols, createCol("MTYPE", 263)) - cols = append(cols, createCol("PRTYPE", 263)) - cols = append(cols, createCol("LEN", 263)) - infSchema["INNODB_SYS_COLUMNS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("PATH", 6165)) - infSchema["INNODB_SYS_DATAFILES"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("INDEX_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("POS", 263)) - infSchema["INNODB_SYS_FIELDS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 6165)) - cols = append(cols, createCol("FOR_NAME", 6165)) - cols = append(cols, createCol("REF_NAME", 6165)) - cols = append(cols, createCol("N_COLS", 263)) - cols = append(cols, createCol("TYPE", 263)) - infSchema["INNODB_SYS_FOREIGN"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 6165)) - cols = append(cols, createCol("FOR_COL_NAME", 6165)) - cols = append(cols, createCol("REF_COL_NAME", 6165)) - cols = append(cols, createCol("POS", 263)) - infSchema["INNODB_SYS_FOREIGN_COLS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("INDEX_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("TYPE", 263)) - cols = append(cols, createCol("N_FIELDS", 263)) - cols = append(cols, createCol("PAGE_NO", 263)) - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("MERGE_THRESHOLD", 263)) - infSchema["INNODB_SYS_INDEXES"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("FLAG", 263)) - cols = append(cols, createCol("N_COLS", 263)) - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("FILE_FORMAT", 6165)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("ZIP_PAGE_SIZE", 263)) - cols = append(cols, createCol("SPACE_TYPE", 6165)) - infSchema["INNODB_SYS_TABLES"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("FLAG", 263)) - cols = append(cols, createCol("FILE_FORMAT", 6165)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("PAGE_SIZE", 263)) - cols = append(cols, createCol("ZIP_PAGE_SIZE", 263)) - cols = append(cols, createCol("SPACE_TYPE", 6165)) - cols = append(cols, createCol("FS_BLOCK_SIZE", 263)) - cols = append(cols, createCol("FILE_SIZE", 265)) - cols = append(cols, createCol("ALLOCATED_SIZE", 265)) - infSchema["INNODB_SYS_TABLESPACES"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("STATS_INITIALIZED", 6165)) - cols = append(cols, createCol("NUM_ROWS", 265)) - cols = append(cols, createCol("CLUST_INDEX_SIZE", 265)) - cols = append(cols, createCol("OTHER_INDEX_SIZE", 265)) - cols = append(cols, createCol("MODIFIED_COUNTER", 265)) - cols = append(cols, createCol("AUTOINC", 265)) - cols = append(cols, createCol("REF_COUNT", 263)) - infSchema["INNODB_SYS_TABLESTATS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("POS", 263)) - cols = append(cols, createCol("BASE_POS", 263)) - infSchema["INNODB_SYS_VIRTUAL"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 265)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("N_COLS", 263)) - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("PER_TABLE_TABLESPACE", 6165)) - cols = append(cols, createCol("IS_COMPRESSED", 6165)) + cols = append(cols, createCol("TABLE_ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 202, 0, false, "")) + cols = append(cols, createCol("N_COLS", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("SPACE", 263, "utf8mb3_general_ci", "0", 11, 0, true, "")) + cols = append(cols, createCol("PER_TABLE_TABLESPACE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IS_COMPRESSED", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) infSchema["INNODB_TEMP_TABLE_INFO"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("trx_id", 6165)) - cols = append(cols, createCol("trx_state", 6165)) - cols = append(cols, createCol("trx_started", 2064)) - cols = append(cols, createCol("trx_requested_lock_id", 6165)) - cols = append(cols, createCol("trx_wait_started", 2064)) - cols = append(cols, createCol("trx_weight", 265)) - cols = append(cols, createCol("trx_mysql_thread_id", 265)) - cols = append(cols, createCol("trx_query", 6165)) - cols = append(cols, createCol("trx_operation_state", 6165)) - cols = append(cols, createCol("trx_tables_in_use", 265)) - cols = append(cols, createCol("trx_tables_locked", 265)) - cols = append(cols, createCol("trx_lock_structs", 265)) - cols = append(cols, createCol("trx_lock_memory_bytes", 265)) - cols = append(cols, createCol("trx_rows_locked", 265)) - cols = append(cols, createCol("trx_rows_modified", 265)) - cols = append(cols, createCol("trx_concurrency_tickets", 265)) - cols = append(cols, createCol("trx_isolation_level", 6165)) - cols = append(cols, createCol("trx_unique_checks", 263)) - cols = append(cols, createCol("trx_foreign_key_checks", 263)) - cols = append(cols, createCol("trx_last_foreign_key_error", 6165)) - cols = append(cols, createCol("trx_adaptive_hash_latched", 263)) - cols = append(cols, createCol("trx_adaptive_hash_timeout", 265)) - cols = append(cols, createCol("trx_is_read_only", 263)) - cols = append(cols, createCol("trx_autocommit_non_locking", 263)) + cols = append(cols, createCol("trx_id", 6165, "utf8mb3_general_ci", "", 18, 0, true, "")) + cols = append(cols, createCol("trx_state", 6165, "utf8mb3_general_ci", "", 13, 0, true, "")) + cols = append(cols, createCol("trx_started", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_requested_lock_id", 6165, "utf8mb3_general_ci", "", 81, 0, false, "")) + cols = append(cols, createCol("trx_wait_started", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("trx_weight", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_mysql_thread_id", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_query", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("trx_operation_state", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("trx_tables_in_use", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_tables_locked", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_lock_structs", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_lock_memory_bytes", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_rows_locked", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_rows_modified", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_concurrency_tickets", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_isolation_level", 6165, "utf8mb3_general_ci", "", 16, 0, true, "")) + cols = append(cols, createCol("trx_unique_checks", 263, "utf8mb3_general_ci", "0", 1, 0, true, "")) + cols = append(cols, createCol("trx_foreign_key_checks", 263, "utf8mb3_general_ci", "0", 1, 0, true, "")) + cols = append(cols, createCol("trx_last_foreign_key_error", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("trx_adaptive_hash_latched", 263, "utf8mb3_general_ci", "0", 1, 0, true, "")) + cols = append(cols, createCol("trx_adaptive_hash_timeout", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("trx_is_read_only", 263, "utf8mb3_general_ci", "0", 1, 0, true, "")) + cols = append(cols, createCol("trx_autocommit_non_locking", 263, "utf8mb3_general_ci", "0", 1, 0, true, "")) infSchema["INNODB_TRX"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 265)) - cols = append(cols, createCol("POSITION_IN_UNIQUE_CONSTRAINT", 265)) - cols = append(cols, createCol("REFERENCED_TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165)) - cols = append(cols, createCol("REFERENCED_COLUMN_NAME", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 265, "utf8mb3_general_ci", "0", 10, 0, true, "")) + cols = append(cols, createCol("POSITION_IN_UNIQUE_CONSTRAINT", 265, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("REFERENCED_TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("REFERENCED_COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) infSchema["KEY_COLUMN_USAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("QUERY", 6163)) - cols = append(cols, createCol("TRACE", 6163)) - cols = append(cols, createCol("MISSING_BYTES_BEYOND_MAX_MEM_SIZE", 263)) - cols = append(cols, createCol("INSUFFICIENT_PRIVILEGES", 257)) + cols = append(cols, createCol("QUERY", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TRACE", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MISSING_BYTES_BEYOND_MAX_MEM_SIZE", 263, "utf8mb3_general_ci", "0", 20, 0, true, "")) + cols = append(cols, createCol("INSUFFICIENT_PRIVILEGES", 257, "utf8mb3_general_ci", "0", 1, 0, true, "")) infSchema["OPTIMIZER_TRACE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPECIFIC_CATALOG", 6165)) - cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165)) - cols = append(cols, createCol("SPECIFIC_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 263)) - cols = append(cols, createCol("PARAMETER_MODE", 6165)) - cols = append(cols, createCol("PARAMETER_NAME", 6165)) - cols = append(cols, createCol("DATA_TYPE", 6165)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 263)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 263)) - cols = append(cols, createCol("NUMERIC_PRECISION", 265)) - cols = append(cols, createCol("NUMERIC_SCALE", 263)) - cols = append(cols, createCol("DATETIME_PRECISION", 265)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("DTD_IDENTIFIER", 6163)) - cols = append(cols, createCol("ROUTINE_TYPE", 6165)) + cols = append(cols, createCol("SPECIFIC_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SPECIFIC_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 263, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("PARAMETER_MODE", 6165, "utf8mb3_general_ci", "", 5, 0, false, "")) + cols = append(cols, createCol("PARAMETER_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DATA_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DTD_IDENTIFIER", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ROUTINE_TYPE", 6165, "utf8mb3_general_ci", "", 9, 0, true, "")) infSchema["PARAMETERS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("PARTITION_NAME", 6165)) - cols = append(cols, createCol("SUBPARTITION_NAME", 6165)) - cols = append(cols, createCol("PARTITION_ORDINAL_POSITION", 265)) - cols = append(cols, createCol("SUBPARTITION_ORDINAL_POSITION", 265)) - cols = append(cols, createCol("PARTITION_METHOD", 6165)) - cols = append(cols, createCol("SUBPARTITION_METHOD", 6165)) - cols = append(cols, createCol("PARTITION_EXPRESSION", 6163)) - cols = append(cols, createCol("SUBPARTITION_EXPRESSION", 6163)) - cols = append(cols, createCol("PARTITION_DESCRIPTION", 6163)) - cols = append(cols, createCol("TABLE_ROWS", 265)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 265)) - cols = append(cols, createCol("DATA_LENGTH", 265)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 265)) - cols = append(cols, createCol("INDEX_LENGTH", 265)) - cols = append(cols, createCol("DATA_FREE", 265)) - cols = append(cols, createCol("CREATE_TIME", 2064)) - cols = append(cols, createCol("UPDATE_TIME", 2064)) - cols = append(cols, createCol("CHECK_TIME", 2064)) - cols = append(cols, createCol("CHECKSUM", 265)) - cols = append(cols, createCol("PARTITION_COMMENT", 6165)) - cols = append(cols, createCol("NODEGROUP", 6165)) - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PARTITION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PARTITION_ORDINAL_POSITION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_ORDINAL_POSITION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("PARTITION_METHOD", 6165, "utf8mb3_general_ci", "", 18, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_METHOD", 6165, "utf8mb3_general_ci", "", 12, 0, false, "")) + cols = append(cols, createCol("PARTITION_EXPRESSION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_EXPRESSION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PARTITION_DESCRIPTION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLE_ROWS", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DATA_LENGTH", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("DATA_FREE", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("CREATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("PARTITION_COMMENT", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("NODEGROUP", 6165, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) infSchema["PARTITIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("PLUGIN_NAME", 6165)) - cols = append(cols, createCol("PLUGIN_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_STATUS", 6165)) - cols = append(cols, createCol("PLUGIN_TYPE", 6165)) - cols = append(cols, createCol("PLUGIN_TYPE_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_LIBRARY", 6165)) - cols = append(cols, createCol("PLUGIN_LIBRARY_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_AUTHOR", 6165)) - cols = append(cols, createCol("PLUGIN_DESCRIPTION", 6163)) - cols = append(cols, createCol("PLUGIN_LICENSE", 6165)) - cols = append(cols, createCol("LOAD_OPTION", 6165)) + cols = append(cols, createCol("PLUGIN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PLUGIN_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("PLUGIN_STATUS", 6165, "utf8mb3_general_ci", "", 10, 0, true, "")) + cols = append(cols, createCol("PLUGIN_TYPE", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("PLUGIN_TYPE_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("PLUGIN_LIBRARY", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PLUGIN_LIBRARY_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("PLUGIN_AUTHOR", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PLUGIN_DESCRIPTION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PLUGIN_LICENSE", 6165, "utf8mb3_general_ci", "", 80, 0, false, "")) + cols = append(cols, createCol("LOAD_OPTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["PLUGINS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 265)) - cols = append(cols, createCol("USER", 6165)) - cols = append(cols, createCol("HOST", 6165)) - cols = append(cols, createCol("DB", 6165)) - cols = append(cols, createCol("COMMAND", 6165)) - cols = append(cols, createCol("TIME", 263)) - cols = append(cols, createCol("STATE", 6165)) - cols = append(cols, createCol("INFO", 6163)) + cols = append(cols, createCol("ID", 265, "utf8mb3_general_ci", "0", 21, 0, true, "")) + cols = append(cols, createCol("USER", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("HOST", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DB", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COMMAND", 6165, "utf8mb3_general_ci", "", 16, 0, true, "")) + cols = append(cols, createCol("TIME", 263, "utf8mb3_general_ci", "0", 7, 0, true, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("INFO", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["PROCESSLIST"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("QUERY_ID", 263)) - cols = append(cols, createCol("SEQ", 263)) - cols = append(cols, createCol("STATE", 6165)) - cols = append(cols, createCol("DURATION", 18)) - cols = append(cols, createCol("CPU_USER", 18)) - cols = append(cols, createCol("CPU_SYSTEM", 18)) - cols = append(cols, createCol("CONTEXT_VOLUNTARY", 263)) - cols = append(cols, createCol("CONTEXT_INVOLUNTARY", 263)) - cols = append(cols, createCol("BLOCK_OPS_IN", 263)) - cols = append(cols, createCol("BLOCK_OPS_OUT", 263)) - cols = append(cols, createCol("MESSAGES_SENT", 263)) - cols = append(cols, createCol("MESSAGES_RECEIVED", 263)) - cols = append(cols, createCol("PAGE_FAULTS_MAJOR", 263)) - cols = append(cols, createCol("PAGE_FAULTS_MINOR", 263)) - cols = append(cols, createCol("SWAPS", 263)) - cols = append(cols, createCol("SOURCE_FUNCTION", 6165)) - cols = append(cols, createCol("SOURCE_FILE", 6165)) - cols = append(cols, createCol("SOURCE_LINE", 263)) + cols = append(cols, createCol("QUERY_ID", 263, "utf8mb3_general_ci", "0", 20, 0, true, "")) + cols = append(cols, createCol("SEQ", 263, "utf8mb3_general_ci", "0", 20, 0, true, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 30, 0, true, "")) + cols = append(cols, createCol("DURATION", 18, "utf8mb3_general_ci", "0.000000", 9, 6, true, "")) + cols = append(cols, createCol("CPU_USER", 18, "utf8mb3_general_ci", "", 9, 6, false, "")) + cols = append(cols, createCol("CPU_SYSTEM", 18, "utf8mb3_general_ci", "", 9, 6, false, "")) + cols = append(cols, createCol("CONTEXT_VOLUNTARY", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("CONTEXT_INVOLUNTARY", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("BLOCK_OPS_IN", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("BLOCK_OPS_OUT", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("MESSAGES_SENT", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("MESSAGES_RECEIVED", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("PAGE_FAULTS_MAJOR", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("PAGE_FAULTS_MINOR", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("SWAPS", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("SOURCE_FUNCTION", 6165, "utf8mb3_general_ci", "", 30, 0, false, "")) + cols = append(cols, createCol("SOURCE_FILE", 6165, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("SOURCE_LINE", 263, "utf8mb3_general_ci", "", 20, 0, false, "")) infSchema["PROFILING"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("MATCH_OPTION", 6165)) - cols = append(cols, createCol("UPDATE_RULE", 6165)) - cols = append(cols, createCol("DELETE_RULE", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("MATCH_OPTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("UPDATE_RULE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DELETE_RULE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["REFERENTIAL_CONSTRAINTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPECIFIC_NAME", 6165)) - cols = append(cols, createCol("ROUTINE_CATALOG", 6165)) - cols = append(cols, createCol("ROUTINE_SCHEMA", 6165)) - cols = append(cols, createCol("ROUTINE_NAME", 6165)) - cols = append(cols, createCol("ROUTINE_TYPE", 6165)) - cols = append(cols, createCol("DATA_TYPE", 6165)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 263)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 263)) - cols = append(cols, createCol("NUMERIC_PRECISION", 265)) - cols = append(cols, createCol("NUMERIC_SCALE", 263)) - cols = append(cols, createCol("DATETIME_PRECISION", 265)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("DTD_IDENTIFIER", 6163)) - cols = append(cols, createCol("ROUTINE_BODY", 6165)) - cols = append(cols, createCol("ROUTINE_DEFINITION", 6163)) - cols = append(cols, createCol("EXTERNAL_NAME", 6165)) - cols = append(cols, createCol("EXTERNAL_LANGUAGE", 6165)) - cols = append(cols, createCol("PARAMETER_STYLE", 6165)) - cols = append(cols, createCol("IS_DETERMINISTIC", 6165)) - cols = append(cols, createCol("SQL_DATA_ACCESS", 6165)) - cols = append(cols, createCol("SQL_PATH", 6165)) - cols = append(cols, createCol("SECURITY_TYPE", 6165)) - cols = append(cols, createCol("CREATED", 2064)) - cols = append(cols, createCol("LAST_ALTERED", 2064)) - cols = append(cols, createCol("SQL_MODE", 6165)) - cols = append(cols, createCol("ROUTINE_COMMENT", 6163)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("SPECIFIC_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("ROUTINE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_TYPE", 6165, "utf8mb3_general_ci", "", 9, 0, true, "")) + cols = append(cols, createCol("DATA_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 263, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DTD_IDENTIFIER", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ROUTINE_BODY", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("ROUTINE_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EXTERNAL_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EXTERNAL_LANGUAGE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PARAMETER_STYLE", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("IS_DETERMINISTIC", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("SQL_DATA_ACCESS", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SQL_PATH", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SECURITY_TYPE", 6165, "utf8mb3_general_ci", "", 7, 0, true, "")) + cols = append(cols, createCol("CREATED", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_ALTERED", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SQL_MODE", 6165, "utf8mb3_general_ci", "", 8192, 0, true, "")) + cols = append(cols, createCol("ROUTINE_COMMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 93, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) infSchema["ROUTINES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 81, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["SCHEMA_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CATALOG_NAME", 6165)) - cols = append(cols, createCol("SCHEMA_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_COLLATION_NAME", 6165)) - cols = append(cols, createCol("SQL_PATH", 6165)) + cols = append(cols, createCol("CATALOG_NAME", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("SCHEMA_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DEFAULT_CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DEFAULT_COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("SQL_PATH", 6165, "utf8mb3_general_ci", "", 512, 0, false, "")) infSchema["SCHEMATA"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("VARIABLE_NAME", 6165)) - cols = append(cols, createCol("VARIABLE_VALUE", 6165)) - infSchema["SESSION_STATUS"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("VARIABLE_NAME", 6165)) - cols = append(cols, createCol("VARIABLE_VALUE", 6165)) - infSchema["SESSION_VARIABLES"] = cols - cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("NON_UNIQUE", 265)) - cols = append(cols, createCol("INDEX_SCHEMA", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("SEQ_IN_INDEX", 265)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("COLLATION", 6165)) - cols = append(cols, createCol("CARDINALITY", 265)) - cols = append(cols, createCol("SUB_PART", 265)) - cols = append(cols, createCol("PACKED", 6165)) - cols = append(cols, createCol("NULLABLE", 6165)) - cols = append(cols, createCol("INDEX_TYPE", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) - cols = append(cols, createCol("INDEX_COMMENT", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("NON_UNIQUE", 265, "utf8mb3_general_ci", "0", 1, 0, true, "")) + cols = append(cols, createCol("INDEX_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SEQ_IN_INDEX", 265, "utf8mb3_general_ci", "0", 2, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLLATION", 6165, "utf8mb3_general_ci", "", 1, 0, false, "")) + cols = append(cols, createCol("CARDINALITY", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("SUB_PART", 265, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("PACKED", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("NULLABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("INDEX_TYPE", 6165, "utf8mb3_general_ci", "", 16, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 16, 0, false, "")) + cols = append(cols, createCol("INDEX_COMMENT", 6165, "utf8mb3_general_ci", "", 1024, 0, true, "")) infSchema["STATISTICS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("CONSTRAINT_TYPE", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["TABLE_CONSTRAINTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 81, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["TABLE_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("TABLE_TYPE", 6165)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("VERSION", 265)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("TABLE_ROWS", 265)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 265)) - cols = append(cols, createCol("DATA_LENGTH", 265)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 265)) - cols = append(cols, createCol("INDEX_LENGTH", 265)) - cols = append(cols, createCol("DATA_FREE", 265)) - cols = append(cols, createCol("AUTO_INCREMENT", 265)) - cols = append(cols, createCol("CREATE_TIME", 2064)) - cols = append(cols, createCol("UPDATE_TIME", 2064)) - cols = append(cols, createCol("CHECK_TIME", 2064)) - cols = append(cols, createCol("TABLE_COLLATION", 6165)) - cols = append(cols, createCol("CHECKSUM", 265)) - cols = append(cols, createCol("CREATE_OPTIONS", 6165)) - cols = append(cols, createCol("TABLE_COMMENT", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("VERSION", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("ROW_FORMAT", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("TABLE_ROWS", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATA_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("DATA_FREE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AUTO_INCREMENT", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CREATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLE_COLLATION", 6165, "utf8mb3_general_ci", "", 32, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("CREATE_OPTIONS", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("TABLE_COMMENT", 6165, "utf8mb3_general_ci", "", 2048, 0, true, "")) infSchema["TABLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("TABLESPACE_TYPE", 6165)) - cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165)) - cols = append(cols, createCol("EXTENT_SIZE", 265)) - cols = append(cols, createCol("AUTOEXTEND_SIZE", 265)) - cols = append(cols, createCol("MAXIMUM_SIZE", 265)) - cols = append(cols, createCol("NODEGROUP_ID", 265)) - cols = append(cols, createCol("TABLESPACE_COMMENT", 6165)) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLESPACE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EXTENT_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("AUTOEXTEND_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("MAXIMUM_SIZE", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("NODEGROUP_ID", 265, "utf8mb3_general_ci", "", 21, 0, false, "")) + cols = append(cols, createCol("TABLESPACE_COMMENT", 6165, "utf8mb3_general_ci", "", 2048, 0, false, "")) infSchema["TABLESPACES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TRIGGER_CATALOG", 6165)) - cols = append(cols, createCol("TRIGGER_SCHEMA", 6165)) - cols = append(cols, createCol("TRIGGER_NAME", 6165)) - cols = append(cols, createCol("EVENT_MANIPULATION", 6165)) - cols = append(cols, createCol("EVENT_OBJECT_CATALOG", 6165)) - cols = append(cols, createCol("EVENT_OBJECT_SCHEMA", 6165)) - cols = append(cols, createCol("EVENT_OBJECT_TABLE", 6165)) - cols = append(cols, createCol("ACTION_ORDER", 265)) - cols = append(cols, createCol("ACTION_CONDITION", 6163)) - cols = append(cols, createCol("ACTION_STATEMENT", 6163)) - cols = append(cols, createCol("ACTION_ORIENTATION", 6165)) - cols = append(cols, createCol("ACTION_TIMING", 6165)) - cols = append(cols, createCol("ACTION_REFERENCE_OLD_TABLE", 6165)) - cols = append(cols, createCol("ACTION_REFERENCE_NEW_TABLE", 6165)) - cols = append(cols, createCol("ACTION_REFERENCE_OLD_ROW", 6165)) - cols = append(cols, createCol("ACTION_REFERENCE_NEW_ROW", 6165)) - cols = append(cols, createCol("CREATED", 2064)) - cols = append(cols, createCol("SQL_MODE", 6165)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("TRIGGER_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TRIGGER_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TRIGGER_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_MANIPULATION", 6165, "utf8mb3_general_ci", "", 6, 0, true, "")) + cols = append(cols, createCol("EVENT_OBJECT_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("EVENT_OBJECT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_OBJECT_TABLE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ACTION_ORDER", 265, "utf8mb3_general_ci", "0", 4, 0, true, "")) + cols = append(cols, createCol("ACTION_CONDITION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ACTION_STATEMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ACTION_ORIENTATION", 6165, "utf8mb3_general_ci", "", 9, 0, true, "")) + cols = append(cols, createCol("ACTION_TIMING", 6165, "utf8mb3_general_ci", "", 6, 0, true, "")) + cols = append(cols, createCol("ACTION_REFERENCE_OLD_TABLE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ACTION_REFERENCE_NEW_TABLE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ACTION_REFERENCE_OLD_ROW", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("ACTION_REFERENCE_NEW_ROW", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("CREATED", 2064, "utf8mb3_general_ci", "", 2, 0, false, "")) + cols = append(cols, createCol("SQL_MODE", 6165, "utf8mb3_general_ci", "", 8192, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 93, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) infSchema["TRIGGERS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 81, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["USER_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("VIEW_DEFINITION", 6163)) - cols = append(cols, createCol("CHECK_OPTION", 6165)) - cols = append(cols, createCol("IS_UPDATABLE", 6165)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("SECURITY_TYPE", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("VIEW_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("CHECK_OPTION", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("IS_UPDATABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 93, 0, true, "")) + cols = append(cols, createCol("SECURITY_TYPE", 6165, "utf8mb3_general_ci", "", 7, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) infSchema["VIEWS"] = cols - return infSchema } @@ -774,896 +697,896 @@ func getInfoSchema57() map[string][]vindexes.Column { func getInfoSchema80() map[string][]vindexes.Column { infSchema := map[string][]vindexes.Column{} var cols []vindexes.Column - cols = append(cols, createCol("USER", 6165)) - cols = append(cols, createCol("HOST", 6165)) - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("GRANTEE_HOST", 6165)) - cols = append(cols, createCol("ROLE_NAME", 6165)) - cols = append(cols, createCol("ROLE_HOST", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) - cols = append(cols, createCol("IS_DEFAULT", 6165)) - cols = append(cols, createCol("IS_MANDATORY", 6165)) + cols = append(cols, createCol("USER", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("GRANTEE_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("ROLE_NAME", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("ROLE_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("IS_DEFAULT", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("IS_MANDATORY", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["ADMINISTRABLE_ROLE_AUTHORIZATIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("USER", 6165)) - cols = append(cols, createCol("HOST", 6165)) - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("GRANTEE_HOST", 6165)) - cols = append(cols, createCol("ROLE_NAME", 6165)) - cols = append(cols, createCol("ROLE_HOST", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) - cols = append(cols, createCol("IS_DEFAULT", 6165)) - cols = append(cols, createCol("IS_MANDATORY", 6165)) + cols = append(cols, createCol("USER", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("GRANTEE_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("ROLE_NAME", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("ROLE_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("IS_DEFAULT", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("IS_MANDATORY", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["APPLICABLE_ROLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_COLLATE_NAME", 6165)) - cols = append(cols, createCol("DESCRIPTION", 6165)) - cols = append(cols, createCol("MAXLEN", 776)) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DEFAULT_COLLATE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DESCRIPTION", 6165, "utf8mb3_general_ci", "", 2048, 0, true, "")) + cols = append(cols, createCol("MAXLEN", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["CHARACTER_SETS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("CHECK_CLAUSE", 6163)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHECK_CLAUSE", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["CHECK_CONSTRAINTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["COLLATION_CHARACTER_SET_APPLICABILITY"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("ID", 778)) - cols = append(cols, createCol("IS_DEFAULT", 6165)) - cols = append(cols, createCol("IS_COMPILED", 6165)) - cols = append(cols, createCol("SORTLEN", 776)) - cols = append(cols, createCol("PAD_ATTRIBUTE", 2074)) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ID", 778, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("IS_DEFAULT", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("IS_COMPILED", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("SORTLEN", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAD_ATTRIBUTE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'PAD SPACE','NO PAD'")) infSchema["COLLATIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 292, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["COLUMN_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SCHEMA_NAME", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("HISTOGRAM", 2078)) + cols = append(cols, createCol("SCHEMA_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("HISTOGRAM", 2078, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["COLUMN_STATISTICS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 776)) - cols = append(cols, createCol("COLUMN_DEFAULT", 6163)) - cols = append(cols, createCol("IS_NULLABLE", 6165)) - cols = append(cols, createCol("DATA_TYPE", 6163)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265)) - cols = append(cols, createCol("NUMERIC_PRECISION", 778)) - cols = append(cols, createCol("NUMERIC_SCALE", 778)) - cols = append(cols, createCol("DATETIME_PRECISION", 776)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("COLUMN_TYPE", 6163)) - cols = append(cols, createCol("COLUMN_KEY", 2074)) - cols = append(cols, createCol("EXTRA", 6165)) - cols = append(cols, createCol("PRIVILEGES", 6165)) - cols = append(cols, createCol("COLUMN_COMMENT", 6163)) - cols = append(cols, createCol("GENERATION_EXPRESSION", 6163)) - cols = append(cols, createCol("SRS_ID", 776)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COLUMN_DEFAULT", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("IS_NULLABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("DATA_TYPE", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLUMN_TYPE", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COLUMN_KEY", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'','PRI','UNI','MUL'")) + cols = append(cols, createCol("EXTRA", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("PRIVILEGES", 6165, "utf8mb3_general_ci", "", 154, 0, false, "")) + cols = append(cols, createCol("COLUMN_COMMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("GENERATION_EXPRESSION", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SRS_ID", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["COLUMNS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078)) - cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["COLUMNS_EXTENSIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ROLE_NAME", 6165)) - cols = append(cols, createCol("ROLE_HOST", 6165)) - cols = append(cols, createCol("IS_DEFAULT", 6165)) - cols = append(cols, createCol("IS_MANDATORY", 6165)) + cols = append(cols, createCol("ROLE_NAME", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("ROLE_HOST", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("IS_DEFAULT", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("IS_MANDATORY", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["ENABLED_ROLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("SUPPORT", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) - cols = append(cols, createCol("TRANSACTIONS", 6165)) - cols = append(cols, createCol("XA", 6165)) - cols = append(cols, createCol("SAVEPOINTS", 6165)) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SUPPORT", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("TRANSACTIONS", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("XA", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("SAVEPOINTS", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) infSchema["ENGINES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("EVENT_CATALOG", 6165)) - cols = append(cols, createCol("EVENT_SCHEMA", 6165)) - cols = append(cols, createCol("EVENT_NAME", 6165)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("TIME_ZONE", 6165)) - cols = append(cols, createCol("EVENT_BODY", 6165)) - cols = append(cols, createCol("EVENT_DEFINITION", 6163)) - cols = append(cols, createCol("EVENT_TYPE", 6165)) - cols = append(cols, createCol("EXECUTE_AT", 2064)) - cols = append(cols, createCol("INTERVAL_VALUE", 6165)) - cols = append(cols, createCol("INTERVAL_FIELD", 2074)) - cols = append(cols, createCol("SQL_MODE", 2075)) - cols = append(cols, createCol("STARTS", 2064)) - cols = append(cols, createCol("ENDS", 2064)) - cols = append(cols, createCol("STATUS", 2074)) - cols = append(cols, createCol("ON_COMPLETION", 6165)) - cols = append(cols, createCol("CREATED", 2061)) - cols = append(cols, createCol("LAST_ALTERED", 2061)) - cols = append(cols, createCol("LAST_EXECUTED", 2064)) - cols = append(cols, createCol("EVENT_COMMENT", 6165)) - cols = append(cols, createCol("ORIGINATOR", 776)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("EVENT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EVENT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EVENT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 288, 0, true, "")) + cols = append(cols, createCol("TIME_ZONE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_BODY", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("EVENT_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("EVENT_TYPE", 6165, "utf8mb3_general_ci", "", 9, 0, true, "")) + cols = append(cols, createCol("EXECUTE_AT", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INTERVAL_VALUE", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("INTERVAL_FIELD", 2074, "utf8mb3_general_ci", "", 0, 0, false, "'YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND'")) + cols = append(cols, createCol("SQL_MODE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','NOT_USED_9','NOT_USED_10','NOT_USED_11','NOT_USED_12','NOT_USED_13','NOT_USED_14','NOT_USED_15','NOT_USED_16','NOT_USED_17','NOT_USED_18','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','ALLOW_INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NOT_USED_29','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','TIME_TRUNCATE_FRACTIONAL'")) + cols = append(cols, createCol("STARTS", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ENDS", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("STATUS", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'ENABLED','DISABLED','SLAVESIDE_DISABLED'")) + cols = append(cols, createCol("ON_COMPLETION", 6165, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("CREATED", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_ALTERED", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_EXECUTED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EVENT_COMMENT", 6165, "utf8mb3_general_ci", "", 2048, 0, true, "")) + cols = append(cols, createCol("ORIGINATOR", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["EVENTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("FILE_ID", 265)) - cols = append(cols, createCol("FILE_NAME", 6163)) - cols = append(cols, createCol("FILE_TYPE", 6165)) - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6167)) - cols = append(cols, createCol("TABLE_SCHEMA", 10264)) - cols = append(cols, createCol("TABLE_NAME", 10264)) - cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165)) - cols = append(cols, createCol("LOGFILE_GROUP_NUMBER", 265)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("FULLTEXT_KEYS", 10264)) - cols = append(cols, createCol("DELETED_ROWS", 10264)) - cols = append(cols, createCol("UPDATE_COUNT", 10264)) - cols = append(cols, createCol("FREE_EXTENTS", 265)) - cols = append(cols, createCol("TOTAL_EXTENTS", 265)) - cols = append(cols, createCol("EXTENT_SIZE", 265)) - cols = append(cols, createCol("INITIAL_SIZE", 265)) - cols = append(cols, createCol("MAXIMUM_SIZE", 265)) - cols = append(cols, createCol("AUTOEXTEND_SIZE", 265)) - cols = append(cols, createCol("CREATION_TIME", 10264)) - cols = append(cols, createCol("LAST_UPDATE_TIME", 10264)) - cols = append(cols, createCol("LAST_ACCESS_TIME", 10264)) - cols = append(cols, createCol("RECOVER_TIME", 10264)) - cols = append(cols, createCol("TRANSACTION_COUNTER", 10264)) - cols = append(cols, createCol("VERSION", 265)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("TABLE_ROWS", 10264)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 10264)) - cols = append(cols, createCol("DATA_LENGTH", 10264)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 10264)) - cols = append(cols, createCol("INDEX_LENGTH", 10264)) - cols = append(cols, createCol("DATA_FREE", 265)) - cols = append(cols, createCol("CREATE_TIME", 10264)) - cols = append(cols, createCol("UPDATE_TIME", 10264)) - cols = append(cols, createCol("CHECK_TIME", 10264)) - cols = append(cols, createCol("CHECKSUM", 10264)) - cols = append(cols, createCol("STATUS", 6165)) - cols = append(cols, createCol("EXTRA", 6165)) + cols = append(cols, createCol("FILE_ID", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("FILE_NAME", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("FILE_TYPE", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 268, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6167, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NUMBER", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("FULLTEXT_KEYS", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DELETED_ROWS", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("UPDATE_COUNT", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("FREE_EXTENTS", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TOTAL_EXTENTS", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EXTENT_SIZE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INITIAL_SIZE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MAXIMUM_SIZE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AUTOEXTEND_SIZE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CREATION_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("LAST_UPDATE_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("LAST_ACCESS_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("RECOVER_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TRANSACTION_COUNTER", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("VERSION", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ROW_FORMAT", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("TABLE_ROWS", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_LENGTH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_FREE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CREATE_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("UPDATE_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("STATUS", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("EXTRA", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) infSchema["FILES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 778)) - cols = append(cols, createCol("BLOCK_ID", 778)) - cols = append(cols, createCol("SPACE", 778)) - cols = append(cols, createCol("PAGE_NUMBER", 778)) - cols = append(cols, createCol("PAGE_TYPE", 6165)) - cols = append(cols, createCol("FLUSH_TYPE", 778)) - cols = append(cols, createCol("FIX_COUNT", 778)) - cols = append(cols, createCol("IS_HASHED", 6165)) - cols = append(cols, createCol("NEWEST_MODIFICATION", 778)) - cols = append(cols, createCol("OLDEST_MODIFICATION", 778)) - cols = append(cols, createCol("ACCESS_TIME", 778)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("NUMBER_RECORDS", 778)) - cols = append(cols, createCol("DATA_SIZE", 778)) - cols = append(cols, createCol("COMPRESSED_SIZE", 778)) - cols = append(cols, createCol("PAGE_STATE", 6165)) - cols = append(cols, createCol("IO_FIX", 6165)) - cols = append(cols, createCol("IS_OLD", 6165)) - cols = append(cols, createCol("FREE_PAGE_CLOCK", 778)) - cols = append(cols, createCol("IS_STALE", 6165)) + cols = append(cols, createCol("POOL_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("BLOCK_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_NUMBER", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("FLUSH_TYPE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("FIX_COUNT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("IS_HASHED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("NEWEST_MODIFICATION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("OLDEST_MODIFICATION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ACCESS_TIME", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("NUMBER_RECORDS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DATA_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COMPRESSED_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_STATE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IO_FIX", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IS_OLD", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("FREE_PAGE_CLOCK", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("IS_STALE", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) infSchema["INNODB_BUFFER_PAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 778)) - cols = append(cols, createCol("LRU_POSITION", 778)) - cols = append(cols, createCol("SPACE", 778)) - cols = append(cols, createCol("PAGE_NUMBER", 778)) - cols = append(cols, createCol("PAGE_TYPE", 6165)) - cols = append(cols, createCol("FLUSH_TYPE", 778)) - cols = append(cols, createCol("FIX_COUNT", 778)) - cols = append(cols, createCol("IS_HASHED", 6165)) - cols = append(cols, createCol("NEWEST_MODIFICATION", 778)) - cols = append(cols, createCol("OLDEST_MODIFICATION", 778)) - cols = append(cols, createCol("ACCESS_TIME", 778)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("NUMBER_RECORDS", 778)) - cols = append(cols, createCol("DATA_SIZE", 778)) - cols = append(cols, createCol("COMPRESSED_SIZE", 778)) - cols = append(cols, createCol("COMPRESSED", 6165)) - cols = append(cols, createCol("IO_FIX", 6165)) - cols = append(cols, createCol("IS_OLD", 6165)) - cols = append(cols, createCol("FREE_PAGE_CLOCK", 778)) + cols = append(cols, createCol("POOL_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LRU_POSITION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_NUMBER", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("FLUSH_TYPE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("FIX_COUNT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("IS_HASHED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("NEWEST_MODIFICATION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("OLDEST_MODIFICATION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ACCESS_TIME", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("NUMBER_RECORDS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DATA_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COMPRESSED_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COMPRESSED", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("IO_FIX", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("IS_OLD", 6165, "utf8mb3_general_ci", "", 3, 0, false, "")) + cols = append(cols, createCol("FREE_PAGE_CLOCK", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_BUFFER_PAGE_LRU"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("POOL_ID", 778)) - cols = append(cols, createCol("POOL_SIZE", 778)) - cols = append(cols, createCol("FREE_BUFFERS", 778)) - cols = append(cols, createCol("DATABASE_PAGES", 778)) - cols = append(cols, createCol("OLD_DATABASE_PAGES", 778)) - cols = append(cols, createCol("MODIFIED_DATABASE_PAGES", 778)) - cols = append(cols, createCol("PENDING_DECOMPRESS", 778)) - cols = append(cols, createCol("PENDING_READS", 778)) - cols = append(cols, createCol("PENDING_FLUSH_LRU", 778)) - cols = append(cols, createCol("PENDING_FLUSH_LIST", 778)) - cols = append(cols, createCol("PAGES_MADE_YOUNG", 778)) - cols = append(cols, createCol("PAGES_NOT_MADE_YOUNG", 778)) - cols = append(cols, createCol("PAGES_MADE_YOUNG_RATE", 1035)) - cols = append(cols, createCol("PAGES_MADE_NOT_YOUNG_RATE", 1035)) - cols = append(cols, createCol("NUMBER_PAGES_READ", 778)) - cols = append(cols, createCol("NUMBER_PAGES_CREATED", 778)) - cols = append(cols, createCol("NUMBER_PAGES_WRITTEN", 778)) - cols = append(cols, createCol("PAGES_READ_RATE", 1035)) - cols = append(cols, createCol("PAGES_CREATE_RATE", 1035)) - cols = append(cols, createCol("PAGES_WRITTEN_RATE", 1035)) - cols = append(cols, createCol("NUMBER_PAGES_GET", 778)) - cols = append(cols, createCol("HIT_RATE", 778)) - cols = append(cols, createCol("YOUNG_MAKE_PER_THOUSAND_GETS", 778)) - cols = append(cols, createCol("NOT_YOUNG_MAKE_PER_THOUSAND_GETS", 778)) - cols = append(cols, createCol("NUMBER_PAGES_READ_AHEAD", 778)) - cols = append(cols, createCol("NUMBER_READ_AHEAD_EVICTED", 778)) - cols = append(cols, createCol("READ_AHEAD_RATE", 1035)) - cols = append(cols, createCol("READ_AHEAD_EVICTED_RATE", 1035)) - cols = append(cols, createCol("LRU_IO_TOTAL", 778)) - cols = append(cols, createCol("LRU_IO_CURRENT", 778)) - cols = append(cols, createCol("UNCOMPRESS_TOTAL", 778)) - cols = append(cols, createCol("UNCOMPRESS_CURRENT", 778)) + cols = append(cols, createCol("POOL_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("POOL_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("FREE_BUFFERS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DATABASE_PAGES", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("OLD_DATABASE_PAGES", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MODIFIED_DATABASE_PAGES", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PENDING_DECOMPRESS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PENDING_READS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PENDING_FLUSH_LRU", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PENDING_FLUSH_LIST", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_YOUNG", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_NOT_MADE_YOUNG", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_YOUNG_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("PAGES_MADE_NOT_YOUNG_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_READ", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_CREATED", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_WRITTEN", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGES_READ_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("PAGES_CREATE_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("PAGES_WRITTEN_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_GET", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("HIT_RATE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("YOUNG_MAKE_PER_THOUSAND_GETS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NOT_YOUNG_MAKE_PER_THOUSAND_GETS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_PAGES_READ_AHEAD", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NUMBER_READ_AHEAD_EVICTED", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("READ_AHEAD_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("READ_AHEAD_EVICTED_RATE", 1035, "utf8mb3_general_ci", "", 12, 0, true, "")) + cols = append(cols, createCol("LRU_IO_TOTAL", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LRU_IO_CURRENT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("UNCOMPRESS_TOTAL", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("UNCOMPRESS_CURRENT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_BUFFER_POOL_STATS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE_ID", 776)) - cols = append(cols, createCol("INDEX_ID", 778)) - cols = append(cols, createCol("N_CACHED_PAGES", 778)) + cols = append(cols, createCol("SPACE_ID", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("INDEX_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("N_CACHED_PAGES", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CACHED_INDEXES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMP"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("database_name", 6165)) - cols = append(cols, createCol("table_name", 6165)) - cols = append(cols, createCol("index_name", 6165)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("database_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("table_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("index_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMP_PER_INDEX"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("database_name", 6165)) - cols = append(cols, createCol("table_name", 6165)) - cols = append(cols, createCol("index_name", 6165)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("database_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("table_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("index_name", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMP_PER_INDEX_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("compress_ops", 263)) - cols = append(cols, createCol("compress_ops_ok", 263)) - cols = append(cols, createCol("compress_time", 263)) - cols = append(cols, createCol("uncompress_ops", 263)) - cols = append(cols, createCol("uncompress_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_ops_ok", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("compress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_ops", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("uncompress_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMP_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("buffer_pool_instance", 263)) - cols = append(cols, createCol("pages_used", 263)) - cols = append(cols, createCol("pages_free", 263)) - cols = append(cols, createCol("relocation_ops", 265)) - cols = append(cols, createCol("relocation_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("buffer_pool_instance", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("pages_used", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("pages_free", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("relocation_ops", 265, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("relocation_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMPMEM"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("page_size", 263)) - cols = append(cols, createCol("buffer_pool_instance", 263)) - cols = append(cols, createCol("pages_used", 263)) - cols = append(cols, createCol("pages_free", 263)) - cols = append(cols, createCol("relocation_ops", 265)) - cols = append(cols, createCol("relocation_time", 263)) + cols = append(cols, createCol("page_size", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("buffer_pool_instance", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("pages_used", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("pages_free", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("relocation_ops", 265, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("relocation_time", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_CMPMEM_RESET"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("POS", 778)) - cols = append(cols, createCol("MTYPE", 263)) - cols = append(cols, createCol("PRTYPE", 263)) - cols = append(cols, createCol("LEN", 263)) - cols = append(cols, createCol("HAS_DEFAULT", 263)) - cols = append(cols, createCol("DEFAULT_VALUE", 6163)) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("POS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MTYPE", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PRTYPE", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LEN", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("HAS_DEFAULT", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DEFAULT_VALUE", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["INNODB_COLUMNS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE", 10262)) - cols = append(cols, createCol("PATH", 6165)) + cols = append(cols, createCol("SPACE", 10262, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("PATH", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) infSchema["INNODB_DATAFILES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("INDEX_ID", 10262)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("POS", 778)) + cols = append(cols, createCol("INDEX_ID", 10262, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("POS", 778, "utf8mb3_general_ci", "0", 0, 0, true, "")) infSchema["INNODB_FIELDS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 6165)) - cols = append(cols, createCol("FOR_NAME", 6165)) - cols = append(cols, createCol("REF_NAME", 6165)) - cols = append(cols, createCol("N_COLS", 265)) - cols = append(cols, createCol("TYPE", 778)) + cols = append(cols, createCol("ID", 6165, "utf8mb3_general_ci", "", 129, 0, false, "")) + cols = append(cols, createCol("FOR_NAME", 6165, "utf8mb3_general_ci", "", 129, 0, false, "")) + cols = append(cols, createCol("REF_NAME", 6165, "utf8mb3_general_ci", "", 129, 0, false, "")) + cols = append(cols, createCol("N_COLS", 265, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("TYPE", 778, "utf8mb3_general_ci", "0", 0, 0, true, "")) infSchema["INNODB_FOREIGN"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 6165)) - cols = append(cols, createCol("FOR_COL_NAME", 6165)) - cols = append(cols, createCol("REF_COL_NAME", 6165)) - cols = append(cols, createCol("POS", 776)) + cols = append(cols, createCol("ID", 6165, "utf8mb3_general_ci", "", 129, 0, false, "")) + cols = append(cols, createCol("FOR_COL_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("REF_COL_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("POS", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_FOREIGN_COLS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("DOC_ID", 778)) + cols = append(cols, createCol("DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_FT_BEING_DELETED"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("KEY", 6165)) - cols = append(cols, createCol("VALUE", 6165)) + cols = append(cols, createCol("KEY", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("VALUE", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) infSchema["INNODB_FT_CONFIG"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("value", 6165)) + cols = append(cols, createCol("value", 6165, "utf8mb3_general_ci", "", 18, 0, true, "")) infSchema["INNODB_FT_DEFAULT_STOPWORD"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("DOC_ID", 778)) + cols = append(cols, createCol("DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_FT_DELETED"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("WORD", 6165)) - cols = append(cols, createCol("FIRST_DOC_ID", 778)) - cols = append(cols, createCol("LAST_DOC_ID", 778)) - cols = append(cols, createCol("DOC_COUNT", 778)) - cols = append(cols, createCol("DOC_ID", 778)) - cols = append(cols, createCol("POSITION", 778)) + cols = append(cols, createCol("WORD", 6165, "utf8mb3_general_ci", "", 337, 0, true, "")) + cols = append(cols, createCol("FIRST_DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DOC_COUNT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("POSITION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_FT_INDEX_CACHE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("WORD", 6165)) - cols = append(cols, createCol("FIRST_DOC_ID", 778)) - cols = append(cols, createCol("LAST_DOC_ID", 778)) - cols = append(cols, createCol("DOC_COUNT", 778)) - cols = append(cols, createCol("DOC_ID", 778)) - cols = append(cols, createCol("POSITION", 778)) + cols = append(cols, createCol("WORD", 6165, "utf8mb3_general_ci", "", 337, 0, true, "")) + cols = append(cols, createCol("FIRST_DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DOC_COUNT", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DOC_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("POSITION", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_FT_INDEX_TABLE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("INDEX_ID", 778)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("TYPE", 263)) - cols = append(cols, createCol("N_FIELDS", 263)) - cols = append(cols, createCol("PAGE_NO", 263)) - cols = append(cols, createCol("SPACE", 263)) - cols = append(cols, createCol("MERGE_THRESHOLD", 263)) + cols = append(cols, createCol("INDEX_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TYPE", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("N_FIELDS", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PAGE_NO", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MERGE_THRESHOLD", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_INDEXES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("SUBSYSTEM", 6165)) - cols = append(cols, createCol("COUNT", 265)) - cols = append(cols, createCol("MAX_COUNT", 265)) - cols = append(cols, createCol("MIN_COUNT", 265)) - cols = append(cols, createCol("AVG_COUNT", 1035)) - cols = append(cols, createCol("COUNT_RESET", 265)) - cols = append(cols, createCol("MAX_COUNT_RESET", 265)) - cols = append(cols, createCol("MIN_COUNT_RESET", 265)) - cols = append(cols, createCol("AVG_COUNT_RESET", 1035)) - cols = append(cols, createCol("TIME_ENABLED", 2064)) - cols = append(cols, createCol("TIME_DISABLED", 2064)) - cols = append(cols, createCol("TIME_ELAPSED", 265)) - cols = append(cols, createCol("TIME_RESET", 2064)) - cols = append(cols, createCol("STATUS", 6165)) - cols = append(cols, createCol("TYPE", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("SUBSYSTEM", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("COUNT", 265, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MAX_COUNT", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MIN_COUNT", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AVG_COUNT", 1035, "utf8mb3_general_ci", "", 12, 0, false, "")) + cols = append(cols, createCol("COUNT_RESET", 265, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MAX_COUNT_RESET", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MIN_COUNT_RESET", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AVG_COUNT_RESET", 1035, "utf8mb3_general_ci", "", 12, 0, false, "")) + cols = append(cols, createCol("TIME_ENABLED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_DISABLED", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_ELAPSED", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TIME_RESET", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("STATUS", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("TYPE", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) infSchema["INNODB_METRICS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 776)) - cols = append(cols, createCol("SPACE", 776)) - cols = append(cols, createCol("PATH", 6165)) - cols = append(cols, createCol("SIZE", 778)) - cols = append(cols, createCol("STATE", 6165)) - cols = append(cols, createCol("PURPOSE", 6165)) + cols = append(cols, createCol("ID", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("PATH", 6165, "utf8mb3_general_ci", "", 4001, 0, true, "")) + cols = append(cols, createCol("SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) + cols = append(cols, createCol("PURPOSE", 6165, "utf8mb3_general_ci", "", 192, 0, true, "")) infSchema["INNODB_SESSION_TEMP_TABLESPACES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("FLAG", 263)) - cols = append(cols, createCol("N_COLS", 263)) - cols = append(cols, createCol("SPACE", 265)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("ZIP_PAGE_SIZE", 776)) - cols = append(cols, createCol("SPACE_TYPE", 6165)) - cols = append(cols, createCol("INSTANT_COLS", 263)) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 655, 0, true, "")) + cols = append(cols, createCol("FLAG", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("N_COLS", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 265, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ROW_FORMAT", 6165, "utf8mb3_general_ci", "", 12, 0, false, "")) + cols = append(cols, createCol("ZIP_PAGE_SIZE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE_TYPE", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("INSTANT_COLS", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("TOTAL_ROW_VERSIONS", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_TABLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE", 776)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("FLAG", 776)) - cols = append(cols, createCol("ROW_FORMAT", 6165)) - cols = append(cols, createCol("PAGE_SIZE", 776)) - cols = append(cols, createCol("ZIP_PAGE_SIZE", 776)) - cols = append(cols, createCol("SPACE_TYPE", 6165)) - cols = append(cols, createCol("FS_BLOCK_SIZE", 776)) - cols = append(cols, createCol("FILE_SIZE", 778)) - cols = append(cols, createCol("ALLOCATED_SIZE", 778)) - cols = append(cols, createCol("AUTOEXTEND_SIZE", 778)) - cols = append(cols, createCol("SERVER_VERSION", 6165)) - cols = append(cols, createCol("SPACE_VERSION", 776)) - cols = append(cols, createCol("ENCRYPTION", 6165)) - cols = append(cols, createCol("STATE", 6165)) + cols = append(cols, createCol("SPACE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 655, 0, true, "")) + cols = append(cols, createCol("FLAG", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ROW_FORMAT", 6165, "utf8mb3_general_ci", "", 22, 0, false, "")) + cols = append(cols, createCol("PAGE_SIZE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ZIP_PAGE_SIZE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE_TYPE", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("FS_BLOCK_SIZE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("FILE_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ALLOCATED_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("AUTOEXTEND_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SERVER_VERSION", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) + cols = append(cols, createCol("SPACE_VERSION", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ENCRYPTION", 6165, "utf8mb3_general_ci", "", 1, 0, false, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 10, 0, false, "")) infSchema["INNODB_TABLESPACES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPACE", 10262)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("PATH", 6165)) - cols = append(cols, createCol("FLAG", 10262)) - cols = append(cols, createCol("SPACE_TYPE", 6165)) + cols = append(cols, createCol("SPACE", 10262, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 268, 0, true, "")) + cols = append(cols, createCol("PATH", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("FLAG", 10262, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("SPACE_TYPE", 6165, "utf8mb3_general_ci", "", 7, 0, true, "")) infSchema["INNODB_TABLESPACES_BRIEF"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("STATS_INITIALIZED", 6165)) - cols = append(cols, createCol("NUM_ROWS", 778)) - cols = append(cols, createCol("CLUST_INDEX_SIZE", 778)) - cols = append(cols, createCol("OTHER_INDEX_SIZE", 778)) - cols = append(cols, createCol("MODIFIED_COUNTER", 778)) - cols = append(cols, createCol("AUTOINC", 778)) - cols = append(cols, createCol("REF_COUNT", 263)) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("STATS_INITIALIZED", 6165, "utf8mb3_general_ci", "", 193, 0, true, "")) + cols = append(cols, createCol("NUM_ROWS", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("CLUST_INDEX_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("OTHER_INDEX_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("MODIFIED_COUNTER", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("AUTOINC", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("REF_COUNT", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_TABLESTATS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("NAME", 6165)) - cols = append(cols, createCol("N_COLS", 776)) - cols = append(cols, createCol("SPACE", 776)) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("N_COLS", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SPACE", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_TEMP_TABLE_INFO"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("trx_id", 778)) - cols = append(cols, createCol("trx_state", 6165)) - cols = append(cols, createCol("trx_started", 2064)) - cols = append(cols, createCol("trx_requested_lock_id", 6165)) - cols = append(cols, createCol("trx_wait_started", 2064)) - cols = append(cols, createCol("trx_weight", 778)) - cols = append(cols, createCol("trx_mysql_thread_id", 778)) - cols = append(cols, createCol("trx_query", 6165)) - cols = append(cols, createCol("trx_operation_state", 6165)) - cols = append(cols, createCol("trx_tables_in_use", 778)) - cols = append(cols, createCol("trx_tables_locked", 778)) - cols = append(cols, createCol("trx_lock_structs", 778)) - cols = append(cols, createCol("trx_lock_memory_bytes", 778)) - cols = append(cols, createCol("trx_rows_locked", 778)) - cols = append(cols, createCol("trx_rows_modified", 778)) - cols = append(cols, createCol("trx_concurrency_tickets", 778)) - cols = append(cols, createCol("trx_isolation_level", 6165)) - cols = append(cols, createCol("trx_unique_checks", 263)) - cols = append(cols, createCol("trx_foreign_key_checks", 263)) - cols = append(cols, createCol("trx_last_foreign_key_error", 6165)) - cols = append(cols, createCol("trx_adaptive_hash_latched", 263)) - cols = append(cols, createCol("trx_adaptive_hash_timeout", 778)) - cols = append(cols, createCol("trx_is_read_only", 263)) - cols = append(cols, createCol("trx_autocommit_non_locking", 263)) - cols = append(cols, createCol("trx_schedule_weight", 778)) + cols = append(cols, createCol("trx_id", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_state", 6165, "utf8mb3_general_ci", "", 13, 0, true, "")) + cols = append(cols, createCol("trx_started", 2064, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_requested_lock_id", 6165, "utf8mb3_general_ci", "", 105, 0, false, "")) + cols = append(cols, createCol("trx_wait_started", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("trx_weight", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_mysql_thread_id", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_query", 6165, "utf8mb3_general_ci", "", 1024, 0, false, "")) + cols = append(cols, createCol("trx_operation_state", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("trx_tables_in_use", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_tables_locked", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_lock_structs", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_lock_memory_bytes", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_rows_locked", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_rows_modified", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_concurrency_tickets", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_isolation_level", 6165, "utf8mb3_general_ci", "", 16, 0, true, "")) + cols = append(cols, createCol("trx_unique_checks", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_foreign_key_checks", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_last_foreign_key_error", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("trx_adaptive_hash_latched", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_adaptive_hash_timeout", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_is_read_only", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_autocommit_non_locking", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("trx_schedule_weight", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["INNODB_TRX"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_ID", 778)) - cols = append(cols, createCol("POS", 776)) - cols = append(cols, createCol("BASE_POS", 776)) + cols = append(cols, createCol("TABLE_ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("POS", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("BASE_POS", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["INNODB_VIRTUAL"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 776)) - cols = append(cols, createCol("POSITION_IN_UNIQUE_CONSTRAINT", 776)) - cols = append(cols, createCol("REFERENCED_TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165)) - cols = append(cols, createCol("REFERENCED_COLUMN_NAME", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 776, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("POSITION_IN_UNIQUE_CONSTRAINT", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("REFERENCED_TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("REFERENCED_COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) infSchema["KEY_COLUMN_USAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("WORD", 6165)) - cols = append(cols, createCol("RESERVED", 263)) + cols = append(cols, createCol("WORD", 6165, "utf8mb3_general_ci", "", 128, 0, false, "")) + cols = append(cols, createCol("RESERVED", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["KEYWORDS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("QUERY", 6165)) - cols = append(cols, createCol("TRACE", 6165)) - cols = append(cols, createCol("MISSING_BYTES_BEYOND_MAX_MEM_SIZE", 263)) - cols = append(cols, createCol("INSUFFICIENT_PRIVILEGES", 257)) + cols = append(cols, createCol("QUERY", 6165, "utf8mb3_general_ci", "", 65535, 0, true, "")) + cols = append(cols, createCol("TRACE", 6165, "utf8mb3_general_ci", "", 65535, 0, true, "")) + cols = append(cols, createCol("MISSING_BYTES_BEYOND_MAX_MEM_SIZE", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("INSUFFICIENT_PRIVILEGES", 257, "utf8mb3_general_ci", "", 1, 0, true, "")) infSchema["OPTIMIZER_TRACE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPECIFIC_CATALOG", 6165)) - cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165)) - cols = append(cols, createCol("SPECIFIC_NAME", 6165)) - cols = append(cols, createCol("ORDINAL_POSITION", 778)) - cols = append(cols, createCol("PARAMETER_MODE", 6165)) - cols = append(cols, createCol("PARAMETER_NAME", 6165)) - cols = append(cols, createCol("DATA_TYPE", 6163)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265)) - cols = append(cols, createCol("NUMERIC_PRECISION", 776)) - cols = append(cols, createCol("NUMERIC_SCALE", 265)) - cols = append(cols, createCol("DATETIME_PRECISION", 776)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("DTD_IDENTIFIER", 6163)) - cols = append(cols, createCol("ROUTINE_TYPE", 2074)) + cols = append(cols, createCol("SPECIFIC_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SPECIFIC_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ORDINAL_POSITION", 778, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("PARAMETER_MODE", 6165, "utf8mb3_general_ci", "", 5, 0, false, "")) + cols = append(cols, createCol("PARAMETER_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DATA_TYPE", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DTD_IDENTIFIER", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ROUTINE_TYPE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'FUNCTION','PROCEDURE'")) infSchema["PARAMETERS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("PARTITION_NAME", 6165)) - cols = append(cols, createCol("SUBPARTITION_NAME", 6165)) - cols = append(cols, createCol("PARTITION_ORDINAL_POSITION", 776)) - cols = append(cols, createCol("SUBPARTITION_ORDINAL_POSITION", 776)) - cols = append(cols, createCol("PARTITION_METHOD", 6165)) - cols = append(cols, createCol("SUBPARTITION_METHOD", 6165)) - cols = append(cols, createCol("PARTITION_EXPRESSION", 6165)) - cols = append(cols, createCol("SUBPARTITION_EXPRESSION", 6165)) - cols = append(cols, createCol("PARTITION_DESCRIPTION", 6163)) - cols = append(cols, createCol("TABLE_ROWS", 778)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 778)) - cols = append(cols, createCol("DATA_LENGTH", 778)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 778)) - cols = append(cols, createCol("INDEX_LENGTH", 778)) - cols = append(cols, createCol("DATA_FREE", 778)) - cols = append(cols, createCol("CREATE_TIME", 2061)) - cols = append(cols, createCol("UPDATE_TIME", 2064)) - cols = append(cols, createCol("CHECK_TIME", 2064)) - cols = append(cols, createCol("CHECKSUM", 265)) - cols = append(cols, createCol("PARTITION_COMMENT", 6163)) - cols = append(cols, createCol("NODEGROUP", 6165)) - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PARTITION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PARTITION_ORDINAL_POSITION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_ORDINAL_POSITION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PARTITION_METHOD", 6165, "utf8mb3_general_ci", "", 13, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_METHOD", 6165, "utf8mb3_general_ci", "", 13, 0, false, "")) + cols = append(cols, createCol("PARTITION_EXPRESSION", 6165, "utf8mb3_general_ci", "", 2048, 0, false, "")) + cols = append(cols, createCol("SUBPARTITION_EXPRESSION", 6165, "utf8mb3_general_ci", "", 2048, 0, false, "")) + cols = append(cols, createCol("PARTITION_DESCRIPTION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLE_ROWS", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_FREE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CREATE_TIME", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PARTITION_COMMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("NODEGROUP", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 268, 0, false, "")) infSchema["PARTITIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("PLUGIN_NAME", 6165)) - cols = append(cols, createCol("PLUGIN_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_STATUS", 6165)) - cols = append(cols, createCol("PLUGIN_TYPE", 6165)) - cols = append(cols, createCol("PLUGIN_TYPE_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_LIBRARY", 6165)) - cols = append(cols, createCol("PLUGIN_LIBRARY_VERSION", 6165)) - cols = append(cols, createCol("PLUGIN_AUTHOR", 6165)) - cols = append(cols, createCol("PLUGIN_DESCRIPTION", 6165)) - cols = append(cols, createCol("PLUGIN_LICENSE", 6165)) - cols = append(cols, createCol("LOAD_OPTION", 6165)) + cols = append(cols, createCol("PLUGIN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PLUGIN_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("PLUGIN_STATUS", 6165, "utf8mb3_general_ci", "", 10, 0, true, "")) + cols = append(cols, createCol("PLUGIN_TYPE", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("PLUGIN_TYPE_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, true, "")) + cols = append(cols, createCol("PLUGIN_LIBRARY", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PLUGIN_LIBRARY_VERSION", 6165, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("PLUGIN_AUTHOR", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("PLUGIN_DESCRIPTION", 6165, "utf8mb3_general_ci", "", 65535, 0, false, "")) + cols = append(cols, createCol("PLUGIN_LICENSE", 6165, "utf8mb3_general_ci", "", 80, 0, false, "")) + cols = append(cols, createCol("LOAD_OPTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["PLUGINS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("ID", 778)) - cols = append(cols, createCol("USER", 6165)) - cols = append(cols, createCol("HOST", 6165)) - cols = append(cols, createCol("DB", 6165)) - cols = append(cols, createCol("COMMAND", 6165)) - cols = append(cols, createCol("TIME", 263)) - cols = append(cols, createCol("STATE", 6165)) - cols = append(cols, createCol("INFO", 6165)) + cols = append(cols, createCol("ID", 778, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("USER", 6165, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("HOST", 6165, "utf8mb3_general_ci", "", 261, 0, true, "")) + cols = append(cols, createCol("DB", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COMMAND", 6165, "utf8mb3_general_ci", "", 16, 0, true, "")) + cols = append(cols, createCol("TIME", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("INFO", 6165, "utf8mb3_general_ci", "", 65535, 0, false, "")) infSchema["PROCESSLIST"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("QUERY_ID", 263)) - cols = append(cols, createCol("SEQ", 263)) - cols = append(cols, createCol("STATE", 6165)) - cols = append(cols, createCol("DURATION", 18)) - cols = append(cols, createCol("CPU_USER", 18)) - cols = append(cols, createCol("CPU_SYSTEM", 18)) - cols = append(cols, createCol("CONTEXT_VOLUNTARY", 263)) - cols = append(cols, createCol("CONTEXT_INVOLUNTARY", 263)) - cols = append(cols, createCol("BLOCK_OPS_IN", 263)) - cols = append(cols, createCol("BLOCK_OPS_OUT", 263)) - cols = append(cols, createCol("MESSAGES_SENT", 263)) - cols = append(cols, createCol("MESSAGES_RECEIVED", 263)) - cols = append(cols, createCol("PAGE_FAULTS_MAJOR", 263)) - cols = append(cols, createCol("PAGE_FAULTS_MINOR", 263)) - cols = append(cols, createCol("SWAPS", 263)) - cols = append(cols, createCol("SOURCE_FUNCTION", 6165)) - cols = append(cols, createCol("SOURCE_FILE", 6165)) - cols = append(cols, createCol("SOURCE_LINE", 263)) + cols = append(cols, createCol("QUERY_ID", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SEQ", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("STATE", 6165, "utf8mb3_general_ci", "", 30, 0, true, "")) + cols = append(cols, createCol("DURATION", 18, "utf8mb3_general_ci", "", 905, 0, true, "")) + cols = append(cols, createCol("CPU_USER", 18, "utf8mb3_general_ci", "", 905, 0, false, "")) + cols = append(cols, createCol("CPU_SYSTEM", 18, "utf8mb3_general_ci", "", 905, 0, false, "")) + cols = append(cols, createCol("CONTEXT_VOLUNTARY", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CONTEXT_INVOLUNTARY", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("BLOCK_OPS_IN", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("BLOCK_OPS_OUT", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MESSAGES_SENT", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MESSAGES_RECEIVED", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PAGE_FAULTS_MAJOR", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PAGE_FAULTS_MINOR", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SWAPS", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SOURCE_FUNCTION", 6165, "utf8mb3_general_ci", "", 30, 0, false, "")) + cols = append(cols, createCol("SOURCE_FILE", 6165, "utf8mb3_general_ci", "", 20, 0, false, "")) + cols = append(cols, createCol("SOURCE_LINE", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["PROFILING"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("UNIQUE_CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("MATCH_OPTION", 2074)) - cols = append(cols, createCol("UPDATE_RULE", 2074)) - cols = append(cols, createCol("DELETE_RULE", 2074)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("UNIQUE_CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("MATCH_OPTION", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'NONE','PARTIAL','FULL'")) + cols = append(cols, createCol("UPDATE_RULE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'NO ACTION','RESTRICT','CASCADE','SET NULL','SET DEFAULT'")) + cols = append(cols, createCol("DELETE_RULE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'NO ACTION','RESTRICT','CASCADE','SET NULL','SET DEFAULT'")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("REFERENCED_TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["REFERENTIAL_CONSTRAINTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("RESOURCE_GROUP_NAME", 6165)) - cols = append(cols, createCol("RESOURCE_GROUP_TYPE", 2074)) - cols = append(cols, createCol("RESOURCE_GROUP_ENABLED", 257)) - cols = append(cols, createCol("VCPU_IDS", 10260)) - cols = append(cols, createCol("THREAD_PRIORITY", 263)) + cols = append(cols, createCol("RESOURCE_GROUP_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("RESOURCE_GROUP_TYPE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'SYSTEM','USER'")) + cols = append(cols, createCol("RESOURCE_GROUP_ENABLED", 257, "utf8mb3_general_ci", "", 1, 0, true, "")) + cols = append(cols, createCol("VCPU_IDS", 10260, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("THREAD_PRIORITY", 263, "utf8mb3_general_ci", "", 0, 0, true, "")) infSchema["RESOURCE_GROUPS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTOR", 6165)) - cols = append(cols, createCol("GRANTOR_HOST", 6165)) - cols = append(cols, createCol("GRANTEE", 6167)) - cols = append(cols, createCol("GRANTEE_HOST", 6167)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6167)) - cols = append(cols, createCol("TABLE_NAME", 6167)) - cols = append(cols, createCol("COLUMN_NAME", 6167)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 2075)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTOR", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("GRANTOR_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("GRANTEE", 6167, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("GRANTEE_HOST", 6167, "utf8mb3_general_ci", "", 255, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'Select','Insert','Update','References'")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["ROLE_COLUMN_GRANTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTOR", 6165)) - cols = append(cols, createCol("GRANTOR_HOST", 6165)) - cols = append(cols, createCol("GRANTEE", 6167)) - cols = append(cols, createCol("GRANTEE_HOST", 6167)) - cols = append(cols, createCol("SPECIFIC_CATALOG", 6165)) - cols = append(cols, createCol("SPECIFIC_SCHEMA", 6167)) - cols = append(cols, createCol("SPECIFIC_NAME", 6167)) - cols = append(cols, createCol("ROUTINE_CATALOG", 6165)) - cols = append(cols, createCol("ROUTINE_SCHEMA", 6167)) - cols = append(cols, createCol("ROUTINE_NAME", 6167)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 2075)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTOR", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("GRANTOR_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("GRANTEE", 6167, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("GRANTEE_HOST", 6167, "utf8mb3_general_ci", "", 255, 0, true, "")) + cols = append(cols, createCol("SPECIFIC_CATALOG", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("SPECIFIC_SCHEMA", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SPECIFIC_NAME", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_CATALOG", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("ROUTINE_SCHEMA", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_NAME", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'Execute','Alter Routine','Grant'")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["ROLE_ROUTINE_GRANTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTOR", 6165)) - cols = append(cols, createCol("GRANTOR_HOST", 6165)) - cols = append(cols, createCol("GRANTEE", 6167)) - cols = append(cols, createCol("GRANTEE_HOST", 6167)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6167)) - cols = append(cols, createCol("TABLE_NAME", 6167)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 2075)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTOR", 6165, "utf8mb3_general_ci", "", 97, 0, false, "")) + cols = append(cols, createCol("GRANTOR_HOST", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("GRANTEE", 6167, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("GRANTEE_HOST", 6167, "utf8mb3_general_ci", "", 255, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6167, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger'")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["ROLE_TABLE_GRANTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SPECIFIC_NAME", 6165)) - cols = append(cols, createCol("ROUTINE_CATALOG", 6165)) - cols = append(cols, createCol("ROUTINE_SCHEMA", 6165)) - cols = append(cols, createCol("ROUTINE_NAME", 6165)) - cols = append(cols, createCol("ROUTINE_TYPE", 2074)) - cols = append(cols, createCol("DATA_TYPE", 6163)) - cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265)) - cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265)) - cols = append(cols, createCol("NUMERIC_PRECISION", 776)) - cols = append(cols, createCol("NUMERIC_SCALE", 776)) - cols = append(cols, createCol("DATETIME_PRECISION", 776)) - cols = append(cols, createCol("CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("COLLATION_NAME", 6165)) - cols = append(cols, createCol("DTD_IDENTIFIER", 6163)) - cols = append(cols, createCol("ROUTINE_BODY", 6165)) - cols = append(cols, createCol("ROUTINE_DEFINITION", 6163)) - cols = append(cols, createCol("EXTERNAL_NAME", 10264)) - cols = append(cols, createCol("EXTERNAL_LANGUAGE", 6165)) - cols = append(cols, createCol("PARAMETER_STYLE", 6165)) - cols = append(cols, createCol("IS_DETERMINISTIC", 6165)) - cols = append(cols, createCol("SQL_DATA_ACCESS", 2074)) - cols = append(cols, createCol("SQL_PATH", 10264)) - cols = append(cols, createCol("SECURITY_TYPE", 2074)) - cols = append(cols, createCol("CREATED", 2061)) - cols = append(cols, createCol("LAST_ALTERED", 2061)) - cols = append(cols, createCol("SQL_MODE", 2075)) - cols = append(cols, createCol("ROUTINE_COMMENT", 6163)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("SPECIFIC_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ROUTINE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ROUTINE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ROUTINE_TYPE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'FUNCTION','PROCEDURE'")) + cols = append(cols, createCol("DATA_TYPE", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_MAXIMUM_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_OCTET_LENGTH", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_PRECISION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NUMERIC_SCALE", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATETIME_PRECISION", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DTD_IDENTIFIER", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ROUTINE_BODY", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("ROUTINE_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EXTERNAL_NAME", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("EXTERNAL_LANGUAGE", 6165, "utf8mb3_general_ci", "SQL", 64, 0, true, "")) + cols = append(cols, createCol("PARAMETER_STYLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("IS_DETERMINISTIC", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("SQL_DATA_ACCESS", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'CONTAINS SQL','NO SQL','READS SQL DATA','MODIFIES SQL DATA'")) + cols = append(cols, createCol("SQL_PATH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SECURITY_TYPE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'DEFAULT','INVOKER','DEFINER'")) + cols = append(cols, createCol("CREATED", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("LAST_ALTERED", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("SQL_MODE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','NOT_USED_9','NOT_USED_10','NOT_USED_11','NOT_USED_12','NOT_USED_13','NOT_USED_14','NOT_USED_15','NOT_USED_16','NOT_USED_17','NOT_USED_18','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','ALLOW_INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NOT_USED_29','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','TIME_TRUNCATE_FRACTIONAL'")) + cols = append(cols, createCol("ROUTINE_COMMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 288, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["ROUTINES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 292, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["SCHEMA_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CATALOG_NAME", 6165)) - cols = append(cols, createCol("SCHEMA_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_CHARACTER_SET_NAME", 6165)) - cols = append(cols, createCol("DEFAULT_COLLATION_NAME", 6165)) - cols = append(cols, createCol("SQL_PATH", 10264)) - cols = append(cols, createCol("DEFAULT_ENCRYPTION", 2074)) + cols = append(cols, createCol("CATALOG_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SCHEMA_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("DEFAULT_CHARACTER_SET_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DEFAULT_COLLATION_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("SQL_PATH", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DEFAULT_ENCRYPTION", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'NO','YES'")) infSchema["SCHEMATA"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CATALOG_NAME", 6165)) - cols = append(cols, createCol("SCHEMA_NAME", 6165)) - cols = append(cols, createCol("OPTIONS", 6165)) + cols = append(cols, createCol("CATALOG_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SCHEMA_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("OPTIONS", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) infSchema["SCHEMATA_EXTENSIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("SRS_NAME", 6165)) - cols = append(cols, createCol("SRS_ID", 776)) - cols = append(cols, createCol("GEOMETRY_TYPE_NAME", 6163)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SRS_NAME", 6165, "utf8mb3_general_ci", "", 80, 0, false, "")) + cols = append(cols, createCol("SRS_ID", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("GEOMETRY_TYPE_NAME", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["ST_GEOMETRY_COLUMNS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("SRS_NAME", 6165)) - cols = append(cols, createCol("SRS_ID", 776)) - cols = append(cols, createCol("ORGANIZATION", 6165)) - cols = append(cols, createCol("ORGANIZATION_COORDSYS_ID", 776)) - cols = append(cols, createCol("DEFINITION", 6165)) - cols = append(cols, createCol("DESCRIPTION", 6165)) + cols = append(cols, createCol("SRS_NAME", 6165, "utf8mb3_general_ci", "", 80, 0, true, "")) + cols = append(cols, createCol("SRS_ID", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ORGANIZATION", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("ORGANIZATION_COORDSYS_ID", 776, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DEFINITION", 6165, "utf8mb3_general_ci", "", 4096, 0, true, "")) + cols = append(cols, createCol("DESCRIPTION", 6165, "utf8mb3_general_ci", "", 2048, 0, false, "")) infSchema["ST_SPATIAL_REFERENCE_SYSTEMS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("UNIT_NAME", 6165)) - cols = append(cols, createCol("UNIT_TYPE", 6165)) - cols = append(cols, createCol("CONVERSION_FACTOR", 1036)) - cols = append(cols, createCol("DESCRIPTION", 6165)) + cols = append(cols, createCol("UNIT_NAME", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) + cols = append(cols, createCol("UNIT_TYPE", 6165, "utf8mb3_general_ci", "", 7, 0, false, "")) + cols = append(cols, createCol("CONVERSION_FACTOR", 1036, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DESCRIPTION", 6165, "utf8mb3_general_ci", "", 255, 0, false, "")) infSchema["ST_UNITS_OF_MEASURE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("NON_UNIQUE", 263)) - cols = append(cols, createCol("INDEX_SCHEMA", 6165)) - cols = append(cols, createCol("INDEX_NAME", 6165)) - cols = append(cols, createCol("SEQ_IN_INDEX", 776)) - cols = append(cols, createCol("COLUMN_NAME", 6165)) - cols = append(cols, createCol("COLLATION", 6165)) - cols = append(cols, createCol("CARDINALITY", 265)) - cols = append(cols, createCol("SUB_PART", 265)) - cols = append(cols, createCol("PACKED", 10264)) - cols = append(cols, createCol("NULLABLE", 6165)) - cols = append(cols, createCol("INDEX_TYPE", 6165)) - cols = append(cols, createCol("COMMENT", 6165)) - cols = append(cols, createCol("INDEX_COMMENT", 6165)) - cols = append(cols, createCol("IS_VISIBLE", 6165)) - cols = append(cols, createCol("EXPRESSION", 6163)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("NON_UNIQUE", 263, "utf8mb3_general_ci", "0", 0, 0, true, "")) + cols = append(cols, createCol("INDEX_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("INDEX_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SEQ_IN_INDEX", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("COLUMN_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("COLLATION", 6165, "utf8mb3_general_ci", "", 1, 0, false, "")) + cols = append(cols, createCol("CARDINALITY", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SUB_PART", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("PACKED", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NULLABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("INDEX_TYPE", 6165, "utf8mb3_general_ci", "", 11, 0, true, "")) + cols = append(cols, createCol("COMMENT", 6165, "utf8mb3_general_ci", "", 8, 0, true, "")) + cols = append(cols, createCol("INDEX_COMMENT", 6165, "utf8mb3_general_ci", "", 2048, 0, true, "")) + cols = append(cols, createCol("IS_VISIBLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("EXPRESSION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["STATISTICS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("CONSTRAINT_TYPE", 6165)) - cols = append(cols, createCol("ENFORCED", 6165)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CONSTRAINT_TYPE", 6165, "utf8mb3_general_ci", "", 11, 0, true, "")) + cols = append(cols, createCol("ENFORCED", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["TABLE_CONSTRAINTS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165)) - cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165)) - cols = append(cols, createCol("CONSTRAINT_NAME", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078)) - cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078)) + cols = append(cols, createCol("CONSTRAINT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("CONSTRAINT_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["TABLE_CONSTRAINTS_EXTENSIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 292, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["TABLE_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("TABLE_TYPE", 2074)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("VERSION", 263)) - cols = append(cols, createCol("ROW_FORMAT", 2074)) - cols = append(cols, createCol("TABLE_ROWS", 778)) - cols = append(cols, createCol("AVG_ROW_LENGTH", 778)) - cols = append(cols, createCol("DATA_LENGTH", 778)) - cols = append(cols, createCol("MAX_DATA_LENGTH", 778)) - cols = append(cols, createCol("INDEX_LENGTH", 778)) - cols = append(cols, createCol("DATA_FREE", 778)) - cols = append(cols, createCol("AUTO_INCREMENT", 778)) - cols = append(cols, createCol("CREATE_TIME", 2061)) - cols = append(cols, createCol("UPDATE_TIME", 2064)) - cols = append(cols, createCol("CHECK_TIME", 2064)) - cols = append(cols, createCol("TABLE_COLLATION", 6165)) - cols = append(cols, createCol("CHECKSUM", 265)) - cols = append(cols, createCol("CREATE_OPTIONS", 6165)) - cols = append(cols, createCol("TABLE_COMMENT", 6163)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_TYPE", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'BASE TABLE','VIEW','SYSTEM VIEW'")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("VERSION", 263, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ROW_FORMAT", 2074, "utf8mb3_general_ci", "", 0, 0, false, "'Fixed','Dynamic','Compressed','Redundant','Compact','Paged'")) + cols = append(cols, createCol("TABLE_ROWS", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AVG_ROW_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MAX_DATA_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("INDEX_LENGTH", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("DATA_FREE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AUTO_INCREMENT", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CREATE_TIME", 2061, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("UPDATE_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_TIME", 2064, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLE_COLLATION", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("CHECKSUM", 265, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CREATE_OPTIONS", 6165, "utf8mb3_general_ci", "", 256, 0, false, "")) + cols = append(cols, createCol("TABLE_COMMENT", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["TABLES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078)) - cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("SECONDARY_ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["TABLES_EXTENSIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) - cols = append(cols, createCol("ENGINE", 6165)) - cols = append(cols, createCol("TABLESPACE_TYPE", 6165)) - cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165)) - cols = append(cols, createCol("EXTENT_SIZE", 778)) - cols = append(cols, createCol("AUTOEXTEND_SIZE", 778)) - cols = append(cols, createCol("MAXIMUM_SIZE", 778)) - cols = append(cols, createCol("NODEGROUP_ID", 778)) - cols = append(cols, createCol("TABLESPACE_COMMENT", 6165)) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("ENGINE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("TABLESPACE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("LOGFILE_GROUP_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EXTENT_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("AUTOEXTEND_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("MAXIMUM_SIZE", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("NODEGROUP_ID", 778, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("TABLESPACE_COMMENT", 6165, "utf8mb3_general_ci", "", 2048, 0, false, "")) infSchema["TABLESPACES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLESPACE_NAME", 6165)) - cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078)) + cols = append(cols, createCol("TABLESPACE_NAME", 6165, "utf8mb3_general_ci", "", 268, 0, true, "")) + cols = append(cols, createCol("ENGINE_ATTRIBUTE", 2078, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["TABLESPACES_EXTENSIONS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TRIGGER_CATALOG", 6165)) - cols = append(cols, createCol("TRIGGER_SCHEMA", 6165)) - cols = append(cols, createCol("TRIGGER_NAME", 6165)) - cols = append(cols, createCol("EVENT_MANIPULATION", 2074)) - cols = append(cols, createCol("EVENT_OBJECT_CATALOG", 6165)) - cols = append(cols, createCol("EVENT_OBJECT_SCHEMA", 6165)) - cols = append(cols, createCol("EVENT_OBJECT_TABLE", 6165)) - cols = append(cols, createCol("ACTION_ORDER", 776)) - cols = append(cols, createCol("ACTION_CONDITION", 10264)) - cols = append(cols, createCol("ACTION_STATEMENT", 6163)) - cols = append(cols, createCol("ACTION_ORIENTATION", 6165)) - cols = append(cols, createCol("ACTION_TIMING", 2074)) - cols = append(cols, createCol("ACTION_REFERENCE_OLD_TABLE", 10264)) - cols = append(cols, createCol("ACTION_REFERENCE_NEW_TABLE", 10264)) - cols = append(cols, createCol("ACTION_REFERENCE_OLD_ROW", 6165)) - cols = append(cols, createCol("ACTION_REFERENCE_NEW_ROW", 6165)) - cols = append(cols, createCol("CREATED", 2061)) - cols = append(cols, createCol("SQL_MODE", 2075)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) - cols = append(cols, createCol("DATABASE_COLLATION", 6165)) + cols = append(cols, createCol("TRIGGER_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TRIGGER_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TRIGGER_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("EVENT_MANIPULATION", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'INSERT','UPDATE','DELETE'")) + cols = append(cols, createCol("EVENT_OBJECT_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EVENT_OBJECT_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("EVENT_OBJECT_TABLE", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("ACTION_ORDER", 776, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ACTION_CONDITION", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ACTION_STATEMENT", 6163, "utf8mb3_general_ci", "", 0, 0, true, "")) + cols = append(cols, createCol("ACTION_ORIENTATION", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("ACTION_TIMING", 2074, "utf8mb3_general_ci", "", 0, 0, true, "'BEFORE','AFTER'")) + cols = append(cols, createCol("ACTION_REFERENCE_OLD_TABLE", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ACTION_REFERENCE_NEW_TABLE", 10264, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("ACTION_REFERENCE_OLD_ROW", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("ACTION_REFERENCE_NEW_ROW", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) + cols = append(cols, createCol("CREATED", 2061, "utf8mb3_general_ci", "", 2, 0, true, "")) + cols = append(cols, createCol("SQL_MODE", 2075, "utf8mb3_general_ci", "", 0, 0, true, "'REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','NOT_USED_9','NOT_USED_10','NOT_USED_11','NOT_USED_12','NOT_USED_13','NOT_USED_14','NOT_USED_15','NOT_USED_16','NOT_USED_17','NOT_USED_18','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','ALLOW_INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NOT_USED_29','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','TIME_TRUNCATE_FRACTIONAL'")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 288, 0, true, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("DATABASE_COLLATION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["TRIGGERS"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("USER", 6167)) - cols = append(cols, createCol("HOST", 6167)) - cols = append(cols, createCol("ATTRIBUTE", 6163)) + cols = append(cols, createCol("USER", 6167, "utf8mb3_general_ci", "", 32, 0, true, "")) + cols = append(cols, createCol("HOST", 6167, "utf8mb3_general_ci", "", 255, 0, true, "")) + cols = append(cols, createCol("ATTRIBUTE", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) infSchema["USER_ATTRIBUTES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("GRANTEE", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("PRIVILEGE_TYPE", 6165)) - cols = append(cols, createCol("IS_GRANTABLE", 6165)) + cols = append(cols, createCol("GRANTEE", 6165, "utf8mb3_general_ci", "", 292, 0, true, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 512, 0, true, "")) + cols = append(cols, createCol("PRIVILEGE_TYPE", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("IS_GRANTABLE", 6165, "utf8mb3_general_ci", "", 3, 0, true, "")) infSchema["USER_PRIVILEGES"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("SPECIFIC_CATALOG", 6165)) - cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165)) - cols = append(cols, createCol("SPECIFIC_NAME", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SPECIFIC_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SPECIFIC_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("SPECIFIC_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["VIEW_ROUTINE_USAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("VIEW_CATALOG", 6165)) - cols = append(cols, createCol("VIEW_SCHEMA", 6165)) - cols = append(cols, createCol("VIEW_NAME", 6165)) - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) + cols = append(cols, createCol("VIEW_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("VIEW_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("VIEW_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) infSchema["VIEW_TABLE_USAGE"] = cols cols = []vindexes.Column{} - cols = append(cols, createCol("TABLE_CATALOG", 6165)) - cols = append(cols, createCol("TABLE_SCHEMA", 6165)) - cols = append(cols, createCol("TABLE_NAME", 6165)) - cols = append(cols, createCol("VIEW_DEFINITION", 6163)) - cols = append(cols, createCol("CHECK_OPTION", 2074)) - cols = append(cols, createCol("IS_UPDATABLE", 2074)) - cols = append(cols, createCol("DEFINER", 6165)) - cols = append(cols, createCol("SECURITY_TYPE", 6165)) - cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165)) - cols = append(cols, createCol("COLLATION_CONNECTION", 6165)) + cols = append(cols, createCol("TABLE_CATALOG", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_SCHEMA", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("TABLE_NAME", 6165, "utf8mb3_general_ci", "", 64, 0, false, "")) + cols = append(cols, createCol("VIEW_DEFINITION", 6163, "utf8mb3_general_ci", "", 0, 0, false, "")) + cols = append(cols, createCol("CHECK_OPTION", 2074, "utf8mb3_general_ci", "", 0, 0, false, "'NONE','LOCAL','CASCADED'")) + cols = append(cols, createCol("IS_UPDATABLE", 2074, "utf8mb3_general_ci", "", 0, 0, false, "'NO','YES'")) + cols = append(cols, createCol("DEFINER", 6165, "utf8mb3_general_ci", "", 288, 0, false, "")) + cols = append(cols, createCol("SECURITY_TYPE", 6165, "utf8mb3_general_ci", "", 7, 0, false, "")) + cols = append(cols, createCol("CHARACTER_SET_CLIENT", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) + cols = append(cols, createCol("COLLATION_CONNECTION", 6165, "utf8mb3_general_ci", "", 64, 0, true, "")) infSchema["VIEWS"] = cols - return infSchema } diff --git a/go/vt/vtgate/semantics/info_schema_gen_test.go b/go/vt/vtgate/semantics/info_schema_gen_test.go index 61241d96653..da06b80ac30 100644 --- a/go/vt/vtgate/semantics/info_schema_gen_test.go +++ b/go/vt/vtgate/semantics/info_schema_gen_test.go @@ -20,12 +20,16 @@ import ( "database/sql" "fmt" "regexp" + "strconv" "strings" "testing" _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/sqlparser" ) @@ -37,11 +41,16 @@ func TestGenerateInfoSchemaMap(t *testing.T) { require.NoError(t, err) defer db.Close() + collationName := collations.Local().LookupName(collations.SystemCollation.Collation) + for _, tbl := range informationSchemaTables80 { - b.WriteString("cols = []vindexes.Column{}\n") result, err := db.Query(fmt.Sprintf("show columns from information_schema.`%s`", tbl)) - require.NoError(t, err) + if err != nil { + t.Logf("error querying table %s: %v", tbl, err) + continue + } defer result.Close() + b.WriteString("cols = []vindexes.Column{}\n") for result.Next() { var r row result.Scan(&r.Field, &r.Type, &r.Null, &r.Key, &r.Default, &r.Extra) @@ -61,7 +70,24 @@ func TestGenerateInfoSchemaMap(t *testing.T) { if int(i2) == 0 { t.Fatalf("%s %s", tbl, r.Field) } - b.WriteString(fmt.Sprintf("cols = append(cols, createCol(\"%s\", %d))\n", r.Field, int(i2))) + var size, scale int64 + var values string + switch i2 { + case sqltypes.Enum, sqltypes.Set: + values = allString[2] + default: + if len(allString) > 1 && allString[2] != "" { + parts := strings.Split(allString[2], ",") + size, err = strconv.ParseInt(parts[0], 10, 32) + require.NoError(t, err) + if len(parts) > 1 { + scale, err = strconv.ParseInt(parts[1], 10, 32) + require.NoError(t, err) + } + } + } + // createCol(name string, typ int, collation string, def string, invisible bool, size, scale int32, notNullable bool) + b.WriteString(fmt.Sprintf("cols = append(cols, createCol(\"%s\", %d, \"%s\", \"%s\", %d, %d, %t, \"%s\"))\n", r.Field, int(i2), collationName, r.Default, size, scale, r.Null == "NO", values)) } b.WriteString(fmt.Sprintf("infSchema[\"%s\"] = cols\n", tbl)) } @@ -85,6 +111,8 @@ var ( "ENGINES", "EVENTS", "FILES", + "GLOBAL_STATUS", + "GLOBAL_VARIABLES", "INNODB_BUFFER_PAGE", "INNODB_BUFFER_PAGE_LRU", "INNODB_BUFFER_POOL_STATS", @@ -158,7 +186,7 @@ type row struct { Type string Null string Key any - Default any + Default string Extra any } diff --git a/go/vt/vtgate/semantics/real_table.go b/go/vt/vtgate/semantics/real_table.go index cf7811f4404..da55d95895f 100644 --- a/go/vt/vtgate/semantics/real_table.go +++ b/go/vt/vtgate/semantics/real_table.go @@ -19,12 +19,9 @@ package semantics import ( "strings" - "vitess.io/vitess/go/mysql/collations" - "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/evalengine" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -125,20 +122,10 @@ func vindexTableToColumnInfo(tbl *vindexes.Table) []ColumnInfo { nameMap := map[string]any{} cols := make([]ColumnInfo, 0, len(tbl.Columns)) for _, col := range tbl.Columns { - collation := collations.DefaultCollationForType(col.Type) - if sqltypes.IsText(col.Type) { - coll, found := collations.Local().LookupID(col.CollationName) - if found { - collation = coll - } - } cols = append(cols, ColumnInfo{ - Name: col.Name.String(), - Type: evalengine.Type{ - Type: col.Type, - Coll: collation, - }, + Name: col.Name.String(), + Type: col.ToEvalengineType(), Invisible: col.Invisible, }) nameMap[col.Name.String()] = nil diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 8292ebdf4aa..6668070a575 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -176,7 +176,9 @@ func (st *SemTable) CopyDependencies(from, to sqlparser.Expr) { st.Recursive[to] = st.RecursiveDeps(from) st.Direct[to] = st.DirectDeps(from) if ValidAsMapKey(from) { - st.ExprTypes[to] = st.ExprTypes[from] + if typ, found := st.ExprTypes[from]; found { + st.ExprTypes[to] = typ + } } } } @@ -609,16 +611,13 @@ func (st *SemTable) TypeForExpr(e sqlparser.Expr) (evalengine.Type, bool) { // We add a lot of WeightString() expressions to queries at late stages of the planning, // which means that they don't have any type information. We can safely assume that they // are VarBinary, since that's the only type that WeightString() can return. - _, isWS := e.(*sqlparser.WeightStringFuncExpr) + ws, isWS := e.(*sqlparser.WeightStringFuncExpr) if isWS { - return evalengine.Type{ - Type: sqltypes.VarBinary, - Coll: collations.CollationBinaryID, - Nullable: false, // TODO: we should check if the argument is nullable - }, true + wt, _ := st.TypeForExpr(ws.Expr) + return evalengine.NewTypeEx(sqltypes.VarBinary, collations.CollationBinaryID, wt.Nullable(), 0, 0), true } - return evalengine.UnknownType(), false + return evalengine.Type{}, false } // NeedsWeightString returns true if the given expression needs weight_string to do safe comparisons @@ -631,7 +630,7 @@ func (st *SemTable) NeedsWeightString(e sqlparser.Expr) bool { if !found { return true } - return typ.Coll == collations.Unknown && !sqltypes.IsNumber(typ.Type) + return typ.Collation() == collations.Unknown && !sqltypes.IsNumber(typ.Type()) } } @@ -701,8 +700,7 @@ func RewriteDerivedTableExpression(expr sqlparser.Expr, vt TableInfo) sqlparser. // CopyExprInfo lookups src in the ExprTypes map and, if a key is found, assign // the corresponding Type value of src to dest. func (st *SemTable) CopyExprInfo(src, dest sqlparser.Expr) { - srcType, found := st.ExprTypes[src] - if found { + if srcType, found := st.ExprTypes[src]; found { st.ExprTypes[dest] = srcType } } diff --git a/go/vt/vtgate/semantics/typer.go b/go/vt/vtgate/semantics/typer.go index 625077f4da1..8b44105d255 100644 --- a/go/vt/vtgate/semantics/typer.go +++ b/go/vt/vtgate/semantics/typer.go @@ -37,21 +37,16 @@ func newTyper() *typer { } func (t *typer) exprType(expr sqlparser.Expr) evalengine.Type { - res, ok := t.m[expr] - if ok { - return res - } - - return evalengine.UnknownType() + return t.m[expr] } func (t *typer) up(cursor *sqlparser.Cursor) error { switch node := cursor.Node().(type) { case *sqlparser.Literal: - t.m[node] = evalengine.Type{Type: node.SQLType(), Coll: collations.DefaultCollationForType(node.SQLType())} + t.m[node] = evalengine.NewType(node.SQLType(), collations.DefaultCollationForType(node.SQLType())) case *sqlparser.Argument: if node.Type >= 0 { - t.m[node] = evalengine.Type{Type: node.Type, Coll: collations.DefaultCollationForType(node.Type)} + t.m[node] = evalengine.NewType(node.Type, collations.DefaultCollationForType(node.Type)) } case sqlparser.AggrFunc: code, ok := opcode.SupportedAggregates[node.AggrName()] @@ -61,11 +56,13 @@ func (t *typer) up(cursor *sqlparser.Cursor) error { inputType := sqltypes.Unknown if arg := node.GetArg(); arg != nil { if tt, ok := t.m[arg]; ok { - inputType = tt.Type + inputType = tt.Type() } } type_ := code.Type(inputType) - t.m[node] = evalengine.Type{Type: type_, Coll: collations.DefaultCollationForType(type_)} + _, isCount := node.(*sqlparser.Count) + _, isCountStart := node.(*sqlparser.CountStar) + t.m[node] = evalengine.NewTypeEx(type_, collations.DefaultCollationForType(type_), !(isCount || isCountStart), 0, 0) } return nil } diff --git a/go/vt/vtgate/semantics/typer_test.go b/go/vt/vtgate/semantics/typer_test.go index 4c77e6f5657..c5417edbf64 100644 --- a/go/vt/vtgate/semantics/typer_test.go +++ b/go/vt/vtgate/semantics/typer_test.go @@ -51,7 +51,7 @@ func TestNormalizerAndSemanticAnalysisIntegration(t *testing.T) { bv := parse.(*sqlparser.Select).SelectExprs[0].(*sqlparser.AliasedExpr).Expr.(*sqlparser.Argument) typ, found := st.ExprTypes[bv] require.True(t, found, "bindvar was not typed") - require.Equal(t, test.typ, typ.Type.String()) + require.Equal(t, test.typ, typ.Type().String()) }) } diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 66321b7a41c..e724794b6cb 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -25,9 +25,11 @@ import ( "strings" "time" + "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqlescape" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/json2" "vitess.io/vitess/go/sqltypes" @@ -188,7 +190,12 @@ type Column struct { Default sqlparser.Expr `json:"default,omitempty"` // Invisible marks this as a column that will not be automatically included in `*` projections - Invisible bool `json:"invisible"` + Invisible bool `json:"invisible,omitempty"` + Size int32 `json:"size,omitempty"` + Scale int32 `json:"scale,omitempty"` + Nullable bool `json:"nullable,omitempty"` + // Values contains the list of values for enum and set types. + Values []string `json:"values,omitempty"` } // MarshalJSON returns a JSON representation of Column. @@ -211,6 +218,17 @@ func (col *Column) MarshalJSON() ([]byte, error) { return json.Marshal(cj) } +func (col *Column) ToEvalengineType() evalengine.Type { + collation := collations.DefaultCollationForType(col.Type) + if sqltypes.IsText(col.Type) { + coll, found := collations.Local().LookupID(col.CollationName) + if found { + collation = coll + } + } + return evalengine.NewTypeEx(col.Type, collation, col.Nullable, col.Size, col.Scale) +} + // KeyspaceSchema contains the schema(table) for a keyspace. type KeyspaceSchema struct { Keyspace *Keyspace @@ -638,8 +656,22 @@ func buildTables(ks *vschemapb.Keyspace, vschema *VSchema, ksvschema *KeyspaceSc "could not parse the '%s' column's default expression '%s' for table '%s'", col.Name, col.Default, tname) } } + nullable := true + if col.Nullable != nil { + nullable = *col.Nullable + } colNames[name.Lowered()] = true - t.Columns = append(t.Columns, Column{Name: name, Type: col.Type, Invisible: col.Invisible, Default: colDefault}) + t.Columns = append(t.Columns, Column{ + Name: name, + Type: col.Type, + CollationName: col.CollationName, + Default: colDefault, + Invisible: col.Invisible, + Size: col.Size, + Scale: col.Scale, + Nullable: nullable, + Values: col.Values, + }) } // Initialize ColumnVindexes. diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index 2b6eaa6161d..4d414c9d58a 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -18,11 +18,13 @@ func TestVSchemaUpdate(t *testing.T) { Type: querypb.Type_INT64, }} cols2 := []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("uid"), - Type: querypb.Type_INT64, + Name: sqlparser.NewIdentifierCI("uid"), + Type: querypb.Type_INT64, + Nullable: true, }, { - Name: sqlparser.NewIdentifierCI("name"), - Type: querypb.Type_VARCHAR, + Name: sqlparser.NewIdentifierCI("name"), + Type: querypb.Type_VARCHAR, + Nullable: true, }} ks := &vindexes.Keyspace{Name: "ks"} tblNoCol := &vindexes.Table{Name: sqlparser.NewIdentifierCS("tbl"), Keyspace: ks, ColumnListAuthoritative: true} @@ -340,11 +342,13 @@ func TestRebuildVSchema(t *testing.T) { Type: querypb.Type_INT64, }} cols2 := []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("uid"), - Type: querypb.Type_INT64, + Name: sqlparser.NewIdentifierCI("uid"), + Type: querypb.Type_INT64, + Nullable: true, }, { - Name: sqlparser.NewIdentifierCI("name"), - Type: querypb.Type_VARCHAR, + Name: sqlparser.NewIdentifierCI("name"), + Type: querypb.Type_VARCHAR, + Nullable: true, }} ks := &vindexes.Keyspace{Name: "ks"} tblNoCol := &vindexes.Table{Name: sqlparser.NewIdentifierCS("tbl"), Keyspace: ks, ColumnListAuthoritative: true} diff --git a/go/vt/vttablet/tabletmanager/vdiff/utils.go b/go/vt/vttablet/tabletmanager/vdiff/utils.go index 5904fd41795..dc11dbf249c 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/utils.go +++ b/go/vt/vttablet/tabletmanager/vdiff/utils.go @@ -42,14 +42,11 @@ func newMergeSorter(participants map[string]*shardStreamer, comparePKs []compare for i, cpk := range comparePKs { weightStringCol := -1 // if the collation is nil or unknown, use binary collation to compare as bytes - t := evalengine.Type{ - Type: sqltypes.Unknown, - Coll: collations.CollationBinaryID, - } + var collation collations.ID = collations.CollationBinaryID if cpk.collation != collations.Unknown { - t.Coll = cpk.collation + collation = cpk.collation } - ob[i] = evalengine.OrderByParams{Col: cpk.colIndex, WeightStringCol: weightStringCol, Type: t} + ob[i] = evalengine.OrderByParams{Col: cpk.colIndex, WeightStringCol: weightStringCol, Type: evalengine.NewType(sqltypes.Unknown, collation)} } return &engine.MergeSort{ Primitives: prims, @@ -69,7 +66,7 @@ func encodeString(in string) string { func pkColsToGroupByParams(pkCols []int) []*engine.GroupByParams { var res []*engine.GroupByParams for _, col := range pkCols { - res = append(res, &engine.GroupByParams{KeyCol: col, WeightStringCol: -1, Type: evalengine.UnknownType()}) + res = append(res, &engine.GroupByParams{KeyCol: col, WeightStringCol: -1}) } return res } diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 2cbe5032c92..3084eba0e29 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -769,7 +769,7 @@ func (df *vdiff) buildTablePlan(table *tabletmanagerdatapb.TableDefinition, quer func pkColsToGroupByParams(pkCols []int) []*engine.GroupByParams { var res []*engine.GroupByParams for _, col := range pkCols { - res = append(res, &engine.GroupByParams{KeyCol: col, WeightStringCol: -1, Type: evalengine.UnknownType()}) + res = append(res, &engine.GroupByParams{KeyCol: col, WeightStringCol: -1, Type: evalengine.Type{}}) } return res } @@ -784,11 +784,11 @@ func newMergeSorter(participants map[string]*shardStreamer, comparePKs []compare for _, cpk := range comparePKs { weightStringCol := -1 // if the collation is nil or unknown, use binary collation to compare as bytes - t := evalengine.Type{Type: sqltypes.Unknown, Coll: collations.CollationBinaryID} + var collation collations.ID = collations.CollationBinaryID if cpk.collation != collations.Unknown { - t.Coll = cpk.collation + collation = cpk.collation } - ob = append(ob, evalengine.OrderByParams{Col: cpk.colIndex, WeightStringCol: weightStringCol, Type: t}) + ob = append(ob, evalengine.OrderByParams{Col: cpk.colIndex, WeightStringCol: weightStringCol, Type: evalengine.NewType(sqltypes.Unknown, collation)}) } return &engine.MergeSort{ Primitives: prims, diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 28422b6cd4d..72e9e215c17 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -23,8 +23,6 @@ import ( "testing" "time" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -406,7 +404,7 @@ func TestVDiffPlanSuccess(t *testing.T) { engine.NewAggregateParam(opcode.AggregateSum, 2, ""), engine.NewAggregateParam(opcode.AggregateSum, 3, ""), }, - GroupByKeys: []*engine.GroupByParams{{KeyCol: 0, WeightStringCol: -1, Type: evalengine.UnknownType()}}, + GroupByKeys: []*engine.GroupByParams{{KeyCol: 0, WeightStringCol: -1}}, Input: newMergeSorter(nil, []compareColInfo{{0, collations.Unknown, true}}), }, targetPrimitive: newMergeSorter(nil, []compareColInfo{{0, collations.Unknown, true}}), diff --git a/proto/vschema.proto b/proto/vschema.proto index c6665688c23..45c1b7a3aa9 100644 --- a/proto/vschema.proto +++ b/proto/vschema.proto @@ -128,6 +128,12 @@ message Column { query.Type type = 2; bool invisible = 3; string default = 4; + string collation_name = 5; + int32 size = 6; + int32 scale = 7; + optional bool nullable = 8; + // values contains the list of values for an enum or set column. + repeated string values = 9; } // SrvVSchema is the roll-up of all the Keyspace schema for a cell. diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index bda230c6570..d50ca0004ee 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -41595,6 +41595,21 @@ export namespace vschema { /** Column default */ "default"?: (string|null); + + /** Column collation_name */ + collation_name?: (string|null); + + /** Column size */ + size?: (number|null); + + /** Column scale */ + scale?: (number|null); + + /** Column nullable */ + nullable?: (boolean|null); + + /** Column values */ + values?: (string[]|null); } /** Represents a Column. */ @@ -41618,6 +41633,24 @@ export namespace vschema { /** Column default. */ public default: string; + /** Column collation_name. */ + public collation_name: string; + + /** Column size. */ + public size: number; + + /** Column scale. */ + public scale: number; + + /** Column nullable. */ + public nullable?: (boolean|null); + + /** Column values. */ + public values: string[]; + + /** Column _nullable. */ + public _nullable?: "nullable"; + /** * Creates a new Column instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index dc1679ee3c0..7730d101e29 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -101274,6 +101274,11 @@ export const vschema = $root.vschema = (() => { * @property {query.Type|null} [type] Column type * @property {boolean|null} [invisible] Column invisible * @property {string|null} ["default"] Column default + * @property {string|null} [collation_name] Column collation_name + * @property {number|null} [size] Column size + * @property {number|null} [scale] Column scale + * @property {boolean|null} [nullable] Column nullable + * @property {Array.|null} [values] Column values */ /** @@ -101285,6 +101290,7 @@ export const vschema = $root.vschema = (() => { * @param {vschema.IColumn=} [properties] Properties to set */ function Column(properties) { + this.values = []; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -101323,6 +101329,60 @@ export const vschema = $root.vschema = (() => { */ Column.prototype["default"] = ""; + /** + * Column collation_name. + * @member {string} collation_name + * @memberof vschema.Column + * @instance + */ + Column.prototype.collation_name = ""; + + /** + * Column size. + * @member {number} size + * @memberof vschema.Column + * @instance + */ + Column.prototype.size = 0; + + /** + * Column scale. + * @member {number} scale + * @memberof vschema.Column + * @instance + */ + Column.prototype.scale = 0; + + /** + * Column nullable. + * @member {boolean|null|undefined} nullable + * @memberof vschema.Column + * @instance + */ + Column.prototype.nullable = null; + + /** + * Column values. + * @member {Array.} values + * @memberof vschema.Column + * @instance + */ + Column.prototype.values = $util.emptyArray; + + // OneOf field names bound to virtual getters and setters + let $oneOfFields; + + /** + * Column _nullable. + * @member {"nullable"|undefined} _nullable + * @memberof vschema.Column + * @instance + */ + Object.defineProperty(Column.prototype, "_nullable", { + get: $util.oneOfGetter($oneOfFields = ["nullable"]), + set: $util.oneOfSetter($oneOfFields) + }); + /** * Creates a new Column instance using the specified properties. * @function create @@ -101355,6 +101415,17 @@ export const vschema = $root.vschema = (() => { writer.uint32(/* id 3, wireType 0 =*/24).bool(message.invisible); if (message["default"] != null && Object.hasOwnProperty.call(message, "default")) writer.uint32(/* id 4, wireType 2 =*/34).string(message["default"]); + if (message.collation_name != null && Object.hasOwnProperty.call(message, "collation_name")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.collation_name); + if (message.size != null && Object.hasOwnProperty.call(message, "size")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.size); + if (message.scale != null && Object.hasOwnProperty.call(message, "scale")) + writer.uint32(/* id 7, wireType 0 =*/56).int32(message.scale); + if (message.nullable != null && Object.hasOwnProperty.call(message, "nullable")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.nullable); + if (message.values != null && message.values.length) + for (let i = 0; i < message.values.length; ++i) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.values[i]); return writer; }; @@ -101405,6 +101476,28 @@ export const vschema = $root.vschema = (() => { message["default"] = reader.string(); break; } + case 5: { + message.collation_name = reader.string(); + break; + } + case 6: { + message.size = reader.int32(); + break; + } + case 7: { + message.scale = reader.int32(); + break; + } + case 8: { + message.nullable = reader.bool(); + break; + } + case 9: { + if (!(message.values && message.values.length)) + message.values = []; + message.values.push(reader.string()); + break; + } default: reader.skipType(tag & 7); break; @@ -101440,6 +101533,7 @@ export const vschema = $root.vschema = (() => { Column.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; + let properties = {}; if (message.name != null && message.hasOwnProperty("name")) if (!$util.isString(message.name)) return "name: string expected"; @@ -101490,6 +101584,27 @@ export const vschema = $root.vschema = (() => { if (message["default"] != null && message.hasOwnProperty("default")) if (!$util.isString(message["default"])) return "default: string expected"; + if (message.collation_name != null && message.hasOwnProperty("collation_name")) + if (!$util.isString(message.collation_name)) + return "collation_name: string expected"; + if (message.size != null && message.hasOwnProperty("size")) + if (!$util.isInteger(message.size)) + return "size: integer expected"; + if (message.scale != null && message.hasOwnProperty("scale")) + if (!$util.isInteger(message.scale)) + return "scale: integer expected"; + if (message.nullable != null && message.hasOwnProperty("nullable")) { + properties._nullable = 1; + if (typeof message.nullable !== "boolean") + return "nullable: boolean expected"; + } + if (message.values != null && message.hasOwnProperty("values")) { + if (!Array.isArray(message.values)) + return "values: array expected"; + for (let i = 0; i < message.values.length; ++i) + if (!$util.isString(message.values[i])) + return "values: string[] expected"; + } return null; }; @@ -101659,6 +101774,21 @@ export const vschema = $root.vschema = (() => { message.invisible = Boolean(object.invisible); if (object["default"] != null) message["default"] = String(object["default"]); + if (object.collation_name != null) + message.collation_name = String(object.collation_name); + if (object.size != null) + message.size = object.size | 0; + if (object.scale != null) + message.scale = object.scale | 0; + if (object.nullable != null) + message.nullable = Boolean(object.nullable); + if (object.values) { + if (!Array.isArray(object.values)) + throw TypeError(".vschema.Column.values: array expected"); + message.values = []; + for (let i = 0; i < object.values.length; ++i) + message.values[i] = String(object.values[i]); + } return message; }; @@ -101675,11 +101805,16 @@ export const vschema = $root.vschema = (() => { if (!options) options = {}; let object = {}; + if (options.arrays || options.defaults) + object.values = []; if (options.defaults) { object.name = ""; object.type = options.enums === String ? "NULL_TYPE" : 0; object.invisible = false; object["default"] = ""; + object.collation_name = ""; + object.size = 0; + object.scale = 0; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; @@ -101689,6 +101824,22 @@ export const vschema = $root.vschema = (() => { object.invisible = message.invisible; if (message["default"] != null && message.hasOwnProperty("default")) object["default"] = message["default"]; + if (message.collation_name != null && message.hasOwnProperty("collation_name")) + object.collation_name = message.collation_name; + if (message.size != null && message.hasOwnProperty("size")) + object.size = message.size; + if (message.scale != null && message.hasOwnProperty("scale")) + object.scale = message.scale; + if (message.nullable != null && message.hasOwnProperty("nullable")) { + object.nullable = message.nullable; + if (options.oneofs) + object._nullable = "nullable"; + } + if (message.values && message.values.length) { + object.values = []; + for (let j = 0; j < message.values.length; ++j) + object.values[j] = message.values[j]; + } return object; }; From 6fe1858031e066d303f57bf126965a2efa2a00c1 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Mon, 20 Nov 2023 16:50:32 +0100 Subject: [PATCH 031/119] mysqlctl: Cleanup stale socket lockfile (#14553) Signed-off-by: Dirkjan Bussink --- go/vt/mysqlctl/mysqld.go | 54 +++++++++++++++++++++++++++++++++-- go/vt/mysqlctl/mysqld_test.go | 21 ++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index b6a743cc120..a2d2c5b7d71 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -38,6 +38,7 @@ import ( "strconv" "strings" "sync" + "syscall" "time" "github.com/spf13/pflag" @@ -321,7 +322,7 @@ func (mysqld *Mysqld) Start(ctx context.Context, cnf *Mycnf, mysqldArgs ...strin return client.Start(ctx, mysqldArgs...) } - if err := mysqld.startNoWait(ctx, cnf, mysqldArgs...); err != nil { + if err := mysqld.startNoWait(cnf, mysqldArgs...); err != nil { return err } @@ -329,7 +330,7 @@ func (mysqld *Mysqld) Start(ctx context.Context, cnf *Mycnf, mysqldArgs ...strin } // startNoWait is the internal version of Start, and it doesn't wait. -func (mysqld *Mysqld) startNoWait(ctx context.Context, cnf *Mycnf, mysqldArgs ...string) error { +func (mysqld *Mysqld) startNoWait(cnf *Mycnf, mysqldArgs ...string) error { var name string ts := fmt.Sprintf("Mysqld.Start(%v)", time.Now().Unix()) @@ -355,6 +356,13 @@ func (mysqld *Mysqld) startNoWait(ctx context.Context, cnf *Mycnf, mysqldArgs .. if err != nil { return err } + // If we're here, and the lockfile still exists for the socket, we have + // to clean that up since we know at this point we need to start MySQL. + // Having this stray lock file present means MySQL fails to start. This + // only happens when running without mysqld_safe. + if err := cleanupLockfile(cnf.SocketFile, ts); err != nil { + return err + } } mysqlBaseDir, err := vtenv.VtMysqlBaseDir() if err != nil { @@ -426,6 +434,46 @@ func (mysqld *Mysqld) startNoWait(ctx context.Context, cnf *Mycnf, mysqldArgs .. return nil } +func cleanupLockfile(socket string, ts string) error { + lockPath := fmt.Sprintf("%s.lock", socket) + pid, err := os.ReadFile(lockPath) + if errors.Is(err, os.ErrNotExist) { + // If there's no lock file, we can early return here, nothing + // to clean up then. + return nil + } else if err != nil { + // Any other errors here are unexpected. + return err + } + p, err := strconv.Atoi(string(pid)) + if err != nil { + log.Errorf("%v: error parsing pid from lock file: %v", ts, err) + return err + } + proc, err := os.FindProcess(p) + if err != nil { + log.Errorf("%v: error finding process: %v", ts, err) + return err + } + err = proc.Signal(syscall.Signal(0)) + if err == nil { + // If the process still exists, it's not safe to + // remove the lock file, so we have to keep it around. + log.Warningf("%v: not removing socket lock file: %v", ts, lockPath) + return nil + } + if !errors.Is(err, os.ErrProcessDone) { + // Any errors except for the process being done + // is unexpected here. + log.Errorf("%v: error checking process: %v", ts, err) + return err + } + + // All good, process is gone and we can safely clean up the lock file. + log.Infof("%v: removing stale socket lock file: %v", ts, lockPath) + return os.Remove(lockPath) +} + // Wait returns nil when mysqld is up and accepting connections. It // will use the dba credentials to try to connect. Use wait() with // different credentials if needed. @@ -642,7 +690,7 @@ func (mysqld *Mysqld) Init(ctx context.Context, cnf *Mycnf, initDBSQLFile string // Start mysqld. We do not use Start, as we have to wait using // the root user. - if err = mysqld.startNoWait(ctx, cnf); err != nil { + if err = mysqld.startNoWait(cnf); err != nil { log.Errorf("failed starting mysqld: %v\n%v", err, readTailOfMysqldErrorLog(cnf.ErrorLogPath)) return err } diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index 435090008f2..5ee21196ddd 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -17,6 +17,8 @@ limitations under the License. package mysqlctl import ( + "os" + "strconv" "testing" "time" @@ -172,3 +174,22 @@ func TestParseBinlogEntryTimestamp(t *testing.T) { }) } } + +func TestCleanupLockfile(t *testing.T) { + t.Cleanup(func() { + os.Remove("mysql.sock.lock") + }) + ts := "prefix" + // All good if no lockfile exists + assert.NoError(t, cleanupLockfile("mysql.sock", ts)) + + // If lockfile exists, but the process is not found, we clean it up. + os.WriteFile("mysql.sock.lock", []byte("123456789"), 0o600) + assert.NoError(t, cleanupLockfile("mysql.sock", ts)) + assert.NoFileExists(t, "mysql.sock.lock") + + // If the lockfile exists, and the process is found, we don't clean it up. + os.WriteFile("mysql.sock.lock", []byte(strconv.Itoa(os.Getpid())), 0o600) + assert.NoError(t, cleanupLockfile("mysql.sock", ts)) + assert.FileExists(t, "mysql.sock.lock") +} From ae1dad963450a2ab3493c32e46484278ac8081d2 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 21 Nov 2023 18:05:28 +0530 Subject: [PATCH 032/119] Remove excessive VTGate logging of default planner selection (#14554) Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/builder.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index f715c230db9..ffa316d4b71 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -24,7 +24,6 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/vschemawrapper" "vitess.io/vitess/go/vt/key" - "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/sqlparser" @@ -130,7 +129,6 @@ func getConfiguredPlanner(vschema plancontext.VSchema, stmt sqlparser.Statement, case Gen4Left2Right, Gen4GreedyOnly, Gen4: default: // default is gen4 plan - log.Infof("Using Gen4 planner instead of %s", planner.String()) planner = Gen4 } return gen4Planner(query, planner), nil From 1b6d2575ce835a09997a825826e9ff3976d9af34 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:39:08 +0530 Subject: [PATCH 033/119] Fix nullability checks in evalengine (#14556) Signed-off-by: Manan Gupta Signed-off-by: Dirkjan Bussink --- go/mysql/collations/integration/main_test.go | 2 +- .../vtgate/evalengine/api_type_aggregation.go | 6 +++ go/vt/vtgate/evalengine/compiler_asm.go | 24 ++++++--- go/vt/vtgate/evalengine/compiler_test.go | 32 ++++++++++++ go/vt/vtgate/evalengine/expr_arithmetic.go | 12 +++-- go/vt/vtgate/evalengine/expr_bit.go | 8 +-- go/vt/vtgate/evalengine/expr_bvar.go | 6 +-- go/vt/vtgate/evalengine/expr_compare.go | 11 +++- go/vt/vtgate/evalengine/expr_logical.go | 10 ++-- go/vt/vtgate/evalengine/expr_tuple.go | 2 +- go/vt/vtgate/evalengine/fn_base64.go | 4 +- go/vt/vtgate/evalengine/fn_bit.go | 4 +- go/vt/vtgate/evalengine/fn_compare.go | 30 ++++++++--- go/vt/vtgate/evalengine/fn_crypto.go | 8 +-- go/vt/vtgate/evalengine/fn_hex.go | 2 +- go/vt/vtgate/evalengine/fn_json.go | 2 +- go/vt/vtgate/evalengine/fn_misc.go | 14 +++--- go/vt/vtgate/evalengine/fn_numeric.go | 10 ++-- go/vt/vtgate/evalengine/fn_string.go | 12 ++--- go/vt/vtgate/evalengine/testcases/inputs.go | 2 + go/vt/vtgate/executor_select_test.go | 50 +++++++++---------- 21 files changed, 166 insertions(+), 85 deletions(-) diff --git a/go/mysql/collations/integration/main_test.go b/go/mysql/collations/integration/main_test.go index f0d8d4dfdfa..23c6f8d2716 100644 --- a/go/mysql/collations/integration/main_test.go +++ b/go/mysql/collations/integration/main_test.go @@ -47,7 +47,7 @@ func mysqlconn(t *testing.T) *mysql.Conn { if err != nil { t.Fatal(err) } - if !strings.HasPrefix(conn.ServerVersion, "8.0.") { + if !strings.HasPrefix(conn.ServerVersion, "8.") { conn.Close() t.Skipf("collation integration tests are only supported in MySQL 8.0+") } diff --git a/go/vt/vtgate/evalengine/api_type_aggregation.go b/go/vt/vtgate/evalengine/api_type_aggregation.go index 5ab1d2e5338..70640c935b4 100644 --- a/go/vt/vtgate/evalengine/api_type_aggregation.go +++ b/go/vt/vtgate/evalengine/api_type_aggregation.go @@ -42,6 +42,8 @@ type typeAggregation struct { geometry uint16 blob uint16 total uint16 + + nullable bool } func AggregateTypes(types []sqltypes.Type) sqltypes.Type { @@ -63,6 +65,7 @@ func (ta *typeAggregation) addEval(e eval) { switch e := e.(type) { case nil: t = sqltypes.Null + ta.nullable = true case *evalBytes: t = sqltypes.Type(e.tt) f = e.flag @@ -73,6 +76,9 @@ func (ta *typeAggregation) addEval(e eval) { } func (ta *typeAggregation) add(tt sqltypes.Type, f typeFlag) { + if f&flagNullable != 0 { + ta.nullable = true + } switch tt { case sqltypes.Float32, sqltypes.Float64: ta.double++ diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index 4b2f0525e9d..19d4c01a399 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -528,7 +528,7 @@ func (asm *assembler) CmpCase(cases int, hasElse bool, tt sqltypes.Type, cc coll asm.emit(func(env *ExpressionEnv) int { end := env.vm.sp - elseOffset for sp := env.vm.sp - stackDepth; sp < end; sp += 2 { - if env.vm.stack[sp].(*evalInt64).i != 0 { + if env.vm.stack[sp] != nil && env.vm.stack[sp].(*evalInt64).i != 0 { env.vm.stack[env.vm.sp-stackDepth], env.vm.err = evalCoerce(env.vm.stack[sp+1], tt, cc.Collation, env.now) goto done } @@ -782,8 +782,8 @@ func (asm *assembler) Convert_bB(offset int) { var f float64 if arg != nil { f, _ = fastparse.ParseFloat64(arg.(*evalBytes).string()) + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(f != 0.0) } - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(f != 0.0) return 1 }, "CONV VARBINARY(SP-%d), BOOL", offset) } @@ -791,7 +791,9 @@ func (asm *assembler) Convert_bB(offset int) { func (asm *assembler) Convert_TB(offset int) { asm.emit(func(env *ExpressionEnv) int { arg := env.vm.stack[env.vm.sp-offset] - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg != nil && !arg.(*evalTemporal).isZero()) + if arg != nil { + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(!arg.(*evalTemporal).isZero()) + } return 1 }, "CONV SQLTYPES(SP-%d), BOOL", offset) } @@ -839,7 +841,9 @@ func (asm *assembler) Convert_Tj(offset int) { func (asm *assembler) Convert_dB(offset int) { asm.emit(func(env *ExpressionEnv) int { arg := env.vm.stack[env.vm.sp-offset] - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg != nil && !arg.(*evalDecimal).dec.IsZero()) + if arg != nil { + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(!arg.(*evalDecimal).dec.IsZero()) + } return 1 }, "CONV DECIMAL(SP-%d), BOOL", offset) } @@ -859,7 +863,9 @@ func (asm *assembler) Convert_dbit(offset int) { func (asm *assembler) Convert_fB(offset int) { asm.emit(func(env *ExpressionEnv) int { arg := env.vm.stack[env.vm.sp-offset] - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg != nil && arg.(*evalFloat).f != 0.0) + if arg != nil { + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg.(*evalFloat).f != 0.0) + } return 1 }, "CONV FLOAT64(SP-%d), BOOL", offset) } @@ -917,7 +923,9 @@ func (asm *assembler) Convert_Tf(offset int) { func (asm *assembler) Convert_iB(offset int) { asm.emit(func(env *ExpressionEnv) int { arg := env.vm.stack[env.vm.sp-offset] - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg != nil && arg.(*evalInt64).i != 0) + if arg != nil { + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg.(*evalInt64).i != 0) + } return 1 }, "CONV INT64(SP-%d), BOOL", offset) } @@ -997,7 +1005,9 @@ func (asm *assembler) Convert_Nj(offset int) { func (asm *assembler) Convert_uB(offset int) { asm.emit(func(env *ExpressionEnv) int { arg := env.vm.stack[env.vm.sp-offset] - env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg != nil && arg.(*evalUint64).u != 0) + if arg != nil { + env.vm.stack[env.vm.sp-offset] = env.vm.arena.newEvalBool(arg.(*evalUint64).u != 0) + } return 1 }, "CONV UINT64(SP-%d), BOOL", offset) } diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go index b2cb9553f49..77174a01d71 100644 --- a/go/vt/vtgate/evalengine/compiler_test.go +++ b/go/vt/vtgate/evalengine/compiler_test.go @@ -532,6 +532,38 @@ func TestCompilerSingle(t *testing.T) { expression: `UNIX_TIMESTAMP('20000101103458.111111') + 1`, result: `DECIMAL(946719299.111111)`, }, + { + expression: `cast(null * 1 as CHAR)`, + result: `NULL`, + }, + { + expression: `cast(null + 1 as CHAR)`, + result: `NULL`, + }, + { + expression: `cast(null - 1 as CHAR)`, + result: `NULL`, + }, + { + expression: `cast(null / 1 as CHAR)`, + result: `NULL`, + }, + { + expression: `cast(null % 1 as CHAR)`, + result: `NULL`, + }, + { + expression: `1 AND NULL * 1`, + result: `NULL`, + }, + { + expression: `case 0 when NULL then 1 else 0 end`, + result: `INT64(0)`, + }, + { + expression: `case when null is null then 23 else null end`, + result: `INT64(23)`, + }, } tz, _ := time.LoadLocation("Europe/Madrid") diff --git a/go/vt/vtgate/evalengine/expr_arithmetic.go b/go/vt/vtgate/evalengine/expr_arithmetic.go index 8814d9ed6b8..938803910cb 100644 --- a/go/vt/vtgate/evalengine/expr_arithmetic.go +++ b/go/vt/vtgate/evalengine/expr_arithmetic.go @@ -127,7 +127,7 @@ func (op *opArithAdd) compile(c *compiler, left, right IR) (ctype, error) { } c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sumtype, Col: collationNumeric}, nil + return ctype{Type: sumtype, Flag: nullableFlags(lt.Flag | rt.Flag), Col: collationNumeric}, nil } func (op *opArithSub) eval(left, right eval) (eval, error) { @@ -210,7 +210,7 @@ func (op *opArithSub) compile(c *compiler, left, right IR) (ctype, error) { } c.asm.jumpDestination(skip1, skip2) - return ctype{Type: subtype, Col: collationNumeric}, nil + return ctype{Type: subtype, Flag: nullableFlags(lt.Flag | rt.Flag), Col: collationNumeric}, nil } func (op *opArithMul) eval(left, right eval) (eval, error) { @@ -270,7 +270,7 @@ func (op *opArithMul) compile(c *compiler, left, right IR) (ctype, error) { } c.asm.jumpDestination(skip1, skip2) - return ctype{Type: multype, Col: collationNumeric}, nil + return ctype{Type: multype, Flag: nullableFlags(lt.Flag | rt.Flag), Col: collationNumeric}, nil } func (op *opArithDiv) eval(left, right eval) (eval, error) { @@ -525,9 +525,13 @@ func (expr *NegateExpr) compile(c *compiler) (ctype, error) { c.asm.jumpDestination(skip) return ctype{ Type: neg, - Flag: arg.Flag & (flagNull | flagNullable), + Flag: nullableFlags(arg.Flag), Size: arg.Size, Scale: arg.Scale, Col: collationNumeric, }, nil } + +func nullableFlags(flag typeFlag) typeFlag { + return flag & (flagNull | flagNullable) +} diff --git a/go/vt/vtgate/evalengine/expr_bit.go b/go/vt/vtgate/evalengine/expr_bit.go index e95d54c5b6c..9c4dbafe2a6 100644 --- a/go/vt/vtgate/evalengine/expr_bit.go +++ b/go/vt/vtgate/evalengine/expr_bit.go @@ -270,7 +270,7 @@ func (expr *BitwiseExpr) compileBinary(c *compiler, asm_ins_bb, asm_ins_uu func( asm_ins_uu() c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sqltypes.Uint64, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Uint64, Flag: nullableFlags(lt.Flag | rt.Flag), Col: collationNumeric}, nil } func (expr *BitwiseExpr) compileShift(c *compiler, i int) (ctype, error) { @@ -299,8 +299,8 @@ func (expr *BitwiseExpr) compileShift(c *compiler, i int) (ctype, error) { return ctype{Type: sqltypes.VarBinary, Col: collationBinary}, nil } - _ = c.compileToBitwiseUint64(lt, 2) - _ = c.compileToUint64(rt, 1) + lt = c.compileToBitwiseUint64(lt, 2) + rt = c.compileToUint64(rt, 1) if i < 0 { c.asm.BitShiftLeft_uu() @@ -309,7 +309,7 @@ func (expr *BitwiseExpr) compileShift(c *compiler, i int) (ctype, error) { } c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sqltypes.Uint64, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Uint64, Flag: nullableFlags(lt.Flag | rt.Flag), Col: collationNumeric}, nil } func (expr *BitwiseExpr) compile(c *compiler) (ctype, error) { diff --git a/go/vt/vtgate/evalengine/expr_bvar.go b/go/vt/vtgate/evalengine/expr_bvar.go index 6bc49caf660..dfbaaafffa7 100644 --- a/go/vt/vtgate/evalengine/expr_bvar.go +++ b/go/vt/vtgate/evalengine/expr_bvar.go @@ -106,11 +106,11 @@ func (bv *BindVariable) typeof(env *ExpressionEnv) (ctype, error) { case sqltypes.Null: return ctype{Type: sqltypes.Null, Flag: flagNull | flagNullable, Col: collationNull}, nil case sqltypes.HexNum, sqltypes.HexVal: - return ctype{Type: sqltypes.VarBinary, Flag: flagHex, Col: collationNumeric}, nil + return ctype{Type: sqltypes.VarBinary, Flag: flagHex | flagNullable, Col: collationNumeric}, nil case sqltypes.BitNum: - return ctype{Type: sqltypes.VarBinary, Flag: flagBit, Col: collationNumeric}, nil + return ctype{Type: sqltypes.VarBinary, Flag: flagBit | flagNullable, Col: collationNumeric}, nil default: - return ctype{Type: tt, Flag: 0, Col: typedCoercionCollation(tt, collations.CollationForType(tt, bv.Collation))}, nil + return ctype{Type: tt, Flag: flagNullable, Col: typedCoercionCollation(tt, collations.CollationForType(tt, bv.Collation))}, nil } } diff --git a/go/vt/vtgate/evalengine/expr_compare.go b/go/vt/vtgate/evalengine/expr_compare.go index 90c2d313b07..7acead2d99a 100644 --- a/go/vt/vtgate/evalengine/expr_compare.go +++ b/go/vt/vtgate/evalengine/expr_compare.go @@ -365,11 +365,13 @@ func (expr *ComparisonExpr) compile(c *compiler) (ctype, error) { swapped := false var skip2 *jump + nullable := true switch expr.Op.(type) { case compareNullSafeEQ: skip2 = c.asm.jumpFrom() c.asm.Cmp_nullsafe(skip2) + nullable = false default: skip2 = c.compileNullCheck1r(rt) } @@ -407,6 +409,9 @@ func (expr *ComparisonExpr) compile(c *compiler) (ctype, error) { } cmptype := ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean} + if nullable { + cmptype.Flag |= nullableFlags(lt.Flag | rt.Flag) + } switch expr.Op.(type) { case compareEQ: @@ -540,16 +545,18 @@ func (expr *InExpr) compile(c *compiler) (ctype, error) { switch rhs := expr.Right.(type) { case TupleExpr: + var rt ctype if table := expr.compileTable(lhs, rhs); table != nil { c.asm.In_table(expr.Negate, table) } else { - _, err := rhs.compile(c) + rt, err = rhs.compile(c) if err != nil { return ctype{}, err } c.asm.In_slow(expr.Negate) } - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean}, nil + + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean | (nullableFlags(lhs.Flag) | (rt.Flag & flagNullable))}, nil case *BindVariable: return ctype{}, c.unsupported(expr) default: diff --git a/go/vt/vtgate/evalengine/expr_logical.go b/go/vt/vtgate/evalengine/expr_logical.go index 9d2f17becec..f22ca091acb 100644 --- a/go/vt/vtgate/evalengine/expr_logical.go +++ b/go/vt/vtgate/evalengine/expr_logical.go @@ -379,7 +379,7 @@ func (expr *NotExpr) compile(c *compiler) (ctype, error) { c.asm.Not_i() } c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: flagNullable | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func (l *LogicalExpr) eval(env *ExpressionEnv) (eval, error) { @@ -450,7 +450,7 @@ func (expr *LogicalExpr) compile(c *compiler) (ctype, error) { expr.op.compileRight(c) c.asm.jumpDestination(jump) - return ctype{Type: sqltypes.Int64, Flag: flagNullable | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: ((lt.Flag | rt.Flag) & flagNullable) | flagIsBoolean, Col: collationNumeric}, nil } func intervalCompare(n, val eval) (int, bool, error) { @@ -711,7 +711,11 @@ func (cs *CaseExpr) compile(c *compiler) (ctype, error) { } } - ct := ctype{Type: ta.result(), Col: ca.result()} + var f typeFlag + if ta.nullable { + f |= flagNullable + } + ct := ctype{Type: ta.result(), Flag: f, Col: ca.result()} c.asm.CmpCase(len(cs.cases), cs.Else != nil, ct.Type, ct.Col) return ct, nil } diff --git a/go/vt/vtgate/evalengine/expr_tuple.go b/go/vt/vtgate/evalengine/expr_tuple.go index 132d38108a0..d4943271ccb 100644 --- a/go/vt/vtgate/evalengine/expr_tuple.go +++ b/go/vt/vtgate/evalengine/expr_tuple.go @@ -66,5 +66,5 @@ func (tuple TupleExpr) FormatFast(buf *sqlparser.TrackedBuffer) { } func (tuple TupleExpr) typeof(*ExpressionEnv) (ctype, error) { - return ctype{Type: sqltypes.Tuple}, nil + return ctype{Type: sqltypes.Tuple, Col: collationBinary}, nil } diff --git a/go/vt/vtgate/evalengine/fn_base64.go b/go/vt/vtgate/evalengine/fn_base64.go index d404d391dd6..a785000ca5d 100644 --- a/go/vt/vtgate/evalengine/fn_base64.go +++ b/go/vt/vtgate/evalengine/fn_base64.go @@ -110,7 +110,7 @@ func (call *builtinToBase64) compile(c *compiler) (ctype, error) { c.asm.Fn_TO_BASE64(t, col) c.asm.jumpDestination(skip) - return ctype{Type: t, Col: col}, nil + return ctype{Type: t, Flag: nullableFlags(str.Flag), Col: col}, nil } func (call *builtinFromBase64) eval(env *ExpressionEnv) (eval, error) { @@ -155,5 +155,5 @@ func (call *builtinFromBase64) compile(c *compiler) (ctype, error) { c.asm.Fn_FROM_BASE64(t) c.asm.jumpDestination(skip) - return ctype{Type: t, Col: collationBinary}, nil + return ctype{Type: t, Flag: nullableFlags(str.Flag), Col: collationBinary}, nil } diff --git a/go/vt/vtgate/evalengine/fn_bit.go b/go/vt/vtgate/evalengine/fn_bit.go index 66edffe268f..9444ee086af 100644 --- a/go/vt/vtgate/evalengine/fn_bit.go +++ b/go/vt/vtgate/evalengine/fn_bit.go @@ -61,11 +61,11 @@ func (expr *builtinBitCount) compile(c *compiler) (ctype, error) { if ct.Type == sqltypes.VarBinary && !ct.isHexOrBitLiteral() { c.asm.BitCount_b() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationBinary}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(ct.Flag), Col: collationBinary}, nil } _ = c.compileToBitwiseUint64(ct, 1) c.asm.BitCount_u() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationBinary}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(ct.Flag), Col: collationBinary}, nil } diff --git a/go/vt/vtgate/evalengine/fn_compare.go b/go/vt/vtgate/evalengine/fn_compare.go index cf40deae94b..835d84c3d39 100644 --- a/go/vt/vtgate/evalengine/fn_compare.go +++ b/go/vt/vtgate/evalengine/fn_compare.go @@ -63,11 +63,15 @@ func (b *builtinCoalesce) compile(c *compiler) (ctype, error) { local = collations.Local() ) + f := flagNullable for _, arg := range b.Arguments { tt, err := arg.compile(c) if err != nil { return ctype{}, err } + if !tt.nullable() { + f = 0 + } ta.add(tt.Type, tt.Flag) if err := ca.add(local, tt.Col); err != nil { return ctype{}, err @@ -87,7 +91,7 @@ func (b *builtinCoalesce) compile(c *compiler) (ctype, error) { return 1 }, "COALESCE (SP-%d) ... (SP-1)", args) - return ctype{Type: ta.result(), Flag: flagNullable, Col: ca.result()}, nil + return ctype{Type: ta.result(), Flag: f, Col: ca.result()}, nil } func getMultiComparisonFunc(args []eval) multiComparisonFunc { @@ -286,7 +290,9 @@ func (call *builtinMultiComparison) compile_c(c *compiler, args []ctype) (ctype, env := collations.Local() var ca collationAggregation + var f typeFlag for _, arg := range args { + f |= nullableFlags(arg.Flag) if err := ca.add(env, arg.Col); err != nil { return ctype{}, err } @@ -294,15 +300,17 @@ func (call *builtinMultiComparison) compile_c(c *compiler, args []ctype) (ctype, tc := ca.result() c.asm.Fn_MULTICMP_c(len(args), call.cmp < 0, tc) - return ctype{Type: sqltypes.VarChar, Col: tc}, nil + return ctype{Type: sqltypes.VarChar, Flag: f, Col: tc}, nil } func (call *builtinMultiComparison) compile_d(c *compiler, args []ctype) (ctype, error) { + var f typeFlag for i, tt := range args { + f |= nullableFlags(tt.Flag) c.compileToDecimal(tt, len(args)-i) } c.asm.Fn_MULTICMP_d(len(args), call.cmp < 0) - return ctype{Type: sqltypes.Decimal, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Decimal, Flag: f, Col: collationNumeric}, nil } func (call *builtinMultiComparison) compile(c *compiler) (ctype, error) { @@ -314,6 +322,7 @@ func (call *builtinMultiComparison) compile(c *compiler) (ctype, error) { text int binary int args []ctype + nullable bool ) /* @@ -333,6 +342,7 @@ func (call *builtinMultiComparison) compile(c *compiler) (ctype, error) { args = append(args, tt) + nullable = nullable || tt.nullable() switch tt.Type { case sqltypes.Int64: signed++ @@ -346,19 +356,25 @@ func (call *builtinMultiComparison) compile(c *compiler) (ctype, error) { text++ case sqltypes.Blob, sqltypes.Binary, sqltypes.VarBinary: binary++ + case sqltypes.Null: + nullable = true default: return ctype{}, c.unsupported(call) } } + var f typeFlag + if nullable { + f |= flagNullable + } if signed+unsigned == len(args) { if signed == len(args) { c.asm.Fn_MULTICMP_i(len(args), call.cmp < 0) - return ctype{Type: sqltypes.Int64, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: f, Col: collationNumeric}, nil } if unsigned == len(args) { c.asm.Fn_MULTICMP_u(len(args), call.cmp < 0) - return ctype{Type: sqltypes.Uint64, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Uint64, Flag: f, Col: collationNumeric}, nil } return call.compile_d(c, args) } @@ -367,14 +383,14 @@ func (call *builtinMultiComparison) compile(c *compiler) (ctype, error) { return call.compile_c(c, args) } c.asm.Fn_MULTICMP_b(len(args), call.cmp < 0) - return ctype{Type: sqltypes.VarBinary, Col: collationBinary}, nil + return ctype{Type: sqltypes.VarBinary, Flag: f, Col: collationBinary}, nil } else { if floats > 0 { for i, tt := range args { c.compileToFloat(tt, len(args)-i) } c.asm.Fn_MULTICMP_f(len(args), call.cmp < 0) - return ctype{Type: sqltypes.Float64, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Float64, Flag: f, Col: collationNumeric}, nil } if decimals > 0 { return call.compile_d(c, args) diff --git a/go/vt/vtgate/evalengine/fn_crypto.go b/go/vt/vtgate/evalengine/fn_crypto.go index 31783291ce7..8adbea6332c 100644 --- a/go/vt/vtgate/evalengine/fn_crypto.go +++ b/go/vt/vtgate/evalengine/fn_crypto.go @@ -68,7 +68,7 @@ func (call *builtinMD5) compile(c *compiler) (ctype, error) { col := typedCoercionCollation(sqltypes.VarChar, c.collation) c.asm.Fn_MD5(col) c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.VarChar, Col: col, Flag: str.Flag}, nil + return ctype{Type: sqltypes.VarChar, Col: col, Flag: nullableFlags(str.Flag)}, nil } type builtinSHA1 struct { @@ -110,7 +110,7 @@ func (call *builtinSHA1) compile(c *compiler) (ctype, error) { col := typedCoercionCollation(sqltypes.VarChar, c.collation) c.asm.Fn_SHA1(col) c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.VarChar, Col: col, Flag: str.Flag}, nil + return ctype{Type: sqltypes.VarChar, Col: col, Flag: nullableFlags(str.Flag)}, nil } type builtinSHA2 struct { @@ -189,7 +189,7 @@ func (call *builtinSHA2) compile(c *compiler) (ctype, error) { col := typedCoercionCollation(sqltypes.VarChar, c.collation) c.asm.Fn_SHA2(col) c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sqltypes.VarChar, Col: col, Flag: str.Flag | flagNullable}, nil + return ctype{Type: sqltypes.VarChar, Col: col, Flag: nullableFlags(str.Flag)}, nil } type builtinRandomBytes struct { @@ -244,5 +244,5 @@ func (call *builtinRandomBytes) compile(c *compiler) (ctype, error) { c.asm.Fn_RandomBytes() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.VarBinary, Col: collationBinary, Flag: arg.Flag | flagNullable}, nil + return ctype{Type: sqltypes.VarBinary, Col: collationBinary, Flag: nullableFlags(arg.Flag) | flagNullable}, nil } diff --git a/go/vt/vtgate/evalengine/fn_hex.go b/go/vt/vtgate/evalengine/fn_hex.go index 8552ab888ae..c52aa4ed756 100644 --- a/go/vt/vtgate/evalengine/fn_hex.go +++ b/go/vt/vtgate/evalengine/fn_hex.go @@ -79,7 +79,7 @@ func (call *builtinHex) compile(c *compiler) (ctype, error) { c.asm.jumpDestination(skip) - return ctype{Type: t, Col: col}, nil + return ctype{Type: t, Flag: nullableFlags(str.Flag), Col: col}, nil } type builtinUnhex struct { diff --git a/go/vt/vtgate/evalengine/fn_json.go b/go/vt/vtgate/evalengine/fn_json.go index 53930b4678b..54038e28339 100644 --- a/go/vt/vtgate/evalengine/fn_json.go +++ b/go/vt/vtgate/evalengine/fn_json.go @@ -402,7 +402,7 @@ func (call *builtinJSONContainsPath) compile(c *compiler) (ctype, error) { } c.asm.Fn_JSON_CONTAINS_PATH(match, paths) - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean}, nil + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean | flagNullable}, nil } type jsonMatch int8 diff --git a/go/vt/vtgate/evalengine/fn_misc.go b/go/vt/vtgate/evalengine/fn_misc.go index 2f228ff55fa..cfa14cafa80 100644 --- a/go/vt/vtgate/evalengine/fn_misc.go +++ b/go/vt/vtgate/evalengine/fn_misc.go @@ -297,7 +297,7 @@ func (call *builtinIsIPV4) compile(c *compiler) (ctype, error) { c.asm.Fn_IS_IPV4() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: arg.Flag | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func (call *builtinIsIPV4Compat) eval(env *ExpressionEnv) (eval, error) { @@ -328,7 +328,7 @@ func (call *builtinIsIPV4Compat) compile(c *compiler) (ctype, error) { c.asm.SetBool(1, false) } c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: arg.Flag | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func (call *builtinIsIPV4Mapped) eval(env *ExpressionEnv) (eval, error) { @@ -359,7 +359,7 @@ func (call *builtinIsIPV4Mapped) compile(c *compiler) (ctype, error) { c.asm.SetBool(1, false) } c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: arg.Flag | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func (call *builtinIsIPV6) eval(env *ExpressionEnv) (eval, error) { @@ -391,7 +391,7 @@ func (call *builtinIsIPV6) compile(c *compiler) (ctype, error) { c.asm.Fn_IS_IPV6() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: arg.Flag | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func errIncorrectUUID(in []byte, f string) error { @@ -463,7 +463,7 @@ func (call *builtinBinToUUID) compile(c *compiler) (ctype, error) { } col := typedCoercionCollation(sqltypes.VarChar, call.collate) - ct := ctype{Type: sqltypes.VarChar, Flag: arg.Flag, Col: col} + ct := ctype{Type: sqltypes.VarChar, Flag: nullableFlags(arg.Flag), Col: col} if len(call.Arguments) == 1 { c.asm.Fn_BIN_TO_UUID0(col) @@ -517,7 +517,7 @@ func (call *builtinIsUUID) compile(c *compiler) (ctype, error) { c.asm.Fn_IS_UUID() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Flag: arg.Flag | flagIsBoolean, Col: collationNumeric}, nil + return ctype{Type: sqltypes.Int64, Flag: nullableFlags(arg.Flag) | flagIsBoolean, Col: collationNumeric}, nil } func (call *builtinUUID) eval(env *ExpressionEnv) (eval, error) { @@ -583,7 +583,7 @@ func (call *builtinUUIDToBin) compile(c *compiler) (ctype, error) { c.asm.Convert_xb(1, sqltypes.VarBinary, 0, false) } - ct := ctype{Type: sqltypes.VarBinary, Flag: arg.Flag, Col: collationBinary} + ct := ctype{Type: sqltypes.VarBinary, Flag: nullableFlags(arg.Flag), Col: collationBinary} if len(call.Arguments) == 1 { c.asm.Fn_UUID_TO_BIN0() diff --git a/go/vt/vtgate/evalengine/fn_numeric.go b/go/vt/vtgate/evalengine/fn_numeric.go index 7bdd8d8b92e..deeb53a3186 100644 --- a/go/vt/vtgate/evalengine/fn_numeric.go +++ b/go/vt/vtgate/evalengine/fn_numeric.go @@ -149,7 +149,7 @@ func (expr *builtinAbs) compile(c *compiler) (ctype, error) { skip := c.compileNullCheck1(arg) - convt := ctype{Type: arg.Type, Col: collationNumeric, Flag: arg.Flag} + convt := ctype{Type: arg.Type, Col: collationNumeric, Flag: nullableFlags(arg.Flag)} switch arg.Type { case sqltypes.Int64: c.asm.Fn_ABS_i() @@ -302,7 +302,7 @@ func (expr *builtinAtan2) compile(c *compiler) (ctype, error) { c.compileToFloat(arg2, 1) c.asm.Fn_ATAN2() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: arg1.Flag | arg2.Flag}, nil + return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: nullableFlags(arg1.Flag | arg2.Flag)}, nil } type builtinCos struct { @@ -538,7 +538,7 @@ func (expr *builtinLog) compile(c *compiler) (ctype, error) { c.compileToFloat(arg2, 1) c.asm.Fn_LOG() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: arg1.Flag | arg2.Flag}, nil + return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: nullableFlags(arg1.Flag | arg2.Flag)}, nil } type builtinLog10 struct { @@ -638,7 +638,7 @@ func (expr *builtinPow) compile(c *compiler) (ctype, error) { c.compileToFloat(arg2, 1) c.asm.Fn_POW() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: arg1.Flag | arg2.Flag | flagNullable}, nil + return ctype{Type: sqltypes.Float64, Col: collationNumeric, Flag: nullableFlags(arg1.Flag | arg2.Flag)}, nil } type builtinSign struct { @@ -718,7 +718,7 @@ func (expr *builtinSign) compile(c *compiler) (ctype, error) { } c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: nullableFlags(arg.Flag)}, nil } type builtinSqrt struct { diff --git a/go/vt/vtgate/evalengine/fn_string.go b/go/vt/vtgate/evalengine/fn_string.go index 8d61905d237..97d461a44d6 100644 --- a/go/vt/vtgate/evalengine/fn_string.go +++ b/go/vt/vtgate/evalengine/fn_string.go @@ -245,7 +245,7 @@ func (call *builtinASCII) compile(c *compiler) (ctype, error) { c.asm.Fn_ASCII() c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: str.Flag}, nil + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: nullableFlags(str.Flag)}, nil } func charOrd(b []byte, coll collations.ID) int64 { @@ -300,7 +300,7 @@ func (call *builtinOrd) compile(c *compiler) (ctype, error) { c.asm.Fn_ORD(col) c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: str.Flag}, nil + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: nullableFlags(str.Flag)}, nil } // maxRepeatLength is the maximum number of times a string can be repeated. @@ -719,7 +719,7 @@ func (call *builtinPad) compile(c *compiler) (ctype, error) { c.asm.Fn_RPAD(col) } c.asm.jumpDestination(skip) - return ctype{Type: sqltypes.VarChar, Col: col}, nil + return ctype{Type: sqltypes.VarChar, Flag: flagNullable, Col: col}, nil } func strcmpCollate(left, right []byte, col collations.ID) int64 { @@ -814,7 +814,7 @@ func (expr *builtinStrcmp) compile(c *compiler) (ctype, error) { c.asm.Strcmp(mcol) c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagNullable}, nil + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: nullableFlags(lt.Flag | rt.Flag)}, nil } func (call builtinTrim) eval(env *ExpressionEnv) (eval, error) { @@ -898,7 +898,7 @@ func (call builtinTrim) compile(c *compiler) (ctype, error) { c.asm.Fn_TRIM1(col) } c.asm.jumpDestination(skip1) - return ctype{Type: sqltypes.VarChar, Col: col}, nil + return ctype{Type: sqltypes.VarChar, Flag: nullableFlags(str.Flag), Col: col}, nil } pat, err := call.Arguments[1].compile(c) @@ -929,7 +929,7 @@ func (call builtinTrim) compile(c *compiler) (ctype, error) { } c.asm.jumpDestination(skip1, skip2) - return ctype{Type: sqltypes.VarChar, Col: col}, nil + return ctype{Type: sqltypes.VarChar, Flag: flagNullable, Col: col}, nil } type builtinConcat struct { diff --git a/go/vt/vtgate/evalengine/testcases/inputs.go b/go/vt/vtgate/evalengine/testcases/inputs.go index c6796ba5d32..afdb5d6e225 100644 --- a/go/vt/vtgate/evalengine/testcases/inputs.go +++ b/go/vt/vtgate/evalengine/testcases/inputs.go @@ -93,6 +93,8 @@ var inputConversions = []string{ `0x0`, `0x1`, `0xff`, `X'00'`, `X'01'`, `X'ff'`, `0b1001`, `b'1001'`, `0x9`, `x'09'`, "NULL", "true", "false", + "NULL * 1", "1 * NULL", "NULL * NULL", "NULL / 1", "1 / NULL", "NULL / NULL", + "NULL + 1", "1 + NULL", "NULL + NULL", "NULL - 1", "1 - NULL", "NULL - NULL", "0xFF666F6F626172FF", "0x666F6F626172FF", "0xFF666F6F626172", "9223372036854775807", "-9223372036854775808", "18446744073709551615", "18446744073709540000e0", diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index f3544c1362e..6607b3d0af4 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -755,7 +755,7 @@ func TestSelectLastInsertId(t *testing.T) { result, err := executorExec(ctx, executor, session, sql, map[string]*querypb.BindVariable{}) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "last_insert_id()", Type: sqltypes.Uint64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_UNSIGNED_FLAG)}, + {Name: "last_insert_id()", Type: sqltypes.Uint64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_UNSIGNED_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewUint64(52), @@ -787,20 +787,20 @@ func TestSelectSystemVariables(t *testing.T) { result, err := executorExec(ctx, executor, session, sql, map[string]*querypb.BindVariable{}) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "@@autocommit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@client_found_rows", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@skip_query_plan_cache", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@enable_system_settings", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@sql_select_limit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@transaction_mode", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@workload", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@read_after_write_gtid", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@read_after_write_timeout", Type: sqltypes.Float64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@session_track_gtids", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@ddl_strategy", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@migration_context", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@socket", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, - {Name: "@@query_timeout", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@autocommit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@client_found_rows", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@skip_query_plan_cache", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@enable_system_settings", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@sql_select_limit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@transaction_mode", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@workload", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@read_after_write_gtid", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@read_after_write_timeout", Type: sqltypes.Float64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@session_track_gtids", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@ddl_strategy", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@migration_context", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@socket", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, + {Name: "@@query_timeout", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, Rows: [][]sqltypes.Value{{ // the following are the uninitialised session values @@ -843,9 +843,9 @@ func TestSelectInitializedVitessAwareVariable(t *testing.T) { result, err := executorExec(ctx, executor, session, sql, nil) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "@@autocommit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@enable_system_settings", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, - {Name: "@@query_timeout", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@autocommit", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@enable_system_settings", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "@@query_timeout", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), @@ -884,7 +884,7 @@ func TestSelectUserDefinedVariable(t *testing.T) { require.NoError(t, err) wantResult = &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "@foo", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, + {Name: "@foo", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewVarChar("bar"), @@ -910,7 +910,7 @@ func TestFoundRows(t *testing.T) { result, err := executorExec(ctx, executor, session, sql, map[string]*querypb.BindVariable{}) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "found_rows()", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "found_rows()", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), @@ -943,7 +943,7 @@ func testRowCount(t *testing.T, ctx context.Context, executor *Executor, session result, err := executorExec(ctx, executor, session, "select row_count()", map[string]*querypb.BindVariable{}) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "row_count()", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "row_count()", Type: sqltypes.Int64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(wantRowCount), @@ -964,7 +964,7 @@ func TestSelectLastInsertIdInUnion(t *testing.T) { result1 := []*sqltypes.Result{{ Fields: []*querypb.Field{ - {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, InsertID: 0, Rows: [][]sqltypes.Value{{ @@ -978,7 +978,7 @@ func TestSelectLastInsertIdInUnion(t *testing.T) { require.NoError(t, err) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG)}, + {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewInt32(52), @@ -1046,7 +1046,7 @@ func TestLastInsertIDInSubQueryExpression(t *testing.T) { require.NoError(t, err) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "x", Type: sqltypes.Uint64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_UNSIGNED_FLAG)}, + {Name: "x", Type: sqltypes.Uint64, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_UNSIGNED_FLAG)}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewUint64(12345), @@ -1077,7 +1077,7 @@ func TestSelectDatabase(t *testing.T) { map[string]*querypb.BindVariable{}) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ - {Name: "database()", Type: sqltypes.VarChar, Charset: uint32(collations.Default()), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG)}, + {Name: "database()", Type: sqltypes.VarChar, Charset: uint32(collations.Default())}, }, Rows: [][]sqltypes.Value{{ sqltypes.NewVarChar("TestExecutor@primary"), From 6547619939b4a2f1ebf80a717273bdf70719342c Mon Sep 17 00:00:00 2001 From: Prakhar Gurunani Date: Tue, 21 Nov 2023 21:36:05 +0530 Subject: [PATCH 034/119] fix: mismatch in column count and value count (#14417) Signed-off-by: Prakhar Gurunani --- go/vt/vtgate/planbuilder/operators/insert.go | 3 +++ go/vt/vtgate/planbuilder/testdata/dml_cases.json | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index e3f0748b78b..fa2f60dcecc 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -641,6 +641,9 @@ func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, v case sqlparser.Values: autoIncValues := make(sqlparser.ValTuple, 0, len(rows)) for rowNum, row := range rows { + if len(ins.Columns) != len(row) { + return nil, vterrors.VT03006() + } // Support the DEFAULT keyword by treating it as null if _, ok := row[colNum].(*sqlparser.Default); ok { row[colNum] = &sqlparser.NullVal{} diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index eebcf63edf3..5ec8210b12d 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -4889,5 +4889,15 @@ "comment": "Unsupported update statement with a replica target destination", "query": "update `user[-]@replica`.user_metadata set id=2", "plan": "VT09002: update statement with a replica target" + }, + { + "comment": "insert row values smaller than number of columns", + "query": "insert into user(one, two, three, four) values (1, 2, 3)", + "plan": "VT03006: column count does not match value count at row 1" + }, + { + "comment": "insert row values greater than number of columns", + "query": "insert into user(one, two, three) values (1, 2, 3, 4)", + "plan": "VT03006: column count does not match value count at row 1" } ] From f89ade40d7fecf13e3ddd4dc4adf85056f46bd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Wed, 22 Nov 2023 01:55:16 +0100 Subject: [PATCH 035/119] expression rewriting: enable more rewrites and limit CNF rewrites (#14560) Co-authored-by: Florent Poinsard --- go/vt/sqlparser/predicate_rewriting.go | 71 +++++++++++++------ go/vt/sqlparser/predicate_rewriting_test.go | 16 ++++- go/vt/vtgate/executor_select_test.go | 2 +- .../planbuilder/testdata/filter_cases.json | 2 +- 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/go/vt/sqlparser/predicate_rewriting.go b/go/vt/sqlparser/predicate_rewriting.go index 40e9a953f57..9dcd239f9eb 100644 --- a/go/vt/sqlparser/predicate_rewriting.go +++ b/go/vt/sqlparser/predicate_rewriting.go @@ -20,11 +20,26 @@ import ( "vitess.io/vitess/go/vt/log" ) +// This is the number of OR expressions in a predicate that will disable the CNF +// rewrite because we don't want to send large queries to MySQL +const CNFOrLimit = 5 + // RewritePredicate walks the input AST and rewrites any boolean logic into a simpler form // This simpler form is CNF plus logic for extracting predicates from OR, plus logic for turning ORs into IN // Note: In order to re-plan, we need to empty the accumulated metadata in the AST, // so ColName.Metadata will be nil:ed out as part of this rewrite func RewritePredicate(ast SQLNode) SQLNode { + count := 0 + _ = Walk(func(node SQLNode) (bool, error) { + if _, isExpr := node.(*OrExpr); isExpr { + count++ + } + + return true, nil + }, ast) + + allowCNF := count < CNFOrLimit + for { printExpr(ast) exprChanged := false @@ -37,7 +52,7 @@ func RewritePredicate(ast SQLNode) SQLNode { return true } - rewritten, state := simplifyExpression(e) + rewritten, state := simplifyExpression(e, allowCNF) if ch, isChange := state.(changed); isChange { printRule(ch.rule, ch.exprMatched) exprChanged = true @@ -52,12 +67,12 @@ func RewritePredicate(ast SQLNode) SQLNode { } } -func simplifyExpression(expr Expr) (Expr, rewriteState) { +func simplifyExpression(expr Expr, allowCNF bool) (Expr, rewriteState) { switch expr := expr.(type) { case *NotExpr: return simplifyNot(expr) case *OrExpr: - return simplifyOr(expr) + return simplifyOr(expr, allowCNF) case *XorExpr: return simplifyXor(expr) case *AndExpr: @@ -113,14 +128,14 @@ func ExtractINFromOR(expr *OrExpr) []Expr { return uniquefy(ins) } -func simplifyOr(expr *OrExpr) (Expr, rewriteState) { +func simplifyOr(expr *OrExpr, allowCNF bool) (Expr, rewriteState) { or := expr // first we search for ANDs and see how they can be simplified land, lok := or.Left.(*AndExpr) rand, rok := or.Right.(*AndExpr) - switch { - case lok && rok: + + if lok && rok { // (<> AND <>) OR (<> AND <>) var a, b, c Expr var change changed @@ -128,40 +143,51 @@ func simplifyOr(expr *OrExpr) (Expr, rewriteState) { case Equals.Expr(land.Left, rand.Left): change = newChange("(A and B) or (A and C) => A AND (B OR C)", f(expr)) a, b, c = land.Left, land.Right, rand.Right + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change case Equals.Expr(land.Left, rand.Right): change = newChange("(A and B) or (C and A) => A AND (B OR C)", f(expr)) a, b, c = land.Left, land.Right, rand.Left + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change case Equals.Expr(land.Right, rand.Left): change = newChange("(B and A) or (A and C) => A AND (B OR C)", f(expr)) a, b, c = land.Right, land.Left, rand.Right + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change case Equals.Expr(land.Right, rand.Right): change = newChange("(B and A) or (C and A) => A AND (B OR C)", f(expr)) a, b, c = land.Right, land.Left, rand.Left - default: - return expr, noChange{} + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change } - return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change - case lok: - // (<> AND <>) OR <> + } + + // (<> AND <>) OR <> + if lok { // Simplification if Equals.Expr(or.Right, land.Left) || Equals.Expr(or.Right, land.Right) { return or.Right, newChange("(A AND B) OR A => A", f(expr)) } - // Distribution Law - return &AndExpr{Left: &OrExpr{Left: land.Left, Right: or.Right}, Right: &OrExpr{Left: land.Right, Right: or.Right}}, - newChange("(A AND B) OR C => (A OR C) AND (B OR C)", f(expr)) - case rok: - // <> OR (<> AND <>) + + if allowCNF { + // Distribution Law + return &AndExpr{Left: &OrExpr{Left: land.Left, Right: or.Right}, Right: &OrExpr{Left: land.Right, Right: or.Right}}, + newChange("(A AND B) OR C => (A OR C) AND (B OR C)", f(expr)) + } + } + + // <> OR (<> AND <>) + if rok { // Simplification if Equals.Expr(or.Left, rand.Left) || Equals.Expr(or.Left, rand.Right) { return or.Left, newChange("A OR (A AND B) => A", f(expr)) } - // Distribution Law - return &AndExpr{ - Left: &OrExpr{Left: or.Left, Right: rand.Left}, - Right: &OrExpr{Left: or.Left, Right: rand.Right}, - }, - newChange("C OR (A AND B) => (C OR A) AND (C OR B)", f(expr)) + + if allowCNF { + // Distribution Law + return &AndExpr{ + Left: &OrExpr{Left: or.Left, Right: rand.Left}, + Right: &OrExpr{Left: or.Left, Right: rand.Right}, + }, + newChange("C OR (A AND B) => (C OR A) AND (C OR B)", f(expr)) + } } // next, we want to try to turn multiple ORs into an IN when possible @@ -257,7 +283,6 @@ func simplifyAnd(expr *AndExpr) (Expr, rewriteState) { and := expr if or, ok := and.Left.(*OrExpr); ok { // Simplification - if Equals.Expr(or.Left, and.Right) { return and.Right, newChange("(A OR B) AND A => A", f(expr)) } diff --git a/go/vt/sqlparser/predicate_rewriting_test.go b/go/vt/sqlparser/predicate_rewriting_test.go index 34e23597894..fba3d2f01dd 100644 --- a/go/vt/sqlparser/predicate_rewriting_test.go +++ b/go/vt/sqlparser/predicate_rewriting_test.go @@ -91,7 +91,7 @@ func TestSimplifyExpression(in *testing.T) { expr, err := ParseExpr(tc.in) require.NoError(t, err) - expr, didRewrite := simplifyExpression(expr) + expr, didRewrite := simplifyExpression(expr, true) assert.True(t, didRewrite.changed()) assert.Equal(t, tc.expected, String(expr)) }) @@ -129,6 +129,17 @@ func TestRewritePredicate(in *testing.T) { }, { in: "A and (B or A)", expected: "A", + }, { + in: "(a = 1 and b = 41) or (a = 2 and b = 42)", + // this might look weird, but it allows the planner to either a or b in a vindex operation + expected: "a in (1, 2) and (a = 1 or b = 42) and ((b = 41 or a = 2) and b in (41, 42))", + }, { + in: "(a = 1 and b = 41) or (a = 2 and b = 42) or (a = 3 and b = 43)", + expected: "a in (1, 2, 3) and (a in (1, 2) or b = 43) and ((a = 1 or b = 42 or a = 3) and (a = 1 or b = 42 or b = 43)) and ((b = 41 or a = 2 or a = 3) and (b = 41 or a = 2 or b = 43) and ((b in (41, 42) or a = 3) and b in (41, 42, 43)))", + }, { + // this has too many OR expressions in it, so we don't even try the CNF rewriting + in: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", + expected: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", }} for _, tc := range tests { @@ -164,6 +175,9 @@ func TestExtractINFromOR(in *testing.T) { }, { in: "(a in (1, 5) and B or C and a in (5, 7))", expected: "a in (1, 5, 7)", + }, { + in: "(a = 5 and b = 1 or b = 2 and a = 6 or b = 3 and a = 4)", + expected: "", }} for _, tc := range tests { diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 6607b3d0af4..8f9fe064918 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -1275,7 +1275,7 @@ func TestSelectINFromOR(t *testing.T) { _, err := executorExec(ctx, executor, session, "select 1 from user where id = 1 and name = 'apa' or id = 2 and name = 'toto'", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select 1 from `user` where id = 1 and `name` = 'apa' or id = 2 and `name` = 'toto'", + Sql: "select 1 from `user` where id in ::__vals and (id = 1 or `name` = 'toto') and (`name` = 'apa' or id = 2) and `name` in ('apa', 'toto')", BindVariables: map[string]*querypb.BindVariable{ "__vals": sqltypes.TestBindVariable([]any{int64(1), int64(2)}), }, diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json index 83e675d89f6..2f8f9d73daa 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json @@ -4110,7 +4110,7 @@ "Sharded": true }, "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5 and `name` = 'foo' or id = 12 and `name` = 'bar'", + "Query": "select id from `user` where id in ::__vals and (id = 5 or `name` = 'bar') and (`name` = 'foo' or id = 12) and `name` in ('foo', 'bar')", "Table": "`user`", "Values": [ "(5, 12)" From 27820b5a235e6ef09f2efe52cc06596784d58e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Wed, 22 Nov 2023 16:24:22 +0100 Subject: [PATCH 036/119] planbuilder: push down ordering through filter (#14583) Signed-off-by: Andres Taylor --- .../planbuilder/operators/query_planning.go | 2 + .../testdata/postprocess_cases.json | 73 +++++++++---------- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 1738d35de43..ab140faf9b9 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -541,6 +541,8 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operat switch src := in.Source.(type) { case *Route: return rewrite.Swap(in, src, "push ordering under route") + case *Filter: + return rewrite.Swap(in, src, "push ordering under filter") case *ApplyJoin: if canPushLeft(ctx, src, in.Order) { // ApplyJoin is stable in regard to the columns coming from the LHS, diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json index 9373ae35a29..cf9bf68dfa4 100644 --- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json @@ -2021,54 +2021,47 @@ "QueryType": "SELECT", "Original": "select a.tcol1 from user a join music b where a.tcol1 = b.tcol2 group by a.tcol1 having repeat(a.tcol1,min(a.id)) like \"A\\%B\" order by a.tcol1", "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(0|2) ASC", + "OperatorType": "Filter", + "Predicate": "repeat(a.tcol1, min(a.id)) like 'A\\%B'", "ResultColumns": 1, "Inputs": [ { - "OperatorType": "Filter", - "Predicate": "repeat(a.tcol1, min(a.id)) like 'A\\%B'", + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "min(1|3) AS min(a.id)", + "GroupBy": "(0|2)", "Inputs": [ { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "min(1|3) AS min(a.id)", - "GroupBy": "(0|2)", + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:1,L:0,L:2,L:3", + "JoinVars": { + "a_tcol1": 1 + }, + "TableName": "`user`_music", "Inputs": [ { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:1,L:0,L:2,L:3", - "JoinVars": { - "a_tcol1": 1 + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select min(a.id), a.tcol1, weight_string(a.tcol1), weight_string(a.id) from `user` as a where 1 != 1 group by a.tcol1, weight_string(a.tcol1), weight_string(a.id)", + "OrderBy": "(1|2) ASC", + "Query": "select min(a.id), a.tcol1, weight_string(a.tcol1), weight_string(a.id) from `user` as a group by a.tcol1, weight_string(a.tcol1), weight_string(a.id) order by a.tcol1 asc", + "Table": "`user`" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select min(a.id), a.tcol1, weight_string(a.tcol1), weight_string(a.id) from `user` as a where 1 != 1 group by a.tcol1, weight_string(a.tcol1), weight_string(a.id)", - "OrderBy": "(1|2) ASC", - "Query": "select min(a.id), a.tcol1, weight_string(a.tcol1), weight_string(a.id) from `user` as a group by a.tcol1, weight_string(a.tcol1), weight_string(a.id) order by a.tcol1 asc", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music as b where 1 != 1 group by .0", - "Query": "select 1 from music as b where b.tcol2 = :a_tcol1 group by .0", - "Table": "music" - } - ] + "FieldQuery": "select 1 from music as b where 1 != 1 group by .0", + "Query": "select 1 from music as b where b.tcol2 = :a_tcol1 group by .0", + "Table": "music" } ] } From f56ab43a58e3b9fb65287c9e5385f8ea05af900b Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 22 Nov 2023 21:08:32 +0530 Subject: [PATCH 037/119] v18.0.1 release notes to main (#14579) Signed-off-by: Harshit Gangal --- changelog/18.0/18.0.1/changelog.md | 40 ++++++++++++++++++++++++++ changelog/18.0/18.0.1/release_notes.md | 7 +++++ changelog/18.0/README.md | 4 +++ 3 files changed, 51 insertions(+) create mode 100644 changelog/18.0/18.0.1/changelog.md create mode 100644 changelog/18.0/18.0.1/release_notes.md diff --git a/changelog/18.0/18.0.1/changelog.md b/changelog/18.0/18.0.1/changelog.md new file mode 100644 index 00000000000..efae252075f --- /dev/null +++ b/changelog/18.0/18.0.1/changelog.md @@ -0,0 +1,40 @@ +# Changelog of Vitess v18.0.1 + +### Bug fixes +#### Backup and Restore + * [release 18.0]: `ReadBinlogFilesTimestamps` backwards compatibility [#14526](https://github.com/vitessio/vitess/pull/14526) +#### Build/CI + * [release-18.0] Update create_release.sh (#14492) [#14516](https://github.com/vitessio/vitess/pull/14516) +#### Evalengine + * [release-18.0] Fix nullability checks in evalengine (#14556) [#14564](https://github.com/vitessio/vitess/pull/14564) +#### Examples + * [release-18.0] examples: fix flag syntax for zkctl (#14469) [#14487](https://github.com/vitessio/vitess/pull/14487) +#### Observability + * [release-18.0] Fix #14414: resilient_server metrics name/prefix logic is inverted, leading to no metrics being recorded (#14415) [#14527](https://github.com/vitessio/vitess/pull/14527) +#### Query Serving + * [release-18.0] Make column resolution closer to MySQL (#14426) [#14430](https://github.com/vitessio/vitess/pull/14430) + * [release-18.0] Bug fix: Use target tablet from health stats cache when checking replication status (#14436) [#14456](https://github.com/vitessio/vitess/pull/14456) + * [release-18.0] Ensure hexval and int don't share BindVar after Normalization (#14451) [#14479](https://github.com/vitessio/vitess/pull/14479) + * [release-18.0] planbuilder bugfix: expose columns through derived tables (#14501) [#14504](https://github.com/vitessio/vitess/pull/14504) + * [release-18.0] expression rewriting: enable more rewrites and limit CNF rewrites (#14560) [#14576](https://github.com/vitessio/vitess/pull/14576) +#### vtctldclient + * [release-18.0] vtctldclient: Apply tablet type filtering for keyspace+shard in GetTablets (#14467) [#14470](https://github.com/vitessio/vitess/pull/14470) +### CI/Build +#### Docker + * [release-18.0] Build and push Docker Images from GitHub Actions [#14511](https://github.com/vitessio/vitess/pull/14511) +### Dependabot +#### General + * [release-18.0] Bump google.golang.org/grpc from 1.55.0-dev to 1.59.0 (#14364) [#14498](https://github.com/vitessio/vitess/pull/14498) +### Documentation +#### Documentation + * [release-18.0] release notes: add FK import to summary (#14518) [#14519](https://github.com/vitessio/vitess/pull/14519) +### Internal Cleanup +#### Query Serving + * [release-18.0] Remove excessive VTGate logging of default planner selection (#14554) [#14561](https://github.com/vitessio/vitess/pull/14561) +### Release +#### General + * [release-18.0] Code Freeze for `v18.0.1` [#14549](https://github.com/vitessio/vitess/pull/14549) +### Testing +#### Query Serving + * [release-18.0] vtgate: Allow additional errors in warnings test (#14461) [#14465](https://github.com/vitessio/vitess/pull/14465) + diff --git a/changelog/18.0/18.0.1/release_notes.md b/changelog/18.0/18.0.1/release_notes.md new file mode 100644 index 00000000000..f6f07d6e652 --- /dev/null +++ b/changelog/18.0/18.0.1/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v18.0.1 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/18.0/18.0.1/changelog.md). + +The release includes 17 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @frouioui, @harshit-gangal, @shlomi-noach + diff --git a/changelog/18.0/README.md b/changelog/18.0/README.md index 97676dc7e39..0c86ff20af1 100644 --- a/changelog/18.0/README.md +++ b/changelog/18.0/README.md @@ -1,4 +1,8 @@ ## v18.0 +* **[18.0.1](18.0.1)** + * [Changelog](18.0.1/changelog.md) + * [Release Notes](18.0.1/release_notes.md) + * **[18.0.0](18.0.0)** * [Changelog](18.0.0/changelog.md) * [Release Notes](18.0.0/release_notes.md) From 85a4ffe062cdc78d9534f80f455008d2a7ac48b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 23 Nov 2023 11:20:43 +0100 Subject: [PATCH 038/119] bug fix: stop all kinds of expressions from cnf-exploding (#14585) Signed-off-by: Andres Taylor --- go/vt/sqlparser/predicate_rewriting.go | 391 ++++++++------------ go/vt/sqlparser/predicate_rewriting_test.go | 9 +- 2 files changed, 157 insertions(+), 243 deletions(-) diff --git a/go/vt/sqlparser/predicate_rewriting.go b/go/vt/sqlparser/predicate_rewriting.go index 9dcd239f9eb..7bad1b3b82f 100644 --- a/go/vt/sqlparser/predicate_rewriting.go +++ b/go/vt/sqlparser/predicate_rewriting.go @@ -16,32 +16,14 @@ limitations under the License. package sqlparser -import ( - "vitess.io/vitess/go/vt/log" -) - -// This is the number of OR expressions in a predicate that will disable the CNF -// rewrite because we don't want to send large queries to MySQL -const CNFOrLimit = 5 - // RewritePredicate walks the input AST and rewrites any boolean logic into a simpler form // This simpler form is CNF plus logic for extracting predicates from OR, plus logic for turning ORs into IN -// Note: In order to re-plan, we need to empty the accumulated metadata in the AST, -// so ColName.Metadata will be nil:ed out as part of this rewrite func RewritePredicate(ast SQLNode) SQLNode { - count := 0 - _ = Walk(func(node SQLNode) (bool, error) { - if _, isExpr := node.(*OrExpr); isExpr { - count++ - } - - return true, nil - }, ast) - - allowCNF := count < CNFOrLimit + original := CloneSQLNode(ast) - for { - printExpr(ast) + // Beware: converting to CNF in this loop might cause exponential formula growth. + // We bail out early to prevent going overboard. + for loop := 0; loop < 15; loop++ { exprChanged := false stopOnChange := func(SQLNode, SQLNode) bool { return !exprChanged @@ -52,9 +34,8 @@ func RewritePredicate(ast SQLNode) SQLNode { return true } - rewritten, state := simplifyExpression(e, allowCNF) - if ch, isChange := state.(changed); isChange { - printRule(ch.rule, ch.exprMatched) + rewritten, changed := simplifyExpression(e) + if changed { exprChanged = true cursor.Replace(rewritten) } @@ -65,70 +46,44 @@ func RewritePredicate(ast SQLNode) SQLNode { return ast } } + + return original } -func simplifyExpression(expr Expr, allowCNF bool) (Expr, rewriteState) { +func simplifyExpression(expr Expr) (Expr, bool) { switch expr := expr.(type) { case *NotExpr: return simplifyNot(expr) case *OrExpr: - return simplifyOr(expr, allowCNF) + return simplifyOr(expr) case *XorExpr: return simplifyXor(expr) case *AndExpr: return simplifyAnd(expr) } - return expr, noChange{} + return expr, false } -func simplifyNot(expr *NotExpr) (Expr, rewriteState) { +func simplifyNot(expr *NotExpr) (Expr, bool) { switch child := expr.Expr.(type) { case *NotExpr: - return child.Expr, - newChange("NOT NOT A => A", f(expr)) + return child.Expr, true case *OrExpr: - return &AndExpr{Right: &NotExpr{Expr: child.Right}, Left: &NotExpr{Expr: child.Left}}, - newChange("NOT (A OR B) => NOT A AND NOT B", f(expr)) + // not(or(a,b)) => and(not(a),not(b)) + return &AndExpr{Right: &NotExpr{Expr: child.Right}, Left: &NotExpr{Expr: child.Left}}, true case *AndExpr: - return &OrExpr{Right: &NotExpr{Expr: child.Right}, Left: &NotExpr{Expr: child.Left}}, - newChange("NOT (A AND B) => NOT A OR NOT B", f(expr)) + // not(and(a,b)) => or(not(a), not(b)) + return &OrExpr{Right: &NotExpr{Expr: child.Right}, Left: &NotExpr{Expr: child.Left}}, true } - return expr, noChange{} + return expr, false } -// ExtractINFromOR will add additional predicated to an OR. -// this rewriter should not be used in a fixed point way, since it returns the original expression with additions, -// and it will therefor OOM before it stops rewriting -func ExtractINFromOR(expr *OrExpr) []Expr { - // we check if we have two comparisons on either side of the OR - // that we can add as an ANDed comparison. - // WHERE (a = 5 and B) or (a = 6 AND C) => - // WHERE (a = 5 AND B) OR (a = 6 AND C) AND a IN (5,6) - // This rewrite makes it possible to find a better route than Scatter if the `a` column has a helpful vindex - lftPredicates := SplitAndExpression(nil, expr.Left) - rgtPredicates := SplitAndExpression(nil, expr.Right) - var ins []Expr - for _, lft := range lftPredicates { - l, ok := lft.(*ComparisonExpr) - if !ok { - continue - } - for _, rgt := range rgtPredicates { - r, ok := rgt.(*ComparisonExpr) - if !ok { - continue - } - in, state := tryTurningOrIntoIn(l, r) - if state.changed() { - ins = append(ins, in) - } - } +func simplifyOr(expr *OrExpr) (Expr, bool) { + res, rewritten := distinctOr(expr) + if rewritten { + return res, true } - return uniquefy(ins) -} - -func simplifyOr(expr *OrExpr, allowCNF bool) (Expr, rewriteState) { or := expr // first we search for ANDs and see how they can be simplified @@ -137,25 +92,21 @@ func simplifyOr(expr *OrExpr, allowCNF bool) (Expr, rewriteState) { if lok && rok { // (<> AND <>) OR (<> AND <>) + // or(and(T1,T2), and(T2, T3)) => and(T1, or(T2, T2)) var a, b, c Expr - var change changed switch { case Equals.Expr(land.Left, rand.Left): - change = newChange("(A and B) or (A and C) => A AND (B OR C)", f(expr)) a, b, c = land.Left, land.Right, rand.Right - return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, true case Equals.Expr(land.Left, rand.Right): - change = newChange("(A and B) or (C and A) => A AND (B OR C)", f(expr)) a, b, c = land.Left, land.Right, rand.Left - return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, true case Equals.Expr(land.Right, rand.Left): - change = newChange("(B and A) or (A and C) => A AND (B OR C)", f(expr)) a, b, c = land.Right, land.Left, rand.Right - return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, true case Equals.Expr(land.Right, rand.Right): - change = newChange("(B and A) or (C and A) => A AND (B OR C)", f(expr)) a, b, c = land.Right, land.Left, rand.Left - return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, change + return &AndExpr{Left: a, Right: &OrExpr{Left: b, Right: c}}, true } } @@ -163,31 +114,38 @@ func simplifyOr(expr *OrExpr, allowCNF bool) (Expr, rewriteState) { if lok { // Simplification if Equals.Expr(or.Right, land.Left) || Equals.Expr(or.Right, land.Right) { - return or.Right, newChange("(A AND B) OR A => A", f(expr)) + // or(and(a,b), c) => c where c=a or c=b + return or.Right, true } - if allowCNF { - // Distribution Law - return &AndExpr{Left: &OrExpr{Left: land.Left, Right: or.Right}, Right: &OrExpr{Left: land.Right, Right: or.Right}}, - newChange("(A AND B) OR C => (A OR C) AND (B OR C)", f(expr)) - } + // Distribution Law + // or(c, and(a,b)) => and(or(c,a), or(c,b)) + return &AndExpr{ + Left: &OrExpr{ + Left: land.Left, + Right: or.Right, + }, + Right: &OrExpr{ + Left: land.Right, + Right: or.Right, + }, + }, true } // <> OR (<> AND <>) if rok { // Simplification if Equals.Expr(or.Left, rand.Left) || Equals.Expr(or.Left, rand.Right) { - return or.Left, newChange("A OR (A AND B) => A", f(expr)) + // or(a,and(b,c)) => a + return or.Left, true } - if allowCNF { - // Distribution Law - return &AndExpr{ - Left: &OrExpr{Left: or.Left, Right: rand.Left}, - Right: &OrExpr{Left: or.Left, Right: rand.Right}, - }, - newChange("C OR (A AND B) => (C OR A) AND (C OR B)", f(expr)) - } + // Distribution Law + // or(and(a,b), c) => and(or(c,a), or(c,b)) + return &AndExpr{ + Left: &OrExpr{Left: or.Left, Right: rand.Left}, + Right: &OrExpr{Left: or.Left, Right: rand.Right}, + }, true } // next, we want to try to turn multiple ORs into an IN when possible @@ -195,63 +153,131 @@ func simplifyOr(expr *OrExpr, allowCNF bool) (Expr, rewriteState) { rgtCmp, rok := or.Right.(*ComparisonExpr) if lok && rok { newExpr, rewritten := tryTurningOrIntoIn(lftCmp, rgtCmp) - if rewritten.changed() { - return newExpr, rewritten + if rewritten { + // or(a=x,a=y) => in(a,[x,y]) + return newExpr, true } } // Try to make distinct - return distinctOr(expr) + result, changed := distinctOr(expr) + if changed { + return result, true + } + return result, false +} + +func simplifyXor(expr *XorExpr) (Expr, bool) { + // xor(a,b) => and(or(a,b), not(and(a,b)) + return &AndExpr{ + Left: &OrExpr{Left: expr.Left, Right: expr.Right}, + Right: &NotExpr{Expr: &AndExpr{Left: expr.Left, Right: expr.Right}}, + }, true } -func tryTurningOrIntoIn(l, r *ComparisonExpr) (Expr, rewriteState) { +func simplifyAnd(expr *AndExpr) (Expr, bool) { + res, rewritten := distinctAnd(expr) + if rewritten { + return res, true + } + and := expr + if or, ok := and.Left.(*OrExpr); ok { + // Simplification + // and(or(a,b),c) => c when c=a or c=b + if Equals.Expr(or.Left, and.Right) { + return and.Right, true + } + if Equals.Expr(or.Right, and.Right) { + return and.Right, true + } + } + if or, ok := and.Right.(*OrExpr); ok { + // Simplification + if Equals.Expr(or.Left, and.Left) { + return and.Left, true + } + if Equals.Expr(or.Right, and.Left) { + return and.Left, true + } + } + + return expr, false +} + +// ExtractINFromOR will add additional predicated to an OR. +// this rewriter should not be used in a fixed point way, since it returns the original expression with additions, +// and it will therefor OOM before it stops rewriting +func ExtractINFromOR(expr *OrExpr) []Expr { + // we check if we have two comparisons on either side of the OR + // that we can add as an ANDed comparison. + // WHERE (a = 5 and B) or (a = 6 AND C) => + // WHERE (a = 5 AND B) OR (a = 6 AND C) AND a IN (5,6) + // This rewrite makes it possible to find a better route than Scatter if the `a` column has a helpful vindex + lftPredicates := SplitAndExpression(nil, expr.Left) + rgtPredicates := SplitAndExpression(nil, expr.Right) + var ins []Expr + for _, lft := range lftPredicates { + l, ok := lft.(*ComparisonExpr) + if !ok { + continue + } + for _, rgt := range rgtPredicates { + r, ok := rgt.(*ComparisonExpr) + if !ok { + continue + } + in, changed := tryTurningOrIntoIn(l, r) + if changed { + ins = append(ins, in) + } + } + } + + return uniquefy(ins) +} + +func tryTurningOrIntoIn(l, r *ComparisonExpr) (Expr, bool) { // looks for A = X OR A = Y and turns them into A IN (X, Y) col, ok := l.Left.(*ColName) if !ok || !Equals.Expr(col, r.Left) { - return nil, noChange{} + return nil, false } var tuple ValTuple - var ruleStr string + switch l.Operator { case EqualOp: tuple = ValTuple{l.Right} - ruleStr = "A = <>" case InOp: lft, ok := l.Right.(ValTuple) if !ok { - return nil, noChange{} + return nil, false } tuple = lft - ruleStr = "A IN (<>, <>)" default: - return nil, noChange{} + return nil, false } - ruleStr += " OR " - switch r.Operator { case EqualOp: tuple = append(tuple, r.Right) - ruleStr += "A = <>" + case InOp: lft, ok := r.Right.(ValTuple) if !ok { - return nil, noChange{} + return nil, false } tuple = append(tuple, lft...) - ruleStr += "A IN (<>, <>)" + default: - return nil, noChange{} + return nil, false } - ruleStr += " => A IN (<>, <>)" - return &ComparisonExpr{ Operator: InOp, Left: col, Right: uniquefy(tuple), - }, newChange(ruleStr, f(&OrExpr{Left: l, Right: r})) + }, true } func uniquefy(tuple ValTuple) (output ValTuple) { @@ -267,44 +293,7 @@ outer: return } -func simplifyXor(expr *XorExpr) (Expr, rewriteState) { - // DeMorgan Rewriter - return &AndExpr{ - Left: &OrExpr{Left: expr.Left, Right: expr.Right}, - Right: &NotExpr{Expr: &AndExpr{Left: expr.Left, Right: expr.Right}}, - }, newChange("(A XOR B) => (A OR B) AND NOT (A AND B)", f(expr)) -} - -func simplifyAnd(expr *AndExpr) (Expr, rewriteState) { - res, rewritten := distinctAnd(expr) - if rewritten.changed() { - return res, rewritten - } - and := expr - if or, ok := and.Left.(*OrExpr); ok { - // Simplification - if Equals.Expr(or.Left, and.Right) { - return and.Right, newChange("(A OR B) AND A => A", f(expr)) - } - if Equals.Expr(or.Right, and.Right) { - return and.Right, newChange("(A OR B) AND B => B", f(expr)) - } - } - if or, ok := and.Right.(*OrExpr); ok { - // Simplification - if Equals.Expr(or.Left, and.Left) { - return and.Left, newChange("A AND (A OR B) => A", f(expr)) - } - if Equals.Expr(or.Right, and.Left) { - return and.Left, newChange("A AND (B OR A) => A", f(expr)) - } - } - - return expr, noChange{} -} - -func distinctOr(in *OrExpr) (Expr, rewriteState) { - var skipped []*OrExpr +func distinctOr(in *OrExpr) (result Expr, changed bool) { todo := []*OrExpr{in} var leaves []Expr for len(todo) > 0 { @@ -321,27 +310,23 @@ func distinctOr(in *OrExpr) (Expr, rewriteState) { addAnd(curr.Left) addAnd(curr.Right) } - original := len(leaves) + var predicates []Expr outer1: - for len(leaves) > 0 { - curr := leaves[0] - leaves = leaves[1:] + for _, curr := range leaves { for _, alreadyIn := range predicates { if Equals.Expr(alreadyIn, curr) { - if log.V(0) { - skipped = append(skipped, &OrExpr{Left: alreadyIn, Right: curr}) - } + changed = true continue outer1 } } predicates = append(predicates, curr) } - if original == len(predicates) { - return in, noChange{} + if !changed { + return in, false } - var result Expr + for i, curr := range predicates { if i == 0 { result = curr @@ -350,25 +335,10 @@ outer1: result = &OrExpr{Left: result, Right: curr} } - return result, newChange("A OR A => A", func() Expr { - var result Expr - for _, orExpr := range skipped { - if result == nil { - result = orExpr - continue - } - - result = &OrExpr{ - Left: result, - Right: orExpr, - } - } - return result - }) + return } -func distinctAnd(in *AndExpr) (Expr, rewriteState) { - var skipped []*AndExpr +func distinctAnd(in *AndExpr) (result Expr, changed bool) { todo := []*AndExpr{in} var leaves []Expr for len(todo) > 0 { @@ -384,25 +354,23 @@ func distinctAnd(in *AndExpr) (Expr, rewriteState) { addExpr(curr.Left) addExpr(curr.Right) } - original := len(leaves) var predicates []Expr outer1: for _, curr := range leaves { for _, alreadyIn := range predicates { if Equals.Expr(alreadyIn, curr) { - if log.V(0) { - skipped = append(skipped, &AndExpr{Left: alreadyIn, Right: curr}) - } + changed = true continue outer1 } } predicates = append(predicates, curr) } - if original == len(predicates) { - return in, noChange{} + + if !changed { + return in, false } - var result Expr + for i, curr := range predicates { if i == 0 { result = curr @@ -410,62 +378,5 @@ outer1: } result = &AndExpr{Left: result, Right: curr} } - return AndExpressions(leaves...), newChange("A AND A => A", func() Expr { - var result Expr - for _, andExpr := range skipped { - if result == nil { - result = andExpr - continue - } - - result = &AndExpr{ - Left: result, - Right: andExpr, - } - } - return result - }) -} - -type ( - rewriteState interface { - changed() bool - } - noChange struct{} - - // changed makes it possible to make sure we have a rule string for each change we do in the expression tree - changed struct { - rule string - - // ExprMatched is a function here so building of this expression can be paid only when we are debug logging - exprMatched func() Expr - } -) - -func (noChange) changed() bool { return false } -func (changed) changed() bool { return true } - -// f returns a function that returns the expression. It's short by design, so it interferes minimally -// used for logging -func f(e Expr) func() Expr { - return func() Expr { return e } -} - -func printRule(rule string, expr func() Expr) { - if log.V(10) { - log.Infof("Rule: %s ON %s", rule, String(expr())) - } -} - -func printExpr(expr SQLNode) { - if log.V(10) { - log.Infof("Current: %s", String(expr)) - } -} - -func newChange(rule string, exprMatched func() Expr) changed { - return changed{ - rule: rule, - exprMatched: exprMatched, - } + return AndExpressions(leaves...), true } diff --git a/go/vt/sqlparser/predicate_rewriting_test.go b/go/vt/sqlparser/predicate_rewriting_test.go index fba3d2f01dd..e106a56f1aa 100644 --- a/go/vt/sqlparser/predicate_rewriting_test.go +++ b/go/vt/sqlparser/predicate_rewriting_test.go @@ -91,8 +91,8 @@ func TestSimplifyExpression(in *testing.T) { expr, err := ParseExpr(tc.in) require.NoError(t, err) - expr, didRewrite := simplifyExpression(expr, true) - assert.True(t, didRewrite.changed()) + expr, changed := simplifyExpression(expr) + assert.True(t, changed) assert.Equal(t, tc.expected, String(expr)) }) } @@ -137,9 +137,12 @@ func TestRewritePredicate(in *testing.T) { in: "(a = 1 and b = 41) or (a = 2 and b = 42) or (a = 3 and b = 43)", expected: "a in (1, 2, 3) and (a in (1, 2) or b = 43) and ((a = 1 or b = 42 or a = 3) and (a = 1 or b = 42 or b = 43)) and ((b = 41 or a = 2 or a = 3) and (b = 41 or a = 2 or b = 43) and ((b in (41, 42) or a = 3) and b in (41, 42, 43)))", }, { - // this has too many OR expressions in it, so we don't even try the CNF rewriting + // the following two tests show some pathological cases that would grow too much, and so we abort the rewriting in: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", expected: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", + }, { + in: "not n0 xor not (n2 and n3) xor (not n2 and (n1 xor n1) xor (n0 xor n0 xor n2))", + expected: "not n0 xor not (n2 and n3) xor (not n2 and (n1 xor n1) xor (n0 xor n0 xor n2))", }} for _, tc := range tests { From d73d9e2d0a46f6a58cd3e44feb97f583c8b44e2f Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 23 Nov 2023 16:44:04 +0530 Subject: [PATCH 039/119] fix concurrency on stream execute engine primitives (#14586) Signed-off-by: Harshit Gangal Signed-off-by: Dirkjan Bussink Co-authored-by: Dirkjan Bussink --- go/vt/vtgate/engine/distinct.go | 6 +- go/vt/vtgate/engine/distinct_test.go | 53 +++++++++++++++++ go/vt/vtgate/engine/fake_primitive_test.go | 51 +++++++++++++++- go/vt/vtgate/engine/filter.go | 6 ++ go/vt/vtgate/engine/filter_test.go | 60 +++++++++++++++++++ go/vt/vtgate/engine/limit.go | 6 +- go/vt/vtgate/engine/limit_test.go | 67 ++++++++++++++++++++++ go/vt/vtgate/engine/memory_sort.go | 5 ++ go/vt/vtgate/engine/memory_sort_test.go | 54 +++++++++++++++++ go/vt/vtgate/engine/projection.go | 3 + go/vt/vtgate/engine/projection_test.go | 55 ++++++++++++++++-- 11 files changed, 356 insertions(+), 10 deletions(-) diff --git a/go/vt/vtgate/engine/distinct.go b/go/vt/vtgate/engine/distinct.go index 7e55138e27e..2d263464a2e 100644 --- a/go/vt/vtgate/engine/distinct.go +++ b/go/vt/vtgate/engine/distinct.go @@ -19,6 +19,7 @@ package engine import ( "context" "fmt" + "sync" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/sqltypes" @@ -197,13 +198,16 @@ func (d *Distinct) TryExecute(ctx context.Context, vcursor VCursor, bindVars map // TryStreamExecute implements the Primitive interface func (d *Distinct) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - pt := newProbeTable(d.CheckCols) + var mu sync.Mutex + pt := newProbeTable(d.CheckCols) err := vcursor.StreamExecutePrimitive(ctx, d.Source, bindVars, wantfields, func(input *sqltypes.Result) error { result := &sqltypes.Result{ Fields: input.Fields, InsertID: input.InsertID, } + mu.Lock() + defer mu.Unlock() for _, row := range input.Rows { exists, err := pt.exists(row) if err != nil { diff --git a/go/vt/vtgate/engine/distinct_test.go b/go/vt/vtgate/engine/distinct_test.go index 4ec3c1c0f4a..a1591403f92 100644 --- a/go/vt/vtgate/engine/distinct_test.go +++ b/go/vt/vtgate/engine/distinct_test.go @@ -130,6 +130,59 @@ func TestDistinct(t *testing.T) { } } +func TestDistinctStreamAsync(t *testing.T) { + distinct := &Distinct{ + Source: &fakePrimitive{ + results: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("myid|id|num|name", "varchar|int64|int64|varchar"), + "a|1|1|a", + "a|1|1|a", + "a|1|1|a", + "a|1|1|a", + "---", + "c|1|1|a", + "a|1|1|a", + "z|1|1|a", + "a|1|1|t", + "a|1|1|a", + "a|1|1|a", + "a|1|1|a", + "---", + "c|1|1|a", + "a|1|1|a", + "---", + "c|1|1|a", + "a|1|1|a", + "a|1|1|a", + "c|1|1|a", + "a|1|1|a", + "a|1|1|a", + "---", + "c|1|1|a", + "a|1|1|a", + ), + async: true, + }, + CheckCols: []CheckCol{ + {Col: 0, Type: evalengine.NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)}, + {Col: 1, Type: evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)}, + {Col: 2, Type: evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)}, + {Col: 3, Type: evalengine.NewType(sqltypes.VarChar, collations.CollationUtf8mb4ID)}, + }, + } + + qr := &sqltypes.Result{} + err := distinct.TryStreamExecute(context.Background(), &noopVCursor{}, nil, true, func(result *sqltypes.Result) error { + qr.Rows = append(qr.Rows, result.Rows...) + return nil + }) + require.NoError(t, err) + require.NoError(t, sqltypes.RowsEqualsStr(` +[[VARCHAR("c") INT64(1) INT64(1) VARCHAR("a")] +[VARCHAR("a") INT64(1) INT64(1) VARCHAR("a")] +[VARCHAR("z") INT64(1) INT64(1) VARCHAR("a")] +[VARCHAR("a") INT64(1) INT64(1) VARCHAR("t")]]`, qr.Rows)) +} + func TestWeightStringFallBack(t *testing.T) { offsetOne := 1 checkCols := []CheckCol{{ diff --git a/go/vt/vtgate/engine/fake_primitive_test.go b/go/vt/vtgate/engine/fake_primitive_test.go index dcec32f1ffd..e992c2a4623 100644 --- a/go/vt/vtgate/engine/fake_primitive_test.go +++ b/go/vt/vtgate/engine/fake_primitive_test.go @@ -23,8 +23,9 @@ import ( "strings" "testing" - "vitess.io/vitess/go/sqltypes" + "golang.org/x/sync/errgroup" + "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -41,6 +42,8 @@ type fakePrimitive struct { log []string allResultsInOneCall bool + + async bool } func (f *fakePrimitive) Inputs() ([]Primitive, []map[string]any) { @@ -86,6 +89,13 @@ func (f *fakePrimitive) TryStreamExecute(ctx context.Context, vcursor VCursor, b return f.sendErr } + if f.async { + return f.asyncCall(callback) + } + return f.syncCall(wantfields, callback) +} + +func (f *fakePrimitive) syncCall(wantfields bool, callback func(*sqltypes.Result) error) error { readMoreResults := true for readMoreResults && f.curResult < len(f.results) { readMoreResults = f.allResultsInOneCall @@ -116,9 +126,46 @@ func (f *fakePrimitive) TryStreamExecute(ctx context.Context, vcursor VCursor, b } } } - return nil } + +func (f *fakePrimitive) asyncCall(callback func(*sqltypes.Result) error) error { + var g errgroup.Group + var fields []*querypb.Field + if len(f.results) > 0 { + fields = f.results[0].Fields + } + for _, res := range f.results { + qr := res + g.Go(func() error { + if qr == nil { + return f.sendErr + } + if err := callback(&sqltypes.Result{Fields: fields}); err != nil { + return err + } + result := &sqltypes.Result{} + for i := 0; i < len(qr.Rows); i++ { + result.Rows = append(result.Rows, qr.Rows[i]) + // Send only two rows at a time. + if i%2 == 1 { + if err := callback(result); err != nil { + return err + } + result = &sqltypes.Result{} + } + } + if len(result.Rows) != 0 { + if err := callback(result); err != nil { + return err + } + } + return nil + }) + } + return g.Wait() +} + func (f *fakePrimitive) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { f.log = append(f.log, fmt.Sprintf("GetFields %v", printBindVars(bindVars))) return f.TryExecute(ctx, vcursor, bindVars, true /* wantfields */) diff --git a/go/vt/vtgate/engine/filter.go b/go/vt/vtgate/engine/filter.go index c0a54f2b6ac..78e9dde4ee2 100644 --- a/go/vt/vtgate/engine/filter.go +++ b/go/vt/vtgate/engine/filter.go @@ -18,6 +18,7 @@ package engine import ( "context" + "sync" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -78,9 +79,14 @@ func (f *Filter) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[s // TryStreamExecute satisfies the Primitive interface. func (f *Filter) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + var mu sync.Mutex + env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) filter := func(results *sqltypes.Result) error { var rows [][]sqltypes.Value + + mu.Lock() + defer mu.Unlock() for _, row := range results.Rows { env.Row = row evalResult, err := env.Evaluate(f.Predicate) diff --git a/go/vt/vtgate/engine/filter_test.go b/go/vt/vtgate/engine/filter_test.go index 9a8335e4d7e..7d3c2cd0696 100644 --- a/go/vt/vtgate/engine/filter_test.go +++ b/go/vt/vtgate/engine/filter_test.go @@ -83,3 +83,63 @@ func TestFilterPass(t *testing.T) { }) } } + +func TestFilterStreaming(t *testing.T) { + utf8mb4Bin := collationEnv.LookupByName("utf8mb4_bin") + predicate := &sqlparser.ComparisonExpr{ + Operator: sqlparser.GreaterThanOp, + Left: sqlparser.NewColName("left"), + Right: sqlparser.NewColName("right"), + } + + tcases := []struct { + name string + res []*sqltypes.Result + expRes string + }{{ + name: "int32", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "int32|int32"), "0|1", "---", "1|0", "2|3"), + expRes: `[[INT32(1) INT32(0)]]`, + }, { + name: "uint16", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "uint16|uint16"), "0|1", "1|0", "---", "2|3"), + expRes: `[[UINT16(1) UINT16(0)]]`, + }, { + name: "uint64_int64", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "uint64|int64"), "0|1", "---", "1|0", "2|3"), + expRes: `[[UINT64(1) INT64(0)]]`, + }, { + name: "int32_uint32", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "int32|uint32"), "0|1", "---", "1|0", "---", "2|3"), + expRes: `[[INT32(1) UINT32(0)]]`, + }, { + name: "uint16_int8", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "uint16|int8"), "0|1", "1|0", "2|3", "---"), + expRes: `[[UINT16(1) INT8(0)]]`, + }, { + name: "uint64_int32", + res: sqltypes.MakeTestStreamingResults(sqltypes.MakeTestFields("left|right", "uint64|int32"), "0|1", "1|0", "2|3", "---", "0|1", "1|3", "5|3"), + expRes: `[[UINT64(1) INT32(0)] [UINT64(5) INT32(3)]]`, + }} + for _, tc := range tcases { + t.Run(tc.name, func(t *testing.T) { + pred, err := evalengine.Translate(predicate, &evalengine.Config{ + Collation: utf8mb4Bin, + ResolveColumn: evalengine.FieldResolver(tc.res[0].Fields).Column, + }) + require.NoError(t, err) + + filter := &Filter{ + Predicate: pred, + Input: &fakePrimitive{results: tc.res, async: true}, + } + qr := &sqltypes.Result{} + err = filter.TryStreamExecute(context.Background(), &noopVCursor{}, nil, false, func(result *sqltypes.Result) error { + qr.Rows = append(qr.Rows, result.Rows...) + return nil + }) + require.NoError(t, err) + require.NoError(t, sqltypes.RowsEqualsStr(tc.expRes, qr.Rows)) + }) + } +} diff --git a/go/vt/vtgate/engine/limit.go b/go/vt/vtgate/engine/limit.go index 4ef809ad1fa..8be186f66bd 100644 --- a/go/vt/vtgate/engine/limit.go +++ b/go/vt/vtgate/engine/limit.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "strconv" + "sync" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/evalengine" @@ -97,8 +98,11 @@ func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars // the offset in memory from the result of the scatter query with count + offset. bindVars["__upper_limit"] = sqltypes.Int64BindVariable(int64(count + offset)) + var mu sync.Mutex err = vcursor.StreamExecutePrimitive(ctx, l.Input, bindVars, wantfields, func(qr *sqltypes.Result) error { - if len(qr.Fields) != 0 { + mu.Lock() + defer mu.Unlock() + if wantfields && len(qr.Fields) != 0 { if err := callback(&sqltypes.Result{Fields: qr.Fields}); err != nil { return err } diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go index 15bda20ace7..8b91dadecb5 100644 --- a/go/vt/vtgate/engine/limit_test.go +++ b/go/vt/vtgate/engine/limit_test.go @@ -451,6 +451,73 @@ func TestLimitStreamExecute(t *testing.T) { } } +func TestLimitStreamExecuteAsync(t *testing.T) { + bindVars := make(map[string]*querypb.BindVariable) + fields := sqltypes.MakeTestFields( + "col1|col2", + "int64|varchar", + ) + inputResults := sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "d|3", + "e|4", + "a|1", + "b|2", + "d|3", + "e|4", + "---", + "c|7", + "x|8", + "y|9", + "c|7", + "x|8", + "y|9", + "c|7", + "x|8", + "y|9", + "---", + "l|4", + "m|5", + "n|6", + "l|4", + "m|5", + "n|6", + "l|4", + "m|5", + "n|6", + ) + fp := &fakePrimitive{ + results: inputResults, + async: true, + } + + const maxCount = 26 + for i := 0; i <= maxCount*20; i++ { + expRows := i + l := &Limit{ + Count: evalengine.NewLiteralInt(int64(expRows)), + Input: fp, + } + // Test with limit smaller than input. + results := &sqltypes.Result{} + + err := l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { + if qr != nil { + results.Rows = append(results.Rows, qr.Rows...) + } + return nil + }) + require.NoError(t, err) + if expRows > maxCount { + expRows = maxCount + } + require.Len(t, results.Rows, expRows) + } + +} + func TestOffsetStreamExecute(t *testing.T) { bindVars := make(map[string]*querypb.BindVariable) fields := sqltypes.MakeTestFields( diff --git a/go/vt/vtgate/engine/memory_sort.go b/go/vt/vtgate/engine/memory_sort.go index b896b303923..8a4cd9188ac 100644 --- a/go/vt/vtgate/engine/memory_sort.go +++ b/go/vt/vtgate/engine/memory_sort.go @@ -23,6 +23,7 @@ import ( "reflect" "strconv" "strings" + "sync" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -101,7 +102,11 @@ func (ms *MemorySort) TryStreamExecute(ctx context.Context, vcursor VCursor, bin Compare: ms.OrderBy, Limit: count, } + + var mu sync.Mutex err = vcursor.StreamExecutePrimitive(ctx, ms.Input, bindVars, wantfields, func(qr *sqltypes.Result) error { + mu.Lock() + defer mu.Unlock() if len(qr.Fields) != 0 { if err := cb(&sqltypes.Result{Fields: qr.Fields}); err != nil { return err diff --git a/go/vt/vtgate/engine/memory_sort_test.go b/go/vt/vtgate/engine/memory_sort_test.go index 4f3d39ca851..3ec7b247029 100644 --- a/go/vt/vtgate/engine/memory_sort_test.go +++ b/go/vt/vtgate/engine/memory_sort_test.go @@ -657,3 +657,57 @@ func TestMemorySortExecuteNoVarChar(t *testing.T) { t.Errorf("StreamExecute err: %v, want %v", err, want) } } + +func TestMemorySortStreamAsync(t *testing.T) { + fields := sqltypes.MakeTestFields( + "c1|c2", + "varbinary|decimal", + ) + fp := &fakePrimitive{ + results: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "g|2", + "a|1", + "---", + "c|3", + "g|2", + "a|1", + "---", + "c|4", + "c|3", + "g|2", + "a|1", + "---", + "c|4", + "c|3", + "g|2", + "a|1", + "---", + "c|4", + "c|3", + ), + async: true, + } + + ms := &MemorySort{ + OrderBy: []evalengine.OrderByParams{{ + WeightStringCol: -1, + Col: 1, + }}, + Input: fp, + } + + qr := &sqltypes.Result{} + err := ms.TryStreamExecute(context.Background(), &noopVCursor{}, nil, true, func(res *sqltypes.Result) error { + qr.Rows = append(qr.Rows, res.Rows...) + return nil + }) + require.NoError(t, err) + require.NoError(t, sqltypes.RowsEqualsStr( + `[[VARBINARY("a") DECIMAL(1)] [VARBINARY("a") DECIMAL(1)] [VARBINARY("a") DECIMAL(1)] [VARBINARY("a") DECIMAL(1)] [VARBINARY("a") DECIMAL(1)] +[VARBINARY("g") DECIMAL(2)] [VARBINARY("g") DECIMAL(2)] [VARBINARY("g") DECIMAL(2)] [VARBINARY("g") DECIMAL(2)] +[VARBINARY("c") DECIMAL(3)] [VARBINARY("c") DECIMAL(3)] [VARBINARY("c") DECIMAL(3)] [VARBINARY("c") DECIMAL(3)] +[VARBINARY("c") DECIMAL(4)] [VARBINARY("c") DECIMAL(4)] [VARBINARY("c") DECIMAL(4)]]`, + qr.Rows)) +} diff --git a/go/vt/vtgate/engine/projection.go b/go/vt/vtgate/engine/projection.go index 166dd88f477..aaa49061c8e 100644 --- a/go/vt/vtgate/engine/projection.go +++ b/go/vt/vtgate/engine/projection.go @@ -88,8 +88,11 @@ func (p *Projection) TryStreamExecute(ctx context.Context, vcursor VCursor, bind env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) var once sync.Once var fields []*querypb.Field + var mu sync.Mutex return vcursor.StreamExecutePrimitive(ctx, p.Input, bindVars, wantfields, func(qr *sqltypes.Result) error { var err error + mu.Lock() + defer mu.Unlock() if wantfields { once.Do(func() { fields, err = p.evalFields(env, qr.Fields) diff --git a/go/vt/vtgate/engine/projection_test.go b/go/vt/vtgate/engine/projection_test.go index 37d1730e2e1..2d260e901ea 100644 --- a/go/vt/vtgate/engine/projection_test.go +++ b/go/vt/vtgate/engine/projection_test.go @@ -72,6 +72,49 @@ func TestMultiply(t *testing.T) { assert.Equal(t, "[[UINT64(6)] [UINT64(0)] [UINT64(2)]]", fmt.Sprintf("%v", qr.Rows)) } +func TestProjectionStreaming(t *testing.T) { + expr := &sqlparser.BinaryExpr{ + Operator: sqlparser.MultOp, + Left: &sqlparser.Offset{V: 0}, + Right: &sqlparser.Offset{V: 1}, + } + evalExpr, err := evalengine.Translate(expr, nil) + require.NoError(t, err) + fp := &fakePrimitive{ + results: sqltypes.MakeTestStreamingResults( + sqltypes.MakeTestFields("a|b", "uint64|uint64"), + "3|2", + "1|0", + "6|2", + "---", + "3|2", + "---", + "1|0", + "---", + "1|2", + "4|2", + "---", + "5|5", + "4|10", + ), + async: true, + } + proj := &Projection{ + Cols: []string{"apa"}, + Exprs: []evalengine.Expr{evalExpr}, + Input: fp, + } + + qr := &sqltypes.Result{} + err = proj.TryStreamExecute(context.Background(), &noopVCursor{}, nil, true, func(result *sqltypes.Result) error { + qr.Rows = append(qr.Rows, result.Rows...) + return nil + }) + require.NoError(t, err) + require.NoError(t, sqltypes.RowsEqualsStr(`[[UINT64(25)] [UINT64(40)] [UINT64(6)] [UINT64(2)] [UINT64(8)] [UINT64(0)] [UINT64(6)] [UINT64(0)] [UINT64(12)]]`, + qr.Rows)) +} + func TestEmptyInput(t *testing.T) { expr := &sqlparser.BinaryExpr{ Operator: sqlparser.MultOp, @@ -93,18 +136,18 @@ func TestEmptyInput(t *testing.T) { require.NoError(t, err) assert.Equal(t, "[]", fmt.Sprintf("%v", qr.Rows)) - //fp = &fakePrimitive{ + // fp = &fakePrimitive{ // results: []*sqltypes.Result{sqltypes.MakeTestResult( // sqltypes.MakeTestFields("a|b", "uint64|uint64"), // "3|2", // "1|0", // "1|2", // )}, - //} - //proj.Input = fp - //qr, err = wrapStreamExecute(proj, newNoopVCursor(context.Background()), nil, true) - //require.NoError(t, err) - //assert.Equal(t, "[[UINT64(6)] [UINT64(0)] [UINT64(2)]]", fmt.Sprintf("%v", qr.Rows)) + // } + // proj.Input = fp + // qr, err = wrapStreamExecute(proj, newNoopVCursor(context.Background()), nil, true) + // require.NoError(t, err) + // assert.Equal(t, "[[UINT64(6)] [UINT64(0)] [UINT64(2)]]", fmt.Sprintf("%v", qr.Rows)) } func TestHexAndBinaryArgument(t *testing.T) { From 174ca1fcaabfa95c05068ee915d425f04baa6f66 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 23 Nov 2023 22:04:34 +0200 Subject: [PATCH 040/119] Snapshot connection: revert to explicit table locks when `FTWRL` is unavailable (#14578) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/vstreamer/snapshot_conn.go | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go index b9a3a70ea98..5c9885ee82e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go +++ b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go @@ -19,18 +19,22 @@ package vstreamer import ( "context" "fmt" + "math" + "strings" "sync/atomic" "time" "github.com/spf13/pflag" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" ) // If the current binary log is greater than this byte size, we @@ -241,8 +245,44 @@ func (conn *snapshotConn) startSnapshotAllTables(ctx context.Context) (gtid stri log.Infof("Locking all tables") if _, err := lockConn.ExecuteFetch("FLUSH TABLES WITH READ LOCK", 1, false); err != nil { + attemptExplicitTablesLocks := false + if sqlErr, ok := err.(*sqlerror.SQLError); ok && sqlErr.Number() == sqlerror.ERAccessDeniedError { + // Access denied. On some systems this is either because the user doesn't have SUPER or RELOAD privileges. + // On some other systems, namely RDS, the command is just unsupported. + // There is an alternative way: run a `LOCK TABLES tbl1 READ, tbl2 READ, ...` for all tables. It not as + // efficient, and make a huge query, but still better than nothing. + attemptExplicitTablesLocks = true + } log.Infof("Error locking all tables") - return "", err + if !attemptExplicitTablesLocks { + return "", err + } + // get list of all tables + rs, err := conn.ExecuteFetch("show full tables", math.MaxInt32, true) + if err != nil { + return "", err + } + + var lockClauses []string + for _, row := range rs.Rows { + tableName := row[0].ToString() + tableType := row[1].ToString() + if tableType != "BASE TABLE" { + continue + } + tableName = sqlparser.String(sqlparser.NewIdentifierCS(tableName)) + lockClause := fmt.Sprintf("%s read", tableName) + lockClauses = append(lockClauses, lockClause) + } + if len(lockClauses) > 0 { + query := fmt.Sprintf("lock tables %s", strings.Join(lockClauses, ",")) + if _, err := lockConn.ExecuteFetch(query, 1, false); err != nil { + log.Error(vterrors.Wrapf(err, "explicitly locking all %v tables", len(lockClauses))) + return "", err + } + } else { + log.Infof("explicit lock tables: no tables found") + } } mpos, err := lockConn.PrimaryPosition() if err != nil { From bc83e8af0b70f936c18a5dcc743fa03db15a2874 Mon Sep 17 00:00:00 2001 From: Matthias Crauwels Date: Fri, 24 Nov 2023 15:11:35 +0100 Subject: [PATCH 041/119] implement `--max-report-sample-rows` for VDiff (#14437) Signed-off-by: Matthias Crauwels Signed-off-by: Rohit Nayak Co-authored-by: Rohit Nayak --- .../command/vreplication/vdiff/vdiff.go | 3 + .../command/vreplication/vdiff/vdiff_test.go | 271 ++++++++++++ .../tabletmanagerdata/tabletmanagerdata.pb.go | 213 ++++----- .../tabletmanagerdata_vtproto.pb.go | 34 +- go/vt/proto/vtctldata/vtctldata.pb.go | 415 +++++++++--------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 30 ++ go/vt/vtctl/vdiff2.go | 7 +- go/vt/vtctl/workflow/server.go | 5 +- go/vt/vttablet/tabletmanager/vdiff/report.go | 4 +- .../tabletmanager/vdiff/table_differ.go | 4 +- .../tabletmanager/vdiff/workflow_differ.go | 16 +- proto/tabletmanagerdata.proto | 1 + proto/vtctldata.proto | 1 + web/vtadmin/src/proto/vtadmin.d.ts | 12 + web/vtadmin/src/proto/vtadmin.js | 74 ++++ 15 files changed, 766 insertions(+), 324 deletions(-) diff --git a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go index a98cf3ad743..726da479b56 100644 --- a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go +++ b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go @@ -60,6 +60,7 @@ var ( Limit uint32 // We only accept positive values but pass on an int64 FilteredReplicationWaitTime time.Duration DebugQuery bool + MaxReportSampleRows uint32 // We only accept positive values but pass on an int64 OnlyPKs bool UpdateTableStats bool MaxExtraRowsToCompare uint32 // We only accept positive values but pass on an int64 @@ -279,6 +280,7 @@ func commandCreate(cmd *cobra.Command, args []string) error { Wait: createOptions.Wait, WaitUpdateInterval: protoutil.DurationToProto(createOptions.WaitUpdateInterval), AutoRetry: createOptions.AutoRetry, + MaxReportSampleRows: int64(createOptions.MaxReportSampleRows), }) if err != nil { @@ -863,6 +865,7 @@ func registerCommands(root *cobra.Command) { create.Flags().DurationVar(&createOptions.FilteredReplicationWaitTime, "filtered-replication-wait-time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for replication to catch up when syncing tablet streams.") create.Flags().Uint32Var(&createOptions.Limit, "limit", math.MaxUint32, "Max rows to stop comparing after.") create.Flags().BoolVar(&createOptions.DebugQuery, "debug-query", false, "Adds a mysql query to the report that can be used for further debugging.") + create.Flags().Uint32Var(&createOptions.MaxReportSampleRows, "max-report-sample-rows", 10, "Maximum number of row differences to report (0 for all differences). NOTE: when increasing this value it is highly recommended to also specify --only-pks") create.Flags().BoolVar(&createOptions.OnlyPKs, "only-pks", false, "When reporting missing rows, only show primary keys in the report.") create.Flags().StringSliceVar(&createOptions.Tables, "tables", nil, "Only run vdiff for these tables in the workflow.") create.Flags().Uint32Var(&createOptions.MaxExtraRowsToCompare, "max-extra-rows-to-compare", 1000, "If there are collation differences between the source and target, you can have rows that are identical but simply returned in a different order from MySQL. We will do a second pass to compare the rows for any actual differences in this case and this flag allows you to control the resources used for this operation.") diff --git a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go index fd535bb2aad..8742d22abd0 100644 --- a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go +++ b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff_test.go @@ -269,6 +269,277 @@ func TestVDiffUnsharded(t *testing.T) { } } ]`), + }, { + id: "9", // --max-vdiff-report-rows=20 --only-pks + result: sqltypes.MakeTestResult(fields, + "completed||t1|"+UUID+"|completed|30|"+starttime+"|30|"+comptime+"|1|"+ + `{"TableName": "t1", "MatchingRows": 10, "ProcessedRows": 30, "MismatchedRows": 20, "ExtraRowsSource": 0, `+ + `"ExtraRowsTarget": 0, "MismatchedRowsSample": [`+ + `{"Source": {"Row": {"c1": "2"}}, "Target": {"Row": {"c1": "2"}}},`+ + `{"Source": {"Row": {"c1": "3"}}, "Target": {"Row": {"c1": "3"}}},`+ + `{"Source": {"Row": {"c1": "4"}}, "Target": {"Row": {"c1": "4"}}},`+ + `{"Source": {"Row": {"c1": "5"}}, "Target": {"Row": {"c1": "5"}}},`+ + `{"Source": {"Row": {"c1": "6"}}, "Target": {"Row": {"c1": "6"}}},`+ + `{"Source": {"Row": {"c1": "7"}}, "Target": {"Row": {"c1": "7"}}},`+ + `{"Source": {"Row": {"c1": "8"}}, "Target": {"Row": {"c1": "8"}}},`+ + `{"Source": {"Row": {"c1": "9"}}, "Target": {"Row": {"c1": "9"}}},`+ + `{"Source": {"Row": {"c1": "10"}}, "Target": {"Row": {"c1": "10"}}},`+ + `{"Source": {"Row": {"c1": "11"}}, "Target": {"Row": {"c1": "11"}}},`+ + `{"Source": {"Row": {"c1": "12"}}, "Target": {"Row": {"c1": "12"}}},`+ + `{"Source": {"Row": {"c1": "13"}}, "Target": {"Row": {"c1": "13"}}},`+ + `{"Source": {"Row": {"c1": "14"}}, "Target": {"Row": {"c1": "14"}}},`+ + `{"Source": {"Row": {"c1": "15"}}, "Target": {"Row": {"c1": "15"}}},`+ + `{"Source": {"Row": {"c1": "16"}}, "Target": {"Row": {"c1": "16"}}},`+ + `{"Source": {"Row": {"c1": "17"}}, "Target": {"Row": {"c1": "17"}}},`+ + `{"Source": {"Row": {"c1": "18"}}, "Target": {"Row": {"c1": "18"}}},`+ + `{"Source": {"Row": {"c1": "19"}}, "Target": {"Row": {"c1": "19"}}},`+ + `{"Source": {"Row": {"c1": "20"}}, "Target": {"Row": {"c1": "20"}}},`+ + `{"Source": {"Row": {"c1": "21"}}, "Target": {"Row": {"c1": "21"}}}`+ + `]}`), + report: fmt.Sprintf(badReportfmt, + env.targetKeyspace, UUID, 30, true, starttime, comptime, 30, 10, 20, 0, 0, 30, 10, 20, 0, 0, + `"MismatchedRowsSample": [ + { + "Source": { + "Row": { + "c1": "2" + } + }, + "Target": { + "Row": { + "c1": "2" + } + } + }, + { + "Source": { + "Row": { + "c1": "3" + } + }, + "Target": { + "Row": { + "c1": "3" + } + } + }, + { + "Source": { + "Row": { + "c1": "4" + } + }, + "Target": { + "Row": { + "c1": "4" + } + } + }, + { + "Source": { + "Row": { + "c1": "5" + } + }, + "Target": { + "Row": { + "c1": "5" + } + } + }, + { + "Source": { + "Row": { + "c1": "6" + } + }, + "Target": { + "Row": { + "c1": "6" + } + } + }, + { + "Source": { + "Row": { + "c1": "7" + } + }, + "Target": { + "Row": { + "c1": "7" + } + } + }, + { + "Source": { + "Row": { + "c1": "8" + } + }, + "Target": { + "Row": { + "c1": "8" + } + } + }, + { + "Source": { + "Row": { + "c1": "9" + } + }, + "Target": { + "Row": { + "c1": "9" + } + } + }, + { + "Source": { + "Row": { + "c1": "10" + } + }, + "Target": { + "Row": { + "c1": "10" + } + } + }, + { + "Source": { + "Row": { + "c1": "11" + } + }, + "Target": { + "Row": { + "c1": "11" + } + } + }, + { + "Source": { + "Row": { + "c1": "12" + } + }, + "Target": { + "Row": { + "c1": "12" + } + } + }, + { + "Source": { + "Row": { + "c1": "13" + } + }, + "Target": { + "Row": { + "c1": "13" + } + } + }, + { + "Source": { + "Row": { + "c1": "14" + } + }, + "Target": { + "Row": { + "c1": "14" + } + } + }, + { + "Source": { + "Row": { + "c1": "15" + } + }, + "Target": { + "Row": { + "c1": "15" + } + } + }, + { + "Source": { + "Row": { + "c1": "16" + } + }, + "Target": { + "Row": { + "c1": "16" + } + } + }, + { + "Source": { + "Row": { + "c1": "17" + } + }, + "Target": { + "Row": { + "c1": "17" + } + } + }, + { + "Source": { + "Row": { + "c1": "18" + } + }, + "Target": { + "Row": { + "c1": "18" + } + } + }, + { + "Source": { + "Row": { + "c1": "19" + } + }, + "Target": { + "Row": { + "c1": "19" + } + } + }, + { + "Source": { + "Row": { + "c1": "20" + } + }, + "Target": { + "Row": { + "c1": "20" + } + } + }, + { + "Source": { + "Row": { + "c1": "21" + } + }, + "Target": { + "Row": { + "c1": "21" + } + } + } + ]`), }, } diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index b35347b3892..6e0ad6dc2b2 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -5439,9 +5439,10 @@ type VDiffReportOptions struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OnlyPks bool `protobuf:"varint,1,opt,name=only_pks,json=onlyPks,proto3" json:"only_pks,omitempty"` - DebugQuery bool `protobuf:"varint,2,opt,name=debug_query,json=debugQuery,proto3" json:"debug_query,omitempty"` - Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` + OnlyPks bool `protobuf:"varint,1,opt,name=only_pks,json=onlyPks,proto3" json:"only_pks,omitempty"` + DebugQuery bool `protobuf:"varint,2,opt,name=debug_query,json=debugQuery,proto3" json:"debug_query,omitempty"` + Format string `protobuf:"bytes,3,opt,name=format,proto3" json:"format,omitempty"` + MaxSampleRows int64 `protobuf:"varint,4,opt,name=max_sample_rows,json=maxSampleRows,proto3" json:"max_sample_rows,omitempty"` } func (x *VDiffReportOptions) Reset() { @@ -5497,6 +5498,13 @@ func (x *VDiffReportOptions) GetFormat() string { return "" } +func (x *VDiffReportOptions) GetMaxSampleRows() int64 { + if x != nil { + return x.MaxSampleRows + } + return 0 +} + type VDiffCoreOptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6807,104 +6815,107 @@ var file_tabletmanagerdata_proto_rawDesc = []byte{ 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x22, 0x68, 0x0a, 0x12, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x22, 0xb0, 0x02, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, - 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, - 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x5f, 0x70, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x50, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, - 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, - 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, - 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, 0x63, 0x6b, - 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 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, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, - 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe9, 0x02, 0x0a, - 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, - 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x6f, - 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x05, 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, 0x3b, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x50, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 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, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x52, 0x65, - 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, - 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x65, 0x64, 0x2a, 0x3e, 0x0a, 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, - 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x03, 0x42, 0x30, 0x5a, 0x2e, 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, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x22, 0x90, 0x01, 0x0a, 0x12, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x6d, 0x61, 0x78, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x22, 0xb0, 0x02, + 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, + 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x70, 0x63, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x63, 0x74, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, + 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x02, 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, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, + 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, 0x65, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe9, 0x02, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, + 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x05, + 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, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x50, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x01, 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, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, + 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, + 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x2a, 0x3e, 0x0a, + 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, + 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x01, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x42, 0x30, 0x5a, + 0x2e, 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, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go index 502a4c17ff9..fe43c4edfc9 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go @@ -2076,9 +2076,10 @@ func (m *VDiffReportOptions) CloneVT() *VDiffReportOptions { return (*VDiffReportOptions)(nil) } r := &VDiffReportOptions{ - OnlyPks: m.OnlyPks, - DebugQuery: m.DebugQuery, - Format: m.Format, + OnlyPks: m.OnlyPks, + DebugQuery: m.DebugQuery, + Format: m.Format, + MaxSampleRows: m.MaxSampleRows, } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -7194,6 +7195,11 @@ func (m *VDiffReportOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MaxSampleRows != 0 { + i = encodeVarint(dAtA, i, uint64(m.MaxSampleRows)) + i-- + dAtA[i] = 0x20 + } if len(m.Format) > 0 { i -= len(m.Format) copy(dAtA[i:], m.Format) @@ -9448,6 +9454,9 @@ func (m *VDiffReportOptions) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + if m.MaxSampleRows != 0 { + n += 1 + sov(uint64(m.MaxSampleRows)) + } n += len(m.unknownFields) return n } @@ -20376,6 +20385,25 @@ func (m *VDiffReportOptions) UnmarshalVT(dAtA []byte) error { } m.Format = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSampleRows", wireType) + } + m.MaxSampleRows = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxSampleRows |= int64(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 a1d8ce39ec1..fafa6d703cc 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -13309,6 +13309,7 @@ type VDiffCreateRequest struct { WaitUpdateInterval *vttime.Duration `protobuf:"bytes,16,opt,name=wait_update_interval,json=waitUpdateInterval,proto3" json:"wait_update_interval,omitempty"` AutoRetry bool `protobuf:"varint,17,opt,name=auto_retry,json=autoRetry,proto3" json:"auto_retry,omitempty"` Verbose bool `protobuf:"varint,18,opt,name=verbose,proto3" json:"verbose,omitempty"` + MaxReportSampleRows int64 `protobuf:"varint,19,opt,name=max_report_sample_rows,json=maxReportSampleRows,proto3" json:"max_report_sample_rows,omitempty"` } func (x *VDiffCreateRequest) Reset() { @@ -13469,6 +13470,13 @@ func (x *VDiffCreateRequest) GetVerbose() bool { return false } +func (x *VDiffCreateRequest) GetMaxReportSampleRows() int64 { + if x != nil { + return x.MaxReportSampleRows + } + return 0 +} + type VDiffCreateResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -17397,7 +17405,7 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, @@ -17446,220 +17454,223 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, - 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, - 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, - 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x15, 0x0a, - 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, - 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, - 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, + 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x52, 0x6f, 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, + 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, + 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, + 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, + 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, - 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x15, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x0a, - 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, - 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x4f, 0x0a, 0x15, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe6, 0x07, - 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, - 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, - 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, - 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, - 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, - 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, - 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, - 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, - 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, - 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, - 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, - 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, - 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, - 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, - 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, - 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, - 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, + 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, + 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, + 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x9a, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, + 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, + 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, + 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, - 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, - 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, - 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, - 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x22, 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x75, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, + 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, + 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, + 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, + 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, + 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, + 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, + 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, + 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, + 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, + 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, + 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, + 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, + 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, + 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, + 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, + 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, + 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, + 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, + 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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 b453eb2a0b2..2e589fe06e1 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -4796,6 +4796,7 @@ func (m *VDiffCreateRequest) CloneVT() *VDiffCreateRequest { WaitUpdateInterval: m.WaitUpdateInterval.CloneVT(), AutoRetry: m.AutoRetry, Verbose: m.Verbose, + MaxReportSampleRows: m.MaxReportSampleRows, } if rhs := m.SourceCells; rhs != nil { tmpContainer := make([]string, len(rhs)) @@ -17908,6 +17909,13 @@ func (m *VDiffCreateRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MaxReportSampleRows != 0 { + i = encodeVarint(dAtA, i, uint64(m.MaxReportSampleRows)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x98 + } if m.Verbose { i-- if m.Verbose { @@ -24109,6 +24117,9 @@ func (m *VDiffCreateRequest) SizeVT() (n int) { if m.Verbose { n += 3 } + if m.MaxReportSampleRows != 0 { + n += 2 + sov(uint64(m.MaxReportSampleRows)) + } n += len(m.unknownFields) return n } @@ -55571,6 +55582,25 @@ func (m *VDiffCreateRequest) UnmarshalVT(dAtA []byte) error { } } m.Verbose = bool(v != 0) + case 19: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxReportSampleRows", wireType) + } + m.MaxReportSampleRows = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxReportSampleRows |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vtctl/vdiff2.go b/go/vt/vtctl/vdiff2.go index 7cd1c7e00ca..9f53bb3590d 100644 --- a/go/vt/vtctl/vdiff2.go +++ b/go/vt/vtctl/vdiff2.go @@ -121,9 +121,10 @@ func commandVDiff2(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.F UpdateTableStats: *updateTableStats, }, ReportOptions: &tabletmanagerdatapb.VDiffReportOptions{ - OnlyPks: *onlyPks, - DebugQuery: *debugQuery, - Format: format, + OnlyPks: *onlyPks, + DebugQuery: *debugQuery, + Format: format, + MaxSampleRows: 10, }, } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 21723504019..3810d7a2944 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -1640,8 +1640,9 @@ func (s *Server) VDiffCreate(ctx context.Context, req *vtctldatapb.VDiffCreateRe UpdateTableStats: req.UpdateTableStats, }, ReportOptions: &tabletmanagerdatapb.VDiffReportOptions{ - OnlyPks: req.OnlyPKs, - DebugQuery: req.DebugQuery, + OnlyPks: req.OnlyPKs, + DebugQuery: req.DebugQuery, + MaxSampleRows: req.MaxReportSampleRows, }, } diff --git a/go/vt/vttablet/tabletmanager/vdiff/report.go b/go/vt/vttablet/tabletmanager/vdiff/report.go index 4f9b264cddd..f61929ea32c 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/report.go +++ b/go/vt/vttablet/tabletmanager/vdiff/report.go @@ -26,9 +26,7 @@ import ( ) const ( - // At most how many samples we should show for row differences in the final report - maxVDiffReportSampleRows = 10 - truncatedNotation = "...[TRUNCATED]" + truncatedNotation = "...[TRUNCATED]" ) // DiffReport is the summary of differences for one table. diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go index c0cba599bdd..2d7f88e1055 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go @@ -462,7 +462,7 @@ func (td *tableDiffer) setupRowSorters() { } } -func (td *tableDiffer) diff(ctx context.Context, rowsToCompare int64, debug, onlyPks bool, maxExtraRowsToCompare int64) (*DiffReport, error) { +func (td *tableDiffer) diff(ctx context.Context, rowsToCompare int64, debug, onlyPks bool, maxExtraRowsToCompare int64, maxReportSampleRows int64) (*DiffReport, error) { dbClient := td.wd.ct.dbClientFactory() if err := dbClient.Connect(); err != nil { return nil, err @@ -629,7 +629,7 @@ func (td *tableDiffer) diff(ctx context.Context, rowsToCompare int64, debug, onl return nil, err case c != 0: // We don't do a second pass to compare mismatched rows so we can cap the slice here - if dr.MismatchedRows < maxVDiffReportSampleRows { + if maxReportSampleRows == 0 || dr.MismatchedRows < maxReportSampleRows { sourceDiffRow, err := td.genRowDiff(td.tablePlan.targetQuery, sourceRow, debug, onlyPks) if err != nil { return nil, vterrors.Wrap(err, "unexpected error generating diff") diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go index d7d2583a5d3..20a1e2dc295 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go @@ -64,7 +64,7 @@ func newWorkflowDiffer(ct *controller, opts *tabletmanagerdatapb.VDiffOptions) ( // by MySQL on each side then we'll have the same number of extras on // both sides. If that's the case, then let's see if the extra rows on // both sides are actually different. -func (wd *workflowDiffer) reconcileExtraRows(dr *DiffReport, maxExtraRowsToCompare int64) error { +func (wd *workflowDiffer) reconcileExtraRows(dr *DiffReport, maxExtraRowsToCompare int64, maxReportSampleRows int64) error { if dr.MismatchedRows == 0 { // Get the VSchema on the target and source keyspaces. We can then use this // for handling additional edge cases, such as adjusting results for reference @@ -122,12 +122,12 @@ func (wd *workflowDiffer) reconcileExtraRows(dr *DiffReport, maxExtraRowsToCompa } } } - // We can now trim the extra rows diffs on both sides to the maxVDiffReportSampleRows value - if len(dr.ExtraRowsSourceDiffs) > maxVDiffReportSampleRows { - dr.ExtraRowsSourceDiffs = dr.ExtraRowsSourceDiffs[:maxVDiffReportSampleRows-1] + // We can now trim the extra rows diffs on both sides to the maxReportSampleRows value + if int64(len(dr.ExtraRowsSourceDiffs)) > maxReportSampleRows && maxReportSampleRows > 0 { + dr.ExtraRowsSourceDiffs = dr.ExtraRowsSourceDiffs[:maxReportSampleRows-1] } - if len(dr.ExtraRowsTargetDiffs) > maxVDiffReportSampleRows { - dr.ExtraRowsTargetDiffs = dr.ExtraRowsTargetDiffs[:maxVDiffReportSampleRows-1] + if int64(len(dr.ExtraRowsTargetDiffs)) > maxReportSampleRows && maxReportSampleRows > 0 { + dr.ExtraRowsTargetDiffs = dr.ExtraRowsTargetDiffs[:maxReportSampleRows-1] } return nil @@ -158,14 +158,14 @@ func (wd *workflowDiffer) diffTable(ctx context.Context, dbClient binlogplayer.D return err } log.Infof("Table initialization done on table %s for vdiff %s", td.table.Name, wd.ct.uuid) - dr, err := td.diff(ctx, wd.opts.CoreOptions.MaxRows, wd.opts.ReportOptions.DebugQuery, wd.opts.ReportOptions.OnlyPks, wd.opts.CoreOptions.MaxExtraRowsToCompare) + dr, err := td.diff(ctx, wd.opts.CoreOptions.MaxRows, wd.opts.ReportOptions.DebugQuery, wd.opts.ReportOptions.OnlyPks, wd.opts.CoreOptions.MaxExtraRowsToCompare, wd.opts.ReportOptions.MaxSampleRows) if err != nil { log.Errorf("Encountered an error diffing table %s for vdiff %s: %v", td.table.Name, wd.ct.uuid, err) return err } log.Infof("Table diff done on table %s for vdiff %s with report: %+v", td.table.Name, wd.ct.uuid, dr) if dr.ExtraRowsSource > 0 || dr.ExtraRowsTarget > 0 { - if err := wd.reconcileExtraRows(dr, wd.opts.CoreOptions.MaxExtraRowsToCompare); err != nil { + if err := wd.reconcileExtraRows(dr, wd.opts.CoreOptions.MaxExtraRowsToCompare, wd.opts.ReportOptions.MaxSampleRows); err != nil { log.Errorf("Encountered an error reconciling extra rows found for table %s for vdiff %s: %v", td.table.Name, wd.ct.uuid, err) return vterrors.Wrap(err, "failed to reconcile extra rows") } diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index fc9f6fa97b9..e44e013c0c9 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -609,6 +609,7 @@ message VDiffReportOptions { bool only_pks = 1; bool debug_query = 2; string format = 3; + int64 max_sample_rows = 4; } message VDiffCoreOptions { diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 3d59ea1bd5e..b84f87c9037 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -1725,6 +1725,7 @@ message VDiffCreateRequest { vttime.Duration wait_update_interval = 16; bool auto_retry = 17; bool verbose = 18; + int64 max_report_sample_rows = 19; } message VDiffCreateResponse { diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index d50ca0004ee..f5f7c100cc5 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -27596,6 +27596,9 @@ export namespace tabletmanagerdata { /** VDiffReportOptions format */ format?: (string|null); + + /** VDiffReportOptions max_sample_rows */ + max_sample_rows?: (number|Long|null); } /** Represents a VDiffReportOptions. */ @@ -27616,6 +27619,9 @@ export namespace tabletmanagerdata { /** VDiffReportOptions format. */ public format: string; + /** VDiffReportOptions max_sample_rows. */ + public max_sample_rows: (number|Long); + /** * Creates a new VDiffReportOptions instance using the specified properties. * @param [properties] Properties to set @@ -65843,6 +65849,9 @@ export namespace vtctldata { /** VDiffCreateRequest verbose */ verbose?: (boolean|null); + + /** VDiffCreateRequest max_report_sample_rows */ + max_report_sample_rows?: (number|Long|null); } /** Represents a VDiffCreateRequest. */ @@ -65908,6 +65917,9 @@ export namespace vtctldata { /** VDiffCreateRequest verbose. */ public verbose: boolean; + /** VDiffCreateRequest max_report_sample_rows. */ + public max_report_sample_rows: (number|Long); + /** * Creates a new VDiffCreateRequest instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 7730d101e29..a7fcd29e3f7 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -63808,6 +63808,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * @property {boolean|null} [only_pks] VDiffReportOptions only_pks * @property {boolean|null} [debug_query] VDiffReportOptions debug_query * @property {string|null} [format] VDiffReportOptions format + * @property {number|Long|null} [max_sample_rows] VDiffReportOptions max_sample_rows */ /** @@ -63849,6 +63850,14 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { */ VDiffReportOptions.prototype.format = ""; + /** + * VDiffReportOptions max_sample_rows. + * @member {number|Long} max_sample_rows + * @memberof tabletmanagerdata.VDiffReportOptions + * @instance + */ + VDiffReportOptions.prototype.max_sample_rows = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + /** * Creates a new VDiffReportOptions instance using the specified properties. * @function create @@ -63879,6 +63888,8 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { writer.uint32(/* id 2, wireType 0 =*/16).bool(message.debug_query); if (message.format != null && Object.hasOwnProperty.call(message, "format")) writer.uint32(/* id 3, wireType 2 =*/26).string(message.format); + if (message.max_sample_rows != null && Object.hasOwnProperty.call(message, "max_sample_rows")) + writer.uint32(/* id 4, wireType 0 =*/32).int64(message.max_sample_rows); return writer; }; @@ -63925,6 +63936,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.format = reader.string(); break; } + case 4: { + message.max_sample_rows = reader.int64(); + break; + } default: reader.skipType(tag & 7); break; @@ -63969,6 +63984,9 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { if (message.format != null && message.hasOwnProperty("format")) if (!$util.isString(message.format)) return "format: string expected"; + if (message.max_sample_rows != null && message.hasOwnProperty("max_sample_rows")) + if (!$util.isInteger(message.max_sample_rows) && !(message.max_sample_rows && $util.isInteger(message.max_sample_rows.low) && $util.isInteger(message.max_sample_rows.high))) + return "max_sample_rows: integer|Long expected"; return null; }; @@ -63990,6 +64008,15 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { message.debug_query = Boolean(object.debug_query); if (object.format != null) message.format = String(object.format); + if (object.max_sample_rows != null) + if ($util.Long) + (message.max_sample_rows = $util.Long.fromValue(object.max_sample_rows)).unsigned = false; + else if (typeof object.max_sample_rows === "string") + message.max_sample_rows = parseInt(object.max_sample_rows, 10); + else if (typeof object.max_sample_rows === "number") + message.max_sample_rows = object.max_sample_rows; + else if (typeof object.max_sample_rows === "object") + message.max_sample_rows = new $util.LongBits(object.max_sample_rows.low >>> 0, object.max_sample_rows.high >>> 0).toNumber(); return message; }; @@ -64010,6 +64037,11 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { object.only_pks = false; object.debug_query = false; object.format = ""; + if ($util.Long) { + let long = new $util.Long(0, 0, false); + object.max_sample_rows = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.max_sample_rows = options.longs === String ? "0" : 0; } if (message.only_pks != null && message.hasOwnProperty("only_pks")) object.only_pks = message.only_pks; @@ -64017,6 +64049,11 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { object.debug_query = message.debug_query; if (message.format != null && message.hasOwnProperty("format")) object.format = message.format; + if (message.max_sample_rows != null && message.hasOwnProperty("max_sample_rows")) + if (typeof message.max_sample_rows === "number") + object.max_sample_rows = options.longs === String ? String(message.max_sample_rows) : message.max_sample_rows; + else + object.max_sample_rows = options.longs === String ? $util.Long.prototype.toString.call(message.max_sample_rows) : options.longs === Number ? new $util.LongBits(message.max_sample_rows.low >>> 0, message.max_sample_rows.high >>> 0).toNumber() : message.max_sample_rows; return object; }; @@ -159912,6 +159949,7 @@ export const vtctldata = $root.vtctldata = (() => { * @property {vttime.IDuration|null} [wait_update_interval] VDiffCreateRequest wait_update_interval * @property {boolean|null} [auto_retry] VDiffCreateRequest auto_retry * @property {boolean|null} [verbose] VDiffCreateRequest verbose + * @property {number|Long|null} [max_report_sample_rows] VDiffCreateRequest max_report_sample_rows */ /** @@ -160077,6 +160115,14 @@ export const vtctldata = $root.vtctldata = (() => { */ VDiffCreateRequest.prototype.verbose = false; + /** + * VDiffCreateRequest max_report_sample_rows. + * @member {number|Long} max_report_sample_rows + * @memberof vtctldata.VDiffCreateRequest + * @instance + */ + VDiffCreateRequest.prototype.max_report_sample_rows = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + /** * Creates a new VDiffCreateRequest instance using the specified properties. * @function create @@ -160144,6 +160190,8 @@ export const vtctldata = $root.vtctldata = (() => { writer.uint32(/* id 17, wireType 0 =*/136).bool(message.auto_retry); if (message.verbose != null && Object.hasOwnProperty.call(message, "verbose")) writer.uint32(/* id 18, wireType 0 =*/144).bool(message.verbose); + if (message.max_report_sample_rows != null && Object.hasOwnProperty.call(message, "max_report_sample_rows")) + writer.uint32(/* id 19, wireType 0 =*/152).int64(message.max_report_sample_rows); return writer; }; @@ -160263,6 +160311,10 @@ export const vtctldata = $root.vtctldata = (() => { message.verbose = reader.bool(); break; } + case 19: { + message.max_report_sample_rows = reader.int64(); + break; + } default: reader.skipType(tag & 7); break; @@ -160392,6 +160444,9 @@ export const vtctldata = $root.vtctldata = (() => { if (message.verbose != null && message.hasOwnProperty("verbose")) if (typeof message.verbose !== "boolean") return "verbose: boolean expected"; + if (message.max_report_sample_rows != null && message.hasOwnProperty("max_report_sample_rows")) + if (!$util.isInteger(message.max_report_sample_rows) && !(message.max_report_sample_rows && $util.isInteger(message.max_report_sample_rows.low) && $util.isInteger(message.max_report_sample_rows.high))) + return "max_report_sample_rows: integer|Long expected"; return null; }; @@ -160551,6 +160606,15 @@ export const vtctldata = $root.vtctldata = (() => { message.auto_retry = Boolean(object.auto_retry); if (object.verbose != null) message.verbose = Boolean(object.verbose); + if (object.max_report_sample_rows != null) + if ($util.Long) + (message.max_report_sample_rows = $util.Long.fromValue(object.max_report_sample_rows)).unsigned = false; + else if (typeof object.max_report_sample_rows === "string") + message.max_report_sample_rows = parseInt(object.max_report_sample_rows, 10); + else if (typeof object.max_report_sample_rows === "number") + message.max_report_sample_rows = object.max_report_sample_rows; + else if (typeof object.max_report_sample_rows === "object") + message.max_report_sample_rows = new $util.LongBits(object.max_report_sample_rows.low >>> 0, object.max_report_sample_rows.high >>> 0).toNumber(); return message; }; @@ -160596,6 +160660,11 @@ export const vtctldata = $root.vtctldata = (() => { object.wait_update_interval = null; object.auto_retry = false; object.verbose = false; + if ($util.Long) { + let long = new $util.Long(0, 0, false); + object.max_report_sample_rows = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.max_report_sample_rows = options.longs === String ? "0" : 0; } if (message.workflow != null && message.hasOwnProperty("workflow")) object.workflow = message.workflow; @@ -160651,6 +160720,11 @@ export const vtctldata = $root.vtctldata = (() => { object.auto_retry = message.auto_retry; if (message.verbose != null && message.hasOwnProperty("verbose")) object.verbose = message.verbose; + if (message.max_report_sample_rows != null && message.hasOwnProperty("max_report_sample_rows")) + if (typeof message.max_report_sample_rows === "number") + object.max_report_sample_rows = options.longs === String ? String(message.max_report_sample_rows) : message.max_report_sample_rows; + else + object.max_report_sample_rows = options.longs === String ? $util.Long.prototype.toString.call(message.max_report_sample_rows) : options.longs === Number ? new $util.LongBits(message.max_report_sample_rows.low >>> 0, message.max_report_sample_rows.high >>> 0).toNumber() : message.max_report_sample_rows; return object; }; From d6e5d866df6ddb00babdf32b9ce09a1d99aa51e6 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Fri, 24 Nov 2023 16:06:32 +0100 Subject: [PATCH 042/119] mysqlctl: Fix cleaning up the stale lock file (#14600) Signed-off-by: Dirkjan Bussink --- go/vt/mysqlctl/mysqld.go | 4 +++- go/vt/mysqlctl/mysqld_test.go | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index a2d2c5b7d71..52f806fe29b 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -438,14 +438,16 @@ func cleanupLockfile(socket string, ts string) error { lockPath := fmt.Sprintf("%s.lock", socket) pid, err := os.ReadFile(lockPath) if errors.Is(err, os.ErrNotExist) { + log.Infof("%v: no stale lock file at %s", ts, lockPath) // If there's no lock file, we can early return here, nothing // to clean up then. return nil } else if err != nil { + log.Errorf("%v: error checking if lock file exists: %v", ts, err) // Any other errors here are unexpected. return err } - p, err := strconv.Atoi(string(pid)) + p, err := strconv.Atoi(string(bytes.TrimSpace(pid))) if err != nil { log.Errorf("%v: error parsing pid from lock file: %v", ts, err) return err diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index 5ee21196ddd..b45ab5bd6d8 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -188,6 +188,11 @@ func TestCleanupLockfile(t *testing.T) { assert.NoError(t, cleanupLockfile("mysql.sock", ts)) assert.NoFileExists(t, "mysql.sock.lock") + // If lockfile exists, but the process is not found, we clean it up. + os.WriteFile("mysql.sock.lock", []byte("123456789\n"), 0o600) + assert.NoError(t, cleanupLockfile("mysql.sock", ts)) + assert.NoFileExists(t, "mysql.sock.lock") + // If the lockfile exists, and the process is found, we don't clean it up. os.WriteFile("mysql.sock.lock", []byte(strconv.Itoa(os.Getpid())), 0o600) assert.NoError(t, cleanupLockfile("mysql.sock", ts)) From 88ae1d83498bed8fca2926514ace4ea30b085713 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Fri, 24 Nov 2023 22:57:44 +0530 Subject: [PATCH 043/119] Type Cast all update expressions in verify queries (#14555) Signed-off-by: Manan Gupta --- go/test/endtoend/vtgate/foreignkey/fk_test.go | 9 ++ go/vt/vtgate/engine/cached_size.go | 4 +- go/vt/vtgate/engine/fk_cascade.go | 23 +-- go/vt/vtgate/planbuilder/operators/update.go | 84 ++++++++--- .../planbuilder/operators/update_test.go | 140 ++++++++++++++++++ .../testdata/foreignkey_cases.json | 63 ++++---- .../testdata/foreignkey_checks_on_cases.json | 49 +++--- .../planbuilder/testdata/vschemas/schema.json | 84 ++++++++++- 8 files changed, 344 insertions(+), 112 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/operators/update_test.go diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index 785310b6ade..101cd313e21 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -905,6 +905,15 @@ func TestFkQueries(t *testing.T) { "update fk_t11 set col = id where id in (1, 5)", }, }, + { + name: "Update on child to 0 when parent has -0", + queries: []string{ + "insert into fk_t15 (id, col) values (2, '-0')", + "insert /*+ SET_VAR(foreign_key_checks=0) */ into fk_t16 (id, col) values (3, '5'), (4, '-5')", + "update fk_t16 set col = col * (col - (col)) where id = 3", + "update fk_t16 set col = col * (col - (col)) where id = 4", + }, + }, } for _, testcase := range testcases { diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 6024c66457a..657e5323f05 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -290,7 +290,7 @@ func (cached *FkChild) CachedSize(alloc bool) int64 { } // field NonLiteralInfo []vitess.io/vitess/go/vt/vtgate/engine.NonLiteralUpdateInfo { - size += hack.RuntimeAllocSize(int64(cap(cached.NonLiteralInfo)) * int64(40)) + size += hack.RuntimeAllocSize(int64(cap(cached.NonLiteralInfo)) * int64(32)) for _, elem := range cached.NonLiteralInfo { size += elem.CachedSize(false) } @@ -625,7 +625,7 @@ func (cached *NonLiteralUpdateInfo) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(48) + size += int64(32) } // field UpdateExprBvName string size += hack.RuntimeAllocSize(int64(len(cached.UpdateExprBvName))) diff --git a/go/vt/vtgate/engine/fk_cascade.go b/go/vt/vtgate/engine/fk_cascade.go index 94732ae161b..3046217ce94 100644 --- a/go/vt/vtgate/engine/fk_cascade.go +++ b/go/vt/vtgate/engine/fk_cascade.go @@ -25,7 +25,6 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/evalengine" ) // FkChild contains the Child Primitive to be executed collecting the values from the Selection Primitive using the column indexes. @@ -42,12 +41,10 @@ type FkChild struct { // NonLiteralUpdateInfo stores the information required to process non-literal update queries. // It stores 4 information- -// 1. ExprCol- The index of the column being updated in the select query. -// 2. CompExprCol- The index of the comparison expression in the select query to know if the row value is actually being changed or not. -// 3. UpdateExprCol- The index of the updated expression in the select query. -// 4. UpdateExprBvName- The bind variable name to store the updated expression into. +// 1. CompExprCol- The index of the comparison expression in the select query to know if the row value is actually being changed or not. +// 2. UpdateExprCol- The index of the updated expression in the select query. +// 3. UpdateExprBvName- The bind variable name to store the updated expression into. type NonLiteralUpdateInfo struct { - ExprCol int CompExprCol int UpdateExprCol int UpdateExprBvName string @@ -188,19 +185,7 @@ func (fkc *FkCascade) executeNonLiteralExprFkChild(ctx context.Context, vcursor // Next, we need to copy the updated expressions value into the bind variables map. for _, info := range child.NonLiteralInfo { - // Type case the value to that of the column that we are updating. - // This is required for example when we receive an updated float value of -0, but - // the column being updated is a varchar column, then if we don't coerce the value of -0 to - // varchar, MySQL ends up setting it to '0' instead of '-0'. - finalVal := row[info.UpdateExprCol] - if !finalVal.IsNull() { - var err error - finalVal, err = evalengine.CoerceTo(finalVal, selectionRes.Fields[info.ExprCol].Type) - if err != nil { - return err - } - } - bindVars[info.UpdateExprBvName] = sqltypes.ValueBindVariable(finalVal) + bindVars[info.UpdateExprBvName] = sqltypes.ValueBindVariable(row[info.UpdateExprCol]) } _, err := vcursor.ExecutePrimitive(ctx, child.Exec, bindVars, wantfields) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 71d82c64216..8868e83c247 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -22,6 +22,8 @@ import ( "slices" "strings" + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" @@ -217,7 +219,7 @@ func buildFkOperator(ctx *plancontext.PlanningContext, updOp ops.Operator, updCl return nil, err } - return createFKVerifyOp(ctx, op, updClone, parentFks, restrictChildFks) + return createFKVerifyOp(ctx, op, updClone, parentFks, restrictChildFks, updatedTable) } // splitChildFks splits the child foreign keys into restrict and cascade list as restrict is handled through Verify operator and cascade is handled through Cascade operator. @@ -268,7 +270,7 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, for _, updExpr := range ue { // We add the expression and a comparison expression to the SELECT exprssion while storing their offsets. var info engine.NonLiteralUpdateInfo - info, selectExprs = addNonLiteralUpdExprToSelect(ctx, updExpr, selectExprs) + info, selectExprs = addNonLiteralUpdExprToSelect(ctx, updatedTable, updExpr, selectExprs) nonLiteralUpdateInfo = append(nonLiteralUpdateInfo, info) } } @@ -329,25 +331,22 @@ func addColumns(ctx *plancontext.PlanningContext, columns sqlparser.Columns, exp // For an update query having non-literal updates, we add the updated expression and a comparison expression to the select query. // For example, for a query like `update fk_table set col = id * 100 + 1` // We would add the expression `id * 100 + 1` and the comparison expression `col <=> id * 100 + 1` to the select query. -func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sqlparser.UpdateExpr, exprs []sqlparser.SelectExpr) (engine.NonLiteralUpdateInfo, []sqlparser.SelectExpr) { +func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updExpr *sqlparser.UpdateExpr, exprs []sqlparser.SelectExpr) (engine.NonLiteralUpdateInfo, []sqlparser.SelectExpr) { // Create the comparison expression. - compExpr := sqlparser.NewComparisonExpr(sqlparser.NullSafeEqualOp, updExpr.Name, updExpr.Expr, nil) + castedExpr := getCastedUpdateExpression(updatedTable, updExpr) + compExpr := sqlparser.NewComparisonExpr(sqlparser.NullSafeEqualOp, updExpr.Name, castedExpr, nil) info := engine.NonLiteralUpdateInfo{ CompExprCol: -1, UpdateExprCol: -1, - ExprCol: -1, } // Add the expressions to the select expressions. We make sure to reuse the offset if it has already been added once. for idx, selectExpr := range exprs { if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, compExpr) { info.CompExprCol = idx } - if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, updExpr.Expr) { + if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, castedExpr) { info.UpdateExprCol = idx } - if ctx.SemTable.EqualsExpr(selectExpr.(*sqlparser.AliasedExpr).Expr, updExpr.Name) { - info.ExprCol = idx - } } // If the expression doesn't exist, then we add the expression and store the offset. if info.CompExprCol == -1 { @@ -356,15 +355,54 @@ func addNonLiteralUpdExprToSelect(ctx *plancontext.PlanningContext, updExpr *sql } if info.UpdateExprCol == -1 { info.UpdateExprCol = len(exprs) - exprs = append(exprs, aeWrap(updExpr.Expr)) - } - if info.ExprCol == -1 { - info.ExprCol = len(exprs) - exprs = append(exprs, aeWrap(updExpr.Name)) + exprs = append(exprs, aeWrap(castedExpr)) } return info, exprs } +func getCastedUpdateExpression(updatedTable *vindexes.Table, updExpr *sqlparser.UpdateExpr) sqlparser.Expr { + castTypeStr := getCastTypeForColumn(updatedTable, updExpr) + if castTypeStr == "" { + return updExpr.Expr + } + return &sqlparser.CastExpr{ + Expr: updExpr.Expr, + Type: &sqlparser.ConvertType{ + Type: castTypeStr, + }, + } +} + +func getCastTypeForColumn(updatedTable *vindexes.Table, updExpr *sqlparser.UpdateExpr) string { + var ty querypb.Type + for _, column := range updatedTable.Columns { + if updExpr.Name.Name.Equal(column.Name) { + ty = column.Type + break + } + } + switch { + case sqltypes.IsNull(ty): + return "" + case sqltypes.IsSigned(ty): + return "SIGNED" + case sqltypes.IsUnsigned(ty): + return "UNSIGNED" + case sqltypes.IsFloat(ty): + return "FLOAT" + case sqltypes.IsDecimal(ty): + return "DECIMAL" + case sqltypes.IsDateOrTime(ty): + return "DATETIME" + case sqltypes.IsBinary(ty): + return "BINARY" + case sqltypes.IsText(ty): + return "CHAR" + default: + return "" + } +} + // createFkChildForUpdate creates the update query operator for the child table based on the foreign key constraints. func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, selectOffsets []int, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) (*FkChild, error) { // Create a ValTuple of child column names @@ -484,6 +522,7 @@ func buildChildUpdOpForSetNull( // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). updateExprs := ctx.SemTable.GetUpdateExpressionsForFk(fk.String(updatedTable)) compExpr := nullSafeNotInComparison(ctx, + updatedTable, updateExprs, fk, updatedTable.GetTableName(), nonLiteralUpdateInfo, false /* appendQualifier */) if compExpr != nil { childWhereExpr = &sqlparser.AndExpr{ @@ -522,6 +561,7 @@ func createFKVerifyOp( updStmt *sqlparser.Update, parentFks []vindexes.ParentFKInfo, restrictChildFks []vindexes.ChildFKInfo, + updatedTable *vindexes.Table, ) (ops.Operator, error) { if len(parentFks) == 0 && len(restrictChildFks) == 0 { return childOp, nil @@ -530,7 +570,7 @@ func createFKVerifyOp( var Verify []*VerifyOp // This validates that new values exists on the parent table. for _, fk := range parentFks { - op, err := createFkVerifyOpForParentFKForUpdate(ctx, updStmt, fk) + op, err := createFkVerifyOpForParentFKForUpdate(ctx, updatedTable, updStmt, fk) if err != nil { return nil, err } @@ -541,7 +581,7 @@ func createFKVerifyOp( } // This validates that the old values don't exist on the child table. for _, fk := range restrictChildFks { - op, err := createFkVerifyOpForChildFKForUpdate(ctx, updStmt, fk) + op, err := createFkVerifyOpForChildFKForUpdate(ctx, updatedTable, updStmt, fk) if err != nil { return nil, err } @@ -568,7 +608,7 @@ func createFKVerifyOp( // where Parent.p1 is null and Parent.p2 is null and Child.id = 1 and Child.c2 + 1 is not null // and Child.c2 is not null and not ((Child.c1) <=> (Child.c2 + 1)) // limit 1 -func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) (ops.Operator, error) { +func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) (ops.Operator, error) { childTblExpr := updStmt.TableExprs[0].(*sqlparser.AliasedTableExpr) childTbl, err := childTblExpr.TableName() if err != nil { @@ -608,7 +648,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS } } else { notEqualColNames = append(notEqualColNames, prefixColNames(ctx, childTbl, matchedExpr.Name)) - prefixedMatchExpr := prefixColNames(ctx, childTbl, matchedExpr.Expr) + prefixedMatchExpr := prefixColNames(ctx, childTbl, getCastedUpdateExpression(updatedTable, matchedExpr)) notEqualExprs = append(notEqualExprs, prefixedMatchExpr) joinExpr = &sqlparser.ComparisonExpr{ Operator: sqlparser.EqualOp, @@ -668,7 +708,7 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updS // verify query: // select 1 from Child join Parent on Parent.p1 = Child.c1 and Parent.p2 = Child.c2 // where Parent.id = 1 and ((Parent.col + 1) IS NULL OR (child.c1) NOT IN ((Parent.col + 1))) limit 1 -func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, cFk vindexes.ChildFKInfo) (ops.Operator, error) { +func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, cFk vindexes.ChildFKInfo) (ops.Operator, error) { // ON UPDATE RESTRICT foreign keys that require validation, should only be allowed in the case where we // are verifying all the FKs on vtgate level. if !ctx.VerifyAllFKs { @@ -710,7 +750,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt // For example, if we are setting `update child cola = :v1 and colb = :v2`, then on the parent, the where condition would look something like this - // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL). - compExpr := nullSafeNotInComparison(ctx, updStmt.Exprs, cFk, parentTbl, nil /* nonLiteralUpdateInfo */, true /* appendQualifier */) + compExpr := nullSafeNotInComparison(ctx, updatedTable, updStmt.Exprs, cFk, parentTbl, nil /* nonLiteralUpdateInfo */, true /* appendQualifier */) if compExpr != nil { whereCond = sqlparser.AndExpressions(whereCond, compExpr) } @@ -735,7 +775,7 @@ func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updSt // `:v1 IS NULL OR :v2 IS NULL OR (cola, colb) NOT IN ((:v1,:v2))` // So, if either of :v1 or :v2 is NULL, then the entire condition is true (which is the same as not having the condition when :v1 or :v2 is NULL) // This expression is used in cascading SET NULLs and in verifying whether an update should be restricted. -func nullSafeNotInComparison(ctx *plancontext.PlanningContext, updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo, parentTbl sqlparser.TableName, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, appendQualifier bool) sqlparser.Expr { +func nullSafeNotInComparison(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updateExprs sqlparser.UpdateExprs, cFk vindexes.ChildFKInfo, parentTbl sqlparser.TableName, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, appendQualifier bool) sqlparser.Expr { var valTuple sqlparser.ValTuple var updateValues sqlparser.ValTuple for idx, updateExpr := range updateExprs { @@ -744,7 +784,7 @@ func nullSafeNotInComparison(ctx *plancontext.PlanningContext, updateExprs sqlpa if sqlparser.IsNull(updateExpr.Expr) { return nil } - childUpdateExpr := prefixColNames(ctx, parentTbl, updateExpr.Expr) + childUpdateExpr := prefixColNames(ctx, parentTbl, getCastedUpdateExpression(updatedTable, updateExpr)) if len(nonLiteralUpdateInfo) > 0 && nonLiteralUpdateInfo[idx].UpdateExprBvName != "" { childUpdateExpr = sqlparser.NewArgument(nonLiteralUpdateInfo[idx].UpdateExprBvName) } diff --git a/go/vt/vtgate/planbuilder/operators/update_test.go b/go/vt/vtgate/planbuilder/operators/update_test.go new file mode 100644 index 00000000000..6cdf7be3f7d --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/update_test.go @@ -0,0 +1,140 @@ +/* +Copyright 2023 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 operators + +import ( + "testing" + + "github.com/stretchr/testify/require" + + querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +// TestGetCastTypeForColumn tests that we get the correct string value to use in a CAST function based on the type of the column. +func TestGetCastTypeForColumn(t *testing.T) { + tests := []struct { + name string + typ querypb.Type + want string + }{ + { + name: "VARCHAR column", + typ: querypb.Type_VARCHAR, + want: "CHAR", + }, + { + name: "CHAR column", + typ: querypb.Type_CHAR, + want: "CHAR", + }, + { + name: "VARBINARY column", + typ: querypb.Type_VARBINARY, + want: "BINARY", + }, + { + name: "BINARY column", + typ: querypb.Type_BINARY, + want: "BINARY", + }, + { + name: "UINT16 column", + typ: querypb.Type_UINT16, + want: "UNSIGNED", + }, + { + name: "UINT24 column", + typ: querypb.Type_UINT24, + want: "UNSIGNED", + }, + { + name: "UINT32 column", + typ: querypb.Type_UINT32, + want: "UNSIGNED", + }, + { + name: "UINT64 column", + typ: querypb.Type_UINT64, + want: "UNSIGNED", + }, + { + name: "INT16 column", + typ: querypb.Type_INT16, + want: "SIGNED", + }, + { + name: "INT24 column", + typ: querypb.Type_INT24, + want: "SIGNED", + }, + { + name: "INT32 column", + typ: querypb.Type_INT32, + want: "SIGNED", + }, + { + name: "INT64 column", + typ: querypb.Type_INT64, + want: "SIGNED", + }, + { + name: "FLOAT32 column", + typ: querypb.Type_FLOAT32, + want: "FLOAT", + }, + { + name: "FLOAT64 column", + typ: querypb.Type_FLOAT64, + want: "FLOAT", + }, + { + name: "DECIMAL column", + typ: querypb.Type_DECIMAL, + want: "DECIMAL", + }, + { + name: "DATETIME column", + typ: querypb.Type_DATETIME, + want: "DATETIME", + }, + { + name: "NULL column", + typ: querypb.Type_NULL_TYPE, + want: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + updExpr := &sqlparser.UpdateExpr{ + Name: sqlparser.NewColName("col"), + } + updatedTable := &vindexes.Table{ + Columns: []vindexes.Column{ + { + Name: sqlparser.NewIdentifierCI("col"), + Type: tt.typ, + }, + }, + } + tyStr := getCastTypeForColumn(updatedTable, updExpr) + require.EqualValues(t, tt.want, tyStr) + }) + } +} diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index 6757f7688e1..deba02e2009 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -328,7 +328,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in (('bar'))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((cast('bar' as CHAR)))", "Table": "u_tbl3" }, { @@ -693,7 +693,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in (('foo'))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast('foo' as CHAR)))", "Table": "u_tbl3" }, { @@ -727,7 +727,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in (('foo')) for update nowait", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast('foo' as CHAR))) for update nowait", "Table": "u_tbl9" }, { @@ -755,7 +755,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in (('foo'))", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast('foo' as CHAR)))", "Table": "u_tbl9" } ] @@ -805,8 +805,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", - "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where cast(u_tbl2.col1 + 'bar' as CHAR) is not null and not (u_tbl2.col2) <=> (cast(u_tbl2.col1 + 'bar' as CHAR)) and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", "Table": "u_tbl1, u_tbl2" }, { @@ -821,8 +821,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where 1 != 1", - "Query": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where id = 1 for update nowait", + "FieldQuery": "select col2, col2 <=> cast(col1 + 'bar' as CHAR), cast(col1 + 'bar' as CHAR) from u_tbl2 where 1 != 1", + "Query": "select col2, col2 <=> cast(col1 + 'bar' as CHAR), cast(col1 + 'bar' as CHAR) from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -840,7 +840,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd" @@ -889,8 +888,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where 1 != 1", - "Query": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where id = 1 for update nowait", + "FieldQuery": "select col1, col1 <=> cast(x + 'bar' as CHAR), cast(x + 'bar' as CHAR) from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> cast(x + 'bar' as CHAR), cast(x + 'bar' as CHAR) from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -902,7 +901,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd" @@ -934,7 +932,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (cast(:fkc_upd as CHAR) is null or (col3) not in ((cast(:fkc_upd as CHAR))))", "Table": "u_tbl3" }, { @@ -960,7 +958,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd1" @@ -1066,7 +1063,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((2))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((cast(2 as CHAR)))", "Table": "u_tbl3" }, { @@ -1143,7 +1140,7 @@ "Cols": [ 0 ], - "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((2))", + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast(2 as CHAR)))", "Table": "u_tbl3" }, { @@ -1177,7 +1174,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((2)) for update nowait", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast(2 as CHAR))) for update nowait", "Table": "u_tbl9" }, { @@ -1205,7 +1202,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((2))", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast(2 as CHAR)))", "Table": "u_tbl9" } ] @@ -1443,8 +1440,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where not (u_tbl8.col8) <=> (cast('foo' as CHAR)) and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", "Table": "u_tbl8, u_tbl9" }, { @@ -1519,8 +1516,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where not (u_tbl4.col4) <=> (cast('foo' as CHAR)) and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1532,7 +1529,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in ((cast('foo' as CHAR))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1608,8 +1605,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where not (u_tbl4.col4) <=> (cast(:v1 as CHAR)) and (u_tbl4.col4) in ::fkc_vals and cast(:v1 as CHAR) is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1621,7 +1618,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (cast(:v1 as CHAR) is null or (u_tbl9.col9) not in ((cast(:v1 as CHAR)))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -2092,8 +2089,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where 1 != 1", - "Query": "select col7, col7 <=> baz + 1 + col7, baz + 1 + col7 from u_tbl7 where bar = 42 for update nowait", + "FieldQuery": "select col7, col7 <=> cast(baz + 1 + col7 as CHAR), cast(baz + 1 + col7 as CHAR) from u_tbl7 where 1 != 1", + "Query": "select col7, col7 <=> cast(baz + 1 + col7 as CHAR), cast(baz + 1 + col7 as CHAR) from u_tbl7 where bar = 42 for update nowait", "Table": "u_tbl7" }, { @@ -2105,7 +2102,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd" @@ -2120,8 +2116,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :fkc_upd where not (u_tbl4.col4) <=> (:fkc_upd) and (u_tbl4.col4) in ::fkc_vals and :fkc_upd is not null and u_tbl3.col3 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:fkc_upd as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:fkc_upd as CHAR) where not (u_tbl4.col4) <=> (cast(:fkc_upd as CHAR)) and (u_tbl4.col4) in ::fkc_vals and cast(:fkc_upd as CHAR) is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -2133,7 +2129,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:fkc_upd is null or (u_tbl9.col9) not in ((:fkc_upd))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (cast(:fkc_upd as CHAR) is null or (u_tbl9.col9) not in ((cast(:fkc_upd as CHAR)))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -2203,7 +2199,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 2, "UpdateExprCol": 3, "UpdateExprBvName": "fkc_upd" @@ -2332,13 +2327,11 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 2, "UpdateExprCol": 3, "UpdateExprBvName": "fkc_upd" }, { - "ExprCol": 1, "CompExprCol": 4, "UpdateExprCol": 5, "UpdateExprBvName": "fkc_upd1" diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json index 1d523f3f24f..b4892a99052 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json @@ -328,7 +328,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in (('bar'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((cast('bar' as CHAR)))", "Table": "u_tbl3" }, { @@ -693,7 +693,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast('foo' as CHAR)))", "Table": "u_tbl3" }, { @@ -727,7 +727,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in (('foo')) for update nowait", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast('foo' as CHAR))) for update nowait", "Table": "u_tbl9" }, { @@ -755,7 +755,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in (('foo'))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast('foo' as CHAR)))", "Table": "u_tbl9" } ] @@ -805,8 +805,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where 1 != 1", - "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = u_tbl2.col1 + 'bar' where u_tbl2.col1 + 'bar' is not null and not (u_tbl2.col2) <=> (u_tbl2.col1 + 'bar') and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where cast(u_tbl2.col1 + 'bar' as CHAR) is not null and not (u_tbl2.col2) <=> (cast(u_tbl2.col1 + 'bar' as CHAR)) and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share nowait", "Table": "u_tbl1, u_tbl2" }, { @@ -821,8 +821,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where 1 != 1", - "Query": "select col2, col2 <=> col1 + 'bar', col1 + 'bar' from u_tbl2 where id = 1 for update nowait", + "FieldQuery": "select col2, col2 <=> cast(col1 + 'bar' as CHAR), cast(col1 + 'bar' as CHAR) from u_tbl2 where 1 != 1", + "Query": "select col2, col2 <=> cast(col1 + 'bar' as CHAR), cast(col1 + 'bar' as CHAR) from u_tbl2 where id = 1 for update nowait", "Table": "u_tbl2" }, { @@ -840,7 +840,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd" @@ -889,8 +888,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where 1 != 1", - "Query": "select col1, col1 <=> x + 'bar', x + 'bar' from u_tbl1 where id = 1 for update nowait", + "FieldQuery": "select col1, col1 <=> cast(x + 'bar' as CHAR), cast(x + 'bar' as CHAR) from u_tbl1 where 1 != 1", + "Query": "select col1, col1 <=> cast(x + 'bar' as CHAR), cast(x + 'bar' as CHAR) from u_tbl1 where id = 1 for update nowait", "Table": "u_tbl1" }, { @@ -902,7 +901,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd" @@ -934,7 +932,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (:fkc_upd is null or (col3) not in ((:fkc_upd)))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (cast(:fkc_upd as CHAR) is null or (col3) not in ((cast(:fkc_upd as CHAR))))", "Table": "u_tbl3" }, { @@ -960,7 +958,6 @@ ], "NonLiteralUpdateInfo": [ { - "ExprCol": 0, "CompExprCol": 1, "UpdateExprCol": 2, "UpdateExprBvName": "fkc_upd1" @@ -1066,7 +1063,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals and (col3) not in ((cast(2 as CHAR)))", "Table": "u_tbl3" }, { @@ -1143,7 +1140,7 @@ "Cols": [ 0 ], - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast(2 as CHAR)))", "Table": "u_tbl3" }, { @@ -1177,7 +1174,7 @@ "Sharded": false }, "FieldQuery": "select col9 from u_tbl9 where 1 != 1", - "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((2)) for update nowait", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast(2 as CHAR))) for update nowait", "Table": "u_tbl9" }, { @@ -1205,7 +1202,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((2))", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast(2 as CHAR)))", "Table": "u_tbl9" } ] @@ -1443,8 +1440,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = 'foo' where not (u_tbl8.col8) <=> ('foo') and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where not (u_tbl8.col8) <=> (cast('foo' as CHAR)) and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait", "Table": "u_tbl8, u_tbl9" }, { @@ -1519,8 +1516,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = 'foo' where not (u_tbl4.col4) <=> ('foo') and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where not (u_tbl4.col4) <=> (cast('foo' as CHAR)) and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1532,7 +1529,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in (('foo')) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in ((cast('foo' as CHAR))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { @@ -1608,8 +1605,8 @@ "Name": "unsharded_fk_allow", "Sharded": false }, - "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where 1 != 1", - "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = :v1 where not (u_tbl4.col4) <=> (:v1) and (u_tbl4.col4) in ::fkc_vals and :v1 is not null and u_tbl3.col3 is null limit 1 for share nowait", + "FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where 1 != 1", + "Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where not (u_tbl4.col4) <=> (cast(:v1 as CHAR)) and (u_tbl4.col4) in ::fkc_vals and cast(:v1 as CHAR) is not null and u_tbl3.col3 is null limit 1 for share nowait", "Table": "u_tbl3, u_tbl4" }, { @@ -1621,7 +1618,7 @@ "Sharded": false }, "FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1", - "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (:v1 is null or (u_tbl9.col9) not in ((:v1))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", + "Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (cast(:v1 as CHAR) is null or (u_tbl9.col9) not in ((cast(:v1 as CHAR)))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share nowait", "Table": "u_tbl4, u_tbl9" }, { diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json index d5b9ece501b..36aa30381e2 100644 --- a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json @@ -752,16 +752,84 @@ "unsharded_fk_allow": { "foreignKeyMode": "managed", "tables": { - "u_tbl1": {}, - "u_tbl2": {}, - "u_tbl3": {}, - "u_tbl4": {}, - "u_tbl5": {}, - "u_tbl6": {}, - "u_tbl7": {}, - "u_tbl8": {}, + "u_tbl1": { + "columns": [ + { + "name": "col1", + "type": "VARCHAR" + }, + { + "name": "col14", + "type": "INT16" + } + ] + }, + "u_tbl2": { + "columns": [ + { + "name": "col2", + "type": "VARCHAR" + } + ] + }, + "u_tbl3": { + "columns": [ + { + "name": "col3", + "type": "VARCHAR" + } + ] + }, + "u_tbl4": { + "columns": [ + { + "name": "col41", + "type": "INT16" + }, + { + "name": "col4", + "type": "VARCHAR" + } + ] + }, + "u_tbl5": { + "columns": [ + { + "name": "col5", + "type": "VARCHAR" + } + ] + }, + "u_tbl6": { + "columns": [ + { + "name": "col6", + "type": "VARCHAR" + } + ] + }, + "u_tbl7": { + "columns": [ + { + "name": "col7", + "type": "VARCHAR" + } + ] + }, + "u_tbl8": { + "columns": [ + { + "name": "col8", + "type": "VARCHAR" + } + ] + }, "u_tbl9": { "columns": [ + { + "name": "col9", + "type": "VARCHAR" + }, {"name": "foo"}, {"name": "bar", "default": "1"} ] From bc286c8e4b13a4d42624b18f3800cf720c48e831 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Sat, 25 Nov 2023 01:34:38 +0100 Subject: [PATCH 044/119] Miscellaneous typo fixes to comments (#14472) --- go/flags/endtoend/vtcombo.txt | 4 +- go/flags/endtoend/vttablet.txt | 4 +- go/vt/schemadiff/schema.go | 10 ++--- go/vt/schemadiff/schema_diff.go | 4 +- go/vt/schemadiff/schema_test.go | 2 +- go/vt/schemadiff/semantics.go | 2 +- go/vt/schemadiff/table.go | 12 +++--- go/vt/sidecardb/sidecardb.go | 2 +- go/vt/vtctl/grpcvtctldserver/server_test.go | 2 +- .../testutil/test_backupstorage.go | 2 +- .../testutil/test_tmclient.go | 4 +- go/vt/vtctl/internal/grpcshim/bidi_stream.go | 4 +- .../reparentutil/emergency_reparenter.go | 2 +- go/vt/vtctl/reparentutil/replication_test.go | 2 +- go/vt/vtctl/vdiff_env_test.go | 2 +- go/vt/vtctl/vtctldclient/client.go | 2 +- go/vt/vtctl/workflow/server.go | 2 +- go/vt/vtctl/workflow/vexec/query_plan.go | 2 +- go/vt/vtgate/endtoend/vstream_test.go | 2 +- go/vt/vtgate/engine/insert.go | 2 +- go/vt/vtgate/engine/rows.go | 2 +- go/vt/vtgate/engine/semi_join.go | 2 +- go/vt/vtgate/executor_select_test.go | 2 +- go/vt/vtgate/executor_test.go | 2 +- .../vtgate/planbuilder/operators/ast_to_op.go | 2 +- .../vtgate/planbuilder/operators/operator.go | 2 +- go/vt/vtgate/planbuilder/set.go | 2 +- go/vt/vtgate/safe_session.go | 2 +- go/vt/vtgate/semantics/analyzer.go | 4 +- go/vt/vtgate/tabletgateway.go | 2 +- go/vt/vtgate/tabletgateway_flaky_test.go | 6 +-- go/vt/vtgate/vindexes/cfc_test.go | 8 ++-- go/vt/vtgate/vindexes/lookup_hash.go | 4 +- go/vt/vtgate/vindexes/lookup_internal.go | 2 +- .../vindexes/lookup_unicodeloosemd5_hash.go | 4 +- go/vt/vtgate/vindexes/vschema_test.go | 4 +- go/vt/vtgate/vstream_manager.go | 2 +- go/vt/vtorc/config/config.go | 4 +- go/vt/vtorc/db/db.go | 2 +- go/vt/vtorc/inst/analysis_dao.go | 2 +- go/vt/vtorc/inst/binlog.go | 8 ++-- go/vt/vtorc/inst/instance_dao.go | 4 +- go/vt/vtorc/logic/topology_recovery.go | 2 +- go/vt/vtorc/logic/topology_recovery_dao.go | 2 +- go/vt/vtorc/logic/topology_recovery_status.go | 2 +- go/vt/vtorc/logic/vtorc.go | 2 +- go/vt/vtorc/metrics/query/aggregated.go | 4 +- go/vt/vtorc/server/api.go | 2 +- go/vt/vttablet/endtoend/call_test.go | 2 +- go/vt/vttablet/endtoend/compatibility_test.go | 2 +- go/vt/vttablet/endtoend/framework/client.go | 2 +- go/vt/vttablet/endtoend/framework/server.go | 2 +- go/vt/vttablet/endtoend/reserve_test.go | 6 +-- go/vt/vttablet/grpctabletconn/conn.go | 2 +- go/vt/vttablet/onlineddl/analysis.go | 4 +- go/vt/vttablet/onlineddl/executor.go | 42 +++++++++---------- go/vt/vttablet/onlineddl/vrepl.go | 4 +- go/vt/vttablet/onlineddl/vrepl/parser.go | 2 +- go/vt/vttablet/onlineddl/vrepl/types.go | 4 +- go/vt/vttablet/sandboxconn/sandboxconn.go | 2 +- .../tabletconntest/fakequeryservice.go | 2 +- go/vt/vttablet/tabletmanager/restore.go | 2 +- .../vttablet/tabletmanager/rpc_replication.go | 2 +- .../tabletmanager/rpc_vreplication.go | 2 +- .../tabletmanager/rpc_vreplication_test.go | 2 +- go/vt/vttablet/tabletmanager/tm_init.go | 8 ++-- go/vt/vttablet/tabletmanager/vdiff/engine.go | 6 +-- .../tabletmanager/vdiff/engine_test.go | 2 +- .../tabletmanager/vreplication/controller.go | 2 +- .../tabletmanager/vreplication/engine.go | 10 ++--- .../vreplication/queryhistory/verifier.go | 4 +- .../tabletmanager/vreplication/vcopier.go | 4 +- .../vreplication/vcopier_test.go | 8 ++-- .../tabletmanager/vreplication/vplayer.go | 4 +- .../tabletmanager/vreplication/vreplicator.go | 4 +- .../vreplication/vreplicator_test.go | 2 +- go/vt/vttablet/tabletserver/controller.go | 2 +- go/vt/vttablet/tabletserver/gc/tablegc.go | 8 ++-- .../vttablet/tabletserver/health_streamer.go | 4 +- .../tabletserver/messager/message_manager.go | 4 +- .../messager/message_manager_test.go | 2 +- .../planbuilder/testdata/exec_cases.txt | 2 +- go/vt/vttablet/tabletserver/query_engine.go | 4 +- .../tabletserver/query_executor_test.go | 4 +- .../tabletserver/repltracker/writer.go | 8 ++-- go/vt/vttablet/tabletserver/rules/map_test.go | 2 +- go/vt/vttablet/tabletserver/rules/rules.go | 4 +- .../tabletserver/schema/engine_test.go | 2 +- go/vt/vttablet/tabletserver/schema/schema.go | 2 +- go/vt/vttablet/tabletserver/state_manager.go | 2 +- .../tabletserver/stream_consolidator.go | 2 +- go/vt/vttablet/tabletserver/tabletenv/env.go | 2 +- .../tabletserver/tabletenv/seconds.go | 2 +- go/vt/vttablet/tabletserver/tabletserver.go | 4 +- .../throttle/base/throttle_metric.go | 2 +- .../vttablet/tabletserver/throttle/client.go | 6 +-- .../throttle/mysql/mysql_throttle_metric.go | 4 +- .../tabletserver/throttle/throttler.go | 16 +++---- .../tabletserver/throttle/throttler_test.go | 2 +- .../tabletserver/throttle/throttlerapp/app.go | 2 +- go/vt/vttablet/tabletserver/tx_executor.go | 2 +- .../tabletserver/txlimiter/tx_limiter_test.go | 2 +- .../txserializer/tx_serializer.go | 4 +- .../tabletserver/txthrottler/tx_throttler.go | 2 +- .../txthrottler/tx_throttler_test.go | 2 +- .../tabletserver/vstreamer/rowstreamer.go | 2 +- .../tabletserver/vstreamer/snapshot_conn.go | 4 +- .../tabletserver/vstreamer/vstreamer.go | 2 +- go/vt/wrangler/schema.go | 2 +- go/vt/wrangler/testlib/vtctl_pipe.go | 2 +- go/vt/wrangler/traffic_switcher_env_test.go | 2 +- go/vt/wrangler/traffic_switcher_test.go | 4 +- go/vt/wrangler/vdiff.go | 8 ++-- go/vt/wrangler/vexec.go | 2 +- 114 files changed, 212 insertions(+), 212 deletions(-) diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index c416af11e31..40720e702b7 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -333,7 +333,7 @@ Flags: --stream_buffer_size int the number of bytes sent from vtgate for each stream call. It's recommended to keep this value in sync with vttablet's query-server-config-stream-buffer-size. (default 32768) --stream_health_buffer_size uint max streaming health entries to buffer per streaming health client (default 20) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class - --table_gc_lifecycle string States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implcitly always included) (default "hold,purge,evac,drop") + --table_gc_lifecycle string States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implicitly always included) (default "hold,purge,evac,drop") --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. --tablet_filters strings Specifies a comma-separated list of 'keyspace|shard_name or keyrange' values to filter the tablets to watch. --tablet_health_keep_alive duration close streaming tablet health connection if there are no requests for this long (default 5m0s) @@ -349,7 +349,7 @@ Flags: --tablet_refresh_interval duration Tablet refresh interval. (default 1m0s) --tablet_refresh_known_tablets Whether to reload the tablet's address/port map from topo in case they change. (default true) --tablet_url_template string Format string describing debug tablet url formatting. See getTabletDebugURL() for how to customize this. (default "http://{{ "{{.GetTabletHostPort}}" }}") - --throttle_tablet_types string Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' aways implicitly included (default "replica") + --throttle_tablet_types string Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' always implicitly included (default "replica") --topo_consul_lock_delay duration LockDelay for consul session. (default 15s) --topo_consul_lock_session_checks string List of checks for consul session. (default "serfHealth") --topo_consul_lock_session_ttl string TTL for consul session. diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index c0926a6f701..7dc29a140b1 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -336,7 +336,7 @@ Flags: --table-acl-config string path to table access checker config file; send SIGHUP to reload this file --table-acl-config-reload-interval duration Ticker to reload ACLs. Duration flag, format e.g.: 30s. Default: do not reload --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class - --table_gc_lifecycle string States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implcitly always included) (default "hold,purge,evac,drop") + --table_gc_lifecycle string States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implicitly always included) (default "hold,purge,evac,drop") --tablet-path string tablet alias --tablet_config string YAML file config for tablet --tablet_dir string The directory within the vtdataroot to store vttablet/mysql files. Defaults to being generated by the tablet uid. @@ -355,7 +355,7 @@ Flags: --tablet_manager_grpc_server_name string the server name to use to validate server certificate --tablet_manager_protocol string Protocol to use to make tabletmanager RPCs to vttablets. (default "grpc") --tablet_protocol string Protocol to use to make queryservice RPCs to vttablets. (default "grpc") - --throttle_tablet_types string Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' aways implicitly included (default "replica") + --throttle_tablet_types string Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' always implicitly included (default "replica") --topo_consul_lock_delay duration LockDelay for consul session. (default 15s) --topo_consul_lock_session_checks string List of checks for consul session. (default "serfHealth") --topo_consul_lock_session_ttl string TTL for consul session. diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 40848a96536..c34f05b7a9f 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -128,7 +128,7 @@ func NewSchemaFromSQL(sql string) (*Schema, error) { return NewSchemaFromStatements(statements) } -// getForeignKeyParentTableNames analyzes a CREATE TABLE definition and extracts all referened foreign key tables names. +// getForeignKeyParentTableNames analyzes a CREATE TABLE definition and extracts all referenced foreign key tables names. // A table name may appear twice in the result output, if it is referenced by more than one foreign key func getForeignKeyParentTableNames(createTable *sqlparser.CreateTable) (names []string) { for _, cs := range createTable.TableSpec.Constraints { @@ -266,7 +266,7 @@ func (s *Schema) normalize() error { // It's possible that there's never been any tables in this schema. Which means // iterationLevel remains zero. // To deal with views, we must have iterationLevel at least 1. This is because any view reads - // from _something_: at the very least it reads from DUAL (inplicitly or explicitly). Which + // from _something_: at the very least it reads from DUAL (implicitly or explicitly). Which // puts the view at a higher level. if iterationLevel < 1 { iterationLevel = 1 @@ -451,7 +451,7 @@ func (s *Schema) diff(other *Schema, hints *DiffHints) (diffs []EntityDiff, err if _, ok := other.named[e.Name()]; !ok { // other schema does not have the entity // Entities are sorted in foreign key CREATE TABLE valid order (create parents first, then children). - // When issuing DROPs, we want to reverse that order. We want to first frop children, then parents. + // When issuing DROPs, we want to reverse that order. We want to first do it for children, then parents. // Instead of analyzing all relationships again, we just reverse the entire order of DROPs, foreign key // related or not. dropDiffs = append([]EntityDiff{e.Drop()}, dropDiffs...) @@ -766,10 +766,10 @@ func (s *Schema) Apply(diffs []EntityDiff) (*Schema, error) { return dup, nil } -// SchemaDiff calulates a rich diff between this schema and the given schema. It builds on top of diff(): +// SchemaDiff calculates a rich diff between this schema and the given schema. It builds on top of diff(): // on top of the list of diffs that can take this schema into the given schema, this function also // evaluates the dependencies between those diffs, if any, and the resulting SchemaDiff object offers OrderedDiffs(), -// the safe ordering of diffs that, when appleid sequentially, does not produce any conflicts and keeps schema valid +// the safe ordering of diffs that, when applied sequentially, does not produce any conflicts and keeps schema valid // at each step. func (s *Schema) SchemaDiff(other *Schema, hints *DiffHints) (*SchemaDiff, error) { diffs, err := s.diff(other, hints) diff --git a/go/vt/schemadiff/schema_diff.go b/go/vt/schemadiff/schema_diff.go index 8fef7c29d28..1429da088c1 100644 --- a/go/vt/schemadiff/schema_diff.go +++ b/go/vt/schemadiff/schema_diff.go @@ -92,7 +92,7 @@ func permutateDiffs(ctx context.Context, diffs []EntityDiff, callback func([]Ent if len(diffs) == 0 { return false, nil } - // Sort by a heristic (DROPs first, ALTERs next, CREATEs last). This ordering is then used first in the permutation + // Sort by a heuristic (DROPs first, ALTERs next, CREATEs last). This ordering is then used first in the permutation // search and serves as seed for the rest of permutations. return permDiff(ctx, diffs, callback, 0) @@ -296,7 +296,7 @@ func (d *SchemaDiff) OrderedDiffs(ctx context.Context) ([]EntityDiff, error) { for i, diff := range d.UnorderedDiffs() { unorderedDiffsMap[diff.CanonicalStatementString()] = i } - // The order of classes in the quivalence relation is, generally speaking, loyal to the order of original diffs. + // The order of classes in the equivalence relation is, generally speaking, loyal to the order of original diffs. for _, class := range d.r.OrderedClasses() { classDiffs := []EntityDiff{} // Which diffs are in this equivalence class? diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 79bf44117e2..3a609bdf769 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -716,7 +716,7 @@ func TestViewReferences(t *testing.T) { } // TestMassiveSchema loads thousands of tables into one schema, and thousands of tables, some of which are different, into another schema. -// It compares the two shemas. +// It compares the two schemas. // The objective of this test is to verify that execution time is _reasonable_. Since this will run in GitHub CI, which is very slow, we allow // for 1 minute total for all operations. func TestMassiveSchema(t *testing.T) { diff --git a/go/vt/schemadiff/semantics.go b/go/vt/schemadiff/semantics.go index 7cfe127cf57..ee7ef4e3b1a 100644 --- a/go/vt/schemadiff/semantics.go +++ b/go/vt/schemadiff/semantics.go @@ -34,7 +34,7 @@ var semanticKS = &vindexes.Keyspace{ var _ semantics.SchemaInformation = (*declarativeSchemaInformation)(nil) -// declarativeSchemaInformation is a utility wrapper arounf FakeSI, and adds a few utility functions +// declarativeSchemaInformation is a utility wrapper around FakeSI, and adds a few utility functions // to make it more simple and accessible to schemadiff's logic. type declarativeSchemaInformation struct { Tables map[string]*vindexes.Table diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index 3f256889721..eef39d51fa2 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -1159,7 +1159,7 @@ func (c *CreateTableEntity) diffOptions(alterTable *sqlparser.AlterTable, // rangePartitionsAddedRemoved returns true when: // - both table partitions are RANGE type -// - there is exactly one consequitive non-empty shared sequence of partitions (same names, same range values, in same order) +// - there is exactly one consecutive non-empty shared sequence of partitions (same names, same range values, in same order) // - table1 may have non-empty list of partitions _preceding_ this sequence, and table2 may not // - table2 may have non-empty list of partitions _following_ this sequence, and table1 may not func (c *CreateTableEntity) isRangePartitionsRotation( @@ -1189,7 +1189,7 @@ func (c *CreateTableEntity) isRangePartitionsRotation( definitions1 = definitions1[1:] } if len(definitions1) == 0 { - // We've exhaused definition1 trying to find a shared partition with definitions2. Nothing found. + // We've exhausted definition1 trying to find a shared partition with definitions2. Nothing found. // so there is no shared sequence between the two tables. return false, nil, nil } @@ -1251,9 +1251,9 @@ func (c *CreateTableEntity) diffPartitions(alterTable *sqlparser.AlterTable, return nil, nil default: // partitioning was changed - // For most cases, we produce a complete re-partitioing schema: we don't try and figure out the minimal + // For most cases, we produce a complete re-partitioning schema: we don't try and figure out the minimal // needed change. For example, maybe the minimal change is to REORGANIZE a specific partition and split - // into two, thus unaffecting the rest of the partitions. But we don't evaluate that, we just set a + // into two, thus not affecting the rest of the partitions. But we don't evaluate that, we just set a // complete new ALTER TABLE ... PARTITION BY statement. // The idea is that it doesn't matter: we're not looking to do optimal in-place ALTERs, we run // Online DDL alters, where we create a new table anyway. Thus, the optimization is meaningless. @@ -1602,7 +1602,7 @@ func (c *CreateTableEntity) diffColumns(alterTable *sqlparser.AlterTable, modifyColumnDiff := t1ColEntity.ColumnDiff(t2ColEntity, hints) if modifyColumnDiff == nil { // even if there's no apparent change, there can still be implicit changes - // it is possible that the table charset is changed. the column may be some col1 TEXT NOT NULL, possibly in both varsions 1 and 2, + // it is possible that the table charset is changed. the column may be some col1 TEXT NOT NULL, possibly in both versions 1 and 2, // but implicitly the column has changed its characters set. So we need to explicitly ass a MODIFY COLUMN statement, so that // MySQL rebuilds it. if tableCharsetChanged && t2ColEntity.IsTextual() && t2Col.Type.Charset.Name == "" { @@ -1684,7 +1684,7 @@ func heuristicallyDetectColumnRenames( // - the DROP and ADD column definitions are identical other than the column name, and // - the DROPped and ADDded column are both FIRST, or they come AFTER the same column, and // - the DROPped and ADDded column are both last, or they come before the same column - // This v1 chcek therefore cannot handle a case where two successive columns are renamed. + // This v1 check therefore cannot handle a case where two successive columns are renamed. // the problem is complex, and with successive renamed, or drops and adds, it can be // impossible to tell apart different scenarios. // At any case, once we heuristically decide that we found a RENAME, we cancel the DROP, diff --git a/go/vt/sidecardb/sidecardb.go b/go/vt/sidecardb/sidecardb.go index 0bb64611607..92d416f9d37 100644 --- a/go/vt/sidecardb/sidecardb.go +++ b/go/vt/sidecardb/sidecardb.go @@ -361,7 +361,7 @@ func (si *schemaInit) getCurrentSchema(tableName string) (string, error) { } // findTableSchemaDiff gets the diff which needs to be applied -// to the current table schema in order toreach the desired one. +// to the current table schema in order to reach the desired one. // The result will be an empty string if they match. // This will be a CREATE statement if the table does not exist // or an ALTER if the table exists but has a different schema. diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 38029f0e799..d597ec49502 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -3986,7 +3986,7 @@ func TestDeleteTablets(t *testing.T) { // value anymore defer unlock(&lerr) - // we do, however, care that the lock context gets propogated + // we do, however, care that the lock context gets propagated // both to additional calls to lock, and to the actual RPC call. ctx = lctx } diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go index dc273dcb962..1097d2994cc 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go @@ -104,7 +104,7 @@ func (a handlesByName) Less(i, j int) bool { return a[i].Name() < a[j].Name() } // *backupstorage.BackupStorageImplementation to this value before use. const BackupStorageImplementation = "grpcvtctldserver.testutil" -// BackupStorage is the singleton test backupstorage.BackupStorage intastnce. It +// BackupStorage is the singleton test backupstorage.BackupStorage instance. It // is public and singleton to allow tests to both mutate and assert against its // state. var BackupStorage = &backupStorage{ diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index ba7c8477d22..20c51968a11 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -1348,7 +1348,7 @@ func (fake *TabletManagerClient) UndoDemotePrimary(ctx context.Context, tablet * return assert.AnError } -// VReplicationExec is part of the tmclient.TabletManagerCLient interface. +// VReplicationExec is part of the tmclient.TabletManagerClient interface. func (fake *TabletManagerClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { if fake.VReplicationExecResults == nil { return nil, assert.AnError @@ -1393,7 +1393,7 @@ func (fake *TabletManagerClient) VReplicationExec(ctx context.Context, tablet *t return nil, assert.AnError } -// CheckThrottler is part of the tmclient.TabletManagerCLient interface. +// CheckThrottler is part of the tmclient.TabletManagerClient interface. func (fake *TabletManagerClient) CheckThrottler(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.CheckThrottlerRequest) (*tabletmanagerdatapb.CheckThrottlerResponse, error) { if fake.CheckThrottlerResults == nil { return nil, assert.AnError diff --git a/go/vt/vtctl/internal/grpcshim/bidi_stream.go b/go/vt/vtctl/internal/grpcshim/bidi_stream.go index a620cb929aa..92e7c24068b 100644 --- a/go/vt/vtctl/internal/grpcshim/bidi_stream.go +++ b/go/vt/vtctl/internal/grpcshim/bidi_stream.go @@ -101,7 +101,7 @@ type BidiStream struct { // NewBidiStream returns a BidiStream ready for embedded use. The provided ctx // will be used for the stream context, and types embedding BidiStream should -// check context cancellation/expiriation in their respective Recv and Send +// check context cancellation/expiration in their respective Recv and Send // methods. // // See the documentation on BidiStream for example usage. @@ -123,7 +123,7 @@ func (bs *BidiStream) Closed() <-chan struct{} { // IsClosed returns true if the stream has been closed for sending. // -// It is a conveince function for attempting to select on the channel returned +// It is a convenience function for attempting to select on the channel returned // by bs.Closed(). func (bs *BidiStream) IsClosed() bool { select { diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter.go b/go/vt/vtctl/reparentutil/emergency_reparenter.go index 7f190a4d994..607fec700b5 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter.go @@ -697,7 +697,7 @@ func (erp *EmergencyReparenter) identifyPrimaryCandidate( } } // Unreachable code. - // We should have found atleast 1 tablet in the valid list. + // We should have found at least 1 tablet in the valid list. // If the list is empty, then we should have errored out much sooner. return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "unreachable - did not find a valid primary candidate even though the valid candidate list was non-empty") } diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go index ed7bd152e9c..b7a2bcb07e7 100644 --- a/go/vt/vtctl/reparentutil/replication_test.go +++ b/go/vt/vtctl/reparentutil/replication_test.go @@ -54,7 +54,7 @@ func TestFindValidEmergencyReparentCandidates(t *testing.T) { statusMap map[string]*replicationdatapb.StopReplicationStatus primaryStatusMap map[string]*replicationdatapb.PrimaryStatus // Note: for these tests, it's simpler to compare keys than actual - // mysql.Postion structs, which are just thin wrappers around the + // mysql.Position structs, which are just thin wrappers around the // mysql.GTIDSet interface. If a tablet alias makes it into the map, we // know it was chosen by the method, and that either // mysql.DecodePosition was successful (in the primary case) or diff --git a/go/vt/vtctl/vdiff_env_test.go b/go/vt/vtctl/vdiff_env_test.go index 955d2673d20..b5324e7bd6e 100644 --- a/go/vt/vtctl/vdiff_env_test.go +++ b/go/vt/vtctl/vdiff_env_test.go @@ -43,7 +43,7 @@ import ( const ( // vdiffStopPosition is the default stop position for the target vreplication. - // It can be overridden with the positons argument to newTestVDiffEnv. + // It can be overridden with the positions argument to newTestVDiffEnv. vdiffStopPosition = "MySQL56/d834e6b8-7cbf-11ed-a1eb-0242ac120002:1-892" // vdiffSourceGtid should be the position reported by the source side VStreamResults. // It's expected to be higher the vdiffStopPosition. diff --git a/go/vt/vtctl/vtctldclient/client.go b/go/vt/vtctl/vtctldclient/client.go index 5b90a08ecdd..6e0c97bb8a5 100644 --- a/go/vt/vtctl/vtctldclient/client.go +++ b/go/vt/vtctl/vtctldclient/client.go @@ -22,7 +22,7 @@ type Factory func(addr string) (VtctldClient, error) var registry = map[string]Factory{} // Register adds a VtctldClient factory for the given name (protocol). -// Attempting to register mulitple factories for the same protocol is a fatal +// Attempting to register multiple factories for the same protocol is a fatal // error. func Register(name string, factory Factory) { if _, ok := registry[name]; ok { diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 3810d7a2944..95f1ecd42d4 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -141,7 +141,7 @@ var ( type Server struct { ts *topo.Server tmc tmclient.TabletManagerClient - // Limt the number of concurrent background goroutines if needed. + // Limit the number of concurrent background goroutines if needed. sem *semaphore.Weighted } diff --git a/go/vt/vtctl/workflow/vexec/query_plan.go b/go/vt/vtctl/workflow/vexec/query_plan.go index e6a9cb3a54d..52e7ee00b61 100644 --- a/go/vt/vtctl/workflow/vexec/query_plan.go +++ b/go/vt/vtctl/workflow/vexec/query_plan.go @@ -31,7 +31,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -// QueryPlan defines the interface to executing a preprared vexec query on one +// QueryPlan defines the interface to executing a prepared 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 { diff --git a/go/vt/vtgate/endtoend/vstream_test.go b/go/vt/vtgate/endtoend/vstream_test.go index 42dd6e3d2a3..871e6cf98c3 100644 --- a/go/vt/vtgate/endtoend/vstream_test.go +++ b/go/vt/vtgate/endtoend/vstream_test.go @@ -493,7 +493,7 @@ func TestVStreamCopyResume(t *testing.T) { // Also, to ensure that the client can resume properly, make sure that // the Fields value is present in the sqltypes.Result field and not missing. // It's not guaranteed that BOTH shards have streamed a row yet as the order - // of events in the stream is non-determinstic. So we check to be sure that + // of events in the stream is non-deterministic. So we check to be sure that // at least one shard has copied rows and thus has a full TableLastPK proto // message. eventStr := ev.String() diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index e0c90d091a0..4fa8eeadce4 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -1049,7 +1049,7 @@ func (ins *Insert) executeUnshardedTableQuery(ctx context.Context, vcursor VCurs return 0, nil, err } - // If processGenerateFromValues generated new values, it supercedes + // If processGenerateFromValues generated new values, it supersedes // any ids that MySQL might have generated. If both generated // values, we don't return an error because this behavior // is required to support migration. diff --git a/go/vt/vtgate/engine/rows.go b/go/vt/vtgate/engine/rows.go index 2b81c85145f..6ff5c5f2aa8 100644 --- a/go/vt/vtgate/engine/rows.go +++ b/go/vt/vtgate/engine/rows.go @@ -34,7 +34,7 @@ type Rows struct { noTxNeeded } -// NewRowsPrimitive returns a new Rows primitie +// NewRowsPrimitive returns a new Rows primitive func NewRowsPrimitive(rows [][]sqltypes.Value, fields []*querypb.Field) Primitive { return &Rows{rows: rows, fields: fields} } diff --git a/go/vt/vtgate/engine/semi_join.go b/go/vt/vtgate/engine/semi_join.go index d291b348da9..8ab0465249c 100644 --- a/go/vt/vtgate/engine/semi_join.go +++ b/go/vt/vtgate/engine/semi_join.go @@ -43,7 +43,7 @@ type SemiJoin struct { // Vars defines the list of SemiJoinVars that need to // be built from the LHS result before invoking - // the RHS subqquery. + // the RHS subquery. Vars map[string]int `json:",omitempty"` } diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 8f9fe064918..09467e85407 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -4170,7 +4170,7 @@ func TestWarmingReads(t *testing.T) { executor.normalize = true session := NewSafeSession(&vtgatepb.Session{TargetString: KsTestUnsharded}) - // Since queries on the replica will run in a separate go-routine, we need sycnronization for the Queries field in the sandboxconn. + // Since queries on the replica will run in a separate go-routine, we need synchronization for the Queries field in the sandboxconn. replica.RequireQueriesLocking() _, err := executor.Execute(ctx, nil, "TestWarmingReads", session, "select age, city from user", map[string]*querypb.BindVariable{}) diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 2a44d0a8b00..38746dea779 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -640,7 +640,7 @@ func TestExecutorShow(t *testing.T) { lastQuery = sbclookup.Queries[len(sbclookup.Queries)-1].Sql assert.Equal(t, wantQuery, lastQuery, "Got: %v. Want: %v", lastQuery, wantQuery) - // Set desitation keyspace in session + // Set destination keyspace in session session.TargetString = KsTestUnsharded _, err = executor.Execute(ctx, nil, "TestExecute", session, "show create table unknown", nil) require.NoError(t, err) diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index 46286b2778f..f6acbadd35a 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -227,7 +227,7 @@ func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement // Now, we can filter the foreign keys further based on the planning context, specifically whether we are running // this query with FOREIGN_KEY_CHECKS off or not. If the foreign key checks are enabled, then we don't need to verify - // the validity of shard-scoped RESTRICT foreign keys, since MySQL will do that for us. Similarily, we don't need to verify + // the validity of shard-scoped RESTRICT foreign keys, since MySQL will do that for us. Similarly, we don't need to verify // if the shard-scoped parent foreign key constraints are valid. switch stmt.(type) { case *sqlparser.Update, *sqlparser.Insert: diff --git a/go/vt/vtgate/planbuilder/operators/operator.go b/go/vt/vtgate/planbuilder/operators/operator.go index 4e58fca9214..b165c5345b0 100644 --- a/go/vt/vtgate/planbuilder/operators/operator.go +++ b/go/vt/vtgate/planbuilder/operators/operator.go @@ -24,7 +24,7 @@ The operators go through a few phases while planning: All the post-processing - aggregations, sorting, limit etc. are at this stage contained in Horizon structs. We try to push these down under routes, and expand the ones that can't be pushed down into individual operators such as Projection, - Agreggation, Limit, etc. + Aggregation, Limit, etc. 2. Planning Once the initial plan has been fully built, we go through a number of phases. recursively running rewriters on the tree in a fixed point fashion, until we've gone diff --git a/go/vt/vtgate/planbuilder/set.go b/go/vt/vtgate/planbuilder/set.go index 7b1e584132d..43d85ee5113 100644 --- a/go/vt/vtgate/planbuilder/set.go +++ b/go/vt/vtgate/planbuilder/set.go @@ -60,7 +60,7 @@ func buildSetPlan(stmt *sqlparser.Set, vschema plancontext.VSchema) (*planResult for _, expr := range stmt.Exprs { // AST struct has been prepared before getting here, so no scope here means that // we have a UDV. If the original query didn't explicitly specify the scope, it - // would have been explictly set to sqlparser.SessionStr before reaching this + // would have been explicitly set to sqlparser.SessionStr before reaching this // phase of planning switch expr.Var.Scope { case sqlparser.GlobalScope: diff --git a/go/vt/vtgate/safe_session.go b/go/vt/vtgate/safe_session.go index e2f3c235c94..60d99ab1952 100644 --- a/go/vt/vtgate/safe_session.go +++ b/go/vt/vtgate/safe_session.go @@ -435,7 +435,7 @@ func (session *SafeSession) AppendOrUpdate(shardSession *vtgatepb.Session_ShardS if session.queryFromVindex { break } - // isSingle is enforced only for normmal commit order operations. + // isSingle is enforced only for normal commit order operations. if session.isSingleDB(txMode) && len(session.ShardSessions) > 1 { count := actualNoOfShardSession(session.ShardSessions) if count <= 1 { diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index 44f2481a6b7..d7dab3da078 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -406,7 +406,7 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table childFKToUpdExprs[childFk.String(tbl.GetVindexTable())] = ue } } - // If we are setting a column to NULL, then we don't need to verify the existance of an + // If we are setting a column to NULL, then we don't need to verify the existence of an // equivalent row in the parent table, even if this column was part of a foreign key to a parent table. if sqlparser.IsNull(updateExpr.Expr) { continue @@ -458,7 +458,7 @@ func (a *analyzer) filterForeignKeysUsingUpdateExpressions(allChildFks map[Table return cFksNeedsHandling, pFksNeedsHandling, childFKToUpdExprs } -// getAllManagedForeignKeys gets all the foreign keys for the query we are analyzing that Vitess is reposible for managing. +// getAllManagedForeignKeys gets all the foreign keys for the query we are analyzing that Vitess is responsible for managing. func (a *analyzer) getAllManagedForeignKeys() (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, error) { allChildFKs := make(map[TableSet][]vindexes.ChildFKInfo) allParentFKs := make(map[TableSet][]vindexes.ParentFKInfo) diff --git a/go/vt/vtgate/tabletgateway.go b/go/vt/vtgate/tabletgateway.go index 9d62be2d357..1be29459bf6 100644 --- a/go/vt/vtgate/tabletgateway.go +++ b/go/vt/vtgate/tabletgateway.go @@ -92,7 +92,7 @@ func createHealthCheck(ctx context.Context, retryDelay, timeout time.Duration, t // NewTabletGateway creates and returns a new TabletGateway func NewTabletGateway(ctx context.Context, hc discovery.HealthCheck, serv srvtopo.Server, localCell string) *TabletGateway { - // hack to accomodate various users of gateway + tests + // hack to accommodate various users of gateway + tests if hc == nil { var topoServer *topo.Server if serv != nil { diff --git a/go/vt/vtgate/tabletgateway_flaky_test.go b/go/vt/vtgate/tabletgateway_flaky_test.go index f625b5599cd..917d931d2ff 100644 --- a/go/vt/vtgate/tabletgateway_flaky_test.go +++ b/go/vt/vtgate/tabletgateway_flaky_test.go @@ -61,7 +61,7 @@ func TestGatewayBufferingWhenPrimarySwitchesServingState(t *testing.T) { tg := NewTabletGateway(ctx, hc, ts, "cell") defer tg.Close(ctx) - // add a primary tabelt which is serving + // add a primary tablet which is serving sbc := hc.AddTestTablet("cell", host, port, keyspace, shard, tabletType, true, 10, nil) // add a result to the sandbox connection @@ -148,7 +148,7 @@ func TestGatewayBufferingWhileReparenting(t *testing.T) { tg := NewTabletGateway(ctx, hc, ts, "cell") defer tg.Close(ctx) - // add a primary tabelt which is serving + // add a primary tablet which is serving sbc := hc.AddTestTablet("cell", host, port, keyspace, shard, tabletType, true, 10, nil) // also add a replica which is serving sbcReplica := hc.AddTestTablet("cell", hostReplica, portReplica, keyspace, shard, topodatapb.TabletType_REPLICA, true, 0, nil) @@ -279,7 +279,7 @@ func TestInconsistentStateDetectedBuffering(t *testing.T) { tg.retryCount = 0 - // add a primary tabelt which is serving + // add a primary tablet which is serving sbc := hc.AddTestTablet("cell", host, port, keyspace, shard, tabletType, true, 10, nil) // add a result to the sandbox connection diff --git a/go/vt/vtgate/vindexes/cfc_test.go b/go/vt/vtgate/vindexes/cfc_test.go index 553d36de6c6..aaf639adec6 100644 --- a/go/vt/vtgate/vindexes/cfc_test.go +++ b/go/vt/vtgate/vindexes/cfc_test.go @@ -199,7 +199,7 @@ func TestCFCComputeKsid(t *testing.T) { testName: "misaligned prefix", id: [][]byte{{3, 4, 5}, {1}}, prefix: true, - // use the first component that's availabe + // use the first component that's available expected: expectedHash([][]byte{{3, 4, 5}}), err: nil, }, @@ -207,7 +207,7 @@ func TestCFCComputeKsid(t *testing.T) { testName: "misaligned prefix", id: [][]byte{{3, 4}}, prefix: true, - // use the first component that's availabe + // use the first component that's available expected: nil, err: nil, }, @@ -286,7 +286,7 @@ func TestCFCComputeKsidXxhash(t *testing.T) { testName: "misaligned prefix", id: [][]byte{{3, 4, 5}, {1}}, prefix: true, - // use the first component that's availabe + // use the first component that's available expected: expectedHashXX([][]byte{{3, 4, 5}}), err: nil, }, @@ -294,7 +294,7 @@ func TestCFCComputeKsidXxhash(t *testing.T) { testName: "misaligned prefix", id: [][]byte{{3, 4}}, prefix: true, - // use the first component that's availabe + // use the first component that's available expected: nil, err: nil, }, diff --git a/go/vt/vtgate/vindexes/lookup_hash.go b/go/vt/vtgate/vindexes/lookup_hash.go index de3d078f556..4a4c6f7a6b5 100644 --- a/go/vt/vtgate/vindexes/lookup_hash.go +++ b/go/vt/vtgate/vindexes/lookup_hash.go @@ -242,7 +242,7 @@ func (lh *LookupHash) MarshalJSON() ([]byte, error) { return json.Marshal(lh.lkp) } -// UnknownParams satisifes the ParamValidating interface. +// UnknownParams satisfies the ParamValidating interface. func (lh *LookupHash) UnknownParams() []string { return lh.unknownParams } @@ -265,7 +265,7 @@ func unhashList(ksids [][]byte) ([]sqltypes.Value, error) { // LookupHashUnique defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's // Unique and a Lookup. -// Warning: This Vindex is being depcreated in favor of LookupUnique +// Warning: This Vindex is being deprecated in favor of LookupUnique type LookupHashUnique struct { name string writeOnly bool diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index dac6ea8c27a..b793d57c3c8 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -356,7 +356,7 @@ nextRow: // Delete deletes the association between ids and value. // rowsColValues contains all the rows that are being deleted. // For each row, we store the value of each column defined in the vindex. -// value cointains the keyspace_id of the vindex entry being deleted. +// value contains the keyspace_id of the vindex entry being deleted. // // Given the following information in a vindex table with two columns: // diff --git a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go index 070aee90305..f7af93187da 100644 --- a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go +++ b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go @@ -56,7 +56,7 @@ func init() { // LookupUnicodeLooseMD5Hash defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's // NonUnique and a Lookup and stores the from value in a hashed form. -// Warning: This Vindex is being depcreated in favor of Lookup +// Warning: This Vindex is being deprecated in favor of Lookup type LookupUnicodeLooseMD5Hash struct { name string writeOnly bool @@ -246,7 +246,7 @@ func (lh *LookupUnicodeLooseMD5Hash) UnknownParams() []string { // LookupUnicodeLooseMD5HashUnique defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's // Unique and a Lookup and will store the from value in a hashed format. -// Warning: This Vindex is being depcreated in favor of LookupUnique +// Warning: This Vindex is being deprecated in favor of LookupUnique type LookupUnicodeLooseMD5HashUnique struct { name string writeOnly bool diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 92c95d64674..ebcb39fef29 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -414,7 +414,7 @@ func TestVSchemaForeignKeys(t *testing.T) { vschema := BuildVSchema(&good) require.NoError(t, vschema.Keyspaces["main"].Error) - // add fk containst a keyspace. + // add fk constraints to a keyspace. vschema.AddForeignKey("main", "t1", &sqlparser.ForeignKeyDefinition{ Source: sqlparser.Columns{sqlparser.NewIdentifierCI("c2")}, ReferenceDefinition: &sqlparser.ReferenceDefinition{ @@ -2987,7 +2987,7 @@ func TestReferenceTableAndSourceAreGloballyRoutable(t *testing.T) { _, err = vs.FindTable("sharded", "t1") require.NoError(t, err) // If the source of a reference table requires explicit routing, then - // neither the reference table nor its souce can be globally routed. + // neither the reference table nor its source can be globally routed. _, err = vs.FindTable("", "t1") require.Error(t, err) require.EqualError(t, err, "table t1 not found") diff --git a/go/vt/vtgate/vstream_manager.go b/go/vt/vtgate/vstream_manager.go index ffb8989ca5d..08553969a50 100644 --- a/go/vt/vtgate/vstream_manager.go +++ b/go/vt/vtgate/vstream_manager.go @@ -705,7 +705,7 @@ func (vs *vstream) streamFromTablet(ctx context.Context, sgtid *binlogdatapb.Sha // shouldRetry determines whether we should exit immediately or retry the vstream. // The first return value determines if the error can be retried, while the second -// indicates whether the tablet with which the error occurred should be ommitted +// indicates whether the tablet with which the error occurred should be omitted // from the candidate list of tablets to choose from on the retry. // // An error should be retried if it is expected to be transient. diff --git a/go/vt/vtorc/config/config.go b/go/vt/vtorc/config/config.go index 83a39303acb..03067d289ac 100644 --- a/go/vt/vtorc/config/config.go +++ b/go/vt/vtorc/config/config.go @@ -44,7 +44,7 @@ const ( DiscoveryQueueMaxStatisticsSize = 120 DiscoveryCollectionRetentionSeconds = 120 UnseenInstanceForgetHours = 240 // Number of hours after which an unseen instance is forgotten - FailureDetectionPeriodBlockMinutes = 60 // The time for which an instance's failure discovery is kept "active", so as to avoid concurrent "discoveries" of the instance's failure; this preceeds any recovery process, if any. + FailureDetectionPeriodBlockMinutes = 60 // The time for which an instance's failure discovery is kept "active", so as to avoid concurrent "discoveries" of the instance's failure; this precedes any recovery process, if any. ) var ( @@ -85,7 +85,7 @@ func RegisterFlags(fs *pflag.FlagSet) { } // Configuration makes for vtorc configuration input, which can be provided by user via JSON formatted file. -// Some of the parameteres have reasonable default values, and some (like database credentials) are +// Some of the parameters have reasonable default values, and some (like database credentials) are // strictly expected from user. // TODO(sougou): change this to yaml parsing, and possible merge with tabletenv. type Configuration struct { diff --git a/go/vt/vtorc/db/db.go b/go/vt/vtorc/db/db.go index d565c9bbdc4..92657eddc3f 100644 --- a/go/vt/vtorc/db/db.go +++ b/go/vt/vtorc/db/db.go @@ -88,7 +88,7 @@ func registerVTOrcDeployment(db *sql.DB) error { } // deployStatements will issue given sql queries that are not already known to be deployed. -// This iterates both lists (to-run and already-deployed) and also verifies no contraditions. +// This iterates both lists (to-run and already-deployed) and also verifies no contradictions. func deployStatements(db *sql.DB, queries []string) error { tx, err := db.Begin() if err != nil { diff --git a/go/vt/vtorc/inst/analysis_dao.go b/go/vt/vtorc/inst/analysis_dao.go index 25082f133da..749827f006c 100644 --- a/go/vt/vtorc/inst/analysis_dao.go +++ b/go/vt/vtorc/inst/analysis_dao.go @@ -521,7 +521,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.Description = "Primary cannot be reached by vtorc and all of its replicas are lagging" // } else if a.IsPrimary && !a.LastCheckValid && !a.LastCheckPartialSuccess && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas > 0 { - // partial success is here to redice noise + // partial success is here to reduce noise a.Analysis = UnreachablePrimary a.Description = "Primary cannot be reached by vtorc but it has replicating replicas; possibly a network/host issue" // diff --git a/go/vt/vtorc/inst/binlog.go b/go/vt/vtorc/inst/binlog.go index 066c2f5c598..9c115e4e457 100644 --- a/go/vt/vtorc/inst/binlog.go +++ b/go/vt/vtorc/inst/binlog.go @@ -68,7 +68,7 @@ func (binlogCoordinates BinlogCoordinates) String() string { return binlogCoordinates.DisplayString() } -// Equals tests equality of this corrdinate and another one. +// Equals tests equality of this coordinate and another one. func (binlogCoordinates *BinlogCoordinates) Equals(other *BinlogCoordinates) bool { if other == nil { return false @@ -106,8 +106,8 @@ func (binlogCoordinates *BinlogCoordinates) FileSmallerThan(other *BinlogCoordin return binlogCoordinates.LogFile < other.LogFile } -// FileNumberDistance returns the numeric distance between this corrdinate's file number and the other's. -// Effectively it means "how many roatets/FLUSHes would make these coordinates's file reach the other's" +// FileNumberDistance returns the numeric distance between this coordinate's file number and the other's. +// Effectively it means "how many rotates/FLUSHes would make these coordinates's file reach the other's" func (binlogCoordinates *BinlogCoordinates) FileNumberDistance(other *BinlogCoordinates) int { thisNumber, _ := binlogCoordinates.FileNumber() otherNumber, _ := other.FileNumber() @@ -163,7 +163,7 @@ func (binlogCoordinates *BinlogCoordinates) NextFileCoordinates() (BinlogCoordin return result, nil } -// Detach returns a detahced form of coordinates +// Detach returns a detached form of coordinates func (binlogCoordinates *BinlogCoordinates) Detach() (detachedCoordinates BinlogCoordinates) { detachedCoordinates = BinlogCoordinates{LogFile: fmt.Sprintf("//%s:%d", binlogCoordinates.LogFile, binlogCoordinates.LogPos), LogPos: binlogCoordinates.LogPos} return detachedCoordinates diff --git a/go/vt/vtorc/inst/instance_dao.go b/go/vt/vtorc/inst/instance_dao.go index 01b8a750f57..adac5623075 100644 --- a/go/vt/vtorc/inst/instance_dao.go +++ b/go/vt/vtorc/inst/instance_dao.go @@ -89,7 +89,7 @@ func initializeInstanceDao() { cacheInitializationCompleted.Store(true) } -// ExecDBWriteFunc chooses how to execute a write onto the database: whether synchronuously or not +// ExecDBWriteFunc chooses how to execute a write onto the database: whether synchronously or not func ExecDBWriteFunc(f func() error) error { m := query.NewMetric() @@ -1105,7 +1105,7 @@ func ForgetInstance(tabletAlias string) error { return nil } -// ForgetLongUnseenInstances will remove entries of all instacnes that have long since been last seen. +// ForgetLongUnseenInstances will remove entries of all instances that have long since been last seen. func ForgetLongUnseenInstances() error { sqlResult, err := db.ExecVTOrc(` delete diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index d3e73c00886..cf99e34e426 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -584,7 +584,7 @@ func runEmergentOperations(analysisEntry *inst.ReplicationAnalysis) { } // executeCheckAndRecoverFunction will choose the correct check & recovery function based on analysis. -// It executes the function synchronuously +// It executes the function synchronously func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (err error) { countPendingRecoveries.Add(1) defer countPendingRecoveries.Add(-1) diff --git a/go/vt/vtorc/logic/topology_recovery_dao.go b/go/vt/vtorc/logic/topology_recovery_dao.go index c835b9ecfe4..4a7a6c77ef1 100644 --- a/go/vt/vtorc/logic/topology_recovery_dao.go +++ b/go/vt/vtorc/logic/topology_recovery_dao.go @@ -369,7 +369,7 @@ func acknowledgeRecoveries(owner string, comment string, markEndRecovery bool, w return rows, err } -// AcknowledgeInstanceCompletedRecoveries marks active and COMPLETED recoveries for given instane as acknowledged. +// AcknowledgeInstanceCompletedRecoveries marks active and COMPLETED recoveries for given instance as acknowledged. // This also implied clearing their active period, which in turn enables further recoveries on those topologies func AcknowledgeInstanceCompletedRecoveries(tabletAlias string, owner string, comment string) (countAcknowledgedEntries int64, err error) { whereClause := ` diff --git a/go/vt/vtorc/logic/topology_recovery_status.go b/go/vt/vtorc/logic/topology_recovery_status.go index d1195963ba1..d128a0637bc 100644 --- a/go/vt/vtorc/logic/topology_recovery_status.go +++ b/go/vt/vtorc/logic/topology_recovery_status.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/vtorc/logic/vtorc.go b/go/vt/vtorc/logic/vtorc.go index 02fb41daa21..f637956fbfd 100644 --- a/go/vt/vtorc/logic/vtorc.go +++ b/go/vt/vtorc/logic/vtorc.go @@ -329,7 +329,7 @@ func onHealthTick() { } } -// ContinuousDiscovery starts an asynchronuous infinite discovery process where instances are +// ContinuousDiscovery starts an asynchronous infinite discovery process where instances are // periodically investigated and their status captured, and long since unseen instances are // purged and forgotten. // nolint SA1015: using time.Tick leaks the underlying ticker diff --git a/go/vt/vtorc/metrics/query/aggregated.go b/go/vt/vtorc/metrics/query/aggregated.go index beece44d53a..a284ca6f74d 100644 --- a/go/vt/vtorc/metrics/query/aggregated.go +++ b/go/vt/vtorc/metrics/query/aggregated.go @@ -1,5 +1,5 @@ -// Package query provdes query metrics with this file providing -// aggregared metrics based on the underlying values. +// Package query provides query metrics with this file providing +// aggregated metrics based on the underlying values. package query import ( diff --git a/go/vt/vtorc/server/api.go b/go/vt/vtorc/server/api.go index f053336e64e..b0112e10add 100644 --- a/go/vt/vtorc/server/api.go +++ b/go/vt/vtorc/server/api.go @@ -117,7 +117,7 @@ func RegisterVTOrcAPIEndpoints() { } } -// returnAsJSON returns the argument received on the resposeWriter as a json object +// returnAsJSON returns the argument received on the responseWriter as a json object func returnAsJSON(response http.ResponseWriter, code int, stuff any) { response.Header().Set("Content-Type", "application/json; charset=utf-8") response.WriteHeader(code) diff --git a/go/vt/vttablet/endtoend/call_test.go b/go/vt/vttablet/endtoend/call_test.go index 3a42eea3780..477a099aa76 100644 --- a/go/vt/vttablet/endtoend/call_test.go +++ b/go/vt/vttablet/endtoend/call_test.go @@ -149,7 +149,7 @@ func TestCallProcedureChangedTx(t *testing.T) { }) } - // This passes as this starts a new transaction by commiting the old transaction implicitly. + // This passes as this starts a new transaction by committing the old transaction implicitly. _, err = client.BeginExecute(`call proc_tx_begin()`, nil, nil) require.NoError(t, err) } diff --git a/go/vt/vttablet/endtoend/compatibility_test.go b/go/vt/vttablet/endtoend/compatibility_test.go index 9b89a602281..4dde4019a99 100644 --- a/go/vt/vttablet/endtoend/compatibility_test.go +++ b/go/vt/vttablet/endtoend/compatibility_test.go @@ -33,7 +33,7 @@ import ( var point12 = "\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@" -func TestCharaterSet(t *testing.T) { +func TestCharacterSet(t *testing.T) { qr, err := framework.NewClient().Execute("select * from vitess_test where intval=1", nil) if err != nil { t.Fatal(err) diff --git a/go/vt/vttablet/endtoend/framework/client.go b/go/vt/vttablet/endtoend/framework/client.go index 3c06f9b465c..e671cb447c7 100644 --- a/go/vt/vttablet/endtoend/framework/client.go +++ b/go/vt/vttablet/endtoend/framework/client.go @@ -134,7 +134,7 @@ func (client *QueryClient) CommitPrepared(dtid string) error { return client.server.CommitPrepared(client.ctx, client.target, dtid) } -// RollbackPrepared rollsback a prepared transaction. +// RollbackPrepared rolls back a prepared transaction. func (client *QueryClient) RollbackPrepared(dtid string, originalID int64) error { return client.server.RollbackPrepared(client.ctx, client.target, dtid, originalID) } diff --git a/go/vt/vttablet/endtoend/framework/server.go b/go/vt/vttablet/endtoend/framework/server.go index 4f8043fba5a..9e78dc08a85 100644 --- a/go/vt/vttablet/endtoend/framework/server.go +++ b/go/vt/vttablet/endtoend/framework/server.go @@ -135,7 +135,7 @@ func StopServer() { Server.StopService() } -// txReolver transmits dtids to be resolved through ResolveChan. +// txResolver transmits dtids to be resolved through ResolveChan. type txResolver struct { fakerpcvtgateconn.FakeVTGateConn } diff --git a/go/vt/vttablet/endtoend/reserve_test.go b/go/vt/vttablet/endtoend/reserve_test.go index 591512d44c6..63b87f9c00f 100644 --- a/go/vt/vttablet/endtoend/reserve_test.go +++ b/go/vt/vttablet/endtoend/reserve_test.go @@ -777,9 +777,9 @@ func TestReserveBeginExecuteWithPreQueriesAndCheckConnectionState(t *testing.T) require.NoError(t, err) assert.NotEqual(t, qr1.Rows, qr2.Rows) - // As the transaction is read commited it is not able to see #5. + // As the transaction is read committed it is not able to see #5. assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)]]`, fmt.Sprintf("%v", qr1.Rows)) - // As the transaction is read uncommited it is able to see #4. + // As the transaction is read uncommitted it is able to see #4. assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(4)] [INT32(5)]]`, fmt.Sprintf("%v", qr2.Rows)) err = rucClient.Commit() @@ -804,7 +804,7 @@ func TestReserveBeginExecuteWithPreQueriesAndCheckConnectionState(t *testing.T) qr2, err = rucClient.Execute(selQuery, nil) require.NoError(t, err) - // As the transaction on read committed client got rollbacked back, table will forget #4. + // As the transaction on read committed client got rolled back, table will forget #4. assert.Equal(t, qr1.Rows, qr2.Rows) assert.Equal(t, `[[INT32(1)] [INT32(2)] [INT32(3)] [INT32(5)]]`, fmt.Sprintf("%v", qr2.Rows)) diff --git a/go/vt/vttablet/grpctabletconn/conn.go b/go/vt/vttablet/grpctabletconn/conn.go index cb97abcbbae..2399420a8d0 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -417,7 +417,7 @@ func (conn *gRPCQueryClient) ConcludeTransaction(ctx context.Context, target *qu return nil } -// ReadTransaction returns the metadata for the sepcified dtid. +// ReadTransaction returns the metadata for the specified dtid. func (conn *gRPCQueryClient) ReadTransaction(ctx context.Context, target *querypb.Target, dtid string) (*querypb.TransactionMetadata, error) { conn.mu.RLock() defer conn.mu.RUnlock() diff --git a/go/vt/vttablet/onlineddl/analysis.go b/go/vt/vttablet/onlineddl/analysis.go index 987f09124a1..68eee5d4b9b 100644 --- a/go/vt/vttablet/onlineddl/analysis.go +++ b/go/vt/vttablet/onlineddl/analysis.go @@ -175,7 +175,7 @@ func analyzeAddRangePartition(alterTable *sqlparser.AlterTable, createTable *sql return op } -// alterOptionAvailableViaInstantDDL chcks if the specific alter option is eligible to run via ALGORITHM=INSTANT +// alterOptionAvailableViaInstantDDL checks if the specific alter option is eligible to run via ALGORITHM=INSTANT // reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html func alterOptionAvailableViaInstantDDL(alterOption sqlparser.AlterOption, createTable *sqlparser.CreateTable, capableOf mysql.CapableOf) (bool, error) { findColumn := func(colName string) *sqlparser.ColumnDefinition { @@ -314,7 +314,7 @@ func alterOptionAvailableViaInstantDDL(alterOption sqlparser.AlterOption, create } // AnalyzeInstantDDL takes declarative CreateTable and AlterTable, as well as a server version, and checks whether it is possible to run the ALTER -// using ALGORITM=INSTANT for that version. +// using ALGORITHM=INSTANT for that version. // This function is INTENTIONALLY public, even though we do not guarantee that it will remain so. func AnalyzeInstantDDL(alterTable *sqlparser.AlterTable, createTable *sqlparser.CreateTable, capableOf mysql.CapableOf) (*SpecialAlterPlan, error) { capable, err := capableOf(mysql.InstantDDLFlavorCapability) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 771a9000435..dca3186f7b3 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -76,7 +76,7 @@ var ( ) var ( - // fixCompletedTimestampDone fixes a nil `completed_tiemstamp` columns, see + // fixCompletedTimestampDone fixes a nil `completed_timestamp` columns, see // https://github.com/vitessio/vitess/issues/13927 // The fix is in release-18.0 // TODO: remove in release-19.0 @@ -238,7 +238,7 @@ func newGCTableRetainTime() time.Time { } // getMigrationCutOverThreshold returns the cut-over threshold for the given migration. The migration's -// DDL Strategy may excplicitly set the threshold; otherwise, we return the default cut-over threshold. +// DDL Strategy may explicitly set the threshold; otherwise, we return the default cut-over threshold. func getMigrationCutOverThreshold(onlineDDL *schema.OnlineDDL) time.Duration { if threshold, _ := onlineDDL.StrategySetting().CutOverThreshold(); threshold != 0 { return threshold @@ -387,7 +387,7 @@ func (e *Executor) matchesShards(commaDelimitedShards string) bool { } // countOwnedRunningMigrations returns an estimate of current count of running migrations; this is -// normally an accurate number, but can be inexact because the exdcutor peridocially reviews +// normally an accurate number, but can be inexact because the executor periodically reviews // e.ownedRunningMigrations and adds/removes migrations based on actual migration state. func (e *Executor) countOwnedRunningMigrations() (count int) { e.ownedRunningMigrations.Range(func(_, val any) bool { @@ -546,7 +546,7 @@ func (e *Executor) readMySQLVariables(ctx context.Context) (variables *mysqlVari } // createOnlineDDLUser creates a gh-ost or pt-osc user account with all -// neccessary privileges and with a random password +// necessary privileges and with a random password func (e *Executor) createOnlineDDLUser(ctx context.Context) (password string, err error) { conn, err := dbconnpool.NewDBConnection(ctx, e.env.Config().DB.DbaConnector()) if err != nil { @@ -844,7 +844,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) er } // This was a best effort optimization. Possibly the error is not nil. Which means we // still have a record of the sentry table, and gcArtifacts() will still be able to take - // care of it in the futre. + // care of it in the future. }() parsed := sqlparser.BuildParsedQuery(sqlCreateSentryTable, sentryTableName) if _, err := e.execQuery(ctx, parsed.Query); err != nil { @@ -904,7 +904,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) er waitForRenameProcess := func() error { // This function waits until it finds the RENAME TABLE... query running in MySQL's PROCESSLIST, or until timeout // The function assumes that one of the renamed tables is locked, thus causing the RENAME to block. If nothing - // is locked, then the RENAME will be near-instantaneious and it's unlikely that the function will find it. + // is locked, then the RENAME will be near-instantaneous and it's unlikely that the function will find it. renameWaitCtx, cancel := context.WithTimeout(ctx, migrationCutOverThreshold) defer cancel() @@ -1301,7 +1301,7 @@ func (e *Executor) duplicateCreateTable(ctx context.Context, onlineDDL *schema.O // createDuplicateTableLike creates the table named by `newTableName` in the likeness of onlineDDL.Table // This function emulates MySQL's `CREATE TABLE LIKE ...` statement. The difference is that this function takes control over the generated CONSTRAINT names, -// if any, such that they are detrministic across shards, as well as preserve original names where possible. +// if any, such that they are deterministic across shards, as well as preserve original names where possible. func (e *Executor) createDuplicateTableLike(ctx context.Context, newTableName string, onlineDDL *schema.OnlineDDL, conn *dbconnpool.DBConnection) ( originalShowCreateTable string, constraintMap map[string]string, @@ -1880,7 +1880,7 @@ export MYSQL_PWD // The following sleep() is temporary and artificial. Because we create a new user for this // migration, and because we throttle by replicas, we need to wait for the replicas to be // caught up with the new user creation. Otherwise, the OSC tools will fail connecting to the replicas... - // Once we have a built in throttling service , we will no longe rneed to have the OSC tools probe the + // Once we have a built in throttling service , we will no longer need to have the OSC tools probe the // replicas. Instead, they will consult with our throttling service. // TODO(shlomi): replace/remove this when we have a proper throttling solution time.Sleep(time.Second) @@ -2229,7 +2229,7 @@ func (e *Executor) UnthrottleAllMigrations(ctx context.Context) (result *sqltype return emptyResult, nil } -// scheduleNextMigration attemps to schedule a single migration to run next. +// scheduleNextMigration attempts to schedule a single migration to run next. // possibly there are migrations to run. // The effect of this function is to move a migration from 'queued' state to 'ready' state, is all. func (e *Executor) scheduleNextMigration(ctx context.Context) error { @@ -2257,7 +2257,7 @@ func (e *Executor) scheduleNextMigration(ctx context.Context) error { if !readyToComplete { // see if we need to update ready_to_complete if isImmediateOperation { - // Whether postponsed or not, CREATE and DROP operations, as well as VIEW operations, + // Whether postponed or not, CREATE and DROP operations, as well as VIEW operations, // are inherently "ready to complete" because their operation is immediate. if err := e.updateMigrationReadyToComplete(ctx, uuid, true); err != nil { return err @@ -2364,7 +2364,7 @@ func (e *Executor) reviewImmediateOperations(ctx context.Context, capableOf mysq // reviewQueuedMigration investigates a single migration found in `queued` state. // It analyzes whether the migration can & should be fulfilled immediately (e.g. via INSTANT DDL or just because it's a CREATE or DROP), -// or backfils necessary information if it's a REVERT. +// or backfills necessary information if it's a REVERT. // If all goes well, it sets `reviewed_timestamp` which then allows the state machine to schedule the migration. func (e *Executor) reviewQueuedMigration(ctx context.Context, uuid string, capableOf mysql.CapableOf) error { onlineDDL, row, err := e.readMigration(ctx, uuid) @@ -2702,7 +2702,7 @@ func (e *Executor) evaluateDeclarativeDiff(ctx context.Context, onlineDDL *schem return diff, nil } -// getCompletedMigrationByContextAndSQL chceks if there exists a completed migration with exact same +// getCompletedMigrationByContextAndSQL checks if there exists a completed migration with exact same // context and SQL as given migration. If so, it returns its UUID. func (e *Executor) getCompletedMigrationByContextAndSQL(ctx context.Context, onlineDDL *schema.OnlineDDL) (completedUUID string, err error) { if onlineDDL.MigrationContext == "" { @@ -3210,7 +3210,7 @@ func (e *Executor) executeMigration(ctx context.Context, onlineDDL *schema.Onlin if exists { // table does exist, so this declarative DROP turns out to really be an actual DROP. No further action is needed here } else { - // table does not exist. We mark this DROP as implicitly sucessful + // table does not exist. We mark this DROP as implicitly successful _ = e.onSchemaMigrationStatus(ctx, onlineDDL.UUID, schema.OnlineDDLStatusComplete, false, progressPctFull, etaSecondsNow, rowsCopiedUnknown, emptyHint) _ = e.updateMigrationMessage(ctx, onlineDDL.UUID, "no change") return nil @@ -3243,7 +3243,7 @@ func (e *Executor) executeMigration(ctx context.Context, onlineDDL *schema.Onlin return failMigration(err) } if diff == nil || diff.IsEmpty() { - // No diff! We mark this CREATE as implicitly sucessful + // No diff! We mark this CREATE as implicitly successful _ = e.onSchemaMigrationStatus(ctx, onlineDDL.UUID, schema.OnlineDDLStatusComplete, false, progressPctFull, etaSecondsNow, rowsCopiedUnknown, emptyHint) _ = e.updateMigrationMessage(ctx, onlineDDL.UUID, "no change") return nil @@ -3507,7 +3507,7 @@ func (e *Executor) isVReplMigrationReadyToCutOver(ctx context.Context, onlineDDL } } { - // Both time_updated and transaction_timestamp must be in close priximity to each + // Both time_updated and transaction_timestamp must be in close proximity to each // other and to the time now, otherwise that means we're lagging and it's not a good time // to cut-over durationDiff := func(t1, t2 time.Time) time.Duration { @@ -3629,7 +3629,7 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i // This VRepl migration may have started from outside this tablet, so // this executor may not own the migration _yet_. We make sure to own it. // VReplication migrations are unique in this respect: we are able to complete - // a vreplicaiton migration started by another tablet. + // a vreplication migration started by another tablet. e.ownedRunningMigrations.Store(uuid, onlineDDL) if lastVitessLivenessIndicator := migrationRow.AsInt64("vitess_liveness_indicator", 0); lastVitessLivenessIndicator < s.livenessTimeIndicator() { _ = e.updateMigrationTimestamp(ctx, "liveness_timestamp", uuid) @@ -3720,7 +3720,7 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i countRunnning++ } { - // now, let's look at UUIDs we own and _think_ should be running, and see which of tham _isn't_ actually running or pending... + // now, let's look at UUIDs we own and _think_ should be running, and see which of them _isn't_ actually running or pending... uuidsFoundPending := map[string]bool{} for _, uuid := range pendingMigrationsUUIDs { uuidsFoundPending[uuid] = true @@ -3873,7 +3873,7 @@ func (e *Executor) gcArtifactTable(ctx context.Context, artifactTable, uuid stri // The fact we're here means the table is not needed anymore. We can throw it away. // We do so by renaming it into a GC table. We use the HOLD state and with a timestamp that is // in the past. So as we rename the table: - // - The Online DDL executor compeltely loses it and has no more access to its data + // - The Online DDL executor completely loses it and has no more access to its data // - TableGC will find it on next iteration, see that it's been on HOLD "long enough", and will // take it from there to transition it into PURGE or EVAC, or DROP, and eventually drop it. renameStatement, toTableName, err := schema.GenerateRenameStatementWithUUID(artifactTable, schema.HoldTableGCState, schema.OnlineDDLToGCUUID(uuid), t) @@ -4648,7 +4648,7 @@ func (e *Executor) submittedMigrationConflictsWithPendingMigrationInSingletonCon return true } -// submitCallbackIfNonConflicting is called internally by SubmitMigration, and is given a callack to execute +// submitCallbackIfNonConflicting is called internally by SubmitMigration, and is given a callback to execute // if the given migration does not conflict any terms. Specifically, this function looks for singleton or // singleton-context conflicts. // The call back can be an insertion of a new migration, or a retry of an existing migration, or whatnot. @@ -4754,10 +4754,10 @@ func (e *Executor) SubmitMigration( // So we will _mostly_ ignore the request: we will not submit a new migration. However, we will do // these things: - // 1. Check that the requested submmited migration macthes the existing one's migration-context, otherwise + // 1. Check that the requested submitted migration matches the existing one's migration-context, otherwise // this doesn't seem right, not the idempotency we were looking for if storedMigration.MigrationContext != onlineDDL.MigrationContext { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "migration rejected: found migration %s with different context: %s than submmitted migration's context: %s", onlineDDL.UUID, storedMigration.MigrationContext, onlineDDL.MigrationContext) + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "migration rejected: found migration %s with different context: %s than submitted migration's context: %s", onlineDDL.UUID, storedMigration.MigrationContext, onlineDDL.MigrationContext) } // 2. Possibly, the existing migration is in 'failed' or 'cancelled' state, in which case this // resubmission should retry the migration. diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index b1dd0ff8629..7934aed6af1 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -168,7 +168,7 @@ func NewVRepl(workflow string, } } -// readAutoIncrement reads the AUTO_INCREMENT vlaue, if any, for a give ntable +// readAutoIncrement reads the AUTO_INCREMENT value, if any, for a give ntable func (v *VRepl) readAutoIncrement(ctx context.Context, conn *dbconnpool.DBConnection, tableName string) (autoIncrement uint64, err error) { query, err := sqlparser.ParseAndBind(sqlGetAutoIncrement, sqltypes.StringBindVariable(v.dbName), @@ -642,7 +642,7 @@ func (v *VRepl) analyze(ctx context.Context, conn *dbconnpool.DBConnection) erro return nil } -// generateInsertStatement generates the INSERT INTO _vt.replication stataement that creates the vreplication workflow +// generateInsertStatement generates the INSERT INTO _vt.replication statement that creates the vreplication workflow func (v *VRepl) generateInsertStatement(ctx context.Context) (string, error) { ig := vreplication.NewInsertGenerator(binlogdatapb.VReplicationWorkflowState_Stopped, v.dbName) ig.AddRow(v.workflow, v.bls, v.pos, "", "in_order:REPLICA,PRIMARY", diff --git a/go/vt/vttablet/onlineddl/vrepl/parser.go b/go/vt/vttablet/onlineddl/vrepl/parser.go index 87f82cb8096..f1f2f1378d8 100644 --- a/go/vt/vttablet/onlineddl/vrepl/parser.go +++ b/go/vt/vttablet/onlineddl/vrepl/parser.go @@ -112,7 +112,7 @@ func (p *AlterTableParser) DroppedColumnsMap() map[string]bool { return p.droppedColumns } -// IsRenameTable returns true when the ALTER TABLE statement inclusdes renaming the table +// IsRenameTable returns true when the ALTER TABLE statement includes renaming the table func (p *AlterTableParser) IsRenameTable() bool { return p.isRenameTable } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index e4ddff6d58e..0ca834ffdf0 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -207,7 +207,7 @@ func (l *ColumnList) Equals(other *ColumnList) bool { return reflect.DeepEqual(l.Columns, other.Columns) } -// EqualsByNames chcks if the names in this list equals the names of another list, in order. Type is ignored. +// EqualsByNames checks if the names in this list equals the names of another list, in order. Type is ignored. func (l *ColumnList) EqualsByNames(other *ColumnList) bool { return reflect.DeepEqual(l.Names(), other.Names()) } @@ -252,7 +252,7 @@ func (l *ColumnList) MappedNamesColumnList(columnNamesMap map[string]string) *Co return NewColumnList(names) } -// SetEnumToTextConversion tells this column list that an enum is conveted to text +// SetEnumToTextConversion tells this column list that an enum is converted to text func (l *ColumnList) SetEnumToTextConversion(columnName string, enumValues string) { l.GetColumn(columnName).EnumToTextConversion = true l.GetColumn(columnName).EnumValues = enumValues diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 0c8485f97e5..55a635984ec 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -391,7 +391,7 @@ func (sbc *SandboxConn) ConcludeTransaction(ctx context.Context, target *querypb return sbc.getError() } -// ReadTransaction returns the metadata for the sepcified dtid. +// ReadTransaction returns the metadata for the specified dtid. func (sbc *SandboxConn) ReadTransaction(ctx context.Context, target *querypb.Target, dtid string) (metadata *querypb.TransactionMetadata, err error) { sbc.ReadTransactionCount.Add(1) if err := sbc.getError(); err != nil { diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index cfe540ead42..d3adff022e4 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -173,7 +173,7 @@ func (f *FakeQueryService) Commit(ctx context.Context, target *querypb.Target, t return 0, nil } -// rollbackTransactionID is a test transactin id for Rollback. +// rollbackTransactionID is a test transaction id for Rollback. const rollbackTransactionID int64 = 999044 // Rollback is part of the queryservice.QueryService interface diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 4512b546f2c..032b7357d43 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -581,7 +581,7 @@ func (tm *TabletManager) catchupToGTID(ctx context.Context, afterGTIDPos string, } } -// disableReplication stopes and resets replication on the mysql server. It moreover sets impossible replication +// disableReplication stops and resets replication on the mysql server. It moreover sets impossible replication // source params, so that the replica can't possibly reconnect. It would take a `CHANGE [MASTER|REPLICATION SOURCE] TO ...` to // make the mysql server replicate again (available via tm.MysqlDaemon.SetReplicationPosition) func (tm *TabletManager) disableReplication(ctx context.Context) error { diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 9981219e4a2..bec905e93ce 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -418,7 +418,7 @@ func (tm *TabletManager) InitReplica(ctx context.Context, parent *topodatapb.Tab // DemotePrimary prepares a PRIMARY tablet to give up leadership to another tablet. // -// It attemps to idempotently ensure the following guarantees upon returning +// It attempts to idempotently ensure the following guarantees upon returning // successfully: // - No future writes will be accepted. // - No writes are in-flight. diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication.go b/go/vt/vttablet/tabletmanager/rpc_vreplication.go index b18caa1063f..d81d2a6e6a4 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication.go @@ -328,7 +328,7 @@ func (tm *TabletManager) UpdateVReplicationWorkflow(ctx context.Context, req *ta // VReplicationExec executes a vreplication command. func (tm *TabletManager) VReplicationExec(ctx context.Context, query string) (*querypb.QueryResult, error) { - // Replace any provided sidecar databsae qualifiers with the correct one. + // Replace any provided sidecar database qualifiers with the correct one. uq, err := sqlparser.ReplaceTableQualifiers(query, sidecar.DefaultName, sidecar.GetName()) if err != nil { return nil, err diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go index a471750da19..a70220a68fc 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go @@ -993,7 +993,7 @@ func TestFailedMoveTablesCreateCleanup(t *testing.T) { ) // We expect the workflow creation to fail due to the invalid time - // zone and thus the workflow iteslf to be cleaned up. + // zone and thus the workflow itself to be cleaned up. tenv.tmc.setVReplicationExecResults(sourceTablet.tablet, fmt.Sprintf(deleteWorkflow, sourceKs, workflow.ReverseWorkflowName(wf)), &sqltypes.Result{RowsAffected: 1}, diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 2cd21c09a21..2873c3a1d5e 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -536,7 +536,7 @@ func (tm *TabletManager) createKeyspaceShard(ctx context.Context) (*topo.ShardIn tm._rebuildKeyspaceDone = make(chan struct{}) go tm.rebuildKeyspace(rebuildKsCtx, tm._rebuildKeyspaceDone, tablet.Keyspace, rebuildKeyspaceRetryInterval) default: - return nil, vterrors.Wrap(err, "initeKeyspaceShardTopo: failed to read SrvKeyspace") + return nil, vterrors.Wrap(err, "initKeyspaceShardTopo: failed to read SrvKeyspace") } // Rebuild vschema graph if this is the first tablet in this keyspace/cell. @@ -546,16 +546,16 @@ func (tm *TabletManager) createKeyspaceShard(ctx context.Context) (*topo.ShardIn // Check if vschema was rebuilt after the initial creation of the keyspace. if _, keyspaceExists := srvVSchema.GetKeyspaces()[tablet.Keyspace]; !keyspaceExists { if err := tm.TopoServer.RebuildSrvVSchema(ctx, []string{tm.tabletAlias.Cell}); err != nil { - return nil, vterrors.Wrap(err, "initeKeyspaceShardTopo: failed to RebuildSrvVSchema") + return nil, vterrors.Wrap(err, "initKeyspaceShardTopo: failed to RebuildSrvVSchema") } } case topo.IsErrType(err, topo.NoNode): // There is no SrvSchema in this cell at all, so we definitely need to rebuild. if err := tm.TopoServer.RebuildSrvVSchema(ctx, []string{tm.tabletAlias.Cell}); err != nil { - return nil, vterrors.Wrap(err, "initeKeyspaceShardTopo: failed to RebuildSrvVSchema") + return nil, vterrors.Wrap(err, "initKeyspaceShardTopo: failed to RebuildSrvVSchema") } default: - return nil, vterrors.Wrap(err, "initeKeyspaceShardTopo: failed to read SrvVSchema") + return nil, vterrors.Wrap(err, "initKeyspaceShardTopo: failed to read SrvVSchema") } return shardInfo, nil } diff --git a/go/vt/vttablet/tabletmanager/vdiff/engine.go b/go/vt/vttablet/tabletmanager/vdiff/engine.go index 72098eb52be..1ccf3dc80e6 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/engine.go +++ b/go/vt/vttablet/tabletmanager/vdiff/engine.go @@ -99,7 +99,7 @@ func NewTestEngine(ts *topo.Server, tablet *topodata.Tablet, dbn string, dbcf fu } func (vde *Engine) InitDBConfig(dbcfgs *dbconfigs.DBConfigs) { - // If it's a test engine and we're already initilized then do nothing. + // If it's a test engine and we're already initialized then do nothing. if vde.fortests && vde.dbClientFactoryFiltered != nil && vde.dbClientFactoryDba != nil { return } @@ -153,7 +153,7 @@ func (vde *Engine) openLocked(ctx context.Context) error { return err } - // At this point we've fully and succesfully opened so begin + // At this point we've fully and successfully opened so begin // retrying error'd VDiffs until the engine is closed. vde.wg.Add(1) go func() { @@ -193,7 +193,7 @@ func (vde *Engine) retry(ctx context.Context, err error) { if err := vde.openLocked(ctx); err == nil { log.Infof("VDiff engine: opened successfully") // Don't invoke cancelRetry because openLocked - // will hold on to this context for later cancelation. + // will hold on to this context for later cancellation. vde.cancelRetry = nil vde.mu.Unlock() return diff --git a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go index 75b0e37d630..0aedeec415b 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go @@ -270,7 +270,7 @@ func TestEngineRetryErroredVDiffs(t *testing.T) { fmt.Sprintf("%s|%s|%s|%s||9223372036854775807|9223372036854775807||PRIMARY,REPLICA|1669511347|0|Running||%s|200||1669511347|1|0||1", id, vdiffenv.workflow, vreplSource, vdiffSourceGtid, vdiffDBName), ), nil) - // At this point we know that we kicked off the expected retry so we can short circit the vdiff. + // At this point we know that we kicked off the expected retry so we can short circuit the vdiff. shortCircuitTestAfterQuery(fmt.Sprintf("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = %s", id), vdiffenv.dbClient) expectedControllerCnt++ diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index b9aad39fe6c..d7a6f5a31b6 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -49,7 +49,7 @@ const ( ) // controller is created by Engine. Members are initialized upfront. -// There is no mutex within a controller becaust its members are +// There is no mutex within a controller because its members are // either read-only or self-synchronized. type controller struct { vre *Engine diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 8b81dd722c6..f230ecce045 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -72,7 +72,7 @@ var waitRetryTime = 1 * time.Second // How frequently vcopier will update _vt.vreplication rows_copied var rowsCopiedUpdateInterval = 30 * time.Second -// How frequntly vcopier will garbage collect old copy_state rows. +// How frequently vcopier will garbage collect old copy_state rows. // By default, do it in between every 2nd and 3rd rows copied update. var copyStateGCInterval = (rowsCopiedUpdateInterval * 3) - (rowsCopiedUpdateInterval / 2) @@ -107,7 +107,7 @@ type Engine struct { throttlerClient *throttle.Client // This should only be set in Test Engines in order to short - // curcuit functions as needed in unit tests. It's automatically + // circuit functions as needed in unit tests. It's automatically // enabled in NewSimpleTestEngine. This should NOT be used in // production. shortcircuit bool @@ -143,7 +143,7 @@ func NewEngine(config *tabletenv.TabletConfig, ts *topo.Server, cell string, mys // InitDBConfig should be invoked after the db name is computed. func (vre *Engine) InitDBConfig(dbcfgs *dbconfigs.DBConfigs) { - // If we're already initilized, it's a test engine. Ignore the call. + // If we're already initialized, it's a test engine. Ignore the call. if vre.dbClientFactoryFiltered != nil && vre.dbClientFactoryDba != nil { return } @@ -173,7 +173,7 @@ func NewTestEngine(ts *topo.Server, cell string, mysqld mysqlctl.MysqlDaemon, db } // NewSimpleTestEngine creates a new Engine for testing that can -// also short curcuit functions as needed. +// also short circuit functions as needed. func NewSimpleTestEngine(ts *topo.Server, cell string, mysqld mysqlctl.MysqlDaemon, dbClientFactoryFiltered func() binlogplayer.DBClient, dbClientFactoryDba func() binlogplayer.DBClient, dbname string, externalConfig map[string]*dbconfigs.DBConfigs) *Engine { vre := &Engine{ controllers: make(map[int32]*controller), @@ -262,7 +262,7 @@ func (vre *Engine) retry(ctx context.Context, err error) { } if err := vre.openLocked(ctx); err == nil { // Don't invoke cancelRetry because openLocked - // will hold on to this context for later cancelation. + // will hold on to this context for later cancellation. vre.cancelRetry = nil vre.mu.Unlock() return diff --git a/go/vt/vttablet/tabletmanager/vreplication/queryhistory/verifier.go b/go/vt/vttablet/tabletmanager/vreplication/queryhistory/verifier.go index a7015b0daf5..ebe145461d7 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/queryhistory/verifier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/queryhistory/verifier.go @@ -41,7 +41,7 @@ func NewVerifier(sequence ExpectationSequence) *Verifier { } // AcceptQuery verifies that the provided query is valid according to the -// internal ExpectationSequence and the internal History of preceeding queries. +// internal ExpectationSequence and the internal History of preceding queries. // Returns a *Result indicating whether the query was accepted and, if not, // diagnostic details indicating why not. func (v *Verifier) AcceptQuery(query string) *Result { @@ -159,7 +159,7 @@ func (v *Verifier) checkQueryAgainstExpectation(query string, expectation Sequen // Query passed expectation. result.Accepted = true result.Matched = true - result.Message = "matched expectated query and expected order" + result.Message = "matched expected query and expected order" return true } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index cbf524c54c3..f88c900f2db 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -612,7 +612,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma case result := <-resultCh: switch result.state { case vcopierCopyTaskCancel: - // A task cancelation probably indicates an expired context due + // A task cancellation probably indicates an expired context due // to a PlannedReparentShard or elapsed copy phase duration, // neither of which are error conditions. case vcopierCopyTaskComplete: @@ -1087,7 +1087,7 @@ func (vbc *vcopierCopyWorker) execute(ctx context.Context, task *vcopierCopyTask advanceFn = func(context.Context, *vcopierCopyTaskArgs) error { // Commit. if err := vbc.vdbClient.Commit(); err != nil { - return vterrors.Wrapf(err, "error commiting transaction") + return vterrors.Wrapf(err, "error committing transaction") } return nil } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index 82a6d211b4f..b960635ff11 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -102,7 +102,7 @@ func testPlayerCopyCharPK(t *testing.T) { defer func() { vttablet.CopyPhaseDuration = savedCopyPhaseDuration }() savedWaitRetryTime := waitRetryTime - // waitRetry time should be very low to cause the wait loop to execute multipel times. + // waitRetry time should be very low to cause the wait loop to execute multiple times. waitRetryTime = 10 * time.Millisecond defer func() { waitRetryTime = savedWaitRetryTime }() @@ -332,7 +332,7 @@ func testPlayerCopyVarcharCompositePKCaseSensitiveCollation(t *testing.T) { defer func() { vttablet.CopyPhaseDuration = savedCopyPhaseDuration }() savedWaitRetryTime := waitRetryTime - // waitRetry time should be very low to cause the wait loop to execute multipel times. + // waitRetry time should be very low to cause the wait loop to execute multiple times. waitRetryTime = 10 * time.Millisecond defer func() { waitRetryTime = savedWaitRetryTime }() @@ -811,7 +811,7 @@ func testPlayerCopyWildcardRule(t *testing.T) { defer func() { vttablet.CopyPhaseDuration = savedCopyPhaseDuration }() savedWaitRetryTime := waitRetryTime - // waitRetry time should be very low to cause the wait loop to execute multipel times. + // waitRetry time should be very low to cause the wait loop to execute multiple times. waitRetryTime = 10 * time.Millisecond defer func() { waitRetryTime = savedWaitRetryTime }() @@ -979,7 +979,7 @@ func testPlayerCopyTableContinuation(t *testing.T) { "update src1 set id2=10 where id1=5", // move row from within to outside range. "update src1 set id1=12 where id1=6", - // move row from outside to witihn range. + // move row from outside to within range. "update src1 set id1=4 where id1=11", // modify the copied table. "update copied set val='bbb' where id=1", diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 8eee211ff9e..3abd24aa0e6 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -346,8 +346,8 @@ func (vp *vplayer) recordHeartbeat() error { // of transactions come in, with the last one being partial. In this case, all transactions // up to the last one have to be committed, and the final one must be partially applied. // -// Of the above events, the saveable ones are COMMIT, DDL, and OTHER. Eventhough -// A GTID comes as a separate event, it's not saveable until a subsequent saveable +// Of the above events, the saveable ones are COMMIT, DDL, and OTHER. Even though +// a GTID comes as a separate event, it's not saveable until a subsequent saveable // event occurs. VStreamer currently sequences the GTID to be sent just before // a saveable event, but we do not rely on this. To handle this, we only remember // the position when a GTID is encountered. The next saveable event causes the diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index e148151934e..c4df7e618d5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -561,7 +561,7 @@ func (vr *vreplicator) setSQLMode(ctx context.Context, dbClient *vdbClient) (fun // - "vreplication" for most flows // - "vreplication:online-ddl" for online ddl flows. // Note that with such name, it's possible to throttle -// the worflow by either /throttler/throttle-app?app=vreplication and/or /throttler/throttle-app?app=online-ddl +// the workflow by either /throttler/throttle-app?app=vreplication and/or /throttler/throttle-app?app=online-ddl // This is useful when we want to throttle all migrations. We throttle "online-ddl" and that applies to both vreplication // migrations as well as gh-ost migrations. func (vr *vreplicator) throttlerAppName() string { @@ -1044,7 +1044,7 @@ func (vr *vreplicator) setExistingRowsCopied() { if vr.stats.CopyRowCount.Get() == 0 { rowsCopiedExisting, err := vr.readExistingRowsCopied(vr.id) if err != nil { - log.Warningf("Failed to read existing rows copied value for %s worfklow: %v", vr.WorkflowName, err) + log.Warningf("Failed to read existing rows copied value for %s workflow: %v", vr.WorkflowName, err) } else if rowsCopiedExisting != 0 { log.Infof("Resuming the %s vreplication workflow started on another tablet, setting rows copied counter to %v", vr.WorkflowName, rowsCopiedExisting) vr.stats.CopyRowCount.Set(rowsCopiedExisting) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go index 128d41d4bc2..aaa4a974191 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go @@ -339,7 +339,7 @@ func TestDeferSecondaryKeys(t *testing.T) { myvr.WorkflowType = int32(binlogdatapb.VReplicationWorkflowType_Reshard) // Insert second post copy action record to simulate a shard merge where you // have N controllers/replicators running for the same table on the tablet. - // This forces a second row, which would otherwise not get created beacause + // This forces a second row, which would otherwise not get created because // when this is called there's no secondary keys to stash anymore. addlAction, err := json.Marshal(PostCopyAction{ Type: PostCopyActionSQL, diff --git a/go/vt/vttablet/tabletserver/controller.go b/go/vt/vttablet/tabletserver/controller.go index ca4eeb8747b..4d7e35862de 100644 --- a/go/vt/vttablet/tabletserver/controller.go +++ b/go/vt/vttablet/tabletserver/controller.go @@ -66,7 +66,7 @@ type Controller interface { // ClearQueryPlanCache clears internal query plan cache ClearQueryPlanCache() - // ReloadSchema makes the quey service reload its schema cache + // ReloadSchema makes the query service reload its schema cache ReloadSchema(ctx context.Context) error // RegisterQueryRuleSource adds a query rule source diff --git a/go/vt/vttablet/tabletserver/gc/tablegc.go b/go/vt/vttablet/tabletserver/gc/tablegc.go index 4947fd9c97a..8658d7c3a3b 100644 --- a/go/vt/vttablet/tabletserver/gc/tablegc.go +++ b/go/vt/vttablet/tabletserver/gc/tablegc.go @@ -65,7 +65,7 @@ func registerGCFlags(fs *pflag.FlagSet) { // purgeReentranceInterval marks the interval between searching tables to purge fs.DurationVar(&purgeReentranceInterval, "gc_purge_check_interval", purgeReentranceInterval, "Interval between purge discovery checks") // gcLifecycle is the sequence of steps the table goes through in the process of getting dropped - fs.StringVar(&gcLifecycle, "table_gc_lifecycle", gcLifecycle, "States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implcitly always included)") + fs.StringVar(&gcLifecycle, "table_gc_lifecycle", gcLifecycle, "States for a DROP TABLE garbage collection cycle. Default is 'hold,purge,evac,drop', use any subset ('drop' implicitly always included)") } var ( @@ -120,7 +120,7 @@ type TableGC struct { lifecycleStates map[schema.TableGCState]bool } -// Status published some status valus from the collector +// Status published some status values from the collector type Status struct { Keyspace string Shard string @@ -575,7 +575,7 @@ func (collector *TableGC) transitionTable(ctx context.Context, transition *trans // when we transition into PURGE, that means we want to begin purging immediately // when we transition into DROP, that means we want to drop immediately - // Thereforce the default timestamp is Now + // Therefore the default timestamp is Now t := time.Now().UTC() switch transition.toGCState { case schema.EvacTableGCState: @@ -601,7 +601,7 @@ func (collector *TableGC) transitionTable(ctx context.Context, transition *trans return nil } -// addPurgingTable adds a table to the list of droppingpurging (or pending purging) tables +// addPurgingTable adds a table to the list of dropping purging (or pending purging) tables func (collector *TableGC) addPurgingTable(tableName string) (added bool) { if _, ok := collector.lifecycleStates[schema.PurgeTableGCState]; !ok { // PURGE is not a handled state. We don't want to purge this table or any other table, diff --git a/go/vt/vttablet/tabletserver/health_streamer.go b/go/vt/vttablet/tabletserver/health_streamer.go index 87c70a7133d..2e75ccf2a20 100644 --- a/go/vt/vttablet/tabletserver/health_streamer.go +++ b/go/vt/vttablet/tabletserver/health_streamer.go @@ -50,8 +50,8 @@ import ( ) var ( - // blpFunc is a legaacy feature. - // TODO(sougou): remove after legacy resharding worflows are removed. + // blpFunc is a legacy feature. + // TODO(sougou): remove after legacy resharding workflows are removed. blpFunc = vreplication.StatusSummary errUnintialized = "tabletserver uninitialized" diff --git a/go/vt/vttablet/tabletserver/messager/message_manager.go b/go/vt/vttablet/tabletserver/messager/message_manager.go index 0629b31629f..be2e0cf7034 100644 --- a/go/vt/vttablet/tabletserver/messager/message_manager.go +++ b/go/vt/vttablet/tabletserver/messager/message_manager.go @@ -227,7 +227,7 @@ type messageManager struct { // wg is for ensuring all running goroutines have returned // before we can close the manager. You need to Add before - // launching any gorooutine while holding a lock on mu. + // launching any goroutine while holding a lock on mu. // The goroutine must in turn defer on Done. wg sync.WaitGroup @@ -272,7 +272,7 @@ func newMessageManager(tsv TabletService, vs VStreamer, table *schema.Table, pos } mm.readByPriorityAndTimeNext = sqlparser.BuildParsedQuery( // There should be a poller_idx defined on (time_acked, priority, time_next desc) - // for this to be as effecient as possible + // for this to be as efficient as possible "select priority, time_next, epoch, time_acked, %s from %v where time_acked is null and time_next < %a order by priority, time_next desc limit %a", columnList, mm.name, ":time_next", ":max") mm.ackQuery = sqlparser.BuildParsedQuery( diff --git a/go/vt/vttablet/tabletserver/messager/message_manager_test.go b/go/vt/vttablet/tabletserver/messager/message_manager_test.go index b8ca47ae46d..5c5ab47d3c8 100644 --- a/go/vt/vttablet/tabletserver/messager/message_manager_test.go +++ b/go/vt/vttablet/tabletserver/messager/message_manager_test.go @@ -317,7 +317,7 @@ func TestMessageManagerPostponeThrottle(t *testing.T) { // Postpone will wait on the unbuffered ch. <-r1.ch - // Set up a second subsriber, add a message. + // Set up a second subscriber, add a message. r2 := newTestReceiver(1) mm.Subscribe(context.Background(), r2.rcv) <-r2.ch diff --git a/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt b/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt index 5565f405bc7..d5bd99ca7a0 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt +++ b/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt @@ -175,7 +175,7 @@ "NextCount": ":a" } -# squence with bad value +# sequence with bad value "select next 12345667852342342342323423423 values from seq" { "PlanID": "Nextval", diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index 7f83a29fc51..c31b65be8dd 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -377,7 +377,7 @@ func (qe *QueryEngine) getPlan(curSchema *currentSchema, sql string) (*TabletPla return plan, errNoCache } -// GetPlan returns the TabletPlan that for the query. Plans are cached in a theine LRU cache. +// GetPlan returns the TabletPlan that for the query. Plans are cached in an LRU cache. func (qe *QueryEngine) GetPlan(ctx context.Context, logStats *tabletenv.LogStats, sql string, skipQueryPlanCache bool) (*TabletPlan, error) { span, _ := trace.NewSpan(ctx, "QueryEngine.GetPlan") defer span.Finish() @@ -424,7 +424,7 @@ func (qe *QueryEngine) getStreamPlan(curSchema *currentSchema, sql string) (*Tab return plan, errNoCache } -// GetStreamPlan returns the TabletPlan that for the query. Plans are cached in a theine LRU cache. +// GetStreamPlan returns the TabletPlan that for the query. Plans are cached in an LRU cache. func (qe *QueryEngine) GetStreamPlan(ctx context.Context, logStats *tabletenv.LogStats, sql string, skipQueryPlanCache bool) (*TabletPlan, error) { span, _ := trace.NewSpan(ctx, "QueryEngine.GetStreamPlan") defer span.Finish() diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index d4058df8ad2..6ea3c90d989 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -71,7 +71,7 @@ func TestQueryExecutorPlans(t *testing.T) { input string // passThrough specifies if planbuilder.PassthroughDML must be set. passThrough bool - // dbResponses specifes the list of queries and responses to add to the fake db. + // dbResponses specifies the list of queries and responses to add to the fake db. dbResponses []dbResponse // resultWant is the result we want. resultWant *sqltypes.Result @@ -1729,7 +1729,7 @@ func TestQueryExecSchemaReloadCount(t *testing.T) { testcases := []struct { // input is the input query. input string - // dbResponses specifes the list of queries and responses to add to the fake db. + // dbResponses specifies the list of queries and responses to add to the fake db. dbResponses []dbResponse schemaReloadCount int }{{ diff --git a/go/vt/vttablet/tabletserver/repltracker/writer.go b/go/vt/vttablet/tabletserver/repltracker/writer.go index b13b78b59b7..801fcc8cd57 100644 --- a/go/vt/vttablet/tabletserver/repltracker/writer.go +++ b/go/vt/vttablet/tabletserver/repltracker/writer.go @@ -92,7 +92,7 @@ func newHeartbeatWriter(env tabletenv.Env, alias *topodatapb.TabletAlias) *heart } if w.onDemandDuration > 0 { // see RequestHeartbeats() for use of onDemandRequestTicks - // it's basically a mechnism to rate limit operation RequestHeartbeats(). + // it's basically a mechanism to rate limit operation RequestHeartbeats(). // and selectively drop excessive requests. w.allowNextHeartbeatRequest() go func() { @@ -123,7 +123,7 @@ func (w *heartbeatWriter) Open() { if w.isOpen { return } - log.Info("Hearbeat Writer: opening") + log.Info("Heartbeat Writer: opening") // We cannot create the database and tables in this Open function // since, this is run when a tablet changes to Primary type. The other replicas @@ -159,7 +159,7 @@ func (w *heartbeatWriter) Close() { w.appPool.Close() w.allPrivsPool.Close() w.isOpen = false - log.Info("Hearbeat Writer: closed") + log.Info("Heartbeat Writer: closed") } // bindHeartbeatVars takes a heartbeat write (insert or update) and @@ -219,7 +219,7 @@ func (w *heartbeatWriter) recordError(err error) { writeErrors.Add(1) } -// enableWrites actives or deactives heartbeat writes +// enableWrites activates or deactivates heartbeat writes func (w *heartbeatWriter) enableWrites(enable bool) { if w.ticks == nil { return diff --git a/go/vt/vttablet/tabletserver/rules/map_test.go b/go/vt/vttablet/tabletserver/rules/map_test.go index 1e86b938a48..bd1030f119c 100644 --- a/go/vt/vttablet/tabletserver/rules/map_test.go +++ b/go/vt/vttablet/tabletserver/rules/map_test.go @@ -136,7 +136,7 @@ func TestMapGetSetQueryRules(t *testing.T) { t.Errorf("Failed to set custom Rules: %s", err) } - // Test if we can successfully retrieve rules that've been set + // Test if we can successfully retrieve rules which been set qrs, err = qri.Get(denyListQueryRules) if err != nil { t.Errorf("GetRules failed to retrieve denyListQueryRules that has been set: %s", err) diff --git a/go/vt/vttablet/tabletserver/rules/rules.go b/go/vt/vttablet/tabletserver/rules/rules.go index c1e572caa2c..4a7d128b950 100644 --- a/go/vt/vttablet/tabletserver/rules/rules.go +++ b/go/vt/vttablet/tabletserver/rules/rules.go @@ -563,7 +563,7 @@ func bvMatch(bvcond BindVarCond, bindVars map[string]*querypb.BindVariable) bool // ----------------------------------------------- // Support types for Rule -// Action speficies the list of actions to perform +// Action specifies the list of actions to perform // when a Rule is triggered. type Action int @@ -655,7 +655,7 @@ func init() { } } -// These are return statii. +// These are return states. const ( QROK = iota QRMismatch diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index 0a98a6ee676..9d55f654d4e 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -565,7 +565,7 @@ func TestSchemaEngineCloseTickRace(t *testing.T) { } finished <- true }() - // Wait until the ticks are stopped or 2 seonds have expired. + // Wait until the ticks are stopped or 2 seconds have expired. select { case <-finished: return diff --git a/go/vt/vttablet/tabletserver/schema/schema.go b/go/vt/vttablet/tabletserver/schema/schema.go index 95c191392cd..4b3d9c88fb5 100644 --- a/go/vt/vttablet/tabletserver/schema/schema.go +++ b/go/vt/vttablet/tabletserver/schema/schema.go @@ -62,7 +62,7 @@ type Table struct { AllocatedSize uint64 } -// SequenceInfo contains info specific to sequence tabels. +// SequenceInfo contains info specific to sequence tables. // It must be locked before accessing the values inside. // If CurVal==LastVal, we have to cache new values. // When the schema is first loaded, the values are all 0, diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index 2115871c6bb..7203174449e 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -121,7 +121,7 @@ type stateManager struct { throttler lagThrottler tableGC tableGarbageCollector - // hcticks starts on initialiazation and runs forever. + // hcticks starts on initialization and runs forever. hcticks *timer.Timer // checkMySQLThrottler ensures that CheckMysql diff --git a/go/vt/vttablet/tabletserver/stream_consolidator.go b/go/vt/vttablet/tabletserver/stream_consolidator.go index 497c9011040..9f720059dce 100644 --- a/go/vt/vttablet/tabletserver/stream_consolidator.go +++ b/go/vt/vttablet/tabletserver/stream_consolidator.go @@ -252,7 +252,7 @@ func (s *streamInFlight) update(result *sqltypes.Result, block bool, maxMemoryQu s.mu.Lock() defer s.mu.Unlock() - // if this stream can still be catched up with, we need to store the result in + // if this stream can still be caught up with, we need to store the result in // a catch up buffer; otherwise, we can skip this altogether and just fan out the result // to all the followers that are already caught up if s.catchupAllowed { diff --git a/go/vt/vttablet/tabletserver/tabletenv/env.go b/go/vt/vttablet/tabletserver/tabletenv/env.go index c7202080c4d..6ae38138922 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/env.go +++ b/go/vt/vttablet/tabletserver/tabletenv/env.go @@ -25,7 +25,7 @@ import ( ) // Env defines the functions supported by TabletServer -// that the sub-componennts need to access. +// that the sub-components need to access. type Env interface { CheckMySQL() Config() *TabletConfig diff --git a/go/vt/vttablet/tabletserver/tabletenv/seconds.go b/go/vt/vttablet/tabletserver/tabletenv/seconds.go index 205b571c9b1..ae11121f2de 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/seconds.go +++ b/go/vt/vttablet/tabletserver/tabletenv/seconds.go @@ -23,7 +23,7 @@ import ( ) // Seconds provides convenience functions for extracting -// duration from flaot64 seconds values. +// duration from float64 seconds values. type Seconds float64 // SecondsVar is like a flag.Float64Var, but it works for Seconds. diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 25eb4da7168..6c1a60928de 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -238,11 +238,11 @@ func (tsv *TabletServer) loadQueryTimeout() time.Duration { // onlineDDLExecutorToggleTableBuffer is called by onlineDDLExecutor as a callback function. onlineDDLExecutor // uses it to start/stop query buffering for a given table. -// It is onlineDDLExecutor's responsibility to make sure beffering is stopped after some definite amount of time. +// It is onlineDDLExecutor's responsibility to make sure buffering is stopped after some definite amount of time. // There are two layers to buffering/unbuffering: // 1. the creation and destruction of a QueryRuleSource. The existence of such source affects query plan rules // for all new queries (see Execute() function and call to GetPlan()) -// 2. affecting already existing rules: a Rule has a concext.WithCancel, that is cancelled by onlineDDLExecutor +// 2. affecting already existing rules: a Rule has a context.WithCancel, that is cancelled by onlineDDLExecutor func (tsv *TabletServer) onlineDDLExecutorToggleTableBuffer(bufferingCtx context.Context, tableName string, timeout time.Duration, bufferQueries bool) { queryRuleSource := fmt.Sprintf("onlineddl/%s", tableName) diff --git a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go index ff6e1b146d9..7070febb3bc 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go +++ b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go @@ -30,7 +30,7 @@ var ErrNoSuchMetric = errors.New("No such metric") // ErrInvalidCheckType is an internal error indicating an unknown check type var ErrInvalidCheckType = errors.New("Unknown throttler check type") -// IsDialTCPError sees if th egiven error indicates a TCP issue +// IsDialTCPError sees if the given error indicates a TCP issue func IsDialTCPError(e error) bool { if e == nil { return false diff --git a/go/vt/vttablet/tabletserver/throttle/client.go b/go/vt/vttablet/tabletserver/throttle/client.go index 41888340b5a..546d75c040d 100644 --- a/go/vt/vttablet/tabletserver/throttle/client.go +++ b/go/vt/vttablet/tabletserver/throttle/client.go @@ -86,7 +86,7 @@ func NewBackgroundClient(throttler *Throttler, appName throttlerapp.Name, checkT // ThrottleCheckOK checks the throttler, and returns 'true' when the throttler is satisfied. // It does not sleep. // The function caches results for a brief amount of time, hence it's safe and efficient to -// be called very frequenty. +// be called very frequently. // The function is not thread safe. func (c *Client) ThrottleCheckOK(ctx context.Context, overrideAppName throttlerapp.Name) (throttleCheckOK bool) { if c == nil { @@ -117,7 +117,7 @@ func (c *Client) ThrottleCheckOK(ctx context.Context, overrideAppName throttlera } -// ThrottleCheckOKOrWait checks the throttler; if throttler is satisfied, the function returns 'true' mmediately, +// ThrottleCheckOKOrWait checks the throttler; if throttler is satisfied, the function returns 'true' immediately, // otherwise it briefly sleeps and returns 'false'. // Non-empty appName overrides the default appName. // The function is not thread safe. @@ -129,7 +129,7 @@ func (c *Client) ThrottleCheckOKOrWaitAppName(ctx context.Context, appName throt return ok } -// ThrottleCheckOKOrWait checks the throttler; if throttler is satisfied, the function returns 'true' mmediately, +// ThrottleCheckOKOrWait checks the throttler; if throttler is satisfied, the function returns 'true' immediately, // otherwise it briefly sleeps and returns 'false'. // The function is not thread safe. func (c *Client) ThrottleCheckOKOrWait(ctx context.Context) bool { diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go index 8c8a5cc4b32..a7e3650f8f3 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go @@ -20,9 +20,9 @@ import ( type MetricsQueryType int const ( - // MetricsQueryTypeDefault indictes the default, internal implementation. Specifically, our throttler runs a replication lag query + // MetricsQueryTypeDefault indicates the default, internal implementation. Specifically, our throttler runs a replication lag query MetricsQueryTypeDefault MetricsQueryType = iota - // MetricsQueryTypeShowGlobal indicatesa SHOW GLOBAL (STATUS|VARIABLES) query + // MetricsQueryTypeShowGlobal indicates SHOW GLOBAL (STATUS|VARIABLES) query MetricsQueryTypeShowGlobal // MetricsQueryTypeSelect indicates a custom SELECT query MetricsQueryTypeSelect diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index b8d84b1ed5e..21f9b068d0e 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -81,7 +81,7 @@ func init() { } func registerThrottlerFlags(fs *pflag.FlagSet) { - fs.StringVar(&throttleTabletTypes, "throttle_tablet_types", throttleTabletTypes, "Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' aways implicitly included") + fs.StringVar(&throttleTabletTypes, "throttle_tablet_types", throttleTabletTypes, "Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' always implicitly included") fs.Duration("throttle_threshold", 0, "Replication lag threshold for default lag throttling") fs.String("throttle_metrics_query", "", "Override default heartbeat/lag metric. Use either `SELECT` (must return single row, single value) or `SHOW GLOBAL ... LIKE ...` queries. Set -throttle_metrics_threshold respectively.") @@ -296,7 +296,7 @@ func (throttler *Throttler) readThrottlerConfig(ctx context.Context) (*topodatap return throttler.normalizeThrottlerConfig(srvks.ThrottlerConfig), nil } -// normalizeThrottlerConfig noramlizes missing throttler config information, as needed. +// normalizeThrottlerConfig normalizes missing throttler config information, as needed. func (throttler *Throttler) normalizeThrottlerConfig(throttlerConfig *topodatapb.ThrottlerConfig) *topodatapb.ThrottlerConfig { if throttlerConfig == nil { throttlerConfig = &topodatapb.ThrottlerConfig{} @@ -405,7 +405,7 @@ func (throttler *Throttler) Enable(ctx context.Context) bool { return true } -// Disable deactivates the probes and associated operations. When disabled, the throttler reponds to check +// Disable deactivates the probes and associated operations. When disabled, the throttler responds to check // queries with "200 OK" irrespective of lag or any other metrics. func (throttler *Throttler) Disable(ctx context.Context) bool { throttler.enableMutex.Lock() @@ -559,7 +559,7 @@ func (throttler *Throttler) readSelfMySQLThrottleMetric(ctx context.Context, pro switch metricsQueryType { case mysql.MetricsQueryTypeSelect: // We expect a single row, single column result. - // The "for" iteration below is just a way to get first result without knowning column name + // The "for" iteration below is just a way to get first result without knowing column name for k := range row { metric.Value, metric.Err = row.ToFloat64(k) } @@ -746,7 +746,7 @@ func (throttler *Throttler) generateTabletHTTPProbeFunction(ctx context.Context, // log.Errorf("error in GRPC call to tablet %v: %v", probe.Tablet.GetAlias(), gRPCErr) } } - // Backwards compatibility to v17: if the underlying tablets do not support CheckThrottler gRPC, attempt a HTTP cehck: + // Backwards compatibility to v17: if the underlying tablets do not support CheckThrottler gRPC, attempt a HTTP check: tabletCheckSelfURL := fmt.Sprintf("http://%s:%d/throttler/check-self?app=%s", probe.TabletHost, probe.TabletPort, throttlerapp.VitessName) resp, err := throttler.httpClient.Get(tabletCheckSelfURL) if err != nil { @@ -866,8 +866,8 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { if !throttler.isLeader.Load() { // This tablet may have used to be the primary, but it isn't now. It may have a recollection // of previous clusters it used to probe. It may have recollection of specific probes for such clusters. - // This now ensures any existing cluster probes are overrridden with an empty list of probes. - // `clusterProbes` was created above as empty, and identificable via `clusterName`. This will in turn + // This now ensures any existing cluster probes are overridden with an empty list of probes. + // `clusterProbes` was created above as empty, and identifiable via `clusterName`. This will in turn // be used to overwrite throttler.mysqlInventory.ClustersProbes[clusterProbes.ClusterName] in // updateMySQLClusterProbes(). throttler.mysqlClusterProbesChan <- clusterProbes @@ -960,7 +960,7 @@ func (throttler *Throttler) expireThrottledApps() { } } -// ThrottleApp instructs the throttler to begin throttling an app, to som eperiod and with some ratio. +// ThrottleApp instructs the throttler to begin throttling an app, to some period and with some ratio. func (throttler *Throttler) ThrottleApp(appName string, expireAt time.Time, ratio float64, exempt bool) (appThrottle *base.AppThrottle) { throttler.throttledAppsMutex.Lock() defer throttler.throttledAppsMutex.Unlock() diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index c47466df522..e1a9c5abc79 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -153,7 +153,7 @@ func TestRefreshMySQLInventory(t *testing.T) { validateClusterProbes := func(t *testing.T, ctx context.Context) { testName := fmt.Sprintf("leader=%t", throttler.isLeader.Load()) t.Run(testName, func(t *testing.T) { - // validateProbesCount expectes number of probes according to cluster name and throttler's leadership status + // validateProbesCount expects a number of probes according to cluster name and throttler's leadership status validateProbesCount := func(t *testing.T, clusterName string, probes *mysql.Probes) { if clusterName == selfStoreName { assert.Equal(t, 1, len(*probes)) diff --git a/go/vt/vttablet/tabletserver/throttle/throttlerapp/app.go b/go/vt/vttablet/tabletserver/throttle/throttlerapp/app.go index cc86ad0620b..4f1f5857837 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttlerapp/app.go +++ b/go/vt/vttablet/tabletserver/throttle/throttlerapp/app.go @@ -73,7 +73,7 @@ var ( ) // ExemptFromChecks returns 'true' for apps that should skip the throttler checks. The throttler should -// always repsond with automated "OK" to those apps, without delay. These apps also do not cause a heartbeat renewal. +// always respond with automated "OK" to those apps, without delay. These apps also do not cause a heartbeat renewal. func ExemptFromChecks(appName string) bool { return exemptFromChecks[appName] } diff --git a/go/vt/vttablet/tabletserver/tx_executor.go b/go/vt/vttablet/tabletserver/tx_executor.go index 9dc92506e84..93d18a200f9 100644 --- a/go/vt/vttablet/tabletserver/tx_executor.go +++ b/go/vt/vttablet/tabletserver/tx_executor.go @@ -235,7 +235,7 @@ func (txe *TxExecutor) ConcludeTransaction(dtid string) error { }) } -// ReadTransaction returns the metadata for the sepcified dtid. +// ReadTransaction returns the metadata for the specified dtid. func (txe *TxExecutor) ReadTransaction(dtid string) (*querypb.TransactionMetadata, error) { if !txe.te.twopcEnabled { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "2pc is not enabled") diff --git a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go index 3a4133b54d6..f41f4a9089c 100644 --- a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go +++ b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go @@ -117,7 +117,7 @@ func TestTxLimiter_LimitsOnlyOffendingUser(t *testing.T) { t.Errorf("Get(im1, ef1) after releasing: got %v, want %v", got, want) } - // Rejection coutner for user 1 should still be 1. + // Rejection count for user 1 should still be 1. if got, want := limiter.rejections.Counts()[key1], int64(1); got != want { t.Errorf("Rejections count for %s: got %d, want %d", key1, got, want) } diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go index ec1ab47758c..4a9124345aa 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go @@ -51,7 +51,7 @@ import ( // - Waiting transactions are unblocked if their context is done. // - Both the local queue (per row range) and global queue (whole process) are // limited to avoid that queued transactions can consume the full capacity -// of vttablet. This is important if the capaciy is finite. For example, the +// of vttablet. This is important if the capacity is finite. For example, the // number of RPCs in flight could be limited by the RPC subsystem. type TxSerializer struct { env tabletenv.Env @@ -151,7 +151,7 @@ func (txs *TxSerializer) Wait(ctx context.Context, key, table string) (done Done if err != nil { if waited { // Waiting failed early e.g. due a canceled context and we did NOT get the - // slot. Call "done" now because we don'txs return it to the caller. + // slot. Call "done" now because we do not return it to the caller. txs.unlockLocked(key, false /* returnSlot */) } return nil, waited, err diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go index 92976bbedf2..4ac2e79d38b 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go index 268a37437d9..64c35f6ea95 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index bd259864981..99ebbbdfaa5 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -165,7 +165,7 @@ func (rs *rowStreamer) buildPlan() error { // "puncture"; this is an event that is captured by vstreamer. The completion of the flow fixes the // puncture, and places a new table under the original table's name, but the way it is done does not // cause vstreamer to refresh schema state. - // There is therefore a reproducable valid sequence of events where vstreamer thinks a table does not + // There is therefore a reproducible valid sequence of events where vstreamer thinks a table does not // exist, where it in fact does exist. // For this reason we give vstreamer a "second chance" to review the up-to-date state of the schema. // In the future, we will reduce this operation to reading a single table rather than the entire schema. diff --git a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go index 5c9885ee82e..db5794646da 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go +++ b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go @@ -81,7 +81,7 @@ func (conn *snapshotConn) streamWithSnapshot(ctx context.Context, table, query s // Rotating the log when it's above a certain size ensures that we are processing // a relatively small binary log that will be minimal in size and GTID events. // We only attempt to rotate it if the current log is of any significant size to - // avoid too many unecessary rotations. + // avoid too many unnecessary rotations. if rotatedLog, err = conn.limitOpenBinlogSize(); err != nil { // This is a best effort operation meant to lower overhead and improve performance. // Thus it should not be required, nor cause the operation to fail. @@ -172,7 +172,7 @@ func (conn *snapshotConn) startSnapshotWithConsistentGTID(ctx context.Context) ( return replication.EncodePosition(mpos), nil } -// Close rollsback any open transactions and closes the connection. +// Close rolls back any open transactions and closes the connection. func (conn *snapshotConn) Close() { _, _ = conn.ExecuteFetch("rollback", 1, false) conn.Conn.Close() diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index f210e756da1..d8a364d1aef 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -211,7 +211,7 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog // GTID->DDL // GTID->OTHER // HEARTBEAT is issued if there's inactivity, which is likely - // to heppend between one group of events and another. + // to happen between one group of events and another. // // Buffering only takes row or statement lengths into consideration. // Length of other events is considered negligible. diff --git a/go/vt/wrangler/schema.go b/go/vt/wrangler/schema.go index e6c1fbc25d9..ae24106c97f 100644 --- a/go/vt/wrangler/schema.go +++ b/go/vt/wrangler/schema.go @@ -262,7 +262,7 @@ func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias *topo } } - // Notify Replicass to reload schema. This is best-effort. + // Notify Replicas to reload schema. This is best-effort. reloadCtx, cancel := context.WithTimeout(ctx, waitReplicasTimeout) defer cancel() resp, err := wr.VtctldServer().ReloadSchemaShard(reloadCtx, &vtctldatapb.ReloadSchemaShardRequest{ diff --git a/go/vt/wrangler/testlib/vtctl_pipe.go b/go/vt/wrangler/testlib/vtctl_pipe.go index 38c535f005f..448f248821a 100644 --- a/go/vt/wrangler/testlib/vtctl_pipe.go +++ b/go/vt/wrangler/testlib/vtctl_pipe.go @@ -138,7 +138,7 @@ func (vp *VtctlPipe) run(args []string, outputFunc func(string)) error { } // RunAndStreamOutput returns the output of the vtctl command as a channel. -// When the channcel is closed, the command did finish. +// When the channel is closed, the command did finish. func (vp *VtctlPipe) RunAndStreamOutput(args []string) (logutil.EventStream, error) { actionTimeout := 30 * time.Second ctx := context.Background() diff --git a/go/vt/wrangler/traffic_switcher_env_test.go b/go/vt/wrangler/traffic_switcher_env_test.go index c8ec71dba96..572b2b4a9e6 100644 --- a/go/vt/wrangler/traffic_switcher_env_test.go +++ b/go/vt/wrangler/traffic_switcher_env_test.go @@ -373,7 +373,7 @@ func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, } // newTestTablePartialMigrater creates a test tablet migrater -// specifially for partial or shard by shard migrations. +// specifically for partial or shard by shard migrations. // The shards must be the same on the source and target, and we // must be moving a subset of them. // fmtQuery should be of the form: 'select a, b %s group by a'. diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index 6c97758ad48..f7aebed185a 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -286,7 +286,7 @@ func TestTableMigrateMainflow(t *testing.T) { verifyQueries(t, tme.allDBClients) //------------------------------------------------------------------------------------------------------------------- - // Test SwitchWrites cancelation on failure. + // Test SwitchWrites cancellation on failure. tme.expectNoPreviousJournals() // Switch all the reads first. @@ -607,7 +607,7 @@ func TestShardMigrateMainflow(t *testing.T) { verifyQueries(t, tme.allDBClients) //------------------------------------------------------------------------------------------------------------------- - // Test SwitchWrites cancelation on failure. + // Test SwitchWrites cancellation on failure. tme.expectNoPreviousJournals() // Switch all the reads first. diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 3084eba0e29..5de1a4b1d3f 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -528,7 +528,7 @@ func findPKs(table *tabletmanagerdatapb.TableDefinition, targetSelect *sqlparser } // getColumnCollations determines the proper collation to use for each -// column in the table definition leveraging MySQL's collation inheritence +// column in the table definition leveraging MySQL's collation inheritance // rules. func getColumnCollations(table *tabletmanagerdatapb.TableDefinition) (map[string]collations.ID, error) { collationEnv := collations.Local() @@ -547,7 +547,7 @@ func getColumnCollations(table *tabletmanagerdatapb.TableDefinition) (map[string tableCharset := tableschema.GetCharset() tableCollation := tableschema.GetCollation() // If no explicit collation is specified for the column then we need - // to walk the inheritence tree. + // to walk the inheritance tree. getColumnCollation := func(column *sqlparser.ColumnDefinition) collations.ID { // If there's an explicit collation listed then use that. if column.Type.Options.Collate != "" { @@ -568,7 +568,7 @@ func getColumnCollations(table *tabletmanagerdatapb.TableDefinition) (map[string return collationEnv.DefaultCollationForCharset(strings.ToLower(tableCharset)) } // The table is using the global default charset and collation and - // we inherite that. + // we inherit that. return collations.Default() } @@ -996,7 +996,7 @@ func (df *vdiff) streamOne(ctx context.Context, keyspace, shard string, particip }() } -// syncTargets fast-forwards the vreplication to the source snapshot positons +// syncTargets fast-forwards the vreplication to the source snapshot positions // and waits for the selected tablets to catch up to that point. func (df *vdiff) syncTargets(ctx context.Context, filteredReplicationWaitTime time.Duration) error { waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) diff --git a/go/vt/wrangler/vexec.go b/go/vt/wrangler/vexec.go index 0734fa7b593..7cad9a5f318 100644 --- a/go/vt/wrangler/vexec.go +++ b/go/vt/wrangler/vexec.go @@ -761,7 +761,7 @@ func (wr *Wrangler) getStreams(ctx context.Context, workflow, keyspace string) ( // Note: this is done here only because golang does // not currently support setting json tags in proto // declarations so that I could request it always be - // ommitted from marshalled JSON output: + // omitted from marshalled JSON output: // https://github.com/golang/protobuf/issues/52 status.Bls.OnDdl = 0 } From f06cea2dfb92b813286f0b56c94cc15428a73507 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:06:07 +0530 Subject: [PATCH 045/119] Foreign Key Fuzzer Benchmark (#14542) Signed-off-by: Manan Gupta --- go/test/endtoend/utils/utils.go | 2 +- .../vtgate/foreignkey/fk_fuzz_test.go | 41 ++++++--- .../endtoend/vtgate/foreignkey/main_test.go | 83 ++++++++++++++----- .../unsharded_unmanaged_vschema.json | 41 +++++++++ .../endtoend/vtgate/foreignkey/utils_test.go | 75 ++++++++++++++++- 5 files changed, 206 insertions(+), 36 deletions(-) create mode 100644 go/test/endtoend/vtgate/foreignkey/unsharded_unmanaged_vschema.json diff --git a/go/test/endtoend/utils/utils.go b/go/test/endtoend/utils/utils.go index 9cf9c767fc7..b6bf207decb 100644 --- a/go/test/endtoend/utils/utils.go +++ b/go/test/endtoend/utils/utils.go @@ -299,7 +299,7 @@ func WaitForTableDeletions(ctx context.Context, t *testing.T, vtgateProcess clus } // WaitForColumn waits for a table's column to be present -func WaitForColumn(t *testing.T, vtgateProcess cluster.VtgateProcess, ks, tbl, col string) error { +func WaitForColumn(t testing.TB, vtgateProcess cluster.VtgateProcess, ks, tbl, col string) error { timeout := time.After(60 * time.Second) for { select { diff --git a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go index 325bdedc5c9..096efead683 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_fuzz_test.go @@ -53,6 +53,7 @@ type fuzzer struct { updateShare int concurrency int queryFormat QueryFormat + noFkSetVar bool fkState *bool // shouldStop is an internal state variable, that tells the fuzzer @@ -83,6 +84,7 @@ func newFuzzer(concurrency int, maxValForId int, maxValForCol int, insertShare i updateShare: updateShare, queryFormat: queryFormat, fkState: fkState, + noFkSetVar: false, wg: sync.WaitGroup{}, } // Initially the fuzzer thread is stopped. @@ -475,7 +477,7 @@ func (fz *fuzzer) generateParameterizedDeleteQuery() (query string, params []any // getSetVarFkChecksVal generates an optimizer hint to randomly set the foreign key checks to on or off or leave them unaltered. func (fz *fuzzer) getSetVarFkChecksVal() string { - if fz.concurrency != 1 { + if fz.concurrency != 1 || fz.noFkSetVar { return "" } val := rand.Intn(3) @@ -703,14 +705,33 @@ func TestFkFuzzTest(t *testing.T) { } } -func validateReplication(t *testing.T) { - for _, keyspace := range clusterInstance.Keyspaces { - for _, shard := range keyspace.Shards { - for _, vttablet := range shard.Vttablets { - if vttablet.Type != "primary" { - checkReplicationHealthy(t, vttablet) - } - } - } +// BenchmarkFkFuzz benchmarks the performance of Vitess unmanaged, Vitess managed and vanilla MySQL performance on a given set of queries generated by the fuzzer. +func BenchmarkFkFuzz(b *testing.B) { + maxValForCol := 10 + maxValForId := 10 + insertShare := 50 + deleteShare := 50 + updateShare := 50 + numQueries := 1000 + // Wait for schema-tracking to be complete. + waitForSchemaTrackingForFkTables(b) + for i := 0; i < b.N; i++ { + queries, mysqlConn, vtConn, vtUnmanagedConn := setupBenchmark(b, maxValForId, maxValForCol, insertShare, deleteShare, updateShare, numQueries) + + // Now we run the benchmarks! + b.Run("MySQL", func(b *testing.B) { + startBenchmark(b) + runQueries(b, mysqlConn, queries) + }) + + b.Run("Vitess Managed Foreign Keys", func(b *testing.B) { + startBenchmark(b) + runQueries(b, vtConn, queries) + }) + + b.Run("Vitess Unmanaged Foreign Keys", func(b *testing.B) { + startBenchmark(b) + runQueries(b, vtUnmanagedConn, queries) + }) } } diff --git a/go/test/endtoend/vtgate/foreignkey/main_test.go b/go/test/endtoend/vtgate/foreignkey/main_test.go index 3ce449f893f..483c1d05e80 100644 --- a/go/test/endtoend/vtgate/foreignkey/main_test.go +++ b/go/test/endtoend/vtgate/foreignkey/main_test.go @@ -17,6 +17,7 @@ limitations under the License. package foreignkey import ( + "context" _ "embed" "flag" "fmt" @@ -31,13 +32,14 @@ import ( ) var ( - clusterInstance *cluster.LocalProcessCluster - vtParams mysql.ConnParams - mysqlParams mysql.ConnParams - vtgateGrpcAddress string - shardedKs = "ks" - unshardedKs = "uks" - Cell = "test" + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + mysqlParams mysql.ConnParams + vtgateGrpcAddress string + shardedKs = "ks" + unshardedKs = "uks" + unshardedUnmanagedKs = "unmanaged_uks" + Cell = "test" //go:embed schema.sql schemaSQL string @@ -48,6 +50,9 @@ var ( //go:embed unsharded_vschema.json unshardedVSchema string + //go:embed unsharded_unmanaged_vschema.json + unshardedUnmanagedVSchema string + fkTables = []string{"fk_t1", "fk_t2", "fk_t3", "fk_t4", "fk_t5", "fk_t6", "fk_t7", "fk_t10", "fk_t11", "fk_t12", "fk_t13", "fk_t15", "fk_t16", "fk_t17", "fk_t18", "fk_t19", "fk_t20", "fk_multicol_t1", "fk_multicol_t2", "fk_multicol_t3", "fk_multicol_t4", "fk_multicol_t5", "fk_multicol_t6", "fk_multicol_t7", @@ -124,6 +129,16 @@ func TestMain(m *testing.M) { return 1 } + unmanagedKs := &cluster.Keyspace{ + Name: unshardedUnmanagedKs, + SchemaSQL: schemaSQL, + VSchema: unshardedUnmanagedVSchema, + } + err = clusterInstance.StartUnshardedKeyspace(*unmanagedKs, 1, false) + if err != nil { + return 1 + } + err = clusterInstance.VtctlclientProcess.ExecuteCommand("RebuildVSchemaGraph") if err != nil { return 1 @@ -157,22 +172,7 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { require.NoError(t, err) deleteAll := func() { - _ = utils.Exec(t, mcmp.VtConn, "use `ks/-80`") - tables := []string{"t4", "t3", "t2", "t1", "multicol_tbl2", "multicol_tbl1"} - tables = append(tables, fkTables...) - for _, table := range tables { - _, _ = mcmp.ExecAndIgnore("delete /*+ SET_VAR(foreign_key_checks=OFF) */ from " + table) - } - _ = utils.Exec(t, mcmp.VtConn, "use `ks/80-`") - for _, table := range tables { - _, _ = mcmp.ExecAndIgnore("delete /*+ SET_VAR(foreign_key_checks=OFF) */ from " + table) - } - _ = utils.Exec(t, mcmp.VtConn, "use `uks`") - tables = []string{"u_t1", "u_t2", "u_t3"} - tables = append(tables, fkTables...) - for _, table := range tables { - _, _ = mcmp.ExecAndIgnore("delete /*+ SET_VAR(foreign_key_checks=OFF) */ from " + table) - } + clearOutAllData(t, mcmp.VtConn, mcmp.MySQLConn) _ = utils.Exec(t, mcmp.VtConn, "use `ks`") } @@ -184,3 +184,40 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { cluster.PanicHandler(t) } } + +func startBenchmark(b *testing.B) { + ctx := context.Background() + vtConn, err := mysql.Connect(ctx, &vtParams) + require.NoError(b, err) + mysqlConn, err := mysql.Connect(ctx, &mysqlParams) + require.NoError(b, err) + + clearOutAllData(b, vtConn, mysqlConn) +} + +func clearOutAllData(t testing.TB, vtConn *mysql.Conn, mysqlConn *mysql.Conn) { + _ = utils.Exec(t, vtConn, "use `ks/-80`") + tables := []string{"t4", "t3", "t2", "t1", "multicol_tbl2", "multicol_tbl1"} + tables = append(tables, fkTables...) + for _, table := range tables { + _, _ = utils.ExecAllowError(t, vtConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + _, _ = utils.ExecAllowError(t, mysqlConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + } + _ = utils.Exec(t, vtConn, "use `ks/80-`") + for _, table := range tables { + _, _ = utils.ExecAllowError(t, vtConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + _, _ = utils.ExecAllowError(t, mysqlConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + } + _ = utils.Exec(t, vtConn, "use `uks`") + tables = []string{"u_t1", "u_t2", "u_t3"} + tables = append(tables, fkTables...) + for _, table := range tables { + _, _ = utils.ExecAllowError(t, vtConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + _, _ = utils.ExecAllowError(t, mysqlConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + } + _ = utils.Exec(t, vtConn, "use `unmanaged_uks`") + for _, table := range tables { + _, _ = utils.ExecAllowError(t, vtConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + _, _ = utils.ExecAllowError(t, mysqlConn, "delete /*+ SET_VAR(foreign_key_checks=OFF) */ from "+table) + } +} diff --git a/go/test/endtoend/vtgate/foreignkey/unsharded_unmanaged_vschema.json b/go/test/endtoend/vtgate/foreignkey/unsharded_unmanaged_vschema.json new file mode 100644 index 00000000000..2698e23dac5 --- /dev/null +++ b/go/test/endtoend/vtgate/foreignkey/unsharded_unmanaged_vschema.json @@ -0,0 +1,41 @@ +{ + "sharded": false, + "foreignKeyMode": "unmanaged", + "tables": { + "u_t1": {}, + "u_t2": {}, + "fk_t1": {}, + "fk_t2": {}, + "fk_t3": {}, + "fk_t4": {}, + "fk_t5": {}, + "fk_t6": {}, + "fk_t7": {}, + "fk_t10": {}, + "fk_t11": {}, + "fk_t12": {}, + "fk_t13": {}, + "fk_t15": {}, + "fk_t16": {}, + "fk_t17": {}, + "fk_t18": {}, + "fk_t19": {}, + "fk_t20": {}, + "fk_multicol_t1": {}, + "fk_multicol_t2": {}, + "fk_multicol_t3": {}, + "fk_multicol_t4": {}, + "fk_multicol_t5": {}, + "fk_multicol_t6": {}, + "fk_multicol_t7": {}, + "fk_multicol_t10": {}, + "fk_multicol_t11": {}, + "fk_multicol_t12": {}, + "fk_multicol_t13": {}, + "fk_multicol_t15": {}, + "fk_multicol_t16": {}, + "fk_multicol_t17": {}, + "fk_multicol_t18": {}, + "fk_multicol_t19": {} + } +} \ No newline at end of file diff --git a/go/test/endtoend/vtgate/foreignkey/utils_test.go b/go/test/endtoend/vtgate/foreignkey/utils_test.go index b97e57d685c..9d4c53145b0 100644 --- a/go/test/endtoend/vtgate/foreignkey/utils_test.go +++ b/go/test/endtoend/vtgate/foreignkey/utils_test.go @@ -17,9 +17,11 @@ limitations under the License. package foreignkey import ( + "context" "database/sql" "fmt" "math/rand" + "slices" "strings" "testing" "time" @@ -75,7 +77,7 @@ func convertIntValueToString(value int) string { // waitForSchemaTrackingForFkTables waits for schema tracking to have run and seen the tables used // for foreign key tests. -func waitForSchemaTrackingForFkTables(t *testing.T) { +func waitForSchemaTrackingForFkTables(t testing.TB) { err := utils.WaitForColumn(t, clusterInstance.VtgateProcess, shardedKs, "fk_t1", "col") require.NoError(t, err) err = utils.WaitForColumn(t, clusterInstance.VtgateProcess, shardedKs, "fk_t18", "col") @@ -88,6 +90,8 @@ func waitForSchemaTrackingForFkTables(t *testing.T) { require.NoError(t, err) err = utils.WaitForColumn(t, clusterInstance.VtgateProcess, unshardedKs, "fk_t11", "col") require.NoError(t, err) + err = utils.WaitForColumn(t, clusterInstance.VtgateProcess, unshardedUnmanagedKs, "fk_t11", "col") + require.NoError(t, err) } // getReplicaTablets gets all the replica tablets. @@ -238,7 +242,7 @@ func verifyDataIsCorrect(t *testing.T, mcmp utils.MySQLCompare, concurrency int) } // verifyDataMatches verifies that the two list of results are the same. -func verifyDataMatches(t *testing.T, resOne []*sqltypes.Result, resTwo []*sqltypes.Result) { +func verifyDataMatches(t testing.TB, resOne []*sqltypes.Result, resTwo []*sqltypes.Result) { require.EqualValues(t, len(resTwo), len(resOne), "Res 1 - %v, Res 2 - %v", resOne, resTwo) for idx, resultOne := range resOne { resultTwo := resTwo[idx] @@ -256,3 +260,70 @@ func collectFkTablesState(conn *mysql.Conn) []*sqltypes.Result { } return tablesData } + +func validateReplication(t *testing.T) { + for _, keyspace := range clusterInstance.Keyspaces { + for _, shard := range keyspace.Shards { + for _, vttablet := range shard.Vttablets { + if vttablet.Type != "primary" { + checkReplicationHealthy(t, vttablet) + } + } + } + } +} + +// compareResultRows compares the rows of the two results provided. +func compareResultRows(resOne *sqltypes.Result, resTwo *sqltypes.Result) bool { + return slices.EqualFunc(resOne.Rows, resTwo.Rows, func(a, b sqltypes.Row) bool { + return sqltypes.RowEqual(a, b) + }) +} + +// setupBenchmark sets up the benchmark by creating the set of queries that we want to run. It also ensures that the 3 modes (MySQL, Vitess Managed, Vitess Unmanaged) we verify all return the same results after the queries have been executed. +func setupBenchmark(b *testing.B, maxValForId int, maxValForCol int, insertShare int, deleteShare int, updateShare int, numQueries int) ([]string, *mysql.Conn, *mysql.Conn, *mysql.Conn) { + // Clear out all the data to ensure we start with a clean slate. + startBenchmark(b) + // Create a fuzzer to generate and store a certain set of queries. + fz := newFuzzer(1, maxValForId, maxValForCol, insertShare, deleteShare, updateShare, SQLQueries, nil) + fz.noFkSetVar = true + var queries []string + for j := 0; j < numQueries; j++ { + genQueries := fz.generateQuery() + require.Len(b, genQueries, 1) + queries = append(queries, genQueries[0]) + } + + // Connect to MySQL and run all the queries + mysqlConn, err := mysql.Connect(context.Background(), &mysqlParams) + require.NoError(b, err) + // Connect to Vitess managed foreign keys keyspace + vtConn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(b, err) + utils.Exec(b, vtConn, fmt.Sprintf("use `%v`", unshardedKs)) + // Connect to Vitess unmanaged foreign keys keyspace + vtUnmanagedConn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(b, err) + utils.Exec(b, vtUnmanagedConn, fmt.Sprintf("use `%v`", unshardedUnmanagedKs)) + + // First we make sure that running all the queries in both the Vitess modes and MySQL gives the same data. + // So we run all the queries and then check that the data in all of them matches. + runQueries(b, mysqlConn, queries) + runQueries(b, vtConn, queries) + runQueries(b, vtUnmanagedConn, queries) + for _, table := range fkTables { + query := fmt.Sprintf("SELECT * FROM %v ORDER BY id", table) + resVitessManaged, _ := vtConn.ExecuteFetch(query, 10000, true) + resMySQL, _ := mysqlConn.ExecuteFetch(query, 10000, true) + resVitessUnmanaged, _ := vtUnmanagedConn.ExecuteFetch(query, 10000, true) + require.True(b, compareResultRows(resVitessManaged, resMySQL), "Results for %v don't match\nVitess Managed\n%v\nMySQL\n%v", table, resVitessManaged, resMySQL) + require.True(b, compareResultRows(resVitessUnmanaged, resMySQL), "Results for %v don't match\nVitess Unmanaged\n%v\nMySQL\n%v", table, resVitessUnmanaged, resMySQL) + } + return queries, mysqlConn, vtConn, vtUnmanagedConn +} + +func runQueries(t testing.TB, conn *mysql.Conn, queries []string) { + for _, query := range queries { + _, _ = utils.ExecAllowError(t, conn, query) + } +} From 97aba81faee4230f0fcff92fc447e3b5909577fc Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:23:27 +0100 Subject: [PATCH 046/119] VReplication: extended e2e test for workflows with tables containing foreign key constraints (#14327) Signed-off-by: Rohit Nayak Signed-off-by: Matt Lord Co-authored-by: Matt Lord --- ...dtoend_vreplication_foreign_key_stress.yml | 170 ++++++ go/test/endtoend/cluster/vttablet_process.go | 24 + go/test/endtoend/vreplication/cluster_test.go | 5 +- .../fk_ext_load_generator_test.go | 503 ++++++++++++++++++ go/test/endtoend/vreplication/fk_ext_test.go | 450 ++++++++++++++++ go/test/endtoend/vreplication/fk_test.go | 11 +- go/test/endtoend/vreplication/helper_test.go | 89 +++- .../vreplication/movetables_buffering_test.go | 2 +- .../partial_movetables_seq_test.go | 12 +- .../vreplication/partial_movetables_test.go | 23 +- .../resharding_workflows_v2_test.go | 36 +- .../schema/fkext/materialize_schema.sql | 2 + .../schema/fkext/source_schema.sql | 2 + .../schema/fkext/source_vschema.json | 6 + .../schema/fkext/target1_vschema.json | 28 + .../schema/fkext/target2_vschema.json | 43 ++ go/test/endtoend/vreplication/vdiff2_test.go | 2 + .../vreplication/vdiff_helper_test.go | 91 +++- .../vdiff_multiple_movetables_test.go | 12 +- .../endtoend/vreplication/wrappers_test.go | 243 +++++++-- .../tabletmanager/vreplication/vplayer.go | 15 +- go/vt/wrangler/traffic_switcher.go | 4 +- test/ci_workflow_gen.go | 1 + test/config.json | 9 + 24 files changed, 1698 insertions(+), 85 deletions(-) create mode 100644 .github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml create mode 100644 go/test/endtoend/vreplication/fk_ext_load_generator_test.go create mode 100644 go/test/endtoend/vreplication/fk_ext_test.go create mode 100644 go/test/endtoend/vreplication/schema/fkext/materialize_schema.sql create mode 100644 go/test/endtoend/vreplication/schema/fkext/source_schema.sql create mode 100644 go/test/endtoend/vreplication/schema/fkext/source_vschema.json create mode 100644 go/test/endtoend/vreplication/schema/fkext/target1_vschema.json create mode 100644 go/test/endtoend/vreplication/schema/fkext/target2_vschema.json diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml new file mode 100644 index 00000000000..50b65ecc27d --- /dev/null +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -0,0 +1,170 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vreplication_foreign_key_stress) +on: [push, pull_request] +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_foreign_key_stress)') + cancel-in-progress: true + +permissions: read-all + +env: + LAUNCHABLE_ORGANIZATION: "vitess" + LAUNCHABLE_WORKSPACE: "vitess-app" + GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" + +jobs: + build: + name: Run endtoend tests on Cluster (vreplication_foreign_key_stress) + runs-on: gh-hosted-runners-4cores-1 + + steps: + - name: Skip CI + run: | + if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check if workflow needs to be skipped + id: skip-workflow + run: | + skip='false' + if [[ "${{github.event.pull_request}}" == "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then + skip='true' + fi + echo Skip ${skip} + echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT + + PR_DATA=$(curl \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}") + draft=$(echo "$PR_DATA" | jq .draft -r) + echo "is_draft=${draft}" >> $GITHUB_OUTPUT + + - name: Check out code + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: actions/checkout@v3 + + - name: Check for changes in relevant files + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: frouioui/paths-filter@main + id: changes + with: + token: '' + filters: | + end_to_end: + - 'go/**/*.go' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml' + + - name: Set up Go + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@v4 + with: + go-version: 1.21.3 + + - name: Set up python + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@v4 + + - name: Tune the OS + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + # Limit local port range to not use ports that overlap with server side + # ports that we listen on. + sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" + # Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio + echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf + sudo sysctl -p /etc/sysctl.conf + + - name: Get dependencies + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + + # Get key to latest MySQL repo + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 + # Setup MySQL 8.0 + wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.24-1_all.deb + echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections + sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config* + sudo apt-get update + # Install everything else we need, and configure + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata xz-utils libncurses5 + + 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 + + # install JUnit report formatter + go install github.com/vitessio/go-junit-report@HEAD + + - name: Setup launchable dependencies + if: steps.skip-workflow.outputs.is_draft == 'false' && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' + run: | + # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up + pip3 install --user launchable~=1.0 > /dev/null + + # verify that launchable setup is all correct. + launchable verify || true + + # Tell Launchable about the build you are producing and testing + launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . + + - name: Run cluster endtoend test + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 45 + run: | + # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file + # which musn't be more than 107 characters long. + export VTDATAROOT="/tmp/" + source build.env + + set -exo pipefail + + # Increase our open file descriptor limit as we could hit this + ulimit -n 65536 + cat <<-EOF>>./config/mycnf/mysql80.cnf + innodb_buffer_pool_dump_at_shutdown=OFF + innodb_buffer_pool_in_core_file=OFF + innodb_buffer_pool_load_at_startup=OFF + innodb_buffer_pool_size=64M + innodb_doublewrite=OFF + innodb_flush_log_at_trx_commit=0 + innodb_flush_method=O_DIRECT + innodb_numa_interleave=ON + innodb_adaptive_hash_index=OFF + sync_binlog=0 + sync_relay_log=0 + performance_schema=OFF + slow-query-log=OFF + EOF + + cat <<-EOF>>./config/mycnf/mysql80.cnf + binlog-transaction-compression=ON + EOF + + # run the tests however you normally do, then produce a JUnit XML file + eatmydata -- go run test.go -docker=false -follow -shard vreplication_foreign_key_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml + + - name: Print test output and Record test result in launchable if PR is not a draft + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + run: | + if [[ "${{steps.skip-workflow.outputs.is_draft}}" == "false" ]]; then + # send recorded tests to launchable + launchable record tests --build "$GITHUB_RUN_ID" go-test . || true + fi + + # print test output + cat output.txt diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index ed6a97a15c2..f51e1838a5b 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -79,6 +79,7 @@ type VttabletProcess struct { DbFlavor string Charset string ConsolidationsURL string + IsPrimary bool // Extra Args to be set before starting the vttablet process ExtraArgs []string @@ -460,6 +461,29 @@ func (vttablet *VttabletProcess) QueryTablet(query string, keyspace string, useD return executeQuery(conn, query) } +// QueryTabletMultiple lets you execute multiple queries -- without any +// results -- against the tablet. +func (vttablet *VttabletProcess) QueryTabletMultiple(queries []string, keyspace string, useDb bool) error { + if !useDb { + keyspace = "" + } + dbParams := NewConnParams(vttablet.DbPort, vttablet.DbPassword, path.Join(vttablet.Directory, "mysql.sock"), keyspace) + conn, err := vttablet.conn(&dbParams) + if err != nil { + return err + } + defer conn.Close() + + for _, query := range queries { + log.Infof("Executing query %s (on %s)", query, vttablet.Name) + _, err := executeQuery(conn, query) + if err != nil { + return err + } + } + return nil +} + func (vttablet *VttabletProcess) defaultConn(dbname string) (*mysql.Conn, error) { dbParams := mysql.ConnParams{ Uname: "vt_dba", diff --git a/go/test/endtoend/vreplication/cluster_test.go b/go/test/endtoend/vreplication/cluster_test.go index 4735e94560f..89cebc7d0b1 100644 --- a/go/test/endtoend/vreplication/cluster_test.go +++ b/go/test/endtoend/vreplication/cluster_test.go @@ -544,6 +544,7 @@ func (vc *VitessCluster) AddShards(t *testing.T, cells []*Cell, keyspace *Keyspa tablets = append(tablets, primary) dbProcesses = append(dbProcesses, proc) primaryTabletUID = primary.Vttablet.TabletUID + primary.Vttablet.IsPrimary = true } for i := 0; i < numReplicas; i++ { @@ -795,13 +796,13 @@ func (vc *VitessCluster) getPrimaryTablet(t *testing.T, ksName, shardName string continue } for _, tablet := range shard.Tablets { - if tablet.Vttablet.GetTabletStatus() == "SERVING" { + if tablet.Vttablet.IsPrimary { return tablet.Vttablet } } } } - require.FailNow(t, "no primary found for %s:%s", ksName, shardName) + require.FailNow(t, "no primary found", "keyspace %s, shard %s", ksName, shardName) return nil } diff --git a/go/test/endtoend/vreplication/fk_ext_load_generator_test.go b/go/test/endtoend/vreplication/fk_ext_load_generator_test.go new file mode 100644 index 00000000000..12b5871781f --- /dev/null +++ b/go/test/endtoend/vreplication/fk_ext_load_generator_test.go @@ -0,0 +1,503 @@ +/* +Copyright 2023 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 vreplication + +import ( + "context" + "fmt" + "math/rand" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/vt/log" +) + +const ( + // Only used when debugging tests. + queryLog = "queries.txt" + + LoadGeneratorStateLoading = "loading" + LoadGeneratorStateRunning = "running" + LoadGeneratorStateStopped = "stopped" + + dataLoadTimeout = 1 * time.Minute + tickInterval = 1 * time.Second + queryTimeout = 1 * time.Minute + + getRandomIdQuery = "SELECT id FROM %s.parent ORDER BY RAND() LIMIT 1" + insertQuery = "INSERT INTO %s.parent (id, name) VALUES (%d, 'name-%d')" + updateQuery = "UPDATE %s.parent SET name = 'rename-%d' WHERE id = %d" + deleteQuery = "DELETE FROM %s.parent WHERE id = %d" + insertChildQuery = "INSERT INTO %s.child (id, parent_id) VALUES (%d, %d)" + insertChildQueryOverrideConstraints = "INSERT /*+ SET_VAR(foreign_key_checks=0) */ INTO %s.child (id, parent_id) VALUES (%d, %d)" +) + +// ILoadGenerator is an interface for load generators that we will use to simulate different types of loads. +type ILoadGenerator interface { + Init(ctx context.Context, vc *VitessCluster) // name & description only for logging. + Teardown() + + // "direct", use direct db connection to primary, only for unsharded keyspace. + // or "vtgate" to use vtgate routing. + // Stop() before calling SetDBStrategy(). + SetDBStrategy(direct, keyspace string) + SetOverrideConstraints(allow bool) // true if load generator can insert rows without FK constraints. + + Keyspace() string + DBStrategy() string // direct or vtgate + State() string // state of load generator (stopped, running) + OverrideConstraints() bool // true if load generator can insert rows without FK constraints. + + Load() error // initial load of data. + Start() error // start populating additional data. + Stop() error // stop populating additional data. + + // Implementation will decide which table to wait for extra rows on. + WaitForAdditionalRows(count int) error + // table == "", implementation will decide which table to get rows from, same table as in WaitForAdditionalRows(). + GetRowCount(table string) (int, error) +} + +var lg ILoadGenerator + +var _ ILoadGenerator = (*SimpleLoadGenerator)(nil) + +type LoadGenerator struct { + ctx context.Context + vc *VitessCluster + state string + dbStrategy string + overrideConstraints bool + keyspace string + tables []string +} + +// SimpleLoadGenerator, which has a single parent table and a single child table for which different types +// of DMLs are run. +type SimpleLoadGenerator struct { + LoadGenerator + currentParentId int + currentChildId int + ch chan bool + runCtx context.Context + runCtxCancel context.CancelFunc +} + +func (lg *SimpleLoadGenerator) SetOverrideConstraints(allow bool) { + lg.overrideConstraints = allow +} + +func (lg *SimpleLoadGenerator) OverrideConstraints() bool { + return lg.overrideConstraints +} + +func (lg *SimpleLoadGenerator) GetRowCount(table string) (int, error) { + vtgateConn, err := lg.getVtgateConn(context.Background()) + if err != nil { + return 0, err + } + defer vtgateConn.Close() + return lg.getNumRows(vtgateConn, table), nil +} + +func (lg *SimpleLoadGenerator) getVtgateConn(ctx context.Context) (*mysql.Conn, error) { + vtParams := mysql.ConnParams{ + Host: lg.vc.ClusterConfig.hostname, + Port: lg.vc.ClusterConfig.vtgateMySQLPort, + Uname: "vt_dba", + } + conn, err := mysql.Connect(ctx, &vtParams) + return conn, err +} + +func (lg *SimpleLoadGenerator) getNumRows(vtgateConn *mysql.Conn, table string) int { + t := lg.vc.t + return getRowCount(t, vtgateConn, table) +} + +func (lg *SimpleLoadGenerator) WaitForAdditionalRows(count int) error { + t := lg.vc.t + vtgateConn := getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) + defer vtgateConn.Close() + numRowsStart := lg.getNumRows(vtgateConn, "parent") + shortCtx, cancel := context.WithTimeout(context.Background(), dataLoadTimeout) + defer cancel() + for { + select { + case <-shortCtx.Done(): + t.Fatalf("Timed out waiting for additional rows in %q table", "parent") + default: + numRows := lg.getNumRows(vtgateConn, "parent") + if numRows >= numRowsStart+count { + return nil + } + time.Sleep(tickInterval) + } + } +} + +func (lg *SimpleLoadGenerator) exec(query string) (*sqltypes.Result, error) { + switch lg.dbStrategy { + case "direct": + // direct is expected to be used only for unsharded keyspaces to simulate an unmanaged keyspace + // that proxies to an external database. + primary := lg.vc.getPrimaryTablet(lg.vc.t, lg.keyspace, "0") + qr, err := primary.QueryTablet(query, lg.keyspace, true) + require.NoError(lg.vc.t, err) + return qr, err + case "vtgate": + return lg.execQueryWithRetry(query) + default: + err := fmt.Errorf("invalid dbStrategy: %v", lg.dbStrategy) + return nil, err + } +} + +// When a workflow switches traffic it is possible to get transient errors from vtgate while executing queries +// due to cluster-level changes. isQueryRetryable() checks for such errors so that tests can wait for such changes +// to complete before proceeding. +func isQueryRetryable(err error) bool { + retryableErrorStrings := []string{ + "retry", + "resharded", + "VT13001", + "Lock wait timeout exceeded", + "errno 2003", + } + for _, e := range retryableErrorStrings { + if strings.Contains(err.Error(), e) { + return true + } + } + return false +} + +func (lg *SimpleLoadGenerator) execQueryWithRetry(query string) (*sqltypes.Result, error) { + ctx, cancel := context.WithTimeout(context.Background(), queryTimeout) + defer cancel() + errCh := make(chan error) + qrCh := make(chan *sqltypes.Result) + var vtgateConn *mysql.Conn + go func() { + var qr *sqltypes.Result + var err error + retry := false + for { + select { + case <-ctx.Done(): + errCh <- fmt.Errorf("query %q did not succeed before the timeout of %s", query, queryTimeout) + return + default: + } + if lg.runCtx != nil && lg.runCtx.Err() != nil { + log.Infof("Load generator run context done, query never completed: %q", query) + errCh <- fmt.Errorf("load generator stopped") + return + } + if retry { + time.Sleep(tickInterval) + } + // We need to parse the error as well as the output of vdiff to determine if the error is retryable, since + // sometimes it is observed that we get the error output as part of vdiff output. + vtgateConn, err = lg.getVtgateConn(ctx) + if err != nil { + if !isQueryRetryable(err) { + errCh <- err + return + } + time.Sleep(tickInterval) + continue + } + qr, err = vtgateConn.ExecuteFetch(query, 1000, false) + vtgateConn.Close() + if err == nil { + qrCh <- qr + return + } + if !isQueryRetryable(err) { + errCh <- err + return + } + retry = true + } + }() + select { + case qr := <-qrCh: + return qr, nil + case err := <-errCh: + log.Infof("query %q failed with error %v", query, err) + return nil, err + } +} + +func (lg *SimpleLoadGenerator) Load() error { + lg.state = LoadGeneratorStateLoading + defer func() { lg.state = LoadGeneratorStateStopped }() + log.Infof("Inserting initial FK data") + var queries = []string{ + "insert into parent values(1, 'parent1'), (2, 'parent2');", + "insert into child values(1, 1, 'child11'), (2, 1, 'child21'), (3, 2, 'child32');", + } + for _, query := range queries { + _, err := lg.exec(query) + require.NoError(lg.vc.t, err) + } + log.Infof("Done inserting initial FK data") + return nil +} + +func (lg *SimpleLoadGenerator) Start() error { + if lg.state == LoadGeneratorStateRunning { + log.Infof("Load generator already running") + return nil + } + lg.state = LoadGeneratorStateRunning + go func() { + defer func() { + lg.state = LoadGeneratorStateStopped + log.Infof("Load generator stopped") + }() + lg.runCtx, lg.runCtxCancel = context.WithCancel(lg.ctx) + defer func() { + lg.runCtx = nil + lg.runCtxCancel = nil + }() + t := lg.vc.t + var err error + log.Infof("Load generator starting") + for i := 0; ; i++ { + if i%1000 == 0 { + // Log occasionally to show that the test is still running. + log.Infof("Load simulation iteration %d", i) + } + select { + case <-lg.ctx.Done(): + log.Infof("Load generator context done") + lg.ch <- true + return + case <-lg.runCtx.Done(): + log.Infof("Load generator run context done") + lg.ch <- true + return + default: + } + op := rand.Intn(100) + switch { + case op < 50: // 50% chance to insert + lg.insert() + case op < 80: // 30% chance to update + lg.update() + default: // 20% chance to delete + lg.delete() + } + require.NoError(t, err) + time.Sleep(1 * time.Millisecond) + } + }() + return nil +} + +func (lg *SimpleLoadGenerator) Stop() error { + if lg.state == LoadGeneratorStateStopped { + log.Infof("Load generator already stopped") + return nil + } + if lg.runCtx != nil && lg.runCtxCancel != nil { + log.Infof("Canceling load generator") + lg.runCtxCancel() + } + // Wait for ch to be closed or we hit a timeout. + timeout := vdiffTimeout + select { + case <-lg.ch: + log.Infof("Load generator stopped") + lg.state = LoadGeneratorStateStopped + return nil + case <-time.After(timeout): + log.Infof("Timed out waiting for load generator to stop") + return fmt.Errorf("timed out waiting for load generator to stop") + } +} + +func (lg *SimpleLoadGenerator) Init(ctx context.Context, vc *VitessCluster) { + lg.ctx = ctx + lg.vc = vc + lg.state = LoadGeneratorStateStopped + lg.currentParentId = 100 + lg.currentChildId = 100 + lg.ch = make(chan bool) + lg.tables = []string{"parent", "child"} +} + +func (lg *SimpleLoadGenerator) Teardown() { + // noop +} + +func (lg *SimpleLoadGenerator) SetDBStrategy(strategy, keyspace string) { + lg.dbStrategy = strategy + lg.keyspace = keyspace +} + +func (lg *SimpleLoadGenerator) Keyspace() string { + return lg.keyspace +} + +func (lg *SimpleLoadGenerator) DBStrategy() string { + return lg.dbStrategy +} + +func (lg *SimpleLoadGenerator) State() string { + return lg.state +} + +func isQueryCancelled(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "load generator stopped") +} + +func (lg *SimpleLoadGenerator) insert() { + t := lg.vc.t + currentParentId++ + query := fmt.Sprintf(insertQuery, lg.keyspace, currentParentId, currentParentId) + qr, err := lg.exec(query) + if isQueryCancelled(err) { + return + } + require.NoError(t, err) + require.NotNil(t, qr) + // Insert one or more children, some with valid foreign keys, some without. + for i := 0; i < rand.Intn(4)+1; i++ { + currentChildId++ + if i == 3 && lg.overrideConstraints { + query = fmt.Sprintf(insertChildQueryOverrideConstraints, lg.keyspace, currentChildId, currentParentId+1000000) + lg.exec(query) + } else { + query = fmt.Sprintf(insertChildQuery, lg.keyspace, currentChildId, currentParentId) + lg.exec(query) + } + } +} + +func (lg *SimpleLoadGenerator) getRandomId() int64 { + t := lg.vc.t + qr, err := lg.exec(fmt.Sprintf(getRandomIdQuery, lg.keyspace)) + if isQueryCancelled(err) { + return 0 + } + require.NoError(t, err) + require.NotNil(t, qr) + if len(qr.Rows) == 0 { + return 0 + } + id, err := qr.Rows[0][0].ToInt64() + require.NoError(t, err) + return id +} + +func (lg *SimpleLoadGenerator) update() { + id := lg.getRandomId() + if id == 0 { + return + } + updateQuery := fmt.Sprintf(updateQuery, lg.keyspace, id, id) + _, err := lg.exec(updateQuery) + if isQueryCancelled(err) { + return + } + require.NoError(lg.vc.t, err) +} + +func (lg *SimpleLoadGenerator) delete() { + id := lg.getRandomId() + if id == 0 { + return + } + deleteQuery := fmt.Sprintf(deleteQuery, lg.keyspace, id) + _, err := lg.exec(deleteQuery) + if isQueryCancelled(err) { + return + } + require.NoError(lg.vc.t, err) +} + +// FIXME: following three functions are copied over from vtgate test utility functions in +// `go/test/endtoend/utils/utils.go`. +// We will to refactor and then reuse the same functionality from vtgate tests, in the near future. + +func convertToMap(input interface{}) map[string]interface{} { + output := input.(map[string]interface{}) + return output +} + +func getTableT2Map(res *interface{}, ks, tbl string) map[string]interface{} { + step1 := convertToMap(*res)["keyspaces"] + step2 := convertToMap(step1)[ks] + step3 := convertToMap(step2)["tables"] + tblMap := convertToMap(step3)[tbl] + return convertToMap(tblMap) +} + +// waitForColumn waits for a table's column to be present in the vschema because vtgate's foreign key managed mode +// expects the column to be present in the vschema before it can be used in a foreign key constraint. +func waitForColumn(t *testing.T, vtgateProcess *cluster.VtgateProcess, ks, tbl, col string) error { + timeout := time.After(defaultTimeout) + for { + select { + case <-timeout: + return fmt.Errorf("schema tracking did not find column '%s' in table '%s'", col, tbl) + default: + time.Sleep(defaultTick) + res, err := vtgateProcess.ReadVSchema() + require.NoError(t, err, res) + t2Map := getTableT2Map(res, ks, tbl) + authoritative, fieldPresent := t2Map["column_list_authoritative"] + if !fieldPresent { + break + } + authoritativeBool, isBool := authoritative.(bool) + if !isBool || !authoritativeBool { + break + } + colMap, exists := t2Map["columns"] + if !exists { + break + } + colList, isSlice := colMap.([]interface{}) + if !isSlice { + break + } + for _, c := range colList { + colDef, isMap := c.(map[string]interface{}) + if !isMap { + break + } + if colName, exists := colDef["name"]; exists && colName == col { + log.Infof("Found column '%s' in table '%s' for keyspace '%s'", col, tbl, ks) + return nil + } + } + } + } +} diff --git a/go/test/endtoend/vreplication/fk_ext_test.go b/go/test/endtoend/vreplication/fk_ext_test.go new file mode 100644 index 00000000000..665f8052486 --- /dev/null +++ b/go/test/endtoend/vreplication/fk_ext_test.go @@ -0,0 +1,450 @@ +/* +Copyright 2023 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 vreplication + +import ( + "context" + _ "embed" + "fmt" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/vt/log" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +const ( + shardStatusWaitTimeout = 30 * time.Second +) + +var ( + //go:embed schema/fkext/source_schema.sql + FKExtSourceSchema string + //go:embed schema/fkext/source_vschema.json + FKExtSourceVSchema string + //go:embed schema/fkext/target1_vschema.json + FKExtTarget1VSchema string + //go:embed schema/fkext/target2_vschema.json + FKExtTarget2VSchema string + //go:embed schema/fkext/materialize_schema.sql + FKExtMaterializeSchema string +) + +type fkextConfigType struct { + *ClusterConfig + sourceKeyspaceName string + target1KeyspaceName string + target2KeyspaceName string + cell string +} + +var fkextConfig *fkextConfigType + +func initFKExtConfig(t *testing.T) { + fkextConfig = &fkextConfigType{ + ClusterConfig: mainClusterConfig, + sourceKeyspaceName: "source", + target1KeyspaceName: "target1", + target2KeyspaceName: "target2", + cell: "zone1", + } +} + +/* +TestFKExt is an end-to-end test for validating the foreign key implementation with respect to, both vreplication +flows and vtgate processing of DMLs for tables with foreign key constraints. It currently: +* Sets up a source keyspace, to simulate the external database, with a parent and child table with a foreign key constraint. +* Creates a target keyspace with two shards, the Vitess keyspace, into which the source data is imported. +* Imports the data using MoveTables. This uses the atomic copy flow +to test that we can import data with foreign key constraints and that data is kept consistent even after the copy phase +since the tables continue to have the FK Constraints. +* Creates a new keyspace with two shards, the Vitess keyspace, into which the data is migrated using MoveTables. +* Materializes the parent and child tables into a different keyspace. +* Reshards the keyspace from 2 shards to 3 shards. +* Reshards the keyspace from 3 shards to 1 shard. + +We drop constraints from the tables from some replicas to simulate a replica that is not doing cascades in +innodb, to confirm that vtgate's fkmanaged mode is working properly. +*/ + +func TestFKExt(t *testing.T) { + setSidecarDBName("_vt") + + // Ensure that there are multiple copy phase cycles per table. + extraVTTabletArgs = append(extraVTTabletArgs, "--vstream_packet_size=256", "--queryserver-config-schema-change-signal") + extraVTGateArgs = append(extraVTGateArgs, "--schema_change_signal=true", "--planner-version", "Gen4") + defer func() { extraVTTabletArgs = nil }() + initFKExtConfig(t) + + cellName := fkextConfig.cell + cells := []string{cellName} + vc = NewVitessCluster(t, t.Name(), cells, fkextConfig.ClusterConfig) + + require.NotNil(t, vc) + allCellNames = cellName + defaultCellName := cellName + defaultCell = vc.Cells[defaultCellName] + cell := vc.Cells[cellName] + + defer vc.TearDown(t) + + sourceKeyspace := fkextConfig.sourceKeyspaceName + vc.AddKeyspace(t, []*Cell{cell}, sourceKeyspace, "0", FKExtSourceVSchema, FKExtSourceSchema, 0, 0, 100, nil) + + vtgate = cell.Vtgates[0] + require.NotNil(t, vtgate) + err := cluster.WaitForHealthyShard(vc.VtctldClient, sourceKeyspace, "0") + require.NoError(t, err) + require.NoError(t, vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.primary", sourceKeyspace, "0"), 1, shardStatusWaitTimeout)) + + vtgateConn = getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) + defer vtgateConn.Close() + verifyClusterHealth(t, vc) + + lg = &SimpleLoadGenerator{} + lg.Init(context.Background(), vc) + lg.SetDBStrategy("vtgate", fkextConfig.sourceKeyspaceName) + if lg.Load() != nil { + t.Fatal("Load failed") + } + if lg.Start() != nil { + t.Fatal("Start failed") + } + t.Run("Import from external db", func(t *testing.T) { + // Import data into vitess from sourceKeyspace to target1Keyspace, both unsharded. + importIntoVitess(t) + }) + + t.Run("MoveTables from unsharded to sharded keyspace", func(t *testing.T) { + // Migrate data from target1Keyspace to the sharded target2Keyspace. Drops constraints from + // replica to simulate a replica that is not doing cascades in innodb to test vtgate's fkmanaged mode. + // The replica with dropped constraints is used as source for the next workflow called in materializeTables(). + moveKeyspace(t) + }) + + t.Run("Materialize parent and copy tables without constraints", func(t *testing.T) { + // Materialize the tables from target2Keyspace to target1Keyspace. Stream only from replicas, one + // shard with constraints dropped. + materializeTables(t) + }) + lg.SetDBStrategy("vtgate", fkextConfig.target2KeyspaceName) + if lg.Start() != nil { + t.Fatal("Start failed") + } + threeShards := "-40,40-c0,c0-" + keyspaceName := fkextConfig.target2KeyspaceName + ks := vc.Cells[fkextConfig.cell].Keyspaces[keyspaceName] + numReplicas := 1 + + t.Run("Reshard keyspace from 2 shards to 3 shards", func(t *testing.T) { + tabletID := 500 + require.NoError(t, vc.AddShards(t, []*Cell{defaultCell}, ks, threeShards, numReplicas, 0, tabletID, nil)) + tablets := make(map[string]*cluster.VttabletProcess) + for i, shard := range strings.Split(threeShards, ",") { + require.NoError(t, vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.replica", keyspaceName, shard), numReplicas, shardStatusWaitTimeout)) + tablets[shard] = vc.Cells[cellName].Keyspaces[keyspaceName].Shards[shard].Tablets[fmt.Sprintf("%s-%d", cellName, tabletID+i*100)].Vttablet + } + sqls := strings.Split(FKExtSourceSchema, "\n") + for _, sql := range sqls { + output, err := vc.VtctlClient.ExecuteCommandWithOutput("ApplySchema", "--", + "--ddl_strategy=direct", "--sql", sql, keyspaceName) + require.NoErrorf(t, err, output) + } + doReshard(t, fkextConfig.target2KeyspaceName, "reshard2to3", "-80,80-", threeShards, tablets) + }) + t.Run("Reshard keyspace from 3 shards to 1 shard", func(t *testing.T) { + tabletID := 800 + shard := "0" + require.NoError(t, vc.AddShards(t, []*Cell{defaultCell}, ks, shard, numReplicas, 0, tabletID, nil)) + tablets := make(map[string]*cluster.VttabletProcess) + require.NoError(t, vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.replica", keyspaceName, shard), numReplicas, shardStatusWaitTimeout)) + tablets[shard] = vc.Cells[cellName].Keyspaces[keyspaceName].Shards[shard].Tablets[fmt.Sprintf("%s-%d", cellName, tabletID)].Vttablet + sqls := strings.Split(FKExtSourceSchema, "\n") + for _, sql := range sqls { + output, err := vc.VtctlClient.ExecuteCommandWithOutput("ApplySchema", "--", + "--ddl_strategy=direct", "--sql", sql, keyspaceName) + require.NoErrorf(t, err, output) + } + doReshard(t, fkextConfig.target2KeyspaceName, "reshard3to1", threeShards, "0", tablets) + }) + lg.Stop() + waitForLowLag(t, fkextConfig.target1KeyspaceName, "mat") + t.Run("Validate materialize counts at end of test", func(t *testing.T) { + validateMaterializeRowCounts(t) + }) + +} + +// compareRowCounts compares the row counts for the parent and child tables in the source and target shards. In addition to vdiffs, +// it is another check to ensure that both tables have the same number of rows in the source and target shards after load generation +// has stopped. +func compareRowCounts(t *testing.T, keyspace string, sourceShards, targetShards []string) error { + log.Infof("Comparing row counts for keyspace %s, source shards: %v, target shards: %v", keyspace, sourceShards, targetShards) + lg.Stop() + defer lg.Start() + if err := waitForCondition("load generator to stop", func() bool { return lg.State() == LoadGeneratorStateStopped }, 10*time.Second); err != nil { + return err + } + + sourceTabs := make(map[string]*cluster.VttabletProcess) + targetTabs := make(map[string]*cluster.VttabletProcess) + for _, shard := range sourceShards { + sourceTabs[shard] = vc.getPrimaryTablet(t, keyspace, shard) + } + for _, shard := range targetShards { + targetTabs[shard] = vc.getPrimaryTablet(t, keyspace, shard) + } + + getCount := func(tab *cluster.VttabletProcess, table string) (int64, error) { + qr, err := tab.QueryTablet(fmt.Sprintf("select count(*) from %s", table), keyspace, true) + if err != nil { + return 0, err + } + return qr.Rows[0][0].ToInt64() + } + + var sourceParentCount, sourceChildCount int64 + var targetParentCount, targetChildCount int64 + for _, tab := range sourceTabs { + count, _ := getCount(tab, "parent") + sourceParentCount += count + count, _ = getCount(tab, "child") + sourceChildCount += count + } + for _, tab := range targetTabs { + count, _ := getCount(tab, "parent") + targetParentCount += count + count, _ = getCount(tab, "child") + targetChildCount += count + } + log.Infof("Source parent count: %d, child count: %d, target parent count: %d, child count: %d.", + sourceParentCount, sourceChildCount, targetParentCount, targetChildCount) + if sourceParentCount != targetParentCount || sourceChildCount != targetChildCount { + return fmt.Errorf(fmt.Sprintf("source and target row counts do not match; source parent count: %d, target parent count: %d, source child count: %d, target child count: %d", + sourceParentCount, targetParentCount, sourceChildCount, targetChildCount)) + } + return nil +} + +func doReshard(t *testing.T, keyspace, workflowName, sourceShards, targetShards string, targetTabs map[string]*cluster.VttabletProcess) { + rs := newReshard(vc, &reshardWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: keyspace, + }, + sourceShards: sourceShards, + targetShards: targetShards, + skipSchemaCopy: true, + }, workflowFlavorVtctl) + rs.Create() + waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", keyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) + for _, targetTab := range targetTabs { + catchup(t, targetTab, workflowName, "Reshard") + } + vdiff(t, keyspace, workflowName, fkextConfig.cell, false, true, nil) + rs.SwitchReadsAndWrites() + //if lg.WaitForAdditionalRows(100) != nil { + // t.Fatal("WaitForAdditionalRows failed") + //} + waitForLowLag(t, keyspace, workflowName+"_reverse") + if compareRowCounts(t, keyspace, strings.Split(sourceShards, ","), strings.Split(targetShards, ",")) != nil { + t.Fatal("Row counts do not match") + } + vdiff(t, keyspace, workflowName+"_reverse", fkextConfig.cell, true, false, nil) + + rs.ReverseReadsAndWrites() + //if lg.WaitForAdditionalRows(100) != nil { + // t.Fatal("WaitForAdditionalRows failed") + //} + waitForLowLag(t, keyspace, workflowName) + if compareRowCounts(t, keyspace, strings.Split(targetShards, ","), strings.Split(sourceShards, ",")) != nil { + t.Fatal("Row counts do not match") + } + vdiff(t, keyspace, workflowName, fkextConfig.cell, false, true, nil) + lg.Stop() + + rs.SwitchReadsAndWrites() + rs.Complete() +} + +func areRowCountsEqual(t *testing.T) bool { + vtgateConn = getConnection(t, vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateMySQLPort) + defer vtgateConn.Close() + parentRowCount := getRowCount(t, vtgateConn, "target2.parent") + childRowCount := getRowCount(t, vtgateConn, "target2.child") + parentCopyRowCount := getRowCount(t, vtgateConn, "target1.parent_copy") + childCopyRowCount := getRowCount(t, vtgateConn, "target1.child_copy") + log.Infof("Post-materialize row counts are parent: %d, child: %d, parent_copy: %d, child_copy: %d", + parentRowCount, childRowCount, parentCopyRowCount, childCopyRowCount) + if parentRowCount != parentCopyRowCount || childRowCount != childCopyRowCount { + return false + } + return true +} + +// validateMaterializeRowCounts expects the Load generator to be stopped before calling it. +func validateMaterializeRowCounts(t *testing.T) { + if lg.State() != LoadGeneratorStateStopped { + t.Fatal("Load generator was unexpectedly still running when validateMaterializeRowCounts was called -- this will produce unreliable results.") + } + areRowCountsEqual2 := func() bool { + return areRowCountsEqual(t) + } + require.NoError(t, waitForCondition("row counts to be equal", areRowCountsEqual2, defaultTimeout)) +} + +const fkExtMaterializeSpec = ` +{"workflow": "%s", "source_keyspace": "%s", "target_keyspace": "%s", +"table_settings": [ {"target_table": "parent_copy", "source_expression": "select * from parent" },{"target_table": "child_copy", "source_expression": "select * from child" }], +"tablet_types": "replica"}` + +func materializeTables(t *testing.T) { + wfName := "mat" + err := vc.VtctlClient.ExecuteCommand("ApplySchema", "--", "--ddl_strategy=direct", + "--sql", FKExtMaterializeSchema, fkextConfig.target1KeyspaceName) + require.NoError(t, err, fmt.Sprintf("ApplySchema Error: %s", err)) + materializeSpec := fmt.Sprintf(fkExtMaterializeSpec, "mat", fkextConfig.target2KeyspaceName, fkextConfig.target1KeyspaceName) + err = vc.VtctlClient.ExecuteCommand("Materialize", materializeSpec) + require.NoError(t, err, "Materialize") + tab := vc.getPrimaryTablet(t, fkextConfig.target1KeyspaceName, "0") + catchup(t, tab, wfName, "Materialize") + validateMaterializeRowCounts(t) +} + +func moveKeyspace(t *testing.T) { + targetTabs := newKeyspace(t, fkextConfig.target2KeyspaceName, "-80,80-", FKExtTarget2VSchema, FKExtSourceSchema, 300, 1) + shard := "-80" + tabletId := fmt.Sprintf("%s-%d", fkextConfig.cell, 301) + replicaTab := vc.Cells[fkextConfig.cell].Keyspaces[fkextConfig.target2KeyspaceName].Shards[shard].Tablets[tabletId].Vttablet + dropReplicaConstraints(t, fkextConfig.target2KeyspaceName, replicaTab) + doMoveTables(t, fkextConfig.target1KeyspaceName, fkextConfig.target2KeyspaceName, "move", "replica", targetTabs, false) +} + +func newKeyspace(t *testing.T, keyspaceName, shards, vschema, schema string, tabletId, numReplicas int) map[string]*cluster.VttabletProcess { + tablets := make(map[string]*cluster.VttabletProcess) + cellName := fkextConfig.cell + cell := vc.Cells[fkextConfig.cell] + vc.AddKeyspace(t, []*Cell{cell}, keyspaceName, shards, vschema, schema, numReplicas, 0, tabletId, nil) + for i, shard := range strings.Split(shards, ",") { + require.NoError(t, vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.replica", keyspaceName, shard), 1, shardStatusWaitTimeout)) + tablets[shard] = vc.Cells[cellName].Keyspaces[keyspaceName].Shards[shard].Tablets[fmt.Sprintf("%s-%d", cellName, tabletId+i*100)].Vttablet + } + err := vc.VtctldClient.ExecuteCommand("RebuildVSchemaGraph") + require.NoError(t, err) + require.NoError(t, waitForColumn(t, vtgate, keyspaceName, "parent", "id")) + require.NoError(t, waitForColumn(t, vtgate, keyspaceName, "child", "parent_id")) + return tablets +} + +func doMoveTables(t *testing.T, sourceKeyspace, targetKeyspace, workflowName, tabletTypes string, targetTabs map[string]*cluster.VttabletProcess, atomicCopy bool) { + mt := newMoveTables(vc, &moveTablesWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: targetKeyspace, + tabletTypes: tabletTypes, + }, + sourceKeyspace: sourceKeyspace, + atomicCopy: atomicCopy, + }, workflowFlavorRandom) + mt.Create() + + waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) + + for _, targetTab := range targetTabs { + catchup(t, targetTab, workflowName, "MoveTables") + } + vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, false, true, nil) + lg.Stop() + lg.SetDBStrategy("vtgate", targetKeyspace) + if lg.Start() != nil { + t.Fatal("Start failed") + } + + mt.SwitchReadsAndWrites() + + if lg.WaitForAdditionalRows(100) != nil { + t.Fatal("WaitForAdditionalRows failed") + } + + waitForLowLag(t, sourceKeyspace, workflowName+"_reverse") + vdiff(t, sourceKeyspace, workflowName+"_reverse", fkextConfig.cell, false, true, nil) + if lg.WaitForAdditionalRows(100) != nil { + t.Fatal("WaitForAdditionalRows failed") + } + + mt.ReverseReadsAndWrites() + if lg.WaitForAdditionalRows(100) != nil { + t.Fatal("WaitForAdditionalRows failed") + } + waitForLowLag(t, targetKeyspace, workflowName) + time.Sleep(5 * time.Second) + vdiff(t, targetKeyspace, workflowName, fkextConfig.cell, false, true, nil) + lg.Stop() + mt.SwitchReadsAndWrites() + mt.Complete() + if err := vc.VtctldClient.ExecuteCommand("ApplyRoutingRules", "--rules={}"); err != nil { + t.Fatal(err) + } +} + +func importIntoVitess(t *testing.T) { + targetTabs := newKeyspace(t, fkextConfig.target1KeyspaceName, "0", FKExtTarget1VSchema, FKExtSourceSchema, 200, 1) + doMoveTables(t, fkextConfig.sourceKeyspaceName, fkextConfig.target1KeyspaceName, "import", "primary", targetTabs, true) +} + +const getConstraintsQuery = ` +SELECT CONSTRAINT_NAME, TABLE_NAME +FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE +WHERE TABLE_SCHEMA = '%s' AND REFERENCED_TABLE_NAME IS NOT NULL; +` + +// dropReplicaConstraints drops all foreign key constraints on replica tables for a given keyspace/shard. +// We do this so that we can replay binlogs from a replica which is not doing cascades but just replaying +// the binlogs created by the primary. This will confirm that vtgate is doing the cascades correctly. +func dropReplicaConstraints(t *testing.T, keyspaceName string, tablet *cluster.VttabletProcess) { + var dropConstraints []string + require.Equal(t, "replica", strings.ToLower(tablet.TabletType)) + dbName := "vt_" + keyspaceName + qr, err := tablet.QueryTablet(fmt.Sprintf(getConstraintsQuery, dbName), keyspaceName, true) + if err != nil { + t.Fatal(err) + } + for _, row := range qr.Rows { + constraintName := row[0].ToString() + tableName := row[1].ToString() + dropConstraints = append(dropConstraints, fmt.Sprintf("ALTER TABLE `%s`.`%s` DROP FOREIGN KEY `%s`", + dbName, tableName, constraintName)) + } + prefixQueries := []string{ + "set sql_log_bin=0", + "SET @@global.super_read_only=0", + } + suffixQueries := []string{ + "SET @@global.super_read_only=1", + "set sql_log_bin=1", + } + queries := append(prefixQueries, dropConstraints...) + queries = append(queries, suffixQueries...) + require.NoError(t, tablet.QueryTabletMultiple(queries, keyspaceName, true)) +} diff --git a/go/test/endtoend/vreplication/fk_test.go b/go/test/endtoend/vreplication/fk_test.go index 31886864f11..06e94e0222d 100644 --- a/go/test/endtoend/vreplication/fk_test.go +++ b/go/test/endtoend/vreplication/fk_test.go @@ -94,12 +94,15 @@ func TestFKWorkflow(t *testing.T) { workflowName := "fk" ksWorkflow := fmt.Sprintf("%s.%s", targetKeyspace, workflowName) - mt := newMoveTables(vc, &moveTables{ - workflowName: workflowName, - targetKeyspace: targetKeyspace, + mt := newMoveTables(vc, &moveTablesWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: targetKeyspace, + }, sourceKeyspace: sourceKeyspace, atomicCopy: true, - }, moveTablesFlavorRandom) + }, workflowFlavorRandom) mt.Create() waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) diff --git a/go/test/endtoend/vreplication/helper_test.go b/go/test/endtoend/vreplication/helper_test.go index d2154f13f1f..07c12caf194 100644 --- a/go/test/endtoend/vreplication/helper_test.go +++ b/go/test/endtoend/vreplication/helper_test.go @@ -24,6 +24,7 @@ import ( "fmt" "io" "net/http" + "os" "os/exec" "regexp" "sort" @@ -56,6 +57,11 @@ const ( workflowStateTimeout = 90 * time.Second ) +func setSidecarDBName(dbName string) { + sidecarDBName = dbName + sidecarDBIdentifier = sqlparser.String(sqlparser.NewIdentifierCS(sidecarDBName)) +} + func execMultipleQueries(t *testing.T, conn *mysql.Conn, database string, lines string) { queries := strings.Split(lines, "\n") for _, query := range queries { @@ -65,8 +71,35 @@ func execMultipleQueries(t *testing.T, conn *mysql.Conn, database string, lines execVtgateQuery(t, conn, database, string(query)) } } + +func execQueryWithRetry(t *testing.T, conn *mysql.Conn, query string, timeout time.Duration) *sqltypes.Result { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + ticker := time.NewTicker(defaultTick) + defer ticker.Stop() + + var qr *sqltypes.Result + var err error + for { + qr, err = conn.ExecuteFetch(query, 1000, false) + if err == nil { + return qr + } + select { + case <-ctx.Done(): + require.FailNow(t, fmt.Sprintf("query %q did not succeed before the timeout of %s; last seen result: %v", + query, timeout, qr.Rows)) + case <-ticker.C: + log.Infof("query %q failed with error %v, retrying in %ds", query, err, defaultTick) + } + } +} + func execQuery(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { qr, err := conn.ExecuteFetch(query, 1000, false) + if err != nil { + log.Errorf("Error executing query: %s: %v", query, err) + } require.NoError(t, err) return qr } @@ -79,7 +112,7 @@ func getConnection(t *testing.T, hostname string, port int) *mysql.Conn { } ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) + require.NoErrorf(t, err, "error connecting to vtgate on %s:%d", hostname, port) return conn } @@ -96,6 +129,19 @@ func execVtgateQuery(t *testing.T, conn *mysql.Conn, database string, query stri return qr } +func execVtgateQueryWithRetry(t *testing.T, conn *mysql.Conn, database string, query string, timeout time.Duration) *sqltypes.Result { + if strings.TrimSpace(query) == "" { + return nil + } + if database != "" { + execQuery(t, conn, "use `"+database+"`;") + } + execQuery(t, conn, "begin") + qr := execQueryWithRetry(t, conn, query, timeout) + execQuery(t, conn, "commit") + return qr +} + func checkHealth(t *testing.T, url string) bool { resp, err := http.Get(url) require.NoError(t, err) @@ -703,6 +749,13 @@ func isBinlogRowImageNoBlob(t *testing.T, tablet *cluster.VttabletProcess) bool return mode == "noblob" } +func getRowCount(t *testing.T, vtgateConn *mysql.Conn, table string) int { + query := fmt.Sprintf("select count(*) from %s", table) + qr := execVtgateQuery(t, vtgateConn, "", query) + numRows, _ := qr.Rows[0][0].ToInt() + return numRows +} + const ( loadTestBufferingWindowDurationStr = "30s" loadTestPostBufferingInsertWindow = 60 * time.Second // should be greater than loadTestBufferingWindowDurationStr @@ -820,3 +873,37 @@ func (lg *loadGenerator) waitForCount(want int64) { } } } + +// appendToQueryLog is useful when debugging tests. +func appendToQueryLog(msg string) { + file, err := os.OpenFile(queryLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Errorf("Error opening query log file: %v", err) + return + } + defer file.Close() + if _, err := file.WriteString(msg + "\n"); err != nil { + log.Errorf("Error writing to query log file: %v", err) + } +} + +func waitForCondition(name string, condition func() bool, timeout time.Duration) error { + if condition() { + return nil + } + + ticker := time.NewTicker(tickInterval) + defer ticker.Stop() + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + for { + select { + case <-ticker.C: + if condition() { + return nil + } + case <-ctx.Done(): + return fmt.Errorf("%s: waiting for %s", ctx.Err(), name) + } + } +} diff --git a/go/test/endtoend/vreplication/movetables_buffering_test.go b/go/test/endtoend/vreplication/movetables_buffering_test.go index 4e4b7cada97..113587a1669 100644 --- a/go/test/endtoend/vreplication/movetables_buffering_test.go +++ b/go/test/endtoend/vreplication/movetables_buffering_test.go @@ -21,7 +21,7 @@ func TestMoveTablesBuffering(t *testing.T) { setupMinimalCustomerKeyspace(t) tables := "loadtest" err := tstWorkflowExec(t, defaultCellName, workflowName, sourceKs, targetKs, - tables, workflowActionCreate, "", "", "", false) + tables, workflowActionCreate, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) diff --git a/go/test/endtoend/vreplication/partial_movetables_seq_test.go b/go/test/endtoend/vreplication/partial_movetables_seq_test.go index 6a1ed92cb9c..f8dc440b62d 100644 --- a/go/test/endtoend/vreplication/partial_movetables_seq_test.go +++ b/go/test/endtoend/vreplication/partial_movetables_seq_test.go @@ -239,7 +239,7 @@ func (wf *workflow) create() { currentWorkflowType = wrangler.MoveTablesWorkflow sourceShards := strings.Join(wf.options.sourceShards, ",") err = tstWorkflowExec(t, cell, wf.name, wf.fromKeyspace, wf.toKeyspace, - strings.Join(wf.options.tables, ","), workflowActionCreate, "", sourceShards, "", false) + strings.Join(wf.options.tables, ","), workflowActionCreate, "", sourceShards, "", defaultWorkflowExecOptions) case "reshard": currentWorkflowType = wrangler.ReshardWorkflow sourceShards := strings.Join(wf.options.sourceShards, ",") @@ -248,7 +248,7 @@ func (wf *workflow) create() { targetShards = sourceShards } err = tstWorkflowExec(t, cell, wf.name, wf.fromKeyspace, wf.toKeyspace, - strings.Join(wf.options.tables, ","), workflowActionCreate, "", sourceShards, targetShards, false) + strings.Join(wf.options.tables, ","), workflowActionCreate, "", sourceShards, targetShards, defaultWorkflowExecOptions) default: panic(fmt.Sprintf("unknown workflow type: %s", wf.typ)) } @@ -266,15 +266,15 @@ func (wf *workflow) create() { } func (wf *workflow) switchTraffic() { - require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionSwitchTraffic, "", "", "", false)) + require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions)) } func (wf *workflow) reverseTraffic() { - require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionReverseTraffic, "", "", "", false)) + require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionReverseTraffic, "", "", "", defaultWorkflowExecOptions)) } func (wf *workflow) complete() { - require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionComplete, "", "", "", false)) + require.NoError(wf.tc.t, tstWorkflowExec(wf.tc.t, wf.tc.defaultCellName, wf.name, wf.fromKeyspace, wf.toKeyspace, "", workflowActionComplete, "", "", "", defaultWorkflowExecOptions)) } // TestPartialMoveTablesWithSequences enhances TestPartialMoveTables by adding an unsharded keyspace which has a @@ -505,7 +505,7 @@ func TestPartialMoveTablesWithSequences(t *testing.T) { // We switched traffic, so it's the reverse workflow we want to cancel. reverseWf := wf + "_reverse" reverseKs := sourceKs // customer - err = tstWorkflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", false) + err = tstWorkflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) output, err := tc.vc.VtctlClient.ExecuteCommandWithOutput("Workflow", fmt.Sprintf("%s.%s", reverseKs, reverseWf), "show") diff --git a/go/test/endtoend/vreplication/partial_movetables_test.go b/go/test/endtoend/vreplication/partial_movetables_test.go index 5583232fbdc..d9573b50e4a 100644 --- a/go/test/endtoend/vreplication/partial_movetables_test.go +++ b/go/test/endtoend/vreplication/partial_movetables_test.go @@ -44,13 +44,16 @@ func testCancel(t *testing.T) { table := "customer2" shard := "80-" // start the partial movetables for 80- - mt := newMoveTables(vc, &moveTables{ - workflowName: workflowName, - targetKeyspace: targetKeyspace, + mt := newMoveTables(vc, &moveTablesWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: targetKeyspace, + }, sourceKeyspace: sourceKeyspace, tables: table, sourceShards: shard, - }, moveTablesFlavorRandom) + }, workflowFlavorRandom) mt.Create() checkDenyList := func(keyspace string, expected bool) { @@ -141,7 +144,7 @@ func TestPartialMoveTablesBasic(t *testing.T) { // start the partial movetables for 80- err := tstWorkflowExec(t, defaultCellName, wfName, sourceKs, targetKs, - "customer,loadtest", workflowActionCreate, "", shard, "", false) + "customer,loadtest", workflowActionCreate, "", shard, "", defaultWorkflowExecOptions) require.NoError(t, err) var lg *loadGenerator if runWithLoad { // start load after routing rules are set, otherwise we end up with ambiguous tables @@ -214,7 +217,7 @@ func TestPartialMoveTablesBasic(t *testing.T) { require.Contains(t, err.Error(), "target: customer.-80.primary", "Query was routed to the target before any SwitchTraffic") // Switch all traffic for the shard - require.NoError(t, tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionSwitchTraffic, "", "", "", false)) + require.NoError(t, tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions)) expectedSwitchOutput := fmt.Sprintf("SwitchTraffic was successful for workflow %s.%s\nStart State: Reads Not Switched. Writes Not Switched\nCurrent State: Reads partially switched, for shards: %s. Writes partially switched, for shards: %s\n\n", targetKs, wfName, shard, shard) require.Equal(t, expectedSwitchOutput, lastOutput) @@ -272,7 +275,7 @@ func TestPartialMoveTablesBasic(t *testing.T) { // We cannot Complete a partial move tables at the moment because // it will find that all traffic has (obviously) not been switched. - err = tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionComplete, "", "", "", false) + err = tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionComplete, "", "", "", defaultWorkflowExecOptions) require.Error(t, err) // Confirm global routing rules: -80 should still be be routed to customer @@ -285,14 +288,14 @@ func TestPartialMoveTablesBasic(t *testing.T) { ksWf = fmt.Sprintf("%s.%s", targetKs, wfName) // Start the partial movetables for -80, 80- has already been switched err = tstWorkflowExec(t, defaultCellName, wfName, sourceKs, targetKs, - "customer,loadtest", workflowActionCreate, "", shard, "", false) + "customer,loadtest", workflowActionCreate, "", shard, "", defaultWorkflowExecOptions) require.NoError(t, err) targetTab2 := vc.getPrimaryTablet(t, targetKs, shard) catchup(t, targetTab2, wfName, "Partial MoveTables Customer to Customer2: -80") vdiffSideBySide(t, ksWf, "") // Switch all traffic for the shard - require.NoError(t, tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionSwitchTraffic, "", "", "", false)) + require.NoError(t, tstWorkflowExec(t, "", wfName, "", targetKs, "", workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions)) expectedSwitchOutput = fmt.Sprintf("SwitchTraffic was successful for workflow %s.%s\nStart State: Reads partially switched, for shards: 80-. Writes partially switched, for shards: 80-\nCurrent State: All Reads Switched. All Writes Switched\n\n", targetKs, wfName) require.Equal(t, expectedSwitchOutput, lastOutput) @@ -313,7 +316,7 @@ func TestPartialMoveTablesBasic(t *testing.T) { // We switched traffic, so it's the reverse workflow we want to cancel. reverseWf := wf + "_reverse" reverseKs := sourceKs // customer - err = tstWorkflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", false) + err = tstWorkflowExec(t, "", reverseWf, "", reverseKs, "", workflowActionCancel, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", fmt.Sprintf("%s.%s", reverseKs, reverseWf), "show") diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index 338310fdf14..401147a3887 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -61,9 +61,18 @@ var ( currentWorkflowType wrangler.VReplicationWorkflowType ) +type workflowExecOptions struct { + deferSecondaryKeys bool + atomicCopy bool +} + +var defaultWorkflowExecOptions = &workflowExecOptions{ + deferSecondaryKeys: true, +} + func createReshardWorkflow(t *testing.T, sourceShards, targetShards string) error { err := tstWorkflowExec(t, defaultCellName, workflowName, targetKs, targetKs, - "", workflowActionCreate, "", sourceShards, targetShards, false) + "", workflowActionCreate, "", sourceShards, targetShards, defaultWorkflowExecOptions) require.NoError(t, err) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) confirmTablesHaveSecondaryKeys(t, []*cluster.VttabletProcess{targetTab1}, targetKs, "") @@ -78,7 +87,7 @@ func createMoveTablesWorkflow(t *testing.T, tables string) { tables = tablesToMove } err := tstWorkflowExec(t, defaultCellName, workflowName, sourceKs, targetKs, - tables, workflowActionCreate, "", "", "", false) + tables, workflowActionCreate, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) confirmTablesHaveSecondaryKeys(t, []*cluster.VttabletProcess{targetTab1}, targetKs, tables) @@ -88,10 +97,12 @@ func createMoveTablesWorkflow(t *testing.T, tables string) { } func tstWorkflowAction(t *testing.T, action, tabletTypes, cells string) error { - return tstWorkflowExec(t, cells, workflowName, sourceKs, targetKs, tablesToMove, action, tabletTypes, "", "", false) + return tstWorkflowExec(t, cells, workflowName, sourceKs, targetKs, tablesToMove, action, tabletTypes, "", "", defaultWorkflowExecOptions) } -func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, action, tabletTypes, sourceShards, targetShards string, atomicCopy bool) error { +func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, action, tabletTypes, + sourceShards, targetShards string, options *workflowExecOptions) error { + var args []string if currentWorkflowType == wrangler.MoveTablesWorkflow { args = append(args, "MoveTables") @@ -104,7 +115,7 @@ func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, if BypassLagCheck { args = append(args, "--max_replication_lag_allowed=2542087h") } - if atomicCopy { + if options.atomicCopy { args = append(args, "--atomic-copy") } switch action { @@ -125,7 +136,8 @@ func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, // Test new experimental --defer-secondary-keys flag switch currentWorkflowType { case wrangler.MoveTablesWorkflow, wrangler.MigrateWorkflow, wrangler.ReshardWorkflow: - if !atomicCopy { + + if !options.atomicCopy && options.deferSecondaryKeys { args = append(args, "--defer-secondary-keys") } args = append(args, "--initialize-target-sequences") // Only used for MoveTables @@ -317,17 +329,17 @@ func testVSchemaForSequenceAfterMoveTables(t *testing.T) { // use MoveTables to move customer2 from product to customer using currentWorkflowType = wrangler.MoveTablesWorkflow err := tstWorkflowExec(t, defaultCellName, "wf2", sourceKs, targetKs, - "customer2", workflowActionCreate, "", "", "", false) + "customer2", workflowActionCreate, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) waitForWorkflowState(t, vc, "customer.wf2", binlogdatapb.VReplicationWorkflowState_Running.String()) waitForLowLag(t, "customer", "wf2") err = tstWorkflowExec(t, defaultCellName, "wf2", sourceKs, targetKs, - "", workflowActionSwitchTraffic, "", "", "", false) + "", workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) err = tstWorkflowExec(t, defaultCellName, "wf2", sourceKs, targetKs, - "", workflowActionComplete, "", "", "", false) + "", workflowActionComplete, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) // sanity check @@ -352,16 +364,16 @@ func testVSchemaForSequenceAfterMoveTables(t *testing.T) { // use MoveTables to move customer2 back to product. Note that now the table has an associated sequence err = tstWorkflowExec(t, defaultCellName, "wf3", targetKs, sourceKs, - "customer2", workflowActionCreate, "", "", "", false) + "customer2", workflowActionCreate, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) waitForWorkflowState(t, vc, "product.wf3", binlogdatapb.VReplicationWorkflowState_Running.String()) waitForLowLag(t, "product", "wf3") err = tstWorkflowExec(t, defaultCellName, "wf3", targetKs, sourceKs, - "", workflowActionSwitchTraffic, "", "", "", false) + "", workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) err = tstWorkflowExec(t, defaultCellName, "wf3", targetKs, sourceKs, - "", workflowActionComplete, "", "", "", false) + "", workflowActionComplete, "", "", "", defaultWorkflowExecOptions) require.NoError(t, err) // sanity check diff --git a/go/test/endtoend/vreplication/schema/fkext/materialize_schema.sql b/go/test/endtoend/vreplication/schema/fkext/materialize_schema.sql new file mode 100644 index 00000000000..6af8ca99b94 --- /dev/null +++ b/go/test/endtoend/vreplication/schema/fkext/materialize_schema.sql @@ -0,0 +1,2 @@ +create table parent_copy(id int, name varchar(128), primary key(id)) engine=innodb; +create table child_copy(id int, parent_id int, name varchar(128), primary key(id)) engine=innodb; \ No newline at end of file diff --git a/go/test/endtoend/vreplication/schema/fkext/source_schema.sql b/go/test/endtoend/vreplication/schema/fkext/source_schema.sql new file mode 100644 index 00000000000..01b788338b6 --- /dev/null +++ b/go/test/endtoend/vreplication/schema/fkext/source_schema.sql @@ -0,0 +1,2 @@ +create table if not exists parent(id int, name varchar(128), primary key(id)) engine=innodb; +create table if not exists child(id int, parent_id int, name varchar(128), primary key(id), foreign key(parent_id) references parent(id) on delete cascade) engine=innodb; \ No newline at end of file diff --git a/go/test/endtoend/vreplication/schema/fkext/source_vschema.json b/go/test/endtoend/vreplication/schema/fkext/source_vschema.json new file mode 100644 index 00000000000..01cde0d643d --- /dev/null +++ b/go/test/endtoend/vreplication/schema/fkext/source_vschema.json @@ -0,0 +1,6 @@ +{ + "tables": { + "parent": {}, + "child": {} + } +} diff --git a/go/test/endtoend/vreplication/schema/fkext/target1_vschema.json b/go/test/endtoend/vreplication/schema/fkext/target1_vschema.json new file mode 100644 index 00000000000..dc89232fbbb --- /dev/null +++ b/go/test/endtoend/vreplication/schema/fkext/target1_vschema.json @@ -0,0 +1,28 @@ +{ + "sharded": false, + "foreignKeyMode": "managed", + "vindexes": { + "reverse_bits": { + "type": "reverse_bits" + } + }, + "tables": { + "parent": { + "column_vindexes": [ + { + "column": "id", + "name": "reverse_bits" + } + ] + }, + "child": { + "column_vindexes": [ + { + "column": "parent_id", + "name": "reverse_bits" + } + ] + } + + } +} diff --git a/go/test/endtoend/vreplication/schema/fkext/target2_vschema.json b/go/test/endtoend/vreplication/schema/fkext/target2_vschema.json new file mode 100644 index 00000000000..06e851a9007 --- /dev/null +++ b/go/test/endtoend/vreplication/schema/fkext/target2_vschema.json @@ -0,0 +1,43 @@ +{ + "sharded": true, + "foreignKeyMode": "managed", + "vindexes": { + "reverse_bits": { + "type": "reverse_bits" + } + }, + "tables": { + "parent": { + "column_vindexes": [ + { + "column": "id", + "name": "reverse_bits" + } + ] + }, + "child": { + "column_vindexes": [ + { + "column": "parent_id", + "name": "reverse_bits" + } + ] + }, + "parent_copy": { + "column_vindexes": [ + { + "column": "id", + "name": "reverse_bits" + } + ] + }, + "child_copy": { + "column_vindexes": [ + { + "column": "parent_id", + "name": "reverse_bits" + } + ] + } + } +} diff --git a/go/test/endtoend/vreplication/vdiff2_test.go b/go/test/endtoend/vreplication/vdiff2_test.go index 72b09e8fede..eb96985af57 100644 --- a/go/test/endtoend/vreplication/vdiff2_test.go +++ b/go/test/endtoend/vreplication/vdiff2_test.go @@ -323,6 +323,7 @@ func testResume(t *testing.T, tc *testCase, cells string) { // expected number of rows in total (original run and resume) _, _ = performVDiff2Action(t, false, ksWorkflow, cells, "resume", uuid, false) info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, ogTime) + require.NotNil(t, info) require.False(t, info.HasMismatch) require.Equal(t, expectedRows, info.RowsCompared) }) @@ -375,6 +376,7 @@ func testAutoRetryError(t *testing.T, tc *testCase, cells string) { // confirm that the VDiff was retried, able to complete, and we compared the expected // number of rows in total (original run and retry) info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, ogTime) + require.NotNil(t, info) require.False(t, info.HasMismatch) require.Equal(t, expectedRows, info.RowsCompared) }) diff --git a/go/test/endtoend/vreplication/vdiff_helper_test.go b/go/test/endtoend/vreplication/vdiff_helper_test.go index 38ae9273a42..7dbc675886b 100644 --- a/go/test/endtoend/vreplication/vdiff_helper_test.go +++ b/go/test/endtoend/vreplication/vdiff_helper_test.go @@ -17,6 +17,7 @@ limitations under the License. package vreplication import ( + "context" "fmt" "strings" "testing" @@ -31,7 +32,10 @@ import ( ) const ( - vdiffTimeout = time.Second * 90 // we can leverage auto retry on error with this longer-than-usual timeout + vdiffTimeout = 90 * time.Second // we can leverage auto retry on error with this longer-than-usual timeout + vdiffRetryTimeout = 30 * time.Second + vdiffStatusCheckInterval = 1 * time.Second + vdiffRetryInterval = 5 * time.Second ) var ( @@ -66,6 +70,7 @@ func doVtctlclientVDiff(t *testing.T, keyspace, workflow, cells string, want *ex // update-table-stats is needed in order to test progress reports. uuid, _ := performVDiff2Action(t, true, ksWorkflow, cells, "create", "", false, "--auto-retry", "--update-table-stats") info := waitForVDiff2ToComplete(t, true, ksWorkflow, cells, uuid, time.Time{}) + require.NotNil(t, info) require.Equal(t, workflow, info.Workflow) require.Equal(t, keyspace, info.Keyspace) if want != nil { @@ -90,9 +95,10 @@ func waitForVDiff2ToComplete(t *testing.T, useVtctlclient bool, ksWorkflow, cell ch := make(chan bool) go func() { for { - time.Sleep(1 * time.Second) + time.Sleep(vdiffStatusCheckInterval) _, jsonStr := performVDiff2Action(t, useVtctlclient, ksWorkflow, cells, "show", uuid, false) info = getVDiffInfo(jsonStr) + require.NotNil(t, info) if info.State == "completed" { if !completedAtMin.IsZero() { ca := info.CompletedAt @@ -136,6 +142,7 @@ func waitForVDiff2ToComplete(t *testing.T, useVtctlclient bool, ksWorkflow, cell case <-ch: return info case <-time.After(vdiffTimeout): + log.Errorf("VDiff never completed for UUID %s", uuid) require.FailNow(t, fmt.Sprintf("VDiff never completed for UUID %s", uuid)) return nil } @@ -153,7 +160,7 @@ func doVtctldclientVDiff(t *testing.T, keyspace, workflow, cells string, want *e // update-table-stats is needed in order to test progress reports. uuid, _ := performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false, "--auto-retry", "--update-table-stats") info := waitForVDiff2ToComplete(t, false, ksWorkflow, cells, uuid, time.Time{}) - + require.NotNil(t, info) require.Equal(t, workflow, info.Workflow) require.Equal(t, keyspace, info.Keyspace) if want != nil { @@ -186,7 +193,7 @@ func performVDiff2Action(t *testing.T, useVtctlclient bool, ksWorkflow, cells, a args = append(args, extraFlags...) } args = append(args, ksWorkflow, action, actionArg) - output, err = vc.VtctlClient.ExecuteCommandWithOutput(args...) + output, err = execVDiffWithRetry(t, expectError, false, args) log.Infof("vdiff output: %+v (err: %+v)", output, err) if !expectError { require.Nil(t, err) @@ -211,7 +218,8 @@ func performVDiff2Action(t *testing.T, useVtctlclient bool, ksWorkflow, cells, a if actionArg != "" { args = append(args, actionArg) } - output, err = vc.VtctldClient.ExecuteCommandWithOutput(args...) + + output, err = execVDiffWithRetry(t, expectError, true, args) log.Infof("vdiff output: %+v (err: %+v)", output, err) if !expectError { require.NoError(t, err) @@ -226,6 +234,79 @@ func performVDiff2Action(t *testing.T, useVtctlclient bool, ksWorkflow, cells, a return uuid, output } +// During SwitchTraffic, due to changes in the cluster, vdiff can return transient errors. isVDiffRetryable() is used to +// ignore such errors and retry vdiff expecting the condition to be resolved. +func isVDiffRetryable(str string) bool { + for _, s := range []string{"Error while dialing", "failed to connect"} { + if strings.Contains(str, s) { + return true + } + } + return false +} + +type vdiffResult struct { + output string + err error +} + +// execVDiffWithRetry will ignore transient errors that can occur during workflow state changes. +func execVDiffWithRetry(t *testing.T, expectError bool, useVtctldClient bool, args []string) (string, error) { + ctx, cancel := context.WithTimeout(context.Background(), vdiffRetryTimeout) + defer cancel() + vdiffResultCh := make(chan vdiffResult) + go func() { + var output string + var err error + retry := false + for { + select { + case <-ctx.Done(): + return + default: + } + if retry { + time.Sleep(vdiffRetryInterval) + } + retry = false + if useVtctldClient { + output, err = vc.VtctldClient.ExecuteCommandWithOutput(args...) + } else { + output, err = vc.VtctlClient.ExecuteCommandWithOutput(args...) + } + if err != nil { + if expectError { + result := vdiffResult{output: output, err: err} + vdiffResultCh <- result + return + } + log.Infof("vdiff error: %s", err) + if isVDiffRetryable(err.Error()) { + retry = true + } else { + result := vdiffResult{output: output, err: err} + vdiffResultCh <- result + return + } + } + if isVDiffRetryable(output) { + retry = true + } + if !retry { + result := vdiffResult{output: output, err: nil} + vdiffResultCh <- result + return + } + } + }() + select { + case <-ctx.Done(): + return "", fmt.Errorf("timed out waiting for vdiff to complete") + case result := <-vdiffResultCh: + return result.output, result.err + } +} + type vdiffInfo struct { Workflow, Keyspace string State, Shards string diff --git a/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go b/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go index 0f6a9f668d0..434ea6db3e0 100644 --- a/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go +++ b/go/test/endtoend/vreplication/vdiff_multiple_movetables_test.go @@ -93,12 +93,16 @@ func TestMultipleConcurrentVDiffs(t *testing.T) { time.Sleep(15 * time.Second) // wait for some rows to be inserted. createWorkflow := func(workflowName, tables string) { - mt := newMoveTables(vc, &moveTables{ - workflowName: workflowName, - targetKeyspace: targetKeyspace, + mt := newMoveTables(vc, &moveTablesWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: targetKeyspace, + tabletTypes: "primary", + }, sourceKeyspace: sourceKeyspace, tables: tables, - }, moveTablesFlavorVtctld) + }, workflowFlavorVtctld) mt.Create() waitForWorkflowState(t, vc, fmt.Sprintf("%s.%s", targetKeyspace, workflowName), binlogdatapb.VReplicationWorkflowState_Running.String()) catchup(t, targetTab, workflowName, "MoveTables") diff --git a/go/test/endtoend/vreplication/wrappers_test.go b/go/test/endtoend/vreplication/wrappers_test.go index 6bd0bbb19d8..76a4e627b1b 100644 --- a/go/test/endtoend/vreplication/wrappers_test.go +++ b/go/test/endtoend/vreplication/wrappers_test.go @@ -20,28 +20,49 @@ import ( "math/rand" "strconv" + "vitess.io/vitess/go/vt/wrangler" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/log" ) -type moveTablesFlavor int +type iWorkflow interface { + Create() + Show() + SwitchReads() + SwitchWrites() + SwitchReadsAndWrites() + ReverseReadsAndWrites() + Cancel() + Complete() + Flavor() string +} + +type workflowFlavor int const ( - moveTablesFlavorRandom moveTablesFlavor = iota - moveTablesFlavorVtctl - moveTablesFlavorVtctld + workflowFlavorRandom workflowFlavor = iota + workflowFlavorVtctl + workflowFlavorVtctld ) -var moveTablesFlavors = []moveTablesFlavor{ - moveTablesFlavorVtctl, - moveTablesFlavorVtctld, +var workflowFlavors = []workflowFlavor{ + workflowFlavorVtctl, + workflowFlavorVtctld, } -type moveTables struct { +type workflowInfo struct { vc *VitessCluster workflowName string targetKeyspace string + tabletTypes string +} + +// MoveTables wrappers + +type moveTablesWorkflow struct { + *workflowInfo sourceKeyspace string tables string atomicCopy bool @@ -49,27 +70,19 @@ type moveTables struct { } type iMoveTables interface { - Create() - Show() - SwitchReads() - SwitchWrites() - SwitchReadsAndWrites() - ReverseReadsAndWrites() - Cancel() - Complete() - Flavor() string + iWorkflow } -func newMoveTables(vc *VitessCluster, mt *moveTables, flavor moveTablesFlavor) iMoveTables { +func newMoveTables(vc *VitessCluster, mt *moveTablesWorkflow, flavor workflowFlavor) iMoveTables { mt.vc = vc var mt2 iMoveTables - if flavor == moveTablesFlavorRandom { - flavor = moveTablesFlavors[rand.Intn(len(moveTablesFlavors))] + if flavor == workflowFlavorRandom { + flavor = workflowFlavors[rand.Intn(len(workflowFlavors))] } switch flavor { - case moveTablesFlavorVtctl: + case workflowFlavorVtctl: mt2 = newVtctlMoveTables(mt) - case moveTablesFlavorVtctld: + case workflowFlavorVtctld: mt2 = newVtctldMoveTables(mt) default: panic("unreachable") @@ -79,33 +92,31 @@ func newMoveTables(vc *VitessCluster, mt *moveTables, flavor moveTablesFlavor) i } type VtctlMoveTables struct { - *moveTables + *moveTablesWorkflow } func (vmt *VtctlMoveTables) Flavor() string { return "vtctl" } -func newVtctlMoveTables(mt *moveTables) *VtctlMoveTables { +func newVtctlMoveTables(mt *moveTablesWorkflow) *VtctlMoveTables { return &VtctlMoveTables{mt} } func (vmt *VtctlMoveTables) Create() { - log.Infof("vmt is %+v", vmt.vc, vmt.tables) - err := tstWorkflowExec(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionCreate, "", vmt.sourceShards, "", vmt.atomicCopy) - require.NoError(vmt.vc.t, err) + currentWorkflowType = wrangler.MoveTablesWorkflow + vmt.exec(workflowActionCreate) } func (vmt *VtctlMoveTables) SwitchReadsAndWrites() { err := tstWorkflowExec(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionSwitchTraffic, "", "", "", vmt.atomicCopy) + vmt.tables, workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions) require.NoError(vmt.vc.t, err) } func (vmt *VtctlMoveTables) ReverseReadsAndWrites() { err := tstWorkflowExec(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionReverseTraffic, "", "", "", vmt.atomicCopy) + vmt.tables, workflowActionReverseTraffic, "", "", "", defaultWorkflowExecOptions) require.NoError(vmt.vc.t, err) } @@ -114,6 +125,15 @@ func (vmt *VtctlMoveTables) Show() { panic("implement me") } +func (vmt *VtctlMoveTables) exec(action string) { + options := &workflowExecOptions{ + deferSecondaryKeys: false, + atomicCopy: vmt.atomicCopy, + } + err := tstWorkflowExec(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, + vmt.tables, action, vmt.tabletTypes, vmt.sourceShards, "", options) + require.NoError(vmt.vc.t, err) +} func (vmt *VtctlMoveTables) SwitchReads() { //TODO implement me panic("implement me") @@ -125,23 +145,20 @@ func (vmt *VtctlMoveTables) SwitchWrites() { } func (vmt *VtctlMoveTables) Cancel() { - err := tstWorkflowExec(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, - vmt.tables, workflowActionCancel, "", "", "", vmt.atomicCopy) - require.NoError(vmt.vc.t, err) + vmt.exec(workflowActionCancel) } func (vmt *VtctlMoveTables) Complete() { - //TODO implement me - panic("implement me") + vmt.exec(workflowActionComplete) } var _ iMoveTables = (*VtctldMoveTables)(nil) type VtctldMoveTables struct { - *moveTables + *moveTablesWorkflow } -func newVtctldMoveTables(mt *moveTables) *VtctldMoveTables { +func newVtctldMoveTables(mt *moveTablesWorkflow) *VtctldMoveTables { return &VtctldMoveTables{mt} } @@ -201,6 +218,158 @@ func (v VtctldMoveTables) Cancel() { } func (v VtctldMoveTables) Complete() { + v.exec("Complete") +} + +// Reshard wrappers + +type reshardWorkflow struct { + *workflowInfo + sourceShards string + targetShards string + skipSchemaCopy bool +} + +type iReshard interface { + iWorkflow +} + +func newReshard(vc *VitessCluster, rs *reshardWorkflow, flavor workflowFlavor) iReshard { + rs.vc = vc + var rs2 iReshard + if flavor == workflowFlavorRandom { + flavor = workflowFlavors[rand.Intn(len(workflowFlavors))] + } + switch flavor { + case workflowFlavorVtctl: + rs2 = newVtctlReshard(rs) + case workflowFlavorVtctld: + rs2 = newVtctldReshard(rs) + default: + panic("unreachable") + } + log.Infof("Using reshard flavor: %s", rs2.Flavor()) + return rs2 +} + +type VtctlReshard struct { + *reshardWorkflow +} + +func (vrs *VtctlReshard) Flavor() string { + return "vtctl" +} + +func newVtctlReshard(rs *reshardWorkflow) *VtctlReshard { + return &VtctlReshard{rs} +} + +func (vrs *VtctlReshard) Create() { + currentWorkflowType = wrangler.ReshardWorkflow + vrs.exec(workflowActionCreate) +} + +func (vrs *VtctlReshard) SwitchReadsAndWrites() { + vrs.exec(workflowActionSwitchTraffic) +} + +func (vrs *VtctlReshard) ReverseReadsAndWrites() { + vrs.exec(workflowActionReverseTraffic) +} + +func (vrs *VtctlReshard) Show() { + //TODO implement me + panic("implement me") +} + +func (vrs *VtctlReshard) exec(action string) { + options := &workflowExecOptions{} + err := tstWorkflowExec(vrs.vc.t, "", vrs.workflowName, "", vrs.targetKeyspace, + "", action, vrs.tabletTypes, vrs.sourceShards, vrs.targetShards, options) + require.NoError(vrs.vc.t, err) +} + +func (vrs *VtctlReshard) SwitchReads() { + //TODO implement me + panic("implement me") +} + +func (vrs *VtctlReshard) SwitchWrites() { + //TODO implement me + panic("implement me") +} + +func (vrs *VtctlReshard) Cancel() { + vrs.exec(workflowActionCancel) +} + +func (vrs *VtctlReshard) Complete() { + vrs.exec(workflowActionComplete) +} + +var _ iReshard = (*VtctldReshard)(nil) + +type VtctldReshard struct { + *reshardWorkflow +} + +func newVtctldReshard(rs *reshardWorkflow) *VtctldReshard { + return &VtctldReshard{rs} +} + +func (v VtctldReshard) Flavor() string { + return "vtctld" +} + +func (v VtctldReshard) exec(args ...string) { + args2 := []string{"Reshard", "--workflow=" + v.workflowName, "--target-keyspace=" + v.targetKeyspace} + args2 = append(args2, args...) + if err := vc.VtctldClient.ExecuteCommand(args2...); err != nil { + v.vc.t.Fatalf("failed to create Reshard workflow: %v", err) + } +} + +func (v VtctldReshard) Create() { + args := []string{"Create"} + if v.sourceShards != "" { + args = append(args, "--source-shards="+v.sourceShards) + } + if v.targetShards != "" { + args = append(args, "--target-shards="+v.targetShards) + } + if v.skipSchemaCopy { + args = append(args, "--skip-schema-copy="+strconv.FormatBool(v.skipSchemaCopy)) + } + v.exec(args...) +} + +func (v VtctldReshard) SwitchReadsAndWrites() { + v.exec("SwitchTraffic") +} + +func (v VtctldReshard) ReverseReadsAndWrites() { + v.exec("ReverseTraffic") +} + +func (v VtctldReshard) Show() { + //TODO implement me + panic("implement me") +} + +func (v VtctldReshard) SwitchReads() { //TODO implement me panic("implement me") } + +func (v VtctldReshard) SwitchWrites() { + //TODO implement me + panic("implement me") +} + +func (v VtctldReshard) Cancel() { + v.exec("Cancel") +} + +func (v VtctldReshard) Complete() { + v.exec("Complete") +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 3abd24aa0e6..be8876f26d2 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -152,8 +152,21 @@ func (vp *vplayer) play(ctx context.Context) error { // The foreign_key_checks value for a transaction is determined by the 2nd bit (least significant) of the flags: // - If set (1), foreign key checks are disabled. // - If unset (0), foreign key checks are enabled. -// updateFKCheck also updates the state for the first row event that this vplayer and hence the connection sees. +// updateFKCheck also updates the state for the first row event that this vplayer, and hence the db connection, sees. func (vp *vplayer) updateFKCheck(ctx context.Context, flags2 uint32) error { + mustUpdate := false + if vp.vr.WorkflowSubType == int32(binlogdatapb.VReplicationWorkflowSubType_AtomicCopy) { + // If this is an atomic copy, we must update the foreign_key_checks state even when the vplayer runs during + // the copy phase, i.e., for catchup and fastforward. + mustUpdate = true + } else if vp.vr.state == binlogdatapb.VReplicationWorkflowState_Running { + // If the vreplication workflow is in Running state, we must update the foreign_key_checks + // state for all workflow types. + mustUpdate = true + } + if !mustUpdate { + return nil + } dbForeignKeyChecksEnabled := true if flags2&NoForeignKeyCheckFlagBitmask == NoForeignKeyCheckFlagBitmask { dbForeignKeyChecksEnabled = false diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index ccbcee9c3b0..e7700e08079 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -1391,8 +1391,8 @@ func (ts *trafficSwitcher) createReverseVReplication(ctx context.Context) error Filter: filter, }) } - log.Infof("Creating reverse workflow vreplication stream on tablet %s: workflow %s, startPos %s", - source.GetPrimary().Alias, ts.ReverseWorkflowName(), target.Position) + log.Infof("Creating reverse workflow vreplication stream on tablet %s: workflow %s, startPos %s for target %s:%s, uid %d", + source.GetPrimary().Alias, ts.ReverseWorkflowName(), target.Position, ts.TargetKeyspaceName(), target.GetShard().ShardName(), uid) _, err := ts.VReplicationExec(ctx, source.GetPrimary().Alias, binlogplayer.CreateVReplicationState(ts.ReverseWorkflowName(), reverseBls, target.Position, binlogdatapb.VReplicationWorkflowState_Stopped, source.GetPrimary().DbName(), ts.workflowType, ts.workflowSubType)) diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index 5a3031d7307..1bc76a2868a 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -122,6 +122,7 @@ var ( "vreplication_v2", "vreplication_partial_movetables_basic", "vreplication_partial_movetables_sequences", + "vreplication_foreign_key_stress", "schemadiff_vrepl", "topo_connection_cache", "vtgate_partial_keyspace", diff --git a/test/config.json b/test/config.json index 66657b4f37e..7aafcaf1a80 100644 --- a/test/config.json +++ b/test/config.json @@ -1220,6 +1220,15 @@ "RetryMax": 1, "Tags": [] }, + "vreplication_foreign_key_stress": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestFKExt"], + "Command": [], + "Manual": false, + "Shard": "vreplication_foreign_key_stress", + "RetryMax": 1, + "Tags": [] + }, "vreplication_across_db_versions": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestV2WorkflowsAcrossDBVersions", "-timeout", "20m"], From 10c843e68260268c1c30c3846a137d6ddd45d488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Mon, 27 Nov 2023 13:55:49 +0100 Subject: [PATCH 047/119] plabuilder: use OR for not in comparisons (#14607) --- .../vtgate/queries/subquery/subquery_test.go | 25 +++++++++++++++++-- .../vtgate/planbuilder/operators/subquery.go | 5 +++- .../planbuilder/testdata/filter_cases.json | 6 ++--- .../planbuilder/testdata/tpch_cases.json | 2 +- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go index 371de19dbe6..ae46a99565d 100644 --- a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go +++ b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go @@ -19,12 +19,11 @@ package subquery import ( "testing" - "vitess.io/vitess/go/test/endtoend/utils" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/utils" ) func start(t *testing.T) (utils.MySQLCompare, func()) { @@ -58,6 +57,28 @@ func TestSubqueriesHasValues(t *testing.T) { mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id1 FROM t1 WHERE id1 > 10) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(6)]]`) } +func TestNotINQueries(t *testing.T) { + utils.SkipIfBinaryIsBelowVersion(t, 19, "vtgate") + + // Tests NOT IN where the RHS contains all rows, some rows and no rows + mcmp, closer := start(t) + defer closer() + + mcmp.Exec("insert into t1(id1, id2) values (0,1),(1,2),(2,3),(3,4),(4,5),(5,6)") + // no matching rows + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id1 FROM t1 WHERE id1 > 10) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(6)]]`) + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id2 FROM t1 WHERE id2 > 10) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(6)]]`) + + // some matching rows + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id1 FROM t1 WHERE id1 > 3) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`) + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id2 FROM t1 WHERE id2 > 3) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`) + + // all rows matching + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id1 FROM t1) ORDER BY id2`, `[]`) + mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id2 FROM t1) ORDER BY id2`, `[[INT64(1)]]`) + +} + // Test only supported in >= v16.0.0 func TestSubqueriesExists(t *testing.T) { utils.SkipIfBinaryIsBelowVersion(t, 16, "vtgate") diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index ae28dd8d9c6..a401b29074d 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -255,7 +255,10 @@ func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer ops.Ope predicates = append(predicates, sqlparser.NewArgument(hasValuesArg()), rhsPred) sq.SubqueryValueName = sq.ArgName case opcode.PulloutNotIn: - predicates = append(predicates, sqlparser.NewNotExpr(sqlparser.NewArgument(hasValuesArg())), rhsPred) + predicates = append(predicates, &sqlparser.OrExpr{ + Left: sqlparser.NewNotExpr(sqlparser.NewArgument(hasValuesArg())), + Right: rhsPred, + }) sq.SubqueryValueName = sq.ArgName case opcode.PulloutValue: predicates = append(predicates, rhsPred) diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json index 2f8f9d73daa..dc8614a8ba7 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json @@ -1966,7 +1966,7 @@ "Sharded": true }, "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where not :__sq_has_values and id not in ::__sq1", + "Query": "select id from `user` where not :__sq_has_values or id not in ::__sq1", "Table": "`user`" } ] @@ -2503,7 +2503,7 @@ "Sharded": true }, "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where not :__sq_has_values and id not in ::__sq1 and :__sq_has_values1 and id in ::__vals", + "Query": "select id from `user` where (not :__sq_has_values or id not in ::__sq1) and :__sq_has_values1 and id in ::__vals", "Table": "`user`", "Values": [ "::__sq2" @@ -2950,7 +2950,7 @@ "Sharded": true }, "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5 and id in (select user_extra.col from user_extra where user_extra.user_id = 5) and not :__sq_has_values and id not in ::__sq1", + "Query": "select id from `user` where id = 5 and id in (select user_extra.col from user_extra where user_extra.user_id = 5) and (not :__sq_has_values or id not in ::__sq1)", "Table": "`user`", "Values": [ "5" diff --git a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json index 61f602c4e33..a5c144df355 100644 --- a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json @@ -1594,7 +1594,7 @@ "Sharded": true }, "FieldQuery": "select ps_suppkey, weight_string(ps_suppkey), ps_partkey from partsupp where 1 != 1", - "Query": "select ps_suppkey, weight_string(ps_suppkey), ps_partkey from partsupp where not :__sq_has_values and ps_suppkey not in ::__sq1", + "Query": "select ps_suppkey, weight_string(ps_suppkey), ps_partkey from partsupp where not :__sq_has_values or ps_suppkey not in ::__sq1", "Table": "partsupp" } ] From 132cbf048d8c336fb027e0f73682f5fa045135c8 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Mon, 27 Nov 2023 14:28:22 +0100 Subject: [PATCH 048/119] evalengine: Fix the min / max calculation for decimals (#14614) Signed-off-by: Dirkjan Bussink --- go/vt/vtgate/evalengine/api_aggregation.go | 2 ++ go/vt/vtgate/evalengine/api_aggregation_test.go | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/go/vt/vtgate/evalengine/api_aggregation.go b/go/vt/vtgate/evalengine/api_aggregation.go index c0d490ced22..05a4f8711ad 100644 --- a/go/vt/vtgate/evalengine/api_aggregation.go +++ b/go/vt/vtgate/evalengine/api_aggregation.go @@ -389,6 +389,7 @@ func (s *aggregationDecimal) Min(value sqltypes.Value) error { } if !s.dec.IsInitialized() || dec.Cmp(s.dec) < 0 { s.dec = dec + s.prec = -dec.Exponent() } return nil } @@ -403,6 +404,7 @@ func (s *aggregationDecimal) Max(value sqltypes.Value) error { } if !s.dec.IsInitialized() || dec.Cmp(s.dec) > 0 { s.dec = dec + s.prec = -dec.Exponent() } return nil } diff --git a/go/vt/vtgate/evalengine/api_aggregation_test.go b/go/vt/vtgate/evalengine/api_aggregation_test.go index aab49541e71..bd3a10547fe 100644 --- a/go/vt/vtgate/evalengine/api_aggregation_test.go +++ b/go/vt/vtgate/evalengine/api_aggregation_test.go @@ -72,6 +72,12 @@ func TestMinMax(t *testing.T) { min: sqltypes.NewVarBinary("a"), max: sqltypes.NewVarBinary("b"), }, + { + type_: sqltypes.Decimal, + values: []sqltypes.Value{sqltypes.NewDecimal("1.001"), sqltypes.NewDecimal("2.1")}, + min: sqltypes.NewDecimal("1.001"), + max: sqltypes.NewDecimal("2.1"), + }, { // accent insensitive type_: sqltypes.VarChar, From 34127ddcf78ce5f4dbc0210aa263333c1ff07fdf Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 27 Nov 2023 16:30:35 +0200 Subject: [PATCH 049/119] Replace use of `WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS` with `WAIT_FOR_EXECUTED_GTID_SET` (#14612) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/flavor_mysql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index 3cc2e08e489..be11126ff9c 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -234,7 +234,7 @@ func (mysqlFlavor) waitUntilPositionCommand(ctx context.Context, pos replication } } - return fmt.Sprintf("SELECT WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS('%s', %v)", pos, timeoutSeconds), nil + return fmt.Sprintf("SELECT WAIT_FOR_EXECUTED_GTID_SET('%s', %v)", pos, timeoutSeconds), nil } // readBinlogEvent is part of the Flavor interface. From 0dc027d24a61d6fe443db06845c56f9837d2273a Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Mon, 27 Nov 2023 15:38:23 +0100 Subject: [PATCH 050/119] evalengine: Handle zero dates correctly (#14610) Signed-off-by: Dirkjan Bussink Signed-off-by: Vicent Marti Co-authored-by: Vicent Marti --- config/mycnf/test-suite.cnf | 9 +-- go/mysql/config/config.go | 3 + go/mysql/endtoend/replication_test.go | 4 + .../vrepl_suite/onlineddl_vrepl_suite_test.go | 6 +- .../vrepl/schemadiff_vrepl_suite_test.go | 6 +- go/vt/sidecardb/sidecardb.go | 3 +- go/vt/vtgate/engine/concatenate.go | 22 +++--- go/vt/vtgate/engine/distinct.go | 5 +- go/vt/vtgate/engine/fake_vcursor_test.go | 5 ++ go/vt/vtgate/engine/hash_join.go | 3 +- go/vt/vtgate/engine/primitive.go | 1 + go/vt/vtgate/evalengine/api_coerce.go | 4 +- go/vt/vtgate/evalengine/api_hash.go | 20 ++--- go/vt/vtgate/evalengine/api_hash_test.go | 16 ++-- go/vt/vtgate/evalengine/compiler.go | 5 +- go/vt/vtgate/evalengine/compiler_asm.go | 46 ++--------- go/vt/vtgate/evalengine/compiler_test.go | 8 ++ go/vt/vtgate/evalengine/eval.go | 12 +-- go/vt/vtgate/evalengine/eval_temporal.go | 76 ++++++++++--------- go/vt/vtgate/evalengine/expr_convert.go | 4 +- go/vt/vtgate/evalengine/expr_env.go | 35 ++++++++- go/vt/vtgate/evalengine/expr_logical.go | 4 +- go/vt/vtgate/evalengine/fn_time.go | 68 ++++++++--------- .../evalengine/integration/comparison_test.go | 5 ++ go/vt/vtgate/evalengine/translate.go | 9 ++- go/vt/vtgate/evalengine/weights.go | 10 +-- go/vt/vtgate/evalengine/weights_test.go | 6 +- go/vt/vtgate/vcursor_impl.go | 12 ++- .../vreplication/framework_test.go | 10 +++ .../vreplication/vcopier_test.go | 20 +++-- 30 files changed, 244 insertions(+), 193 deletions(-) create mode 100644 go/mysql/config/config.go diff --git a/config/mycnf/test-suite.cnf b/config/mycnf/test-suite.cnf index e6d0992f6e6..28f4ac16e0d 100644 --- a/config/mycnf/test-suite.cnf +++ b/config/mycnf/test-suite.cnf @@ -1,5 +1,5 @@ # This sets some unsafe settings specifically for -# the test-suite which is currently MySQL 5.7 based +# the test-suite which is currently MySQL 8.0 based # In future it should be renamed testsuite.cnf innodb_buffer_pool_size = 32M @@ -14,13 +14,6 @@ key_buffer_size = 2M sync_binlog=0 innodb_doublewrite=0 -# These two settings are required for the testsuite to pass, -# but enabling them does not spark joy. They should be removed -# in the future. See: -# https://github.com/vitessio/vitess/issues/5396 - -sql_mode = STRICT_TRANS_TABLES - # set a short heartbeat interval in order to detect failures quickly slave_net_timeout = 4 # Disabling `super-read-only`. `test-suite` is mainly used for `vttestserver`. Since `vttestserver` uses a single MySQL for primary and replicas, diff --git a/go/mysql/config/config.go b/go/mysql/config/config.go new file mode 100644 index 00000000000..8abf9d7dc71 --- /dev/null +++ b/go/mysql/config/config.go @@ -0,0 +1,3 @@ +package config + +const DefaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" diff --git a/go/mysql/endtoend/replication_test.go b/go/mysql/endtoend/replication_test.go index 0c1fa006347..441209b35f7 100644 --- a/go/mysql/endtoend/replication_test.go +++ b/go/mysql/endtoend/replication_test.go @@ -908,6 +908,10 @@ func TestRowReplicationTypes(t *testing.T) { t.Fatal(err) } defer dConn.Close() + // We have tests for zero dates, so we need to allow that for this session. + if _, err := dConn.ExecuteFetch("SET @@session.sql_mode=REPLACE(REPLACE(@@session.sql_mode, 'NO_ZERO_DATE', ''), 'NO_ZERO_IN_DATE', '')", 0, false); err != nil { + t.Fatal(err) + } // Set the connection time zone for execution of the // statements to PST. That way we're sure to test the 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 c8b87215036..56818069e05 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 @@ -28,6 +28,7 @@ import ( "time" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" @@ -58,8 +59,7 @@ var ( ) const ( - testDataPath = "testdata" - defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" + testDataPath = "testdata" ) func TestMain(m *testing.M) { @@ -178,7 +178,7 @@ func testSingle(t *testing.T, testName string) { } } - sqlMode := defaultSQLMode + sqlMode := config.DefaultSQLMode if overrideSQLMode, exists := readTestFile(t, testName, "sql_mode"); exists { sqlMode = overrideSQLMode } diff --git a/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go b/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go index 2dc79840018..055dc7a1df5 100644 --- a/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go +++ b/go/test/endtoend/schemadiff/vrepl/schemadiff_vrepl_suite_test.go @@ -53,8 +53,8 @@ var ( ) const ( - testDataPath = "../../onlineddl/vrepl_suite/testdata" - defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" + testDataPath = "../../onlineddl/vrepl_suite/testdata" + sqlModeAllowsZeroDate = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" ) type testTableSchema struct { @@ -202,7 +202,7 @@ func testSingle(t *testing.T, testName string) { return } - sqlModeQuery := fmt.Sprintf("set @@global.sql_mode='%s'", defaultSQLMode) + sqlModeQuery := fmt.Sprintf("set @@global.sql_mode='%s'", sqlModeAllowsZeroDate) _ = mysqlExec(t, sqlModeQuery, "") _ = mysqlExec(t, "set @@global.event_scheduler=0", "") diff --git a/go/vt/sidecardb/sidecardb.go b/go/vt/sidecardb/sidecardb.go index 92d416f9d37..4b8c37039d7 100644 --- a/go/vt/sidecardb/sidecardb.go +++ b/go/vt/sidecardb/sidecardb.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/history" + "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/mysql/fakesqldb" @@ -485,7 +486,7 @@ func AddSchemaInitQueries(db *fakesqldb.DB, populateTables bool) { sqlModeResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "sql_mode", "varchar"), - "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION", + config.DefaultSQLMode, ) db.AddQuery("select @@session.sql_mode as sql_mode", sqlModeResult) diff --git a/go/vt/vtgate/engine/concatenate.go b/go/vt/vtgate/engine/concatenate.go index 1e8cb655547..27b35c32aa8 100644 --- a/go/vt/vtgate/engine/concatenate.go +++ b/go/vt/vtgate/engine/concatenate.go @@ -105,7 +105,7 @@ func (c *Concatenate) TryExecute(ctx context.Context, vcursor VCursor, bindVars err = c.coerceAndVisitResults(res, fields, func(result *sqltypes.Result) error { rows = append(rows, result.Rows...) return nil - }) + }, evalengine.ParseSQLMode(vcursor.SQLMode())) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (c *Concatenate) TryExecute(ctx context.Context, vcursor VCursor, bindVars }, nil } -func (c *Concatenate) coerceValuesTo(row sqltypes.Row, fields []*querypb.Field) error { +func (c *Concatenate) coerceValuesTo(row sqltypes.Row, fields []*querypb.Field, sqlmode evalengine.SQLMode) error { if len(row) != len(fields) { return errWrongNumberOfColumnsInSelect } @@ -126,7 +126,7 @@ func (c *Concatenate) coerceValuesTo(row sqltypes.Row, fields []*querypb.Field) continue } if fields[i].Type != value.Type() { - newValue, err := evalengine.CoerceTo(value, fields[i].Type) + newValue, err := evalengine.CoerceTo(value, fields[i].Type, sqlmode) if err != nil { return err } @@ -228,16 +228,17 @@ func (c *Concatenate) sequentialExec(ctx context.Context, vcursor VCursor, bindV // TryStreamExecute performs a streaming exec. func (c *Concatenate) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, _ bool, callback func(*sqltypes.Result) error) error { + sqlmode := evalengine.ParseSQLMode(vcursor.SQLMode()) if vcursor.Session().InTransaction() { // as we are in a transaction, we need to execute all queries inside a single connection, // which holds the single transaction we have - return c.sequentialStreamExec(ctx, vcursor, bindVars, callback) + return c.sequentialStreamExec(ctx, vcursor, bindVars, callback, sqlmode) } // not in transaction, so execute in parallel. - return c.parallelStreamExec(ctx, vcursor, bindVars, callback) + return c.parallelStreamExec(ctx, vcursor, bindVars, callback, sqlmode) } -func (c *Concatenate) parallelStreamExec(inCtx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, in func(*sqltypes.Result) error) error { +func (c *Concatenate) parallelStreamExec(inCtx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, in func(*sqltypes.Result) error, sqlmode evalengine.SQLMode) error { // Scoped context; any early exit triggers cancel() to clean up ongoing work. ctx, cancel := context.WithCancel(inCtx) defer cancel() @@ -271,7 +272,7 @@ func (c *Concatenate) parallelStreamExec(inCtx context.Context, vcursor VCursor, // Apply type coercion if needed. if needsCoercion { for _, row := range res.Rows { - if err := c.coerceValuesTo(row, fields); err != nil { + if err := c.coerceValuesTo(row, fields, sqlmode); err != nil { return err } } @@ -340,7 +341,7 @@ func (c *Concatenate) parallelStreamExec(inCtx context.Context, vcursor VCursor, return wg.Wait() } -func (c *Concatenate) sequentialStreamExec(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { +func (c *Concatenate) sequentialStreamExec(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error, sqlmode evalengine.SQLMode) error { // all the below fields ensure that the fields are sent only once. results := make([][]*sqltypes.Result, len(c.Sources)) @@ -374,7 +375,7 @@ func (c *Concatenate) sequentialStreamExec(ctx context.Context, vcursor VCursor, return err } for _, res := range results { - if err = c.coerceAndVisitResults(res, fields, callback); err != nil { + if err = c.coerceAndVisitResults(res, fields, callback, sqlmode); err != nil { return err } } @@ -386,6 +387,7 @@ func (c *Concatenate) coerceAndVisitResults( res []*sqltypes.Result, fields []*querypb.Field, callback func(*sqltypes.Result) error, + sqlmode evalengine.SQLMode, ) error { for _, r := range res { if len(r.Rows) > 0 && @@ -402,7 +404,7 @@ func (c *Concatenate) coerceAndVisitResults( } if needsCoercion { for _, row := range r.Rows { - err := c.coerceValuesTo(row, fields) + err := c.coerceValuesTo(row, fields, sqlmode) if err != nil { return err } diff --git a/go/vt/vtgate/engine/distinct.go b/go/vt/vtgate/engine/distinct.go index 2d263464a2e..c7d6742c136 100644 --- a/go/vt/vtgate/engine/distinct.go +++ b/go/vt/vtgate/engine/distinct.go @@ -46,6 +46,7 @@ type ( probeTable struct { seenRows map[evalengine.HashCode][]sqltypes.Row checkCols []CheckCol + sqlmode evalengine.SQLMode } ) @@ -119,14 +120,14 @@ func (pt *probeTable) hashCodeForRow(inputRow sqltypes.Row) (evalengine.HashCode return 0, vterrors.VT13001("index out of range in row when creating the DISTINCT hash code") } col := inputRow[checkCol.Col] - hashcode, err := evalengine.NullsafeHashcode(col, checkCol.Type.Collation(), col.Type()) + hashcode, err := evalengine.NullsafeHashcode(col, checkCol.Type.Collation(), col.Type(), pt.sqlmode) if err != nil { if err != evalengine.UnsupportedCollationHashError || checkCol.WsCol == nil { return 0, err } checkCol = checkCol.SwitchToWeightString() pt.checkCols[i] = checkCol - hashcode, err = evalengine.NullsafeHashcode(inputRow[checkCol.Col], checkCol.Type.Collation(), col.Type()) + hashcode, err = evalengine.NullsafeHashcode(inputRow[checkCol.Col], checkCol.Type.Collation(), col.Type(), pt.sqlmode) if err != nil { return 0, err } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 0ee95a72e60..f9cedd74bfc 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -31,6 +31,7 @@ import ( "github.com/google/go-cmp/cmp" "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/key" @@ -135,6 +136,10 @@ func (t *noopVCursor) TimeZone() *time.Location { return nil } +func (t *noopVCursor) SQLMode() string { + return config.DefaultSQLMode +} + func (t *noopVCursor) ExecutePrimitive(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { return primitive.TryExecute(ctx, t, bindVars, wantfields) } diff --git a/go/vt/vtgate/engine/hash_join.go b/go/vt/vtgate/engine/hash_join.go index 4f205f1bcdc..4e305e8b59d 100644 --- a/go/vt/vtgate/engine/hash_join.go +++ b/go/vt/vtgate/engine/hash_join.go @@ -75,6 +75,7 @@ type ( lhsKey, rhsKey int cols []int hasher vthash.Hasher + sqlmode evalengine.SQLMode } probeTableEntry struct { @@ -283,7 +284,7 @@ func (pt *hashJoinProbeTable) addLeftRow(r sqltypes.Row) error { } func (pt *hashJoinProbeTable) hash(val sqltypes.Value) (vthash.Hash, error) { - err := evalengine.NullsafeHashcode128(&pt.hasher, val, pt.coll, pt.typ) + err := evalengine.NullsafeHashcode128(&pt.hasher, val, pt.coll, pt.typ, pt.sqlmode) if err != nil { return vthash.Hash{}, err } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index dc1259e2267..833f4cc3b45 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -88,6 +88,7 @@ type ( ConnCollation() collations.ID TimeZone() *time.Location + SQLMode() string ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShard, query *querypb.BoundQuery, lockFuncType sqlparser.LockingFuncType) (*sqltypes.Result, error) diff --git a/go/vt/vtgate/evalengine/api_coerce.go b/go/vt/vtgate/evalengine/api_coerce.go index 143d22ab78c..89b36458198 100644 --- a/go/vt/vtgate/evalengine/api_coerce.go +++ b/go/vt/vtgate/evalengine/api_coerce.go @@ -23,8 +23,8 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -func CoerceTo(value sqltypes.Value, typ sqltypes.Type) (sqltypes.Value, error) { - cast, err := valueToEvalCast(value, value.Type(), collations.Unknown) +func CoerceTo(value sqltypes.Value, typ sqltypes.Type, sqlmode SQLMode) (sqltypes.Value, error) { + cast, err := valueToEvalCast(value, value.Type(), collations.Unknown, sqlmode) if err != nil { return sqltypes.Value{}, err } diff --git a/go/vt/vtgate/evalengine/api_hash.go b/go/vt/vtgate/evalengine/api_hash.go index 209f766840d..3bce100839c 100644 --- a/go/vt/vtgate/evalengine/api_hash.go +++ b/go/vt/vtgate/evalengine/api_hash.go @@ -34,8 +34,8 @@ type HashCode = uint64 // NullsafeHashcode returns an int64 hashcode that is guaranteed to be the same // for two values that are considered equal by `NullsafeCompare`. -func NullsafeHashcode(v sqltypes.Value, collation collations.ID, coerceType sqltypes.Type) (HashCode, error) { - e, err := valueToEvalCast(v, coerceType, collation) +func NullsafeHashcode(v sqltypes.Value, collation collations.ID, coerceType sqltypes.Type, sqlmode SQLMode) (HashCode, error) { + e, err := valueToEvalCast(v, coerceType, collation, sqlmode) if err != nil { return 0, err } @@ -75,7 +75,7 @@ var ErrHashCoercionIsNotExact = vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, " // for two values that are considered equal by `NullsafeCompare`. // This can be used to avoid having to do comparison checks after a hash, // since we consider the 128 bits of entropy enough to guarantee uniqueness. -func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collations.ID, coerceTo sqltypes.Type) error { +func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collations.ID, coerceTo sqltypes.Type, sqlmode SQLMode) error { switch { case v.IsNull(), sqltypes.IsNull(coerceTo): hash.Write16(hashPrefixNil) @@ -97,7 +97,7 @@ func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collat case v.IsText(), v.IsBinary(): f, _ = fastparse.ParseFloat64(v.RawStr()) default: - return nullsafeHashcode128Default(hash, v, collation, coerceTo) + return nullsafeHashcode128Default(hash, v, collation, coerceTo, sqlmode) } if err != nil { return err @@ -137,7 +137,7 @@ func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collat } neg = i < 0 default: - return nullsafeHashcode128Default(hash, v, collation, coerceTo) + return nullsafeHashcode128Default(hash, v, collation, coerceTo, sqlmode) } if err != nil { return err @@ -180,7 +180,7 @@ func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collat u, err = uint64(fval), nil } default: - return nullsafeHashcode128Default(hash, v, collation, coerceTo) + return nullsafeHashcode128Default(hash, v, collation, coerceTo, sqlmode) } if err != nil { return err @@ -223,20 +223,20 @@ func NullsafeHashcode128(hash *vthash.Hasher, v sqltypes.Value, collation collat fval, _ := fastparse.ParseFloat64(v.RawStr()) dec = decimal.NewFromFloat(fval) default: - return nullsafeHashcode128Default(hash, v, collation, coerceTo) + return nullsafeHashcode128Default(hash, v, collation, coerceTo, sqlmode) } hash.Write16(hashPrefixDecimal) dec.Hash(hash) default: - return nullsafeHashcode128Default(hash, v, collation, coerceTo) + return nullsafeHashcode128Default(hash, v, collation, coerceTo, sqlmode) } return nil } -func nullsafeHashcode128Default(hash *vthash.Hasher, v sqltypes.Value, collation collations.ID, coerceTo sqltypes.Type) error { +func nullsafeHashcode128Default(hash *vthash.Hasher, v sqltypes.Value, collation collations.ID, coerceTo sqltypes.Type, sqlmode SQLMode) error { // Slow path to handle all other types. This uses the generic // logic for value casting to ensure we match MySQL here. - e, err := valueToEvalCast(v, coerceTo, collation) + e, err := valueToEvalCast(v, coerceTo, collation, sqlmode) if err != nil { return err } diff --git a/go/vt/vtgate/evalengine/api_hash_test.go b/go/vt/vtgate/evalengine/api_hash_test.go index 0add16de89d..c1e5d880bdd 100644 --- a/go/vt/vtgate/evalengine/api_hash_test.go +++ b/go/vt/vtgate/evalengine/api_hash_test.go @@ -56,10 +56,10 @@ func TestHashCodes(t *testing.T) { require.NoError(t, err) require.Equalf(t, tc.equal, cmp == 0, "got %v %s %v (expected %s)", tc.static, equality(cmp == 0).Operator(), tc.dynamic, equality(tc.equal)) - h1, err := NullsafeHashcode(tc.static, collations.CollationUtf8mb4ID, tc.static.Type()) + h1, err := NullsafeHashcode(tc.static, collations.CollationUtf8mb4ID, tc.static.Type(), 0) require.NoError(t, err) - h2, err := NullsafeHashcode(tc.dynamic, collations.CollationUtf8mb4ID, tc.static.Type()) + h2, err := NullsafeHashcode(tc.dynamic, collations.CollationUtf8mb4ID, tc.static.Type(), 0) require.ErrorIs(t, err, tc.err) assert.Equalf(t, tc.equal, h1 == h2, "HASH(%v) %s HASH(%v) (expected %s)", tc.static, equality(h1 == h2).Operator(), tc.dynamic, equality(tc.equal)) @@ -82,9 +82,9 @@ func TestHashCodesRandom(t *testing.T) { typ, err := coerceTo(v1.Type(), v2.Type()) require.NoError(t, err) - hash1, err := NullsafeHashcode(v1, collation, typ) + hash1, err := NullsafeHashcode(v1, collation, typ, 0) require.NoError(t, err) - hash2, err := NullsafeHashcode(v2, collation, typ) + hash2, err := NullsafeHashcode(v2, collation, typ, 0) require.NoError(t, err) if cmp == 0 { equal++ @@ -142,11 +142,11 @@ func TestHashCodes128(t *testing.T) { require.Equalf(t, tc.equal, cmp == 0, "got %v %s %v (expected %s)", tc.static, equality(cmp == 0).Operator(), tc.dynamic, equality(tc.equal)) hasher1 := vthash.New() - err = NullsafeHashcode128(&hasher1, tc.static, collations.CollationUtf8mb4ID, tc.static.Type()) + err = NullsafeHashcode128(&hasher1, tc.static, collations.CollationUtf8mb4ID, tc.static.Type(), 0) require.NoError(t, err) hasher2 := vthash.New() - err = NullsafeHashcode128(&hasher2, tc.dynamic, collations.CollationUtf8mb4ID, tc.static.Type()) + err = NullsafeHashcode128(&hasher2, tc.dynamic, collations.CollationUtf8mb4ID, tc.static.Type(), 0) require.ErrorIs(t, err, tc.err) h1 := hasher1.Sum128() @@ -172,10 +172,10 @@ func TestHashCodesRandom128(t *testing.T) { require.NoError(t, err) hasher1 := vthash.New() - err = NullsafeHashcode128(&hasher1, v1, collation, typ) + err = NullsafeHashcode128(&hasher1, v1, collation, typ, 0) require.NoError(t, err) hasher2 := vthash.New() - err = NullsafeHashcode128(&hasher2, v2, collation, typ) + err = NullsafeHashcode128(&hasher2, v2, collation, typ, 0) require.NoError(t, err) if cmp == 0 { equal++ diff --git a/go/vt/vtgate/evalengine/compiler.go b/go/vt/vtgate/evalengine/compiler.go index e7d0e962fab..d757b3c3192 100644 --- a/go/vt/vtgate/evalengine/compiler.go +++ b/go/vt/vtgate/evalengine/compiler.go @@ -33,6 +33,7 @@ type compiler struct { collation collations.ID dynamicTypes []ctype asm assembler + sqlmode SQLMode } type CompilerLog interface { @@ -257,7 +258,7 @@ func (c *compiler) compileToDate(doct ctype, offset int) ctype { case sqltypes.Date: return doct default: - c.asm.Convert_xD(offset) + c.asm.Convert_xD(offset, c.sqlmode.AllowZeroDate()) } return ctype{Type: sqltypes.Date, Col: collationBinary, Flag: flagNullable} } @@ -268,7 +269,7 @@ func (c *compiler) compileToDateTime(doct ctype, offset, prec int) ctype { c.asm.Convert_tp(offset, prec) return doct default: - c.asm.Convert_xDT(offset, prec) + c.asm.Convert_xDT(offset, prec, c.sqlmode.AllowZeroDate()) } return ctype{Type: sqltypes.Datetime, Size: int32(prec), Col: collationBinary, Flag: flagNullable} } diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index 19d4c01a399..cbf9df9c57e 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -516,7 +516,7 @@ func (asm *assembler) Cmp_ne_n() { }, "CMPFLAG NE [NULL]") } -func (asm *assembler) CmpCase(cases int, hasElse bool, tt sqltypes.Type, cc collations.TypedCollation) { +func (asm *assembler) CmpCase(cases int, hasElse bool, tt sqltypes.Type, cc collations.TypedCollation, allowZeroDate bool) { elseOffset := 0 if hasElse { elseOffset = 1 @@ -529,12 +529,12 @@ func (asm *assembler) CmpCase(cases int, hasElse bool, tt sqltypes.Type, cc coll end := env.vm.sp - elseOffset for sp := env.vm.sp - stackDepth; sp < end; sp += 2 { if env.vm.stack[sp] != nil && env.vm.stack[sp].(*evalInt64).i != 0 { - env.vm.stack[env.vm.sp-stackDepth], env.vm.err = evalCoerce(env.vm.stack[sp+1], tt, cc.Collation, env.now) + env.vm.stack[env.vm.sp-stackDepth], env.vm.err = evalCoerce(env.vm.stack[sp+1], tt, cc.Collation, env.now, allowZeroDate) goto done } } if elseOffset != 0 { - env.vm.stack[env.vm.sp-stackDepth], env.vm.err = evalCoerce(env.vm.stack[env.vm.sp-1], tt, cc.Collation, env.now) + env.vm.stack[env.vm.sp-stackDepth], env.vm.err = evalCoerce(env.vm.stack[env.vm.sp-1], tt, cc.Collation, env.now, allowZeroDate) } else { env.vm.stack[env.vm.sp-stackDepth] = nil } @@ -1126,12 +1126,12 @@ func (asm *assembler) Convert_xu(offset int) { }, "CONV (SP-%d), UINT64", offset) } -func (asm *assembler) Convert_xD(offset int) { +func (asm *assembler) Convert_xD(offset int, allowZero bool) { asm.emit(func(env *ExpressionEnv) int { // Need to explicitly check here or we otherwise // store a nil wrapper in an interface vs. a direct // nil. - d := evalToDate(env.vm.stack[env.vm.sp-offset], env.now) + d := evalToDate(env.vm.stack[env.vm.sp-offset], env.now, allowZero) if d == nil { env.vm.stack[env.vm.sp-offset] = nil } else { @@ -1141,27 +1141,12 @@ func (asm *assembler) Convert_xD(offset int) { }, "CONV (SP-%d), DATE", offset) } -func (asm *assembler) Convert_xD_nz(offset int) { +func (asm *assembler) Convert_xDT(offset, prec int, allowZero bool) { asm.emit(func(env *ExpressionEnv) int { // Need to explicitly check here or we otherwise // store a nil wrapper in an interface vs. a direct // nil. - d := evalToDate(env.vm.stack[env.vm.sp-offset], env.now) - if d == nil || d.isZero() { - env.vm.stack[env.vm.sp-offset] = nil - } else { - env.vm.stack[env.vm.sp-offset] = d - } - return 1 - }, "CONV (SP-%d), DATE(NOZERO)", offset) -} - -func (asm *assembler) Convert_xDT(offset, prec int) { - asm.emit(func(env *ExpressionEnv) int { - // Need to explicitly check here or we otherwise - // store a nil wrapper in an interface vs. a direct - // nil. - dt := evalToDateTime(env.vm.stack[env.vm.sp-offset], prec, env.now) + dt := evalToDateTime(env.vm.stack[env.vm.sp-offset], prec, env.now, allowZero) if dt == nil { env.vm.stack[env.vm.sp-offset] = nil } else { @@ -1171,21 +1156,6 @@ func (asm *assembler) Convert_xDT(offset, prec int) { }, "CONV (SP-%d), DATETIME", offset) } -func (asm *assembler) Convert_xDT_nz(offset, prec int) { - asm.emit(func(env *ExpressionEnv) int { - // Need to explicitly check here or we otherwise - // store a nil wrapper in an interface vs. a direct - // nil. - dt := evalToDateTime(env.vm.stack[env.vm.sp-offset], prec, env.now) - if dt == nil || dt.isZero() { - env.vm.stack[env.vm.sp-offset] = nil - } else { - env.vm.stack[env.vm.sp-offset] = dt - } - return 1 - }, "CONV (SP-%d), DATETIME(NOZERO)", offset) -} - func (asm *assembler) Convert_xT(offset, prec int) { asm.emit(func(env *ExpressionEnv) int { t := evalToTime(env.vm.stack[env.vm.sp-offset], prec) @@ -4189,7 +4159,7 @@ func (asm *assembler) Fn_DATEADD_s(unit datetime.IntervalType, sub bool, col col goto baddate } - tmp = evalToTemporal(env.vm.stack[env.vm.sp-2]) + tmp = evalToTemporal(env.vm.stack[env.vm.sp-2], true) if tmp == nil { goto baddate } diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go index 77174a01d71..e7b51b41748 100644 --- a/go/vt/vtgate/evalengine/compiler_test.go +++ b/go/vt/vtgate/evalengine/compiler_test.go @@ -564,6 +564,14 @@ func TestCompilerSingle(t *testing.T) { expression: `case when null is null then 23 else null end`, result: `INT64(23)`, }, + { + expression: `CAST(0 AS DATE)`, + result: `NULL`, + }, + { + expression: `DAYOFMONTH(0)`, + result: `INT64(0)`, + }, } tz, _ := time.LoadLocation("Europe/Madrid") diff --git a/go/vt/vtgate/evalengine/eval.go b/go/vt/vtgate/evalengine/eval.go index 82f1ec688c7..33312cddc5f 100644 --- a/go/vt/vtgate/evalengine/eval.go +++ b/go/vt/vtgate/evalengine/eval.go @@ -176,7 +176,7 @@ func evalIsTruthy(e eval) boolean { } } -func evalCoerce(e eval, typ sqltypes.Type, col collations.ID, now time.Time) (eval, error) { +func evalCoerce(e eval, typ sqltypes.Type, col collations.ID, now time.Time, allowZero bool) (eval, error) { if e == nil { return nil, nil } @@ -208,9 +208,9 @@ func evalCoerce(e eval, typ sqltypes.Type, col collations.ID, now time.Time) (ev case sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint32, sqltypes.Uint64: return evalToInt64(e).toUint64(), nil case sqltypes.Date: - return evalToDate(e, now), nil + return evalToDate(e, now, allowZero), nil case sqltypes.Datetime, sqltypes.Timestamp: - return evalToDateTime(e, -1, now), nil + return evalToDateTime(e, -1, now, allowZero), nil case sqltypes.Time: return evalToTime(e, -1), nil default: @@ -218,7 +218,7 @@ func evalCoerce(e eval, typ sqltypes.Type, col collations.ID, now time.Time) (ev } } -func valueToEvalCast(v sqltypes.Value, typ sqltypes.Type, collation collations.ID) (eval, error) { +func valueToEvalCast(v sqltypes.Value, typ sqltypes.Type, collation collations.ID, sqlmode SQLMode) (eval, error) { switch { case typ == sqltypes.Null: return nil, nil @@ -338,7 +338,7 @@ func valueToEvalCast(v sqltypes.Value, typ sqltypes.Type, collation collations.I return nil, err } // Separate return here to avoid nil wrapped in interface type - d := evalToDate(e, time.Now()) + d := evalToDate(e, time.Now(), sqlmode.AllowZeroDate()) if d == nil { return nil, nil } @@ -349,7 +349,7 @@ func valueToEvalCast(v sqltypes.Value, typ sqltypes.Type, collation collations.I return nil, err } // Separate return here to avoid nil wrapped in interface type - dt := evalToDateTime(e, -1, time.Now()) + dt := evalToDateTime(e, -1, time.Now(), sqlmode.AllowZeroDate()) if dt == nil { return nil, nil } diff --git a/go/vt/vtgate/evalengine/eval_temporal.go b/go/vt/vtgate/evalengine/eval_temporal.go index d44839a6853..7952fc5aa5d 100644 --- a/go/vt/vtgate/evalengine/eval_temporal.go +++ b/go/vt/vtgate/evalengine/eval_temporal.go @@ -164,11 +164,17 @@ func (e *evalTemporal) addInterval(interval *datetime.Interval, coll collations. return tmp } -func newEvalDateTime(dt datetime.DateTime, l int) *evalTemporal { +func newEvalDateTime(dt datetime.DateTime, l int, allowZero bool) *evalTemporal { + if !allowZero && dt.IsZero() { + return nil + } return &evalTemporal{t: sqltypes.Datetime, dt: dt.Round(l), prec: uint8(l)} } -func newEvalDate(d datetime.Date) *evalTemporal { +func newEvalDate(d datetime.Date, allowZero bool) *evalTemporal { + if !allowZero && d.IsZero() { + return nil + } return &evalTemporal{t: sqltypes.Date, dt: datetime.DateTime{Date: d}} } @@ -185,7 +191,7 @@ func parseDate(s []byte) (*evalTemporal, error) { if !ok { return nil, errIncorrectTemporal("DATE", s) } - return newEvalDate(t), nil + return newEvalDate(t, true), nil } func parseDateTime(s []byte) (*evalTemporal, error) { @@ -193,7 +199,7 @@ func parseDateTime(s []byte) (*evalTemporal, error) { if !ok { return nil, errIncorrectTemporal("DATETIME", s) } - return newEvalDateTime(t, l), nil + return newEvalDateTime(t, l, true), nil } func parseTime(s []byte) (*evalTemporal, error) { @@ -211,56 +217,56 @@ func precision(req, got int) int { return req } -func evalToTemporal(e eval) *evalTemporal { +func evalToTemporal(e eval, allowZero bool) *evalTemporal { switch e := e.(type) { case *evalTemporal: return e case *evalBytes: if t, l, ok := datetime.ParseDateTime(e.string(), -1); ok { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, ok := datetime.ParseDate(e.string()); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } if t, l, ok := datetime.ParseTime(e.string(), -1); ok { return newEvalTime(t, l) } case *evalInt64: if t, ok := datetime.ParseDateTimeInt64(e.i); ok { - return newEvalDateTime(t, 0) + return newEvalDateTime(t, 0, allowZero) } if d, ok := datetime.ParseDateInt64(e.i); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } if t, ok := datetime.ParseTimeInt64(e.i); ok { return newEvalTime(t, 0) } case *evalUint64: if t, ok := datetime.ParseDateTimeInt64(int64(e.u)); ok { - return newEvalDateTime(t, 0) + return newEvalDateTime(t, 0, allowZero) } if d, ok := datetime.ParseDateInt64(int64(e.u)); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } if t, ok := datetime.ParseTimeInt64(int64(e.u)); ok { return newEvalTime(t, 0) } case *evalFloat: if t, l, ok := datetime.ParseDateTimeFloat(e.f, -1); ok { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, ok := datetime.ParseDateFloat(e.f); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } if t, l, ok := datetime.ParseTimeFloat(e.f, -1); ok { return newEvalTime(t, l) } case *evalDecimal: if t, l, ok := datetime.ParseDateTimeDecimal(e.dec, e.length, -1); ok { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, ok := datetime.ParseDateDecimal(e.dec); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } if d, l, ok := datetime.ParseTimeDecimal(e.dec, e.length, -1); ok { return newEvalTime(d, l) @@ -271,9 +277,9 @@ func evalToTemporal(e eval) *evalTemporal { return newEvalTime(dt.Time, datetime.DefaultPrecision) } if dt.Time.IsZero() { - return newEvalDate(dt.Date) + return newEvalDate(dt.Date, allowZero) } - return newEvalDateTime(dt, datetime.DefaultPrecision) + return newEvalDateTime(dt, datetime.DefaultPrecision, allowZero) } } return nil @@ -326,74 +332,74 @@ func evalToTime(e eval, l int) *evalTemporal { return nil } -func evalToDateTime(e eval, l int, now time.Time) *evalTemporal { +func evalToDateTime(e eval, l int, now time.Time, allowZero bool) *evalTemporal { switch e := e.(type) { case *evalTemporal: return e.toDateTime(precision(l, int(e.prec)), now) case *evalBytes: if t, l, _ := datetime.ParseDateTime(e.string(), l); !t.IsZero() { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, _ := datetime.ParseDate(e.string()); !d.IsZero() { - return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0)) + return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0), allowZero) } case *evalInt64: if t, ok := datetime.ParseDateTimeInt64(e.i); ok { - return newEvalDateTime(t, precision(l, 0)) + return newEvalDateTime(t, precision(l, 0), allowZero) } if d, ok := datetime.ParseDateInt64(e.i); ok { - return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0)) + return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0), allowZero) } case *evalUint64: if t, ok := datetime.ParseDateTimeInt64(int64(e.u)); ok { - return newEvalDateTime(t, precision(l, 0)) + return newEvalDateTime(t, precision(l, 0), allowZero) } if d, ok := datetime.ParseDateInt64(int64(e.u)); ok { - return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0)) + return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0), allowZero) } case *evalFloat: if t, l, ok := datetime.ParseDateTimeFloat(e.f, l); ok { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, ok := datetime.ParseDateFloat(e.f); ok { - return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0)) + return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0), allowZero) } case *evalDecimal: if t, l, ok := datetime.ParseDateTimeDecimal(e.dec, e.length, l); ok { - return newEvalDateTime(t, l) + return newEvalDateTime(t, l, allowZero) } if d, ok := datetime.ParseDateDecimal(e.dec); ok { - return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0)) + return newEvalDateTime(datetime.DateTime{Date: d}, precision(l, 0), allowZero) } case *evalJSON: if dt, ok := e.DateTime(); ok { - return newEvalDateTime(dt, precision(l, datetime.DefaultPrecision)) + return newEvalDateTime(dt, precision(l, datetime.DefaultPrecision), allowZero) } } return nil } -func evalToDate(e eval, now time.Time) *evalTemporal { +func evalToDate(e eval, now time.Time, allowZero bool) *evalTemporal { switch e := e.(type) { case *evalTemporal: return e.toDate(now) case *evalBytes: if t, _ := datetime.ParseDate(e.string()); !t.IsZero() { - return newEvalDate(t) + return newEvalDate(t, allowZero) } if dt, _, _ := datetime.ParseDateTime(e.string(), -1); !dt.IsZero() { - return newEvalDate(dt.Date) + return newEvalDate(dt.Date, allowZero) } case evalNumeric: if t, ok := datetime.ParseDateInt64(e.toInt64().i); ok { - return newEvalDate(t) + return newEvalDate(t, allowZero) } if dt, ok := datetime.ParseDateTimeInt64(e.toInt64().i); ok { - return newEvalDate(dt.Date) + return newEvalDate(dt.Date, allowZero) } case *evalJSON: if d, ok := e.Date(); ok { - return newEvalDate(d) + return newEvalDate(d, allowZero) } } return nil diff --git a/go/vt/vtgate/evalengine/expr_convert.go b/go/vt/vtgate/evalengine/expr_convert.go index 900d4e37f8f..5b2d82b707f 100644 --- a/go/vt/vtgate/evalengine/expr_convert.go +++ b/go/vt/vtgate/evalengine/expr_convert.go @@ -124,12 +124,12 @@ func (c *ConvertExpr) eval(env *ExpressionEnv) (eval, error) { case p > 6: return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Too-big precision %d specified for 'CONVERT'. Maximum is 6.", p) } - if dt := evalToDateTime(e, c.Length, env.now); dt != nil { + if dt := evalToDateTime(e, c.Length, env.now, env.sqlmode.AllowZeroDate()); dt != nil { return dt, nil } return nil, nil case "DATE": - if d := evalToDate(e, env.now); d != nil { + if d := evalToDate(e, env.now, env.sqlmode.AllowZeroDate()); d != nil { return d, nil } return nil, nil diff --git a/go/vt/vtgate/evalengine/expr_env.go b/go/vt/vtgate/evalengine/expr_env.go index a6ca1411e74..1c92b0a45ee 100644 --- a/go/vt/vtgate/evalengine/expr_env.go +++ b/go/vt/vtgate/evalengine/expr_env.go @@ -30,6 +30,7 @@ import ( type VCursor interface { TimeZone() *time.Location GetKeyspace() string + SQLMode() string } type ( @@ -43,9 +44,10 @@ type ( Fields []*querypb.Field // internal state - now time.Time - vc VCursor - user *querypb.VTGateCallerID + now time.Time + vc VCursor + user *querypb.VTGateCallerID + sqlmode SQLMode } ) @@ -121,5 +123,32 @@ func NewExpressionEnv(ctx context.Context, bindVars map[string]*querypb.BindVari env := &ExpressionEnv{BindVars: bindVars, vc: vc} env.user = callerid.ImmediateCallerIDFromContext(ctx) env.SetTime(time.Now()) + if vc != nil { + env.sqlmode = ParseSQLMode(vc.SQLMode()) + } return env } + +const ( + sqlModeParsed = 1 << iota + sqlModeNoZeroDate +) + +type SQLMode uint32 + +func (mode SQLMode) AllowZeroDate() bool { + if mode == 0 { + // default: do not allow zero-date if the sqlmode is not set + return false + } + return (mode & sqlModeNoZeroDate) == 0 +} + +func ParseSQLMode(sqlmode string) SQLMode { + var mode SQLMode + if strings.Contains(sqlmode, "NO_ZERO_DATE") { + mode |= sqlModeNoZeroDate + } + mode |= sqlModeParsed + return mode +} diff --git a/go/vt/vtgate/evalengine/expr_logical.go b/go/vt/vtgate/evalengine/expr_logical.go index f22ca091acb..7fe836d7164 100644 --- a/go/vt/vtgate/evalengine/expr_logical.go +++ b/go/vt/vtgate/evalengine/expr_logical.go @@ -633,7 +633,7 @@ func (c *CaseExpr) eval(env *ExpressionEnv) (eval, error) { if !matched { return nil, nil } - return evalCoerce(result, ta.result(), ca.result().Collation, env.now) + return evalCoerce(result, ta.result(), ca.result().Collation, env.now, env.sqlmode.AllowZeroDate()) } func (c *CaseExpr) constant() bool { @@ -716,7 +716,7 @@ func (cs *CaseExpr) compile(c *compiler) (ctype, error) { f |= flagNullable } ct := ctype{Type: ta.result(), Flag: f, Col: ca.result()} - c.asm.CmpCase(len(cs.cases), cs.Else != nil, ct.Type, ct.Col) + c.asm.CmpCase(len(cs.cases), cs.Else != nil, ct.Type, ct.Col, c.sqlmode.AllowZeroDate()) return ct, nil } diff --git a/go/vt/vtgate/evalengine/fn_time.go b/go/vt/vtgate/evalengine/fn_time.go index b0e7366ce8f..49a328a852f 100644 --- a/go/vt/vtgate/evalengine/fn_time.go +++ b/go/vt/vtgate/evalengine/fn_time.go @@ -266,7 +266,7 @@ func (b *builtinDateFormat) eval(env *ExpressionEnv) (eval, error) { case *evalTemporal: t = e.toDateTime(datetime.DefaultPrecision, env.now) default: - t = evalToDateTime(date, datetime.DefaultPrecision, env.now) + t = evalToDateTime(date, datetime.DefaultPrecision, env.now, env.sqlmode.AllowZeroDate()) if t == nil || t.isZero() { return nil, nil } @@ -291,7 +291,7 @@ func (call *builtinDateFormat) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Datetime, sqltypes.Date: default: - c.asm.Convert_xDT_nz(1, datetime.DefaultPrecision) + c.asm.Convert_xDT(1, datetime.DefaultPrecision, false) } format, err := call.Arguments[1].compile(c) @@ -359,7 +359,7 @@ func (call *builtinConvertTz) eval(env *ExpressionEnv) (eval, error) { return nil, nil } - dt := evalToDateTime(n, -1, env.now) + dt := evalToDateTime(n, -1, env.now, env.sqlmode.AllowZeroDate()) if dt == nil || dt.isZero() { return nil, nil } @@ -368,7 +368,7 @@ func (call *builtinConvertTz) eval(env *ExpressionEnv) (eval, error) { if !ok { return nil, nil } - return newEvalDateTime(out, int(dt.prec)), nil + return newEvalDateTime(out, int(dt.prec), env.sqlmode.AllowZeroDate()), nil } func (call *builtinConvertTz) compile(c *compiler) (ctype, error) { @@ -402,7 +402,7 @@ func (call *builtinConvertTz) compile(c *compiler) (ctype, error) { switch n.Type { case sqltypes.Datetime, sqltypes.Date: default: - c.asm.Convert_xDT_nz(3, -1) + c.asm.Convert_xDT(3, -1, false) } c.asm.Fn_CONVERT_TZ() @@ -418,7 +418,7 @@ func (b *builtinDate) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil { return nil, nil } @@ -436,7 +436,7 @@ func (call *builtinDate) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, c.sqlmode.AllowZeroDate()) } c.asm.jumpDestination(skip) @@ -451,7 +451,7 @@ func (b *builtinDayOfMonth) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, true) if d == nil { return nil, nil } @@ -469,7 +469,7 @@ func (call *builtinDayOfMonth) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, true) } c.asm.Fn_DAYOFMONTH() c.asm.jumpDestination(skip) @@ -484,7 +484,7 @@ func (b *builtinDayOfWeek) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -502,7 +502,7 @@ func (call *builtinDayOfWeek) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } c.asm.Fn_DAYOFWEEK() c.asm.jumpDestination(skip) @@ -517,7 +517,7 @@ func (b *builtinDayOfYear) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -535,7 +535,7 @@ func (call *builtinDayOfYear) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } c.asm.Fn_DAYOFYEAR() c.asm.jumpDestination(skip) @@ -610,7 +610,7 @@ func (b *builtinFromUnixtime) eval(env *ExpressionEnv) (eval, error) { t = t.In(tz) } - dt := newEvalDateTime(datetime.NewDateTimeFromStd(t), prec) + dt := newEvalDateTime(datetime.NewDateTimeFromStd(t), prec, env.sqlmode.AllowZeroDate()) if len(b.Arguments) == 1 { return dt, nil @@ -761,7 +761,7 @@ func (b *builtinMakedate) eval(env *ExpressionEnv) (eval, error) { if t.IsZero() { return nil, nil } - return newEvalDate(datetime.NewDateTimeFromStd(t).Date), nil + return newEvalDate(datetime.NewDateTimeFromStd(t).Date, env.sqlmode.AllowZeroDate()), nil } func (call *builtinMakedate) compile(c *compiler) (ctype, error) { @@ -1102,7 +1102,7 @@ func (b *builtinMonth) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, true) if d == nil { return nil, nil } @@ -1120,7 +1120,7 @@ func (call *builtinMonth) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, true) } c.asm.Fn_MONTH() c.asm.jumpDestination(skip) @@ -1135,7 +1135,7 @@ func (b *builtinMonthName) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil { return nil, nil } @@ -1158,7 +1158,7 @@ func (call *builtinMonthName) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, c.sqlmode.AllowZeroDate()) } col := typedCoercionCollation(sqltypes.VarChar, call.collate) c.asm.Fn_MONTHNAME(col) @@ -1174,7 +1174,7 @@ func (b *builtinQuarter) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, true) if d == nil { return nil, nil } @@ -1192,7 +1192,7 @@ func (call *builtinQuarter) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, true) } c.asm.Fn_QUARTER() c.asm.jumpDestination(skip) @@ -1270,7 +1270,7 @@ func dateTimeUnixTimestamp(env *ExpressionEnv, date eval) evalNumeric { case *evalTemporal: dt = e.toDateTime(int(e.prec), env.now) default: - dt = evalToDateTime(date, -1, env.now) + dt = evalToDateTime(date, -1, env.now, env.sqlmode.AllowZeroDate()) if dt == nil || dt.isZero() { var prec int32 switch d := date.(type) { @@ -1351,7 +1351,7 @@ func (call *builtinUnixTimestamp) compile(c *compiler) (ctype, error) { return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil } if lit, ok := call.Arguments[0].(*Literal); ok { - if dt := evalToDateTime(lit.inner, -1, time.Now()); dt != nil { + if dt := evalToDateTime(lit.inner, -1, time.Now(), c.sqlmode.AllowZeroDate()); dt != nil { if dt.prec == 0 { return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: arg.Flag}, nil } @@ -1373,7 +1373,7 @@ func (b *builtinWeek) eval(env *ExpressionEnv) (eval, error) { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -1406,7 +1406,7 @@ func (call *builtinWeek) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } if len(call.Arguments) == 1 { @@ -1433,7 +1433,7 @@ func (b *builtinWeekDay) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -1451,7 +1451,7 @@ func (call *builtinWeekDay) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } c.asm.Fn_WEEKDAY() @@ -1467,7 +1467,7 @@ func (b *builtinWeekOfYear) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -1487,7 +1487,7 @@ func (call *builtinWeekOfYear) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } c.asm.Fn_WEEKOFYEAR() @@ -1503,7 +1503,7 @@ func (b *builtinYear) eval(env *ExpressionEnv) (eval, error) { if date == nil { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, true) if d == nil { return nil, nil } @@ -1522,7 +1522,7 @@ func (call *builtinYear) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD(1) + c.asm.Convert_xD(1, true) } c.asm.Fn_YEAR() @@ -1539,7 +1539,7 @@ func (b *builtinYearWeek) eval(env *ExpressionEnv) (eval, error) { return nil, nil } - d := evalToDate(date, env.now) + d := evalToDate(date, env.now, env.sqlmode.AllowZeroDate()) if d == nil || d.isZero() { return nil, nil } @@ -1572,7 +1572,7 @@ func (call *builtinYearWeek) compile(c *compiler) (ctype, error) { switch arg.Type { case sqltypes.Date, sqltypes.Datetime: default: - c.asm.Convert_xD_nz(1) + c.asm.Convert_xD(1, false) } if len(call.Arguments) == 1 { @@ -1624,7 +1624,7 @@ func (call *builtinDateMath) eval(env *ExpressionEnv) (eval, error) { return tmp.addInterval(interval, collations.Unknown, env.now), nil } - if tmp := evalToTemporal(date); tmp != nil { + if tmp := evalToTemporal(date, env.sqlmode.AllowZeroDate()); tmp != nil { return tmp.addInterval(interval, call.collate, env.now), nil } diff --git a/go/vt/vtgate/evalengine/integration/comparison_test.go b/go/vt/vtgate/evalengine/integration/comparison_test.go index 649dc7b5583..44c02b2a5a5 100644 --- a/go/vt/vtgate/evalengine/integration/comparison_test.go +++ b/go/vt/vtgate/evalengine/integration/comparison_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/mysql/format" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" @@ -215,6 +216,10 @@ func (vc *vcursor) TimeZone() *time.Location { return time.Local } +func (vc *vcursor) SQLMode() string { + return config.DefaultSQLMode +} + func initTimezoneData(t *testing.T, conn *mysql.Conn) { // We load the timezone information into MySQL. The evalengine assumes // our backend MySQL is configured with the timezone information as well diff --git a/go/vt/vtgate/evalengine/translate.go b/go/vt/vtgate/evalengine/translate.go index 7993854db36..ea38f116de2 100644 --- a/go/vt/vtgate/evalengine/translate.go +++ b/go/vt/vtgate/evalengine/translate.go @@ -569,6 +569,7 @@ type Config struct { Collation collations.ID NoConstantFolding bool NoCompilation bool + SQLMode SQLMode } func Translate(e sqlparser.Expr, cfg *Config) (Expr, error) { @@ -603,7 +604,7 @@ func Translate(e sqlparser.Expr, cfg *Config) (Expr, error) { } if len(ast.untyped) == 0 && !cfg.NoCompilation { - comp := compiler{collation: cfg.Collation} + comp := compiler{collation: cfg.Collation, sqlmode: cfg.SQLMode} return comp.compile(expr) } @@ -626,9 +627,9 @@ type typedExpr struct { err error } -func (typed *typedExpr) compile(expr IR, collation collations.ID) (*CompiledExpr, error) { +func (typed *typedExpr) compile(expr IR, collation collations.ID, sqlmode SQLMode) (*CompiledExpr, error) { typed.once.Do(func() { - comp := compiler{collation: collation, dynamicTypes: typed.types} + comp := compiler{collation: collation, dynamicTypes: typed.types, sqlmode: sqlmode} typed.compiled, typed.err = comp.compile(expr) }) return typed.compiled, typed.err @@ -695,7 +696,7 @@ func (u *UntypedExpr) Compile(env *ExpressionEnv) (*CompiledExpr, error) { if err != nil { return nil, err } - return typed.compile(u.ir, u.collation) + return typed.compile(u.ir, u.collation, env.sqlmode) } func (u *UntypedExpr) typeof(env *ExpressionEnv) (ctype, error) { diff --git a/go/vt/vtgate/evalengine/weights.go b/go/vt/vtgate/evalengine/weights.go index fa7fa7e11a6..2a9d6c9f93e 100644 --- a/go/vt/vtgate/evalengine/weights.go +++ b/go/vt/vtgate/evalengine/weights.go @@ -41,11 +41,11 @@ import ( // externally communicates with the `WEIGHT_STRING` function, so that we // can also use this to order / sort other types like Float and Decimal // as well. -func WeightString(dst []byte, v sqltypes.Value, coerceTo sqltypes.Type, col collations.ID, length, precision int) ([]byte, bool, error) { +func WeightString(dst []byte, v sqltypes.Value, coerceTo sqltypes.Type, col collations.ID, length, precision int, sqlmode SQLMode) ([]byte, bool, error) { // We optimize here for the case where we already have the desired type. // Otherwise, we fall back to the general evalengine conversion logic. if v.Type() != coerceTo { - return fallbackWeightString(dst, v, coerceTo, col, length, precision) + return fallbackWeightString(dst, v, coerceTo, col, length, precision, sqlmode) } switch { @@ -117,12 +117,12 @@ func WeightString(dst []byte, v sqltypes.Value, coerceTo sqltypes.Type, col coll } return j.WeightString(dst), false, nil default: - return fallbackWeightString(dst, v, coerceTo, col, length, precision) + return fallbackWeightString(dst, v, coerceTo, col, length, precision, sqlmode) } } -func fallbackWeightString(dst []byte, v sqltypes.Value, coerceTo sqltypes.Type, col collations.ID, length, precision int) ([]byte, bool, error) { - e, err := valueToEvalCast(v, coerceTo, col) +func fallbackWeightString(dst []byte, v sqltypes.Value, coerceTo sqltypes.Type, col collations.ID, length, precision int, sqlmode SQLMode) ([]byte, bool, error) { + e, err := valueToEvalCast(v, coerceTo, col, sqlmode) if err != nil { return dst, false, err } diff --git a/go/vt/vtgate/evalengine/weights_test.go b/go/vt/vtgate/evalengine/weights_test.go index 0dee4c72d03..7e43315f7df 100644 --- a/go/vt/vtgate/evalengine/weights_test.go +++ b/go/vt/vtgate/evalengine/weights_test.go @@ -136,7 +136,7 @@ func TestWeightStrings(t *testing.T) { items := make([]item, 0, Length) for i := 0; i < Length; i++ { v := tc.gen() - w, _, err := WeightString(nil, v, typ, tc.col, tc.len, tc.prec) + w, _, err := WeightString(nil, v, typ, tc.col, tc.len, tc.prec, 0) require.NoError(t, err) items = append(items, item{value: v, weight: string(w)}) @@ -156,9 +156,9 @@ func TestWeightStrings(t *testing.T) { a := items[i] b := items[i+1] - v1, err := valueToEvalCast(a.value, typ, tc.col) + v1, err := valueToEvalCast(a.value, typ, tc.col, 0) require.NoError(t, err) - v2, err := valueToEvalCast(b.value, typ, tc.col) + v2, err := valueToEvalCast(b.value, typ, tc.col, 0) require.NoError(t, err) cmp, err := evalCompareNullSafe(v1, v2) diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 9ec4bb0dc03..db678d56354 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -27,10 +27,9 @@ import ( "github.com/google/uuid" - "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/vt/sysvars" - "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/mysql/config" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/discovery" @@ -44,6 +43,7 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/topo" topoprotopb "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" @@ -211,6 +211,12 @@ func (vc *vcursorImpl) TimeZone() *time.Location { return vc.safeSession.TimeZone() } +func (vc *vcursorImpl) SQLMode() string { + // TODO: Implement return the current sql_mode. + // This is currently hardcoded to the default in MySQL 8.0. + return config.DefaultSQLMode +} + // MaxMemoryRows returns the maxMemoryRows flag value. func (vc *vcursorImpl) MaxMemoryRows() int { return maxMemoryRows diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 576ce4c22a8..ee1a1dbc06c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -29,6 +29,7 @@ import ( "time" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/vttablet" "vitess.io/vitess/go/test/utils" @@ -225,6 +226,15 @@ func execStatements(t *testing.T, queries []string) { } } +func execConnStatements(t *testing.T, conn *dbconnpool.DBConnection, queries []string) { + t.Helper() + for _, query := range queries { + if _, err := conn.ExecuteFetch(query, 10000, false); err != nil { + t.Fatalf("ExecuteFetch(%v) failed: %v", query, err) + } + } +} + //-------------------------------------- // Topos and tablets diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index b960635ff11..0e35036321f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -1676,22 +1676,26 @@ func TestCopyTablesWithInvalidDates(t *testing.T) { func testCopyTablesWithInvalidDates(t *testing.T) { defer deleteTablet(addTablet(100)) - execStatements(t, []string{ - "create table src1(id int, dt date, primary key(id))", - fmt.Sprintf("create table %s.dst1(id int, dt date, primary key(id))", vrepldb), - "insert into src1 values(1, '2020-01-12'), (2, '0000-00-00');", - }) + conn, err := env.Mysqld.GetDbaConnection(context.Background()) + require.NoError(t, err) // default mysql flavor allows invalid dates: so disallow explicitly for this test - if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "SET @@global.sql_mode=REPLACE(REPLACE(@@session.sql_mode, 'NO_ZERO_DATE', ''), 'NO_ZERO_IN_DATE', '')"); err != nil { + if _, err := conn.ExecuteFetch("SET @@session.sql_mode=REPLACE(REPLACE(@@session.sql_mode, 'NO_ZERO_DATE', ''), 'NO_ZERO_IN_DATE', '')", 0, false); err != nil { fmt.Fprintf(os.Stderr, "%v", err) } defer func() { - if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "SET @@global.sql_mode=REPLACE(@@global.sql_mode, ',NO_ZERO_DATE,NO_ZERO_IN_DATE','')"); err != nil { + if _, err := conn.ExecuteFetch("SET @@session.sql_mode=REPLACE(@@session.sql_mode, ',NO_ZERO_DATE,NO_ZERO_IN_DATE','')", 0, false); err != nil { fmt.Fprintf(os.Stderr, "%v", err) } }() - defer execStatements(t, []string{ + + execConnStatements(t, conn, []string{ + "create table src1(id int, dt date, primary key(id))", + fmt.Sprintf("create table %s.dst1(id int, dt date, primary key(id))", vrepldb), + "insert into src1 values(1, '2020-01-12'), (2, '0000-00-00');", + }) + + defer execConnStatements(t, conn, []string{ "drop table src1", fmt.Sprintf("drop table %s.dst1", vrepldb), }) From 46d1c010107bb1fda7a556599acd5be37f8a009c Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:49:59 +0530 Subject: [PATCH 051/119] Add summary changes for recent PRs (#14598) --- changelog/19.0/19.0.0/summary.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index be560d50f58..5580bc6e6f5 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -7,6 +7,8 @@ - [VTTablet Flags](#vttablet-flags) - **[Docker](#docker)** - [New MySQL Image](#mysql-image) + - **[VTGate](#vtgate)** + - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) - **[Query Compatibility](#query-compatibility)** - [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces) @@ -31,6 +33,12 @@ This lightweight image is a replacement of `vitess/lite` to only run `mysqld`. Several tags are available to let you choose what version of MySQL you want to use: `vitess/mysql:8.0.30`, `vitess/mysql:8.0.34`. +### VTGate + +#### `FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable + +When VTGate receives a query to change the `FOREIGN_KEY_CHECKS` value for a session, instead of sending the value down to MySQL, VTGate now keeps track of the value and changes the queries by adding `SET_VAR(FOREIGN_KEY_CHECKS=On/Off)` style query optimizer hints wherever required. + ### Query Compatibility #### `SHOW VSCHEMA KEYSPACES` Query @@ -42,11 +50,11 @@ error in the VSchema for the keyspace. An example output of the query looks like - ```sql mysql> show vschema keyspaces; -+---------------+---------+------------------+-------+ -| Keyspace Name | Sharded | Foreign Key Mode | Error | -+---------------+---------+------------------+-------+ -| uks | false | managed | | -| ks | true | managed | | -+---------------+---------+------------------+-------+ -2 rows in set (0.00 sec) ++----------+---------+-------------+---------+ +| Keyspace | Sharded | Foreign Key | Comment | ++----------+---------+-------------+---------+ +| ks | true | managed | | +| uks | false | managed | | ++----------+---------+-------------+---------+ +2 rows in set (0.01 sec) ``` From 79ece46fcfb25c4028c43701d9262bda8dfb119f Mon Sep 17 00:00:00 2001 From: Pedro Kaj Kjellerup Nacht Date: Mon, 27 Nov 2023 12:39:34 -0300 Subject: [PATCH 052/119] Set minimal tokens for auto_approve_pr (#14534) Signed-off-by: Pedro Kaj Kjellerup Nacht --- .github/workflows/auto_approve_pr.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto_approve_pr.yml b/.github/workflows/auto_approve_pr.yml index 552f1ec2e68..115e648c3d2 100644 --- a/.github/workflows/auto_approve_pr.yml +++ b/.github/workflows/auto_approve_pr.yml @@ -3,14 +3,20 @@ on: pull_request: types: [opened, reopened] +permissions: + contents: read + jobs: auto_approve: name: Auto Approve Pull Request runs-on: ubuntu-latest + + permissions: + pull-requests: write # only given on local PRs, forks run with `read` access + steps: - name: Checkout code uses: actions/checkout@v3 - - name: Auto Approve Pull Request env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 0dac1b696bfe18bc1616735e218f9f402874b864 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:19:07 -0600 Subject: [PATCH 053/119] Support unlimited number of ORs in `ExtractINFromOR` (#14566) Signed-off-by: Florent Poinsard --- go/vt/sqlparser/predicate_rewriting.go | 140 ++++++++++++++++---- go/vt/sqlparser/predicate_rewriting_test.go | 35 +++-- 2 files changed, 133 insertions(+), 42 deletions(-) diff --git a/go/vt/sqlparser/predicate_rewriting.go b/go/vt/sqlparser/predicate_rewriting.go index 7bad1b3b82f..234a2f4acd5 100644 --- a/go/vt/sqlparser/predicate_rewriting.go +++ b/go/vt/sqlparser/predicate_rewriting.go @@ -16,6 +16,8 @@ limitations under the License. package sqlparser +import "slices" + // RewritePredicate walks the input AST and rewrites any boolean logic into a simpler form // This simpler form is CNF plus logic for extracting predicates from OR, plus logic for turning ORs into IN func RewritePredicate(ast SQLNode) SQLNode { @@ -204,36 +206,128 @@ func simplifyAnd(expr *AndExpr) (Expr, bool) { return expr, false } -// ExtractINFromOR will add additional predicated to an OR. -// this rewriter should not be used in a fixed point way, since it returns the original expression with additions, -// and it will therefor OOM before it stops rewriting +// ExtractINFromOR rewrites the OR expression into an IN clause. +// Each side of each ORs has to be an equality comparison expression and the column names have to +// match for all sides of each comparison. +// This rewriter takes a query that looks like this WHERE a = 1 and b = 11 or a = 2 and b = 12 or a = 3 and b = 13 +// And rewrite that to WHERE (a, b) IN ((1,11), (2,12), (3,13)) func ExtractINFromOR(expr *OrExpr) []Expr { - // we check if we have two comparisons on either side of the OR - // that we can add as an ANDed comparison. - // WHERE (a = 5 and B) or (a = 6 AND C) => - // WHERE (a = 5 AND B) OR (a = 6 AND C) AND a IN (5,6) - // This rewrite makes it possible to find a better route than Scatter if the `a` column has a helpful vindex - lftPredicates := SplitAndExpression(nil, expr.Left) - rgtPredicates := SplitAndExpression(nil, expr.Right) - var ins []Expr - for _, lft := range lftPredicates { - l, ok := lft.(*ComparisonExpr) - if !ok { - continue + var varNames []*ColName + var values []Exprs + orSlice := orToSlice(expr) + for _, expr := range orSlice { + andSlice := andToSlice(expr) + if len(andSlice) == 0 { + return nil } - for _, rgt := range rgtPredicates { - r, ok := rgt.(*ComparisonExpr) - if !ok { - continue + + var currentVarNames []*ColName + var currentValues []Expr + for _, comparisonExpr := range andSlice { + if comparisonExpr.Operator != EqualOp { + return nil } - in, changed := tryTurningOrIntoIn(l, r) - if changed { - ins = append(ins, in) + + var colName *ColName + if left, ok := comparisonExpr.Left.(*ColName); ok { + colName = left + currentValues = append(currentValues, comparisonExpr.Right) + } + + if right, ok := comparisonExpr.Right.(*ColName); ok { + if colName != nil { + return nil + } + colName = right + currentValues = append(currentValues, comparisonExpr.Left) + } + + if colName == nil { + return nil } + + currentVarNames = append(currentVarNames, colName) + } + + if len(varNames) == 0 { + varNames = currentVarNames + } else if !slices.EqualFunc(varNames, currentVarNames, func(col1, col2 *ColName) bool { return col1.Equal(col2) }) { + return nil } + + values = append(values, currentValues) + } + + var nameTuple ValTuple + for _, name := range varNames { + nameTuple = append(nameTuple, name) + } + + var valueTuple ValTuple + for _, value := range values { + valueTuple = append(valueTuple, ValTuple(value)) + } + + return []Expr{&ComparisonExpr{ + Operator: InOp, + Left: nameTuple, + Right: valueTuple, + }} +} + +func orToSlice(expr *OrExpr) []Expr { + var exprs []Expr + + handleOrSide := func(e Expr) { + switch e := e.(type) { + case *OrExpr: + exprs = append(exprs, orToSlice(e)...) + default: + exprs = append(exprs, e) + } + } + + handleOrSide(expr.Left) + handleOrSide(expr.Right) + return exprs +} + +func andToSlice(expr Expr) []*ComparisonExpr { + var andExpr *AndExpr + switch expr := expr.(type) { + case *AndExpr: + andExpr = expr + case *ComparisonExpr: + return []*ComparisonExpr{expr} + default: + return nil + } + + var exprs []*ComparisonExpr + handleAndSide := func(e Expr) bool { + switch e := e.(type) { + case *AndExpr: + slice := andToSlice(e) + if slice == nil { + return false + } + exprs = append(exprs, slice...) + case *ComparisonExpr: + exprs = append(exprs, e) + default: + return false + } + return true + } + + if !handleAndSide(andExpr.Left) { + return nil + } + if !handleAndSide(andExpr.Right) { + return nil } - return uniquefy(ins) + return exprs } func tryTurningOrIntoIn(l, r *ComparisonExpr) (Expr, bool) { diff --git a/go/vt/sqlparser/predicate_rewriting_test.go b/go/vt/sqlparser/predicate_rewriting_test.go index e106a56f1aa..a4bbb5f7b5c 100644 --- a/go/vt/sqlparser/predicate_rewriting_test.go +++ b/go/vt/sqlparser/predicate_rewriting_test.go @@ -140,6 +140,18 @@ func TestRewritePredicate(in *testing.T) { // the following two tests show some pathological cases that would grow too much, and so we abort the rewriting in: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", expected: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", + }, { + in: "a = 5 and B or a = 6 and C", + expected: "a in (5, 6) and (a = 5 or C) and ((B or a = 6) and (B or C))", + }, { + in: "(a = 5 and b = 1 or b = 2 and a = 6)", + expected: "(a = 5 or b = 2) and a in (5, 6) and (b in (1, 2) and (b = 1 or a = 6))", + }, { + in: "(a in (1,5) and B or C and a = 6)", + expected: "(a in (1, 5) or C) and a in (1, 5, 6) and ((B or C) and (B or a = 6))", + }, { + in: "(a in (1, 5) and B or C and a in (5, 7))", + expected: "(a in (1, 5) or C) and a in (1, 5, 7) and ((B or C) and (B or a in (5, 7)))", }, { in: "not n0 xor not (n2 and n3) xor (not n2 and (n1 xor n1) xor (n0 xor n0 xor n2))", expected: "not n0 xor not (n2 and n3) xor (not n2 and (n1 xor n1) xor (n0 xor n0 xor n2))", @@ -161,26 +173,11 @@ func TestExtractINFromOR(in *testing.T) { in string expected string }{{ - in: "(A and B) or (B and A)", - expected: "", - }, { - in: "(a = 5 and B) or A", - expected: "", - }, { - in: "a = 5 and B or a = 6 and C", - expected: "a in (5, 6)", - }, { - in: "(a = 5 and b = 1 or b = 2 and a = 6)", - expected: "a in (5, 6) and b in (1, 2)", - }, { - in: "(a in (1,5) and B or C and a = 6)", - expected: "a in (1, 5, 6)", - }, { - in: "(a in (1, 5) and B or C and a in (5, 7))", - expected: "a in (1, 5, 7)", + in: "a = 1 and b = 41 or a = 2 and b = 42 or a = 3 and b = 43 or a = 4 and b = 44 or a = 5 and b = 45 or a = 6 and b = 46", + expected: "(a, b) in ((1, 41), (2, 42), (3, 43), (4, 44), (5, 45), (6, 46))", }, { - in: "(a = 5 and b = 1 or b = 2 and a = 6 or b = 3 and a = 4)", - expected: "", + in: "a = 1 or a = 2 or a = 3 or a = 4 or a = 5 or a = 6", + expected: "(a) in ((1), (2), (3), (4), (5), (6))", }} for _, tc := range tests { From 7fd0930fcac0c45c6186c9226c89f8552f38798c Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Mon, 27 Nov 2023 16:02:39 -0500 Subject: [PATCH 054/119] remove deprecated flags from the codebase (#14544) Signed-off-by: Andrew Mason --- go/cmd/vtctldclient/command/schema.go | 2 -- go/flags/endtoend/vtbench.txt | 6 +++--- go/flags/endtoend/vtclient.txt | 6 +++--- .../onlineddl/revert/onlineddl_revert_test.go | 8 -------- .../tabletgateway/buffer/buffer_test_helpers.go | 1 - go/vt/vtctl/vtctl.go | 1 - go/vt/vtgate/tabletgateway.go | 3 --- go/vt/vtgate/vtgate.go | 10 +--------- go/vt/vttablet/tabletserver/tabletenv/config.go | 6 ------ go/vt/vttablet/tabletserver/throttle/throttler.go | 12 ------------ 10 files changed, 7 insertions(+), 48 deletions(-) diff --git a/go/cmd/vtctldclient/command/schema.go b/go/cmd/vtctldclient/command/schema.go index 795b1315e89..2d31e3500c1 100644 --- a/go/cmd/vtctldclient/command/schema.go +++ b/go/cmd/vtctldclient/command/schema.go @@ -286,8 +286,6 @@ func commandReloadSchemaShard(cmd *cobra.Command, args []string) error { } func init() { - ApplySchema.Flags().Bool("allow-long-unavailability", false, "Deprecated and has no effect.") - ApplySchema.Flags().MarkDeprecated("--allow-long-unavailability", "") ApplySchema.Flags().StringVar(&applySchemaOptions.DDLStrategy, "ddl-strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'.") ApplySchema.Flags().StringSliceVar(&applySchemaOptions.UUIDList, "uuid", nil, "Optional, comma-delimited, repeatable, explicit UUIDs for migration. If given, must match number of DDL changes.") ApplySchema.Flags().StringVar(&applySchemaOptions.MigrationContext, "migration-context", "", "For Online DDL, optionally supply a custom unique string used as context for the migration(s) in this command. By default a unique context is auto-generated by Vitess.") diff --git a/go/flags/endtoend/vtbench.txt b/go/flags/endtoend/vtbench.txt index d74dc13ebc8..22066778fe2 100644 --- a/go/flags/endtoend/vtbench.txt +++ b/go/flags/endtoend/vtbench.txt @@ -64,7 +64,7 @@ Flags: --host string VTGate host(s) in the form 'host1,host2,...' --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -78,7 +78,7 @@ Flags: --sql string SQL statement to execute --sql-max-length-errors int truncate queries in error logs to the given length (default unlimited) --sql-max-length-ui int truncate queries in debug UIs to the given length (default 512) (default 512) - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --tablet_grpc_ca string the server ca to use to validate servers when connecting --tablet_grpc_cert string the cert to use to connect --tablet_grpc_crl string the server crl to use to validate server certificates when connecting @@ -89,7 +89,7 @@ Flags: --user string Username to connect using mysql (password comes from the db-credentials-file) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vtgate_grpc_ca string the server ca to use to validate servers when connecting --vtgate_grpc_cert string the cert to use to connect --vtgate_grpc_crl string the server crl to use to validate server certificates when connecting diff --git a/go/flags/endtoend/vtclient.txt b/go/flags/endtoend/vtclient.txt index 3d17734168c..e82b2807603 100644 --- a/go/flags/endtoend/vtclient.txt +++ b/go/flags/endtoend/vtclient.txt @@ -28,7 +28,7 @@ Flags: --json Output JSON instead of human-readable table --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_backtrace_at traceLocations when logging hits line file:N, emit a stack trace --log_dir string If non-empty, write log files in this directory --log_err_stacks log stack traces for errors --log_rotate_max_size uint size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800) @@ -42,11 +42,11 @@ Flags: --qps int queries per second to throttle each thread at. --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --server string vtgate server to connect to - --stderrthreshold severity logs at or above this threshold go to stderr (default 1) + --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --streaming use a streaming query --target string keyspace:shard@tablet_type --timeout duration timeout for queries (default 30s) --use_random_sequence use random sequence for generating [min_sequence_id, max_sequence_id) --v Level log level for V logs -v, --version print binary version - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging diff --git a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go index 3220465269e..9d8322f07b9 100644 --- a/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go +++ b/go/test/endtoend/onlineddl/revert/onlineddl_revert_test.go @@ -157,14 +157,6 @@ func TestMain(m *testing.M) { "--heartbeat_on_demand_duration", "5s", "--migration_check_interval", "5s", "--watch_replication_stream", - // The next flags are deprecated, and we incldue them to verify that they are nonetheless still allowed. - // The values are irrelevant. Just the fact that the flags are allowed in what's important. - // These should be included in v18, and removed in v19. - "--throttle_threshold", "1m", - "--throttle_metrics_query", "select 1 from dual", - "--throttle_metrics_threshold", "1.5", - "--throttle_check_as_check_self=false", - "--throttler-config-via-topo=true", } clusterInstance.VtGateExtraArgs = []string{ "--ddl_strategy", "online", diff --git a/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go b/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go index 8a3dd4f9b73..5ba71f7ab6e 100644 --- a/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go +++ b/go/test/endtoend/tabletgateway/buffer/buffer_test_helpers.go @@ -241,7 +241,6 @@ func (bt *BufferingTest) createCluster() (*cluster.LocalProcessCluster, int) { "--buffer_window", "10m", "--buffer_max_failover_duration", "10m", "--buffer_min_time_between_failovers", "20m", - "--buffer_implementation", "keyspace_events", "--tablet_refresh_interval", "1s", } clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, bt.VtGateExtraArgs...) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 90e5d0d8ddd..c340485b597 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2900,7 +2900,6 @@ func commandValidateSchemaKeyspace(ctx context.Context, wr *wrangler.Wrangler, s } func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.FlagSet, args []string) error { - subFlags.MarkDeprecated("allow_long_unavailability", "") sql := subFlags.String("sql", "", "A list of semicolon-delimited SQL commands") sqlFile := subFlags.String("sql-file", "", "Identifies the file that contains the SQL commands") ddlStrategy := subFlags.String("ddl_strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'") diff --git a/go/vt/vtgate/tabletgateway.go b/go/vt/vtgate/tabletgateway.go index 1be29459bf6..7703f47c4fa 100644 --- a/go/vt/vtgate/tabletgateway.go +++ b/go/vt/vtgate/tabletgateway.go @@ -49,7 +49,6 @@ var ( // CellsToWatch is the list of cells the healthcheck operates over. If it is empty, only the local cell is watched CellsToWatch string - bufferImplementation = "keyspace_events" initialTabletTimeout = 30 * time.Second // retryCount is the number of times a query will be retried on error retryCount = 2 @@ -58,8 +57,6 @@ var ( func init() { servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) { fs.StringVar(&CellsToWatch, "cells_to_watch", "", "comma-separated list of cells for watching tablets") - fs.StringVar(&bufferImplementation, "buffer_implementation", "keyspace_events", "Allowed values: healthcheck (legacy implementation), keyspace_events (default)") - fs.MarkDeprecated("buffer_implementation", "The 'healthcheck' buffer implementation has been removed in v18 and this option will be removed in v19") fs.DurationVar(&initialTabletTimeout, "gateway_initial_tablet_timeout", 30*time.Second, "At startup, the tabletGateway will wait up to this duration to get at least one tablet per keyspace/shard/tablet type") fs.IntVar(&retryCount, "retry-count", 2, "retry count") }) diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index b66ea93226e..a5ace194c2f 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -151,16 +151,8 @@ func registerFlags(fs *pflag.FlagSet) { fs.IntVar(&warmingReadsPercent, "warming-reads-percent", 0, "Percentage of reads on the primary to forward to replicas. Useful for keeping buffer pools warm") fs.IntVar(&warmingReadsConcurrency, "warming-reads-concurrency", 500, "Number of concurrent warming reads allowed") fs.DurationVar(&warmingReadsQueryTimeout, "warming-reads-query-timeout", 5*time.Second, "Timeout of warming read queries") - - _ = fs.String("schema_change_signal_user", "", "User to be used to send down query to vttablet to retrieve schema changes") - _ = fs.MarkDeprecated("schema_change_signal_user", "schema tracking uses an internal api and does not require a user to be specified") - - fs.Int64("gate_query_cache_size", 0, "gate server query cache size, maximum number of queries to be cached. vtgate analyzes every incoming query and generate a query plan, these plans are being cached in a cache. This config controls the expected amount of unique entries in the cache.") - _ = fs.MarkDeprecated("gate_query_cache_size", "`--gate_query_cache_size` is deprecated and will be removed in `v19.0`. This option only applied to LRU caches, which are now unsupported.") - - fs.Bool("gate_query_cache_lfu", false, "gate server cache algorithm. when set to true, a new cache algorithm based on a TinyLFU admission policy will be used to improve cache behavior and prevent pollution from sparse queries") - _ = fs.MarkDeprecated("gate_query_cache_lfu", "`--gate_query_cache_lfu` is deprecated and will be removed in `v19.0`. The query cache always uses a LFU implementation now.") } + func init() { servenv.OnParseFor("vtgate", registerFlags) servenv.OnParseFor("vtcombo", registerFlags) diff --git a/go/vt/vttablet/tabletserver/tabletenv/config.go b/go/vt/vttablet/tabletserver/tabletenv/config.go index d490c97326a..ac2629709b9 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/config.go +++ b/go/vt/vttablet/tabletserver/tabletenv/config.go @@ -132,14 +132,8 @@ func registerTabletEnvFlags(fs *pflag.FlagSet) { fs.IntVar(¤tConfig.StreamBufferSize, "queryserver-config-stream-buffer-size", defaultConfig.StreamBufferSize, "query server stream buffer size, the maximum number of bytes sent from vttablet for each stream call. It's recommended to keep this value in sync with vtgate's stream_buffer_size.") - fs.Int("queryserver-config-query-cache-size", 0, "query server query cache size, maximum number of queries to be cached. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache.") - _ = fs.MarkDeprecated("queryserver-config-query-cache-size", "`--queryserver-config-query-cache-size` is deprecated and will be removed in `v19.0`. This option only applied to LRU caches, which are now unsupported.") - fs.Int64Var(¤tConfig.QueryCacheMemory, "queryserver-config-query-cache-memory", defaultConfig.QueryCacheMemory, "query server query cache size in bytes, maximum amount of memory to be used for caching. vttablet analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache.") - fs.Bool("queryserver-config-query-cache-lfu", false, "query server cache algorithm. when set to true, a new cache algorithm based on a TinyLFU admission policy will be used to improve cache behavior and prevent pollution from sparse queries") - _ = fs.MarkDeprecated("queryserver-config-query-cache-lfu", "`--queryserver-config-query-cache-lfu` is deprecated and will be removed in `v19.0`. The query cache always uses a LFU implementation now.") - currentConfig.SchemaReloadIntervalSeconds = defaultConfig.SchemaReloadIntervalSeconds.Clone() fs.Var(¤tConfig.SchemaReloadIntervalSeconds, currentConfig.SchemaReloadIntervalSeconds.Name(), "query server schema reload time, how often vttablet reloads schemas from underlying MySQL instance in seconds. vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time.") fs.DurationVar(¤tConfig.SchemaChangeReloadTimeout, "schema-change-reload-timeout", defaultConfig.SchemaChangeReloadTimeout, "query server schema change reload timeout, this is how long to wait for the signaled schema reload operation to complete before giving up") diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 21f9b068d0e..1e03a1dec73 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -82,18 +82,6 @@ func init() { func registerThrottlerFlags(fs *pflag.FlagSet) { fs.StringVar(&throttleTabletTypes, "throttle_tablet_types", throttleTabletTypes, "Comma separated VTTablet types to be considered by the throttler. default: 'replica'. example: 'replica,rdonly'. 'replica' always implicitly included") - - fs.Duration("throttle_threshold", 0, "Replication lag threshold for default lag throttling") - fs.String("throttle_metrics_query", "", "Override default heartbeat/lag metric. Use either `SELECT` (must return single row, single value) or `SHOW GLOBAL ... LIKE ...` queries. Set -throttle_metrics_threshold respectively.") - fs.Float64("throttle_metrics_threshold", 0, "Override default throttle threshold, respective to --throttle_metrics_query") - fs.Bool("throttle_check_as_check_self", false, "Should throttler/check return a throttler/check-self result (changes throttler behavior for writes)") - fs.Bool("throttler-config-via-topo", false, "Deprecated, will be removed in v19. Assumed to be 'true'") - - fs.MarkDeprecated("throttle_threshold", "Replication lag threshold for default lag throttling") - fs.MarkDeprecated("throttle_metrics_query", "Override default heartbeat/lag metric. Use either `SELECT` (must return single row, single value) or `SHOW GLOBAL ... LIKE ...` queries. Set -throttle_metrics_threshold respectively.") - fs.MarkDeprecated("throttle_metrics_threshold", "Override default throttle threshold, respective to --throttle_metrics_query") - fs.MarkDeprecated("throttle_check_as_check_self", "Should throttler/check return a throttler/check-self result (changes throttler behavior for writes)") - fs.MarkDeprecated("throttler-config-via-topo", "Assumed to be 'true'") } var ( From 71e5bce3c90dd10edb8729ee769ca7cf0b6613c7 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Mon, 27 Nov 2023 13:15:29 -0800 Subject: [PATCH 055/119] logging: log time taken for tablet initialization only once (#14597) Signed-off-by: deepthi --- go/vt/vttablet/tabletserver/state_manager.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index 7203174449e..75d1a7c7c3b 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -64,6 +64,7 @@ func (state servingState) String() string { // transitionRetryInterval is for tests. var transitionRetryInterval = 1 * time.Second +var logInitTime sync.Once // stateManager manages state transition for all the TabletServer // subcomponents. @@ -611,9 +612,9 @@ func (sm *stateManager) setTimeBomb() chan struct{} { // setState changes the state and logs the event. func (sm *stateManager) setState(tabletType topodatapb.TabletType, state servingState) { - defer func() { + defer logInitTime.Do(func() { log.Infof("Tablet Init took %d ms", time.Since(servenv.GetInitStartTime()).Milliseconds()) - }() + }) sm.mu.Lock() defer sm.mu.Unlock() if tabletType == topodatapb.TabletType_UNKNOWN { From 9b80411ad056d3c662dc93048d6da6efbec9b10d Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 28 Nov 2023 14:40:57 +0530 Subject: [PATCH 056/119] Make vttablet wait for vt_dba user to be granted privileges (#14565) Signed-off-by: Manan Gupta --- go/cmd/vttablet/cli/cli.go | 9 + go/vt/vttablet/tabletserver/tabletserver.go | 34 +++- .../tabletserver/tabletserver_test.go | 154 ++++++++++++++++++ 3 files changed, 195 insertions(+), 2 deletions(-) diff --git a/go/cmd/vttablet/cli/cli.go b/go/cmd/vttablet/cli/cli.go index 1efa35613d7..2f8b0e5bab3 100644 --- a/go/cmd/vttablet/cli/cli.go +++ b/go/cmd/vttablet/cli/cli.go @@ -102,6 +102,10 @@ vttablet \ } ) +const ( + dbaGrantWaitTime = 10 * time.Second +) + func run(cmd *cobra.Command, args []string) error { servenv.Init() @@ -244,6 +248,11 @@ func createTabletServer(ctx context.Context, config *tabletenv.TabletConfig, ts } else if enforceTableACLConfig { return nil, fmt.Errorf("table acl config has to be specified with table-acl-config flag because enforce-tableacl-config is set.") } + + err := tabletserver.WaitForDBAGrants(config, dbaGrantWaitTime) + if err != nil { + return nil, err + } // creates and registers the query service qsc := tabletserver.NewTabletServer(ctx, "", config, ts, tabletAlias) servenv.OnRun(func() { diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 6c1a60928de..34b284c9ee6 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -33,16 +33,16 @@ import ( "syscall" "time" + "vitess.io/vitess/go/acl" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/pools/smartconnpool" - - "vitess.io/vitess/go/acl" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/tb" "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" @@ -232,6 +232,36 @@ func NewTabletServer(ctx context.Context, name string, config *tabletenv.TabletC return tsv } +// WaitForDBAGrants waits for DBA user to have the required privileges to function properly. +func WaitForDBAGrants(config *tabletenv.TabletConfig, waitTime time.Duration) error { + if waitTime == 0 { + return nil + } + timer := time.NewTimer(waitTime) + ctx, cancel := context.WithTimeout(context.Background(), waitTime) + defer cancel() + for { + conn, err := dbconnpool.NewDBConnection(ctx, config.DB.DbaConnector()) + if err == nil { + res, fetchErr := conn.ExecuteFetch("SHOW GRANTS", 1000, false) + if fetchErr == nil && res != nil && len(res.Rows) > 0 && len(res.Rows[0]) > 0 { + privileges := res.Rows[0][0].ToString() + // In MySQL 8.0, all the privileges are listed out explicitly, so we can search for SUPER in the output. + // In MySQL 5.7, all the privileges are not listed explicitly, instead ALL PRIVILEGES is written, so we search for that too. + if strings.Contains(privileges, "SUPER") || strings.Contains(privileges, "ALL PRIVILEGES") { + return nil + } + } + } + select { + case <-timer.C: + return fmt.Errorf("waited %v for dba user to have the required permissions", waitTime) + default: + time.Sleep(100 * time.Millisecond) + } + } +} + func (tsv *TabletServer) loadQueryTimeout() time.Duration { return time.Duration(tsv.QueryTimeout.Load()) } diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index d2fb10e5a77..71ad86bf854 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -31,7 +31,10 @@ import ( "time" "vitess.io/vitess/go/mysql/sqlerror" + "vitess.io/vitess/go/vt/dbconfigs" + vttestpb "vitess.io/vitess/go/vt/proto/vttest" "vitess.io/vitess/go/vt/sidecardb" + "vitess.io/vitess/go/vt/vttest" "vitess.io/vitess/go/vt/callerid" @@ -2626,3 +2629,154 @@ func addTabletServerSupportedQueries(db *fakesqldb.DB) { }}, }) } + +func TestWaitForDBAGrants(t *testing.T) { + tests := []struct { + name string + waitTime time.Duration + errWanted string + setupFunc func(t *testing.T) (*tabletenv.TabletConfig, func()) + }{ + { + name: "Success without any wait", + waitTime: 1 * time.Second, + errWanted: "", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + // Create a new mysql instance, and the dba user with required grants. + // Since all the grants already exist, this should pass without any waiting to be needed. + testUser := "vt_test_dba" + cluster, err := startMySQLAndCreateUser(t, testUser) + require.NoError(t, err) + grantAllPrivilegesToUser(t, cluster.MySQLConnParams(), testUser) + tc := &tabletenv.TabletConfig{ + DB: &dbconfigs.DBConfigs{}, + } + connParams := cluster.MySQLConnParams() + connParams.Uname = testUser + tc.DB.SetDbParams(connParams, mysql.ConnParams{}, mysql.ConnParams{}) + return tc, func() { + cluster.TearDown() + } + }, + }, + { + name: "Success with wait", + waitTime: 1 * time.Second, + errWanted: "", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + // Create a new mysql instance, but delay granting the privileges to the dba user. + // This makes the waitForDBAGrants function retry the grant check. + testUser := "vt_test_dba" + cluster, err := startMySQLAndCreateUser(t, testUser) + require.NoError(t, err) + + go func() { + time.Sleep(500 * time.Millisecond) + grantAllPrivilegesToUser(t, cluster.MySQLConnParams(), testUser) + }() + + tc := &tabletenv.TabletConfig{ + DB: &dbconfigs.DBConfigs{}, + } + connParams := cluster.MySQLConnParams() + connParams.Uname = testUser + tc.DB.SetDbParams(connParams, mysql.ConnParams{}, mysql.ConnParams{}) + return tc, func() { + cluster.TearDown() + } + }, + }, { + name: "Failure due to timeout", + waitTime: 300 * time.Millisecond, + errWanted: "waited 300ms for dba user to have the required permissions", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + // Create a new mysql but don't give the grants to the vt_dba user at all. + // This should cause a timeout after waiting, since the privileges are never granted. + testUser := "vt_test_dba" + cluster, err := startMySQLAndCreateUser(t, testUser) + require.NoError(t, err) + + tc := &tabletenv.TabletConfig{ + DB: &dbconfigs.DBConfigs{}, + } + connParams := cluster.MySQLConnParams() + connParams.Uname = testUser + tc.DB.SetDbParams(connParams, mysql.ConnParams{}, mysql.ConnParams{}) + return tc, func() { + cluster.TearDown() + } + }, + }, { + name: "Empty timeout", + waitTime: 0, + errWanted: "", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + return nil, func() {} + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config, cleanup := tt.setupFunc(t) + defer cleanup() + err := WaitForDBAGrants(config, tt.waitTime) + if tt.errWanted == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tt.errWanted) + } + }) + } +} + +// startMySQLAndCreateUser starts a MySQL instance and creates the given user +func startMySQLAndCreateUser(t *testing.T, testUser string) (vttest.LocalCluster, error) { + // Launch MySQL. + // We need a Keyspace in the topology, so the DbName is set. + // We need a Shard too, so the database 'vttest' is created. + cfg := vttest.Config{ + Topology: &vttestpb.VTTestTopology{ + Keyspaces: []*vttestpb.Keyspace{ + { + Name: "vttest", + Shards: []*vttestpb.Shard{ + { + Name: "0", + DbNameOverride: "vttest", + }, + }, + }, + }, + }, + OnlyMySQL: true, + Charset: "utf8mb4", + } + cluster := vttest.LocalCluster{ + Config: cfg, + } + err := cluster.Setup() + if err != nil { + return cluster, nil + } + + connParams := cluster.MySQLConnParams() + conn, err := mysql.Connect(context.Background(), &connParams) + require.NoError(t, err) + _, err = conn.ExecuteFetch(fmt.Sprintf(`CREATE USER '%v'@'localhost';`, testUser), 1000, false) + conn.Close() + + return cluster, err +} + +// grantAllPrivilegesToUser grants all the privileges to the user specified. +func grantAllPrivilegesToUser(t *testing.T, connParams mysql.ConnParams, testUser string) { + conn, err := mysql.Connect(context.Background(), &connParams) + require.NoError(t, err) + _, err = conn.ExecuteFetch(fmt.Sprintf(`GRANT ALL ON *.* TO '%v'@'localhost';`, testUser), 1000, false) + require.NoError(t, err) + _, err = conn.ExecuteFetch(fmt.Sprintf(`GRANT GRANT OPTION ON *.* TO '%v'@'localhost';`, testUser), 1000, false) + require.NoError(t, err) + _, err = conn.ExecuteFetch("FLUSH PRIVILEGES;", 1000, false) + require.NoError(t, err) + conn.Close() +} From 02b445c78ccd002b351b0874212aa3e5274cebbe Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 28 Nov 2023 21:28:39 +0100 Subject: [PATCH 057/119] tabletserver: Skip wait for DBA grants for external tablets (#14629) Signed-off-by: Dirkjan Bussink --- go/vt/vttablet/tabletserver/tabletserver.go | 4 ++- .../tabletserver/tabletserver_test.go | 28 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 34b284c9ee6..63f06b125d1 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -234,7 +234,9 @@ func NewTabletServer(ctx context.Context, name string, config *tabletenv.TabletC // WaitForDBAGrants waits for DBA user to have the required privileges to function properly. func WaitForDBAGrants(config *tabletenv.TabletConfig, waitTime time.Duration) error { - if waitTime == 0 { + // We don't wait for grants if the tablet is externally managed. Permissions + // are then the responsibility of the DBA. + if config.DB.HasGlobalSettings() || waitTime == 0 { return nil } timer := time.NewTimer(waitTime) diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index 71ad86bf854..0f85e1018f5 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -2706,12 +2706,38 @@ func TestWaitForDBAGrants(t *testing.T) { cluster.TearDown() } }, + }, { + name: "Success for externally managed tablet", + waitTime: 300 * time.Millisecond, + errWanted: "", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + // Create a new mysql but don't give the grants to the vt_dba user at all. + // This should cause a timeout after waiting, since the privileges are never granted. + testUser := "vt_test_dba" + cluster, err := startMySQLAndCreateUser(t, testUser) + require.NoError(t, err) + + tc := &tabletenv.TabletConfig{ + DB: &dbconfigs.DBConfigs{ + Host: "some.unknown.host", + }, + } + connParams := cluster.MySQLConnParams() + connParams.Uname = testUser + tc.DB.SetDbParams(connParams, mysql.ConnParams{}, mysql.ConnParams{}) + return tc, func() { + cluster.TearDown() + } + }, }, { name: "Empty timeout", waitTime: 0, errWanted: "", setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { - return nil, func() {} + tc := &tabletenv.TabletConfig{ + DB: &dbconfigs.DBConfigs{}, + } + return tc, func() {} }, }, } From 0d1206e67008f3e3696ca6e1681b6116179e8204 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:20:27 +0200 Subject: [PATCH 058/119] Materializer: normalize schema via schemadiff on --atomic-copy (#14636) --- go/test/endtoend/vreplication/fk_test.go | 2 +- go/vt/vtctl/workflow/materializer.go | 16 ++++++++++++++++ go/vt/wrangler/materializer.go | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/vreplication/fk_test.go b/go/test/endtoend/vreplication/fk_test.go index 06e94e0222d..4798edfb975 100644 --- a/go/test/endtoend/vreplication/fk_test.go +++ b/go/test/endtoend/vreplication/fk_test.go @@ -88,7 +88,7 @@ func TestFKWorkflow(t *testing.T) { } targetKeyspace := "fktarget" targetTabletId := 200 - vc.AddKeyspace(t, []*Cell{cell}, targetKeyspace, shardName, initialFKTargetVSchema, initialFKSchema, 0, 0, targetTabletId, sourceKsOpts) + vc.AddKeyspace(t, []*Cell{cell}, targetKeyspace, shardName, initialFKTargetVSchema, "", 0, 0, targetTabletId, sourceKsOpts) vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.primary", targetKeyspace, shardName), 1, 30*time.Second) workflowName := "fk" diff --git a/go/vt/vtctl/workflow/materializer.go b/go/vt/vtctl/workflow/materializer.go index 6be5ac7f445..52196661eb5 100644 --- a/go/vt/vtctl/workflow/materializer.go +++ b/go/vt/vtctl/workflow/materializer.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + "vitess.io/vitess/go/vt/schemadiff" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtctl/schematools" @@ -444,6 +445,21 @@ func (mz *materializer) deploySchema() error { } if len(applyDDLs) > 0 { + if mz.ms.AtomicCopy { + // AtomicCopy suggests we may be interested in Foreign Key support. As such, we want to + // normalize the source schema: ensure the order of table definitions is compatible with + // the constraints graph. We want to first create the parents, then the children. + // We use schemadiff to normalize the schema. + // For now, and because this is could have wider implications, we ignore any errors in + // reading the source schema. + schema, err := schemadiff.NewSchemaFromQueries(applyDDLs) + if err != nil { + log.Error(vterrors.Wrapf(err, "AtomicCopy: failed to normalize schema via schemadiff")) + } else { + applyDDLs = schema.ToQueries() + log.Infof("AtomicCopy used, and schema was normalized via schemadiff. %v queries normalized", len(applyDDLs)) + } + } sql := strings.Join(applyDDLs, ";\n") _, err = mz.tmc.ApplySchema(mz.ctx, targetTablet.Tablet, &tmutils.SchemaChange{ diff --git a/go/vt/wrangler/materializer.go b/go/vt/wrangler/materializer.go index 990492bd191..01a3a640fb8 100644 --- a/go/vt/wrangler/materializer.go +++ b/go/vt/wrangler/materializer.go @@ -39,6 +39,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/tmutils" "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/schemadiff" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" @@ -1260,6 +1261,21 @@ func (mz *materializer) deploySchema(ctx context.Context) error { } if len(applyDDLs) > 0 { + if mz.ms.AtomicCopy { + // AtomicCopy suggests we may be interested in Foreign Key support. As such, we want to + // normalize the source schema: ensure the order of table definitions is compatible with + // the constraints graph. We want to first create the parents, then the children. + // We use schemadiff to normalize the schema. + // For now, and because this is could have wider implications, we ignore any errors in + // reading the source schema. + schema, err := schemadiff.NewSchemaFromQueries(applyDDLs) + if err != nil { + log.Error(vterrors.Wrapf(err, "AtomicCopy: failed to normalize schema via schemadiff")) + } else { + applyDDLs = schema.ToQueries() + log.Infof("AtomicCopy used, and schema was normalized via schemadiff. %v queries normalized", len(applyDDLs)) + } + } sql := strings.Join(applyDDLs, ";\n") _, err = mz.wr.tmc.ApplySchema(ctx, targetTablet.Tablet, &tmutils.SchemaChange{ From 372d3e75842698802c12330fd121565394e0ee22 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Wed, 29 Nov 2023 07:04:21 -0600 Subject: [PATCH 059/119] Fix license header typo (#14630) Signed-off-by: Florent Poinsard --- go/cmd/topo2topo/cli/plugin_consultopo.go | 2 +- go/cmd/vtclient/cli/vtclient_test.go | 2 +- go/cmd/vtctl/plugin_cephbackupstorage.go | 2 +- go/cmd/vtctl/plugin_s3backupstorage.go | 2 +- go/cmd/vtctld/cli/cli.go | 2 +- go/cmd/vtctld/cli/plugin_cephbackupstorage.go | 2 +- go/cmd/vtctld/cli/plugin_consultopo.go | 2 +- go/cmd/vtctld/cli/plugin_s3backupstorage.go | 2 +- go/cmd/vtctld/cli/plugin_zk2topo.go | 2 +- go/cmd/vtctld/cli/schema.go | 2 +- go/cmd/vtctld/main.go | 2 +- go/cmd/vtgate/cli/cli.go | 2 +- go/cmd/vtgate/cli/plugin_auth_ldap.go | 2 +- go/cmd/vtgate/cli/plugin_auth_static.go | 2 +- go/cmd/vtgate/cli/plugin_auth_vault.go | 2 +- go/cmd/vtgate/cli/plugin_consultopo.go | 2 +- go/cmd/vtgate/cli/plugin_zk2topo.go | 2 +- go/cmd/vtgate/cli/status.go | 2 +- go/cmd/vtorc/cli/plugin_consultopo.go | 2 +- go/cmd/vtorc/cli/plugin_zk2topo.go | 2 +- go/cmd/vttablet/cli/cli.go | 2 +- go/cmd/vttablet/cli/plugin_cephbackupstorage.go | 2 +- go/cmd/vttablet/cli/plugin_consultopo.go | 2 +- go/cmd/vttablet/cli/plugin_s3backupstorage.go | 2 +- go/cmd/vttablet/cli/plugin_sysloglogger.go | 2 +- go/cmd/vttablet/cli/plugin_zk2topo.go | 2 +- go/cmd/vttablet/cli/status.go | 2 +- go/cmd/vttlstest/cli/vttlstest.go | 2 +- go/cmd/vttlstest/vttlstest.go | 2 +- go/cmd/zk/command/add_auth.go | 2 +- go/cmd/zk/command/cat.go | 2 +- go/cmd/zk/command/chmod.go | 2 +- go/cmd/zk/command/cp.go | 2 +- go/cmd/zk/command/edit.go | 2 +- go/cmd/zk/command/ls.go | 2 +- go/cmd/zk/command/rm.go | 2 +- go/cmd/zk/command/root.go | 2 +- go/cmd/zk/command/stat.go | 2 +- go/cmd/zk/command/touch.go | 2 +- go/cmd/zk/command/unzip.go | 2 +- go/cmd/zk/command/wait.go | 2 +- go/cmd/zk/command/watch.go | 2 +- go/cmd/zk/command/zip.go | 2 +- go/cmd/zk/internal/zkfilepath/zkfilepath.go | 2 +- go/cmd/zk/internal/zkfs/zkfs.go | 2 +- go/cmd/zk/zkcmd.go | 2 +- go/event/event_test.go | 2 +- go/event/hooks_test.go | 2 +- go/event/syslogger/fake_logger.go | 2 +- go/event/syslogger/syslogger_test.go | 2 +- go/exit/exit_test.go | 2 +- go/fileutil/wildcards_test.go | 2 +- go/flagutil/enum.go | 2 +- go/flagutil/flagutil.go | 2 +- go/flagutil/flagutil_test.go | 2 +- go/history/history.go | 2 +- go/history/history_test.go | 2 +- go/vt/discovery/utils_test.go | 2 +- go/vt/topo/topotests/shard_watch_test.go | 2 +- go/vt/vttest/plugin_consultopo.go | 2 +- go/vt/vttest/plugin_zk2topo.go | 2 +- 61 files changed, 61 insertions(+), 61 deletions(-) diff --git a/go/cmd/topo2topo/cli/plugin_consultopo.go b/go/cmd/topo2topo/cli/plugin_consultopo.go index a128f294a42..56d178e2975 100644 --- a/go/cmd/topo2topo/cli/plugin_consultopo.go +++ b/go/cmd/topo2topo/cli/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtclient/cli/vtclient_test.go b/go/cmd/vtclient/cli/vtclient_test.go index a5ee571cd0b..a323ab5c63a 100644 --- a/go/cmd/vtclient/cli/vtclient_test.go +++ b/go/cmd/vtclient/cli/vtclient_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctl/plugin_cephbackupstorage.go b/go/cmd/vtctl/plugin_cephbackupstorage.go index 6cd2d5619d0..0d4710ec982 100644 --- a/go/cmd/vtctl/plugin_cephbackupstorage.go +++ b/go/cmd/vtctl/plugin_cephbackupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctl/plugin_s3backupstorage.go b/go/cmd/vtctl/plugin_s3backupstorage.go index a5b5c671ebb..f1d1a454041 100644 --- a/go/cmd/vtctl/plugin_s3backupstorage.go +++ b/go/cmd/vtctl/plugin_s3backupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/cli.go b/go/cmd/vtctld/cli/cli.go index e5124133adb..f7fef555896 100644 --- a/go/cmd/vtctld/cli/cli.go +++ b/go/cmd/vtctld/cli/cli.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/plugin_cephbackupstorage.go b/go/cmd/vtctld/cli/plugin_cephbackupstorage.go index 171198f5e29..7755e1cae2d 100644 --- a/go/cmd/vtctld/cli/plugin_cephbackupstorage.go +++ b/go/cmd/vtctld/cli/plugin_cephbackupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/plugin_consultopo.go b/go/cmd/vtctld/cli/plugin_consultopo.go index 4617d753953..b8f8f2e8cdc 100644 --- a/go/cmd/vtctld/cli/plugin_consultopo.go +++ b/go/cmd/vtctld/cli/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/plugin_s3backupstorage.go b/go/cmd/vtctld/cli/plugin_s3backupstorage.go index 4b3ecb33edb..e09f6060809 100644 --- a/go/cmd/vtctld/cli/plugin_s3backupstorage.go +++ b/go/cmd/vtctld/cli/plugin_s3backupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/plugin_zk2topo.go b/go/cmd/vtctld/cli/plugin_zk2topo.go index 77f86d98d52..f1e5f27ea1b 100644 --- a/go/cmd/vtctld/cli/plugin_zk2topo.go +++ b/go/cmd/vtctld/cli/plugin_zk2topo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/cli/schema.go b/go/cmd/vtctld/cli/schema.go index 480679a09e6..68dc47b2b6f 100644 --- a/go/cmd/vtctld/cli/schema.go +++ b/go/cmd/vtctld/cli/schema.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtctld/main.go b/go/cmd/vtctld/main.go index 6f9ab7384fc..46ce01e409f 100644 --- a/go/cmd/vtctld/main.go +++ b/go/cmd/vtctld/main.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/cli.go b/go/cmd/vtgate/cli/cli.go index 9182bfcf9a4..bcd280890e5 100644 --- a/go/cmd/vtgate/cli/cli.go +++ b/go/cmd/vtgate/cli/cli.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/plugin_auth_ldap.go b/go/cmd/vtgate/cli/plugin_auth_ldap.go index 7dc5b246f72..7aab7e9c7f4 100644 --- a/go/cmd/vtgate/cli/plugin_auth_ldap.go +++ b/go/cmd/vtgate/cli/plugin_auth_ldap.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/plugin_auth_static.go b/go/cmd/vtgate/cli/plugin_auth_static.go index 9ffd60a79f2..76cdf8318ba 100644 --- a/go/cmd/vtgate/cli/plugin_auth_static.go +++ b/go/cmd/vtgate/cli/plugin_auth_static.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/plugin_auth_vault.go b/go/cmd/vtgate/cli/plugin_auth_vault.go index 2aee32e3940..fe5fe2207d4 100644 --- a/go/cmd/vtgate/cli/plugin_auth_vault.go +++ b/go/cmd/vtgate/cli/plugin_auth_vault.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/plugin_consultopo.go b/go/cmd/vtgate/cli/plugin_consultopo.go index a128f294a42..56d178e2975 100644 --- a/go/cmd/vtgate/cli/plugin_consultopo.go +++ b/go/cmd/vtgate/cli/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/plugin_zk2topo.go b/go/cmd/vtgate/cli/plugin_zk2topo.go index 1870a3b2bb3..66d14988c75 100644 --- a/go/cmd/vtgate/cli/plugin_zk2topo.go +++ b/go/cmd/vtgate/cli/plugin_zk2topo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtgate/cli/status.go b/go/cmd/vtgate/cli/status.go index 9652392dc65..d38cac2d50e 100644 --- a/go/cmd/vtgate/cli/status.go +++ b/go/cmd/vtgate/cli/status.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtorc/cli/plugin_consultopo.go b/go/cmd/vtorc/cli/plugin_consultopo.go index a128f294a42..56d178e2975 100644 --- a/go/cmd/vtorc/cli/plugin_consultopo.go +++ b/go/cmd/vtorc/cli/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vtorc/cli/plugin_zk2topo.go b/go/cmd/vtorc/cli/plugin_zk2topo.go index d71a7e2e196..0b2884cc258 100644 --- a/go/cmd/vtorc/cli/plugin_zk2topo.go +++ b/go/cmd/vtorc/cli/plugin_zk2topo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/cli.go b/go/cmd/vttablet/cli/cli.go index 2f8b0e5bab3..bed53d284e8 100644 --- a/go/cmd/vttablet/cli/cli.go +++ b/go/cmd/vttablet/cli/cli.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/plugin_cephbackupstorage.go b/go/cmd/vttablet/cli/plugin_cephbackupstorage.go index 171198f5e29..7755e1cae2d 100644 --- a/go/cmd/vttablet/cli/plugin_cephbackupstorage.go +++ b/go/cmd/vttablet/cli/plugin_cephbackupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/plugin_consultopo.go b/go/cmd/vttablet/cli/plugin_consultopo.go index a128f294a42..56d178e2975 100644 --- a/go/cmd/vttablet/cli/plugin_consultopo.go +++ b/go/cmd/vttablet/cli/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/plugin_s3backupstorage.go b/go/cmd/vttablet/cli/plugin_s3backupstorage.go index 4b3ecb33edb..e09f6060809 100644 --- a/go/cmd/vttablet/cli/plugin_s3backupstorage.go +++ b/go/cmd/vttablet/cli/plugin_s3backupstorage.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/plugin_sysloglogger.go b/go/cmd/vttablet/cli/plugin_sysloglogger.go index a7260d6f8cc..303bf014d83 100644 --- a/go/cmd/vttablet/cli/plugin_sysloglogger.go +++ b/go/cmd/vttablet/cli/plugin_sysloglogger.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/plugin_zk2topo.go b/go/cmd/vttablet/cli/plugin_zk2topo.go index d71a7e2e196..0b2884cc258 100644 --- a/go/cmd/vttablet/cli/plugin_zk2topo.go +++ b/go/cmd/vttablet/cli/plugin_zk2topo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttablet/cli/status.go b/go/cmd/vttablet/cli/status.go index 762a9fa646e..de3bfcbce74 100644 --- a/go/cmd/vttablet/cli/status.go +++ b/go/cmd/vttablet/cli/status.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttlstest/cli/vttlstest.go b/go/cmd/vttlstest/cli/vttlstest.go index 4e0f9c2b95e..9791645cdc2 100644 --- a/go/cmd/vttlstest/cli/vttlstest.go +++ b/go/cmd/vttlstest/cli/vttlstest.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/vttlstest/vttlstest.go b/go/cmd/vttlstest/vttlstest.go index 08e994c096d..8b98687c7a8 100644 --- a/go/cmd/vttlstest/vttlstest.go +++ b/go/cmd/vttlstest/vttlstest.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/add_auth.go b/go/cmd/zk/command/add_auth.go index 566c463f4a8..117ddf1cd8a 100644 --- a/go/cmd/zk/command/add_auth.go +++ b/go/cmd/zk/command/add_auth.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/cat.go b/go/cmd/zk/command/cat.go index 1d5460f7006..6dae3c903a9 100644 --- a/go/cmd/zk/command/cat.go +++ b/go/cmd/zk/command/cat.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/chmod.go b/go/cmd/zk/command/chmod.go index 39125d618c4..63bd103fdb2 100644 --- a/go/cmd/zk/command/chmod.go +++ b/go/cmd/zk/command/chmod.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/cp.go b/go/cmd/zk/command/cp.go index e89486413ea..b45baab1b6e 100644 --- a/go/cmd/zk/command/cp.go +++ b/go/cmd/zk/command/cp.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/edit.go b/go/cmd/zk/command/edit.go index ec4b74c4b62..90348161502 100644 --- a/go/cmd/zk/command/edit.go +++ b/go/cmd/zk/command/edit.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/ls.go b/go/cmd/zk/command/ls.go index 83c1d31363b..5d28f20ae60 100644 --- a/go/cmd/zk/command/ls.go +++ b/go/cmd/zk/command/ls.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/rm.go b/go/cmd/zk/command/rm.go index 5e5b5f4c494..8b710b2fb74 100644 --- a/go/cmd/zk/command/rm.go +++ b/go/cmd/zk/command/rm.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/root.go b/go/cmd/zk/command/root.go index f3f02e7d4f2..2aabcd50e4f 100644 --- a/go/cmd/zk/command/root.go +++ b/go/cmd/zk/command/root.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/stat.go b/go/cmd/zk/command/stat.go index 713a68a3d4e..28aa6bb3465 100644 --- a/go/cmd/zk/command/stat.go +++ b/go/cmd/zk/command/stat.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/touch.go b/go/cmd/zk/command/touch.go index 76c390cf169..53e80a05214 100644 --- a/go/cmd/zk/command/touch.go +++ b/go/cmd/zk/command/touch.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/unzip.go b/go/cmd/zk/command/unzip.go index f4c800e0533..81e04bf4564 100644 --- a/go/cmd/zk/command/unzip.go +++ b/go/cmd/zk/command/unzip.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/wait.go b/go/cmd/zk/command/wait.go index 864f6e83626..8aa844d8bc6 100644 --- a/go/cmd/zk/command/wait.go +++ b/go/cmd/zk/command/wait.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/watch.go b/go/cmd/zk/command/watch.go index eb28cc29ca2..7d6de784718 100644 --- a/go/cmd/zk/command/watch.go +++ b/go/cmd/zk/command/watch.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/command/zip.go b/go/cmd/zk/command/zip.go index b765f5bb00e..5f06b97c508 100644 --- a/go/cmd/zk/command/zip.go +++ b/go/cmd/zk/command/zip.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/internal/zkfilepath/zkfilepath.go b/go/cmd/zk/internal/zkfilepath/zkfilepath.go index 7febc7a9677..7d5b76cc664 100644 --- a/go/cmd/zk/internal/zkfilepath/zkfilepath.go +++ b/go/cmd/zk/internal/zkfilepath/zkfilepath.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/internal/zkfs/zkfs.go b/go/cmd/zk/internal/zkfs/zkfs.go index 9bab19ec1e4..648c6753fd6 100644 --- a/go/cmd/zk/internal/zkfs/zkfs.go +++ b/go/cmd/zk/internal/zkfs/zkfs.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/cmd/zk/zkcmd.go b/go/cmd/zk/zkcmd.go index f03ac41c6ef..f0c39d6b0f8 100644 --- a/go/cmd/zk/zkcmd.go +++ b/go/cmd/zk/zkcmd.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/event/event_test.go b/go/event/event_test.go index 36d4d56bf5d..f7356a98f3e 100644 --- a/go/event/event_test.go +++ b/go/event/event_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/event/hooks_test.go b/go/event/hooks_test.go index 197dd59a062..3d8e3361e94 100644 --- a/go/event/hooks_test.go +++ b/go/event/hooks_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/event/syslogger/fake_logger.go b/go/event/syslogger/fake_logger.go index 63c0942c069..852ca2a72a6 100644 --- a/go/event/syslogger/fake_logger.go +++ b/go/event/syslogger/fake_logger.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/event/syslogger/syslogger_test.go b/go/event/syslogger/syslogger_test.go index 4847fecac2a..fddeef12b27 100644 --- a/go/event/syslogger/syslogger_test.go +++ b/go/event/syslogger/syslogger_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/exit/exit_test.go b/go/exit/exit_test.go index e51a0938534..7f08f4ea1e2 100644 --- a/go/exit/exit_test.go +++ b/go/exit/exit_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/fileutil/wildcards_test.go b/go/fileutil/wildcards_test.go index 9d332a507db..e4494dd7b2c 100644 --- a/go/fileutil/wildcards_test.go +++ b/go/fileutil/wildcards_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/flagutil/enum.go b/go/flagutil/enum.go index 5bc279ee493..4426f13a8b6 100644 --- a/go/flagutil/enum.go +++ b/go/flagutil/enum.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/flagutil/flagutil.go b/go/flagutil/flagutil.go index ebf4ccef485..28d0b54e4ec 100644 --- a/go/flagutil/flagutil.go +++ b/go/flagutil/flagutil.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/flagutil/flagutil_test.go b/go/flagutil/flagutil_test.go index f95c46a53f7..df2b9bc3bd0 100644 --- a/go/flagutil/flagutil_test.go +++ b/go/flagutil/flagutil_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/history/history.go b/go/history/history.go index 94af347ec52..f38be9239e0 100644 --- a/go/history/history.go +++ b/go/history/history.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/history/history_test.go b/go/history/history_test.go index 8b0559bd47e..3e817b34bb2 100644 --- a/go/history/history_test.go +++ b/go/history/history_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/discovery/utils_test.go b/go/vt/discovery/utils_test.go index 27416da44b0..edca8c17602 100644 --- a/go/vt/discovery/utils_test.go +++ b/go/vt/discovery/utils_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/topo/topotests/shard_watch_test.go b/go/vt/topo/topotests/shard_watch_test.go index 80b696c106d..f4ac83c627a 100644 --- a/go/vt/topo/topotests/shard_watch_test.go +++ b/go/vt/topo/topotests/shard_watch_test.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/vttest/plugin_consultopo.go b/go/vt/vttest/plugin_consultopo.go index cb10acc2cd2..3d47ee51681 100644 --- a/go/vt/vttest/plugin_consultopo.go +++ b/go/vt/vttest/plugin_consultopo.go @@ -7,7 +7,7 @@ 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 +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 diff --git a/go/vt/vttest/plugin_zk2topo.go b/go/vt/vttest/plugin_zk2topo.go index 3859454f7bd..7f1f81a5701 100644 --- a/go/vt/vttest/plugin_zk2topo.go +++ b/go/vt/vttest/plugin_zk2topo.go @@ -7,7 +7,7 @@ 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 +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 From 9f6f5f6f1d533caba382cbfd686704016bf6bcb9 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Wed, 29 Nov 2023 20:03:55 +0530 Subject: [PATCH 060/119] Add log for error to help debug (#14632) --- go/vt/vttablet/tabletserver/tabletserver.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 63f06b125d1..2e1831e0acd 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -246,6 +246,9 @@ func WaitForDBAGrants(config *tabletenv.TabletConfig, waitTime time.Duration) er conn, err := dbconnpool.NewDBConnection(ctx, config.DB.DbaConnector()) if err == nil { res, fetchErr := conn.ExecuteFetch("SHOW GRANTS", 1000, false) + if fetchErr != nil { + log.Errorf("Error running SHOW GRANTS - %v", fetchErr) + } if fetchErr == nil && res != nil && len(res.Rows) > 0 && len(res.Rows[0]) > 0 { privileges := res.Rows[0][0].ToString() // In MySQL 8.0, all the privileges are listed out explicitly, so we can search for SUPER in the output. From 277d7863e4adc4585af9eac863525035130fa0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Wed, 29 Nov 2023 18:15:12 +0100 Subject: [PATCH 061/119] refactor the INSERT engine primitive (#14606) Signed-off-by: Andres Taylor Signed-off-by: Harshit Gangal Co-authored-by: Harshit Gangal --- go/vt/vtgate/engine/cached_size.go | 64 +- go/vt/vtgate/engine/insert.go | 889 ++---------------- go/vt/vtgate/engine/insert_common.go | 480 ++++++++++ go/vt/vtgate/engine/insert_select.go | 423 +++++++++ go/vt/vtgate/engine/insert_test.go | 273 +++--- go/vt/vtgate/planbuilder/insert.go | 29 +- .../planbuilder/operator_transformers.go | 56 +- .../planbuilder/testdata/dml_cases.json | 4 +- 8 files changed, 1224 insertions(+), 994 deletions(-) create mode 100644 go/vt/vtgate/engine/insert_common.go create mode 100644 go/vt/vtgate/engine/insert_select.go diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 657e5323f05..807c7604412 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -386,10 +386,10 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(240) + size += int64(192) } - // field Keyspace *vitess.io/vitess/go/vt/vtgate/vindexes.Keyspace - size += cached.Keyspace.CachedSize(true) + // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon + size += cached.InsertCommon.CachedSize(false) // field Query string size += hack.RuntimeAllocSize(int64(len(cached.Query))) // field VindexValues [][][]vitess.io/vitess/go/vt/vtgate/evalengine.Expr @@ -411,19 +411,6 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } } } - // field ColVindexes []*vitess.io/vitess/go/vt/vtgate/vindexes.ColumnVindex - { - size += hack.RuntimeAllocSize(int64(cap(cached.ColVindexes)) * int64(8)) - for _, elem := range cached.ColVindexes { - size += elem.CachedSize(true) - } - } - // field TableName string - size += hack.RuntimeAllocSize(int64(len(cached.TableName))) - // field Generate *vitess.io/vitess/go/vt/vtgate/engine.Generate - size += cached.Generate.CachedSize(true) - // field Prefix string - size += hack.RuntimeAllocSize(int64(len(cached.Prefix))) // field Mid vitess.io/vitess/go/vt/sqlparser.Values { size += hack.RuntimeAllocSize(int64(cap(cached.Mid)) * int64(24)) @@ -438,8 +425,49 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } } } + return size +} +func (cached *InsertCommon) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(128) + } + // field Keyspace *vitess.io/vitess/go/vt/vtgate/vindexes.Keyspace + size += cached.Keyspace.CachedSize(true) + // field TableName string + size += hack.RuntimeAllocSize(int64(len(cached.TableName))) + // field Generate *vitess.io/vitess/go/vt/vtgate/engine.Generate + size += cached.Generate.CachedSize(true) + // field ColVindexes []*vitess.io/vitess/go/vt/vtgate/vindexes.ColumnVindex + { + size += hack.RuntimeAllocSize(int64(cap(cached.ColVindexes)) * int64(8)) + for _, elem := range cached.ColVindexes { + size += elem.CachedSize(true) + } + } + // field Prefix string + size += hack.RuntimeAllocSize(int64(len(cached.Prefix))) // field Suffix string size += hack.RuntimeAllocSize(int64(len(cached.Suffix))) + return size +} +func (cached *InsertSelect) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(176) + } + // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon + size += cached.InsertCommon.CachedSize(false) + // field Input vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.Input.(cachedObject); ok { + size += cc.CachedSize(true) + } // field VindexValueOffset [][]int { size += hack.RuntimeAllocSize(int64(cap(cached.VindexValueOffset)) * int64(24)) @@ -449,10 +477,6 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } } } - // field Input vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.Input.(cachedObject); ok { - size += cc.CachedSize(true) - } return size } diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 4fa8eeadce4..46043413732 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -18,14 +18,10 @@ package engine import ( "context" - "encoding/json" "fmt" "strconv" "strings" - "sync" - "time" - "vitess.io/vitess/go/slice" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" querypb "vitess.io/vitess/go/vt/proto/query" @@ -40,95 +36,41 @@ import ( var _ Primitive = (*Insert)(nil) -type ( - // Insert represents the instructions to perform an insert operation. - Insert struct { - // Opcode is the execution opcode. - Opcode InsertOpcode +// Insert represents the instructions to perform an insert operation. +type Insert struct { + InsertCommon - // Ignore is for INSERT IGNORE and INSERT...ON DUPLICATE KEY constructs - // for sharded cases. - Ignore bool + // Query specifies the query to be executed. + // For InsertSharded plans, this value is unused, + // and Prefix, Mid and Suffix are used instead. + Query string - // Keyspace specifies the keyspace to send the query to. - Keyspace *vindexes.Keyspace + // VindexValues specifies values for all the vindex columns. + // This is a three-dimensional data structure: + // Insert.Values[i] represents the values to be inserted for the i'th colvindex (i < len(Insert.Table.ColumnVindexes)) + // Insert.Values[i].Values[j] represents values for the j'th column of the given colVindex (j < len(colVindex[i].Columns) + // Insert.Values[i].Values[j].Values[k] represents the value pulled from row k for that column: (k < len(ins.rows)) + VindexValues [][][]evalengine.Expr - // Query specifies the query to be executed. - // For InsertSharded plans, this value is unused, - // and Prefix, Mid and Suffix are used instead. - Query string + // Mid is the row values for the sharded insert plans. + Mid sqlparser.Values - // VindexValues specifies values for all the vindex columns. - // This is a three-dimensional data structure: - // Insert.Values[i] represents the values to be inserted for the i'th colvindex (i < len(Insert.Table.ColumnVindexes)) - // Insert.Values[i].Values[j] represents values for the j'th column of the given colVindex (j < len(colVindex[i].Columns) - // Insert.Values[i].Values[j].Values[k] represents the value pulled from row k for that column: (k < len(ins.rows)) - VindexValues [][][]evalengine.Expr - - // ColVindexes are the vindexes that will use the VindexValues - ColVindexes []*vindexes.ColumnVindex - - // TableName is the name of the table on which row will be inserted. - TableName string - - // Generate is only set for inserts where a sequence must be generated. - Generate *Generate - - // Prefix, Mid and Suffix are for sharded insert plans. - Prefix string - Mid sqlparser.Values - Suffix string - - // Option to override the standard behavior and allow a multi-shard insert - // to use single round trip autocommit. - // - // This is a clear violation of the SQL semantics since it means the statement - // is not atomic in the presence of PK conflicts on one shard and not another. - // However some application use cases would prefer that the statement partially - // succeed in order to get the performance benefits of autocommit. - MultiShardAutocommit bool - - // QueryTimeout contains the optional timeout (in milliseconds) to apply to this query - QueryTimeout int - - // VindexValueOffset stores the offset for each column in the ColumnVindex - // that will appear in the result set of the select query. - VindexValueOffset [][]int - - // Input is a select query plan to retrieve results for inserting data. - Input Primitive `json:",omitempty"` - - // ForceNonStreaming is true when the insert table and select table are same. - // This will avoid locking by the select table. - ForceNonStreaming bool - - PreventAutoCommit bool - - // Insert needs tx handling - txNeeded - } - - ksID = []byte -) - -func (ins *Insert) Inputs() ([]Primitive, []map[string]any) { - if ins.Input == nil { - return nil, nil - } - return []Primitive{ins.Input}, nil + noInputs } -// NewQueryInsert creates an Insert with a query string. -func NewQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query string) *Insert { +// newQueryInsert creates an Insert with a query string. +func newQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query string) *Insert { return &Insert{ - Opcode: opcode, - Keyspace: keyspace, - Query: query, + InsertCommon: InsertCommon{ + Opcode: opcode, + Keyspace: keyspace, + }, + Query: query, } } -// NewInsert creates a new Insert. -func NewInsert( +// newInsert creates a new Insert. +func newInsert( opcode InsertOpcode, ignore bool, keyspace *vindexes.Keyspace, @@ -139,13 +81,15 @@ func NewInsert( suffix string, ) *Insert { ins := &Insert{ - Opcode: opcode, - Ignore: ignore, - Keyspace: keyspace, + InsertCommon: InsertCommon{ + Opcode: opcode, + Keyspace: keyspace, + Ignore: ignore, + Prefix: prefix, + Suffix: suffix, + }, VindexValues: vindexValues, - Prefix: prefix, Mid: mid, - Suffix: suffix, } if table != nil { ins.TableName = table.Name.String() @@ -159,208 +103,59 @@ func NewInsert( return ins } -// Generate represents the instruction to generate -// a value from a sequence. -type Generate struct { - Keyspace *vindexes.Keyspace - Query string - // Values are the supplied values for the column, which - // will be stored as a list within the expression. New - // values will be generated based on how many were not - // supplied (NULL). - Values evalengine.Expr - // Insert using Select, offset for auto increment column - Offset int -} - -// InsertOpcode is a number representing the opcode -// for the Insert primitive. -type InsertOpcode int - -const ( - // InsertUnsharded is for routing an insert statement - // to an unsharded keyspace. - InsertUnsharded = InsertOpcode(iota) - // InsertSharded is for routing an insert statement - // to individual shards. Requires: A list of Values, one - // for each ColVindex. If the table has an Autoinc column, - // A Generate subplan must be created. - InsertSharded - // InsertSelect is for routing an insert statement - // based on rows returned from the select statement. - InsertSelect -) - -var insName = map[InsertOpcode]string{ - InsertUnsharded: "InsertUnsharded", - InsertSharded: "InsertSharded", - InsertSelect: "InsertSelect", -} - -// String returns the opcode -func (code InsertOpcode) String() string { - return strings.ReplaceAll(insName[code], "Insert", "") -} - -// MarshalJSON serializes the InsertOpcode as a JSON string. -// It's used for testing and diagnostics. -func (code InsertOpcode) MarshalJSON() ([]byte, error) { - return json.Marshal(insName[code]) -} - // RouteType returns a description of the query routing type used by the primitive func (ins *Insert) RouteType() string { return insName[ins.Opcode] } -// GetKeyspaceName specifies the Keyspace that this primitive routes to. -func (ins *Insert) GetKeyspaceName() string { - return ins.Keyspace.Name -} - -// GetTableName specifies the table that this primitive routes to. -func (ins *Insert) GetTableName() string { - return ins.TableName -} - // TryExecute performs a non-streaming exec. -func (ins *Insert) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { +func (ins *Insert) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { ctx, cancelFunc := addQueryTimeout(ctx, vcursor, ins.QueryTimeout) defer cancelFunc() switch ins.Opcode { case InsertUnsharded: - return ins.execInsertUnsharded(ctx, vcursor, bindVars) + return ins.insertIntoUnshardedTable(ctx, vcursor, bindVars) case InsertSharded: - return ins.execInsertSharded(ctx, vcursor, bindVars) - case InsertSelect: - return ins.execInsertFromSelect(ctx, vcursor, bindVars) + return ins.insertIntoShardedTable(ctx, vcursor, bindVars) default: - // Unreachable. - return nil, fmt.Errorf("unsupported query route: %v", ins) + return nil, vterrors.VT13001("unexpected query route: %v", ins.Opcode) } } // TryStreamExecute performs a streaming exec. func (ins *Insert) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - if ins.Input == nil || ins.ForceNonStreaming { - res, err := ins.TryExecute(ctx, vcursor, bindVars, wantfields) - if err != nil { - return err - } - return callback(res) - } - if ins.QueryTimeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, time.Duration(ins.QueryTimeout)*time.Millisecond) - defer cancel() - } - - unsharded := ins.Opcode == InsertUnsharded - var mu sync.Mutex - output := &sqltypes.Result{} - - err := vcursor.StreamExecutePrimitiveStandalone(ctx, ins.Input, bindVars, false, func(result *sqltypes.Result) error { - if len(result.Rows) == 0 { - return nil - } - - // should process only one chunk at a time. - // as parallel chunk insert will try to use the same transaction in the vttablet - // this will cause transaction in use error. - mu.Lock() - defer mu.Unlock() - - var insertID int64 - var qr *sqltypes.Result - var err error - if unsharded { - insertID, qr, err = ins.insertIntoUnshardedTable(ctx, vcursor, bindVars, result) - } else { - insertID, qr, err = ins.insertIntoShardedTable(ctx, vcursor, bindVars, result) - } - if err != nil { - return err - } - - output.RowsAffected += qr.RowsAffected - // InsertID needs to be updated to the least insertID value in sqltypes.Result - if output.InsertID == 0 || output.InsertID > uint64(insertID) { - output.InsertID = uint64(insertID) - } - return nil - }) + res, err := ins.TryExecute(ctx, vcursor, bindVars, wantfields) if err != nil { return err } - return callback(output) + return callback(res) } -func (ins *Insert) insertIntoShardedTable(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, result *sqltypes.Result) (int64, *sqltypes.Result, error) { - insertID, err := ins.processGenerateFromRows(ctx, vcursor, result.Rows) - if err != nil { - return 0, nil, err - } - - rss, queries, err := ins.getInsertSelectQueries(ctx, vcursor, bindVars, result.Rows) +func (ins *Insert) insertIntoUnshardedTable(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + insertID, err := ins.processGenerateFromValues(ctx, vcursor, ins, bindVars) if err != nil { - return 0, nil, err - } - - qr, err := ins.executeInsertQueries(ctx, vcursor, rss, queries, insertID) - if err != nil { - return 0, nil, err - } - return insertID, qr, nil -} - -// GetFields fetches the field info. -func (ins *Insert) GetFields(context.Context, VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unreachable code for %q", ins.Query) -} - -func (ins *Insert) execInsertUnsharded(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - query := ins.Query - if ins.Input != nil { - result, err := vcursor.ExecutePrimitive(ctx, ins.Input, bindVars, false) - if err != nil { - return nil, err - } - if len(result.Rows) == 0 { - return &sqltypes.Result{}, nil - } - query = ins.getInsertQueryForUnsharded(result, bindVars) + return nil, err } - _, qr, err := ins.executeUnshardedTableQuery(ctx, vcursor, bindVars, query) - return qr, err -} - -func (ins *Insert) getInsertQueryForUnsharded(result *sqltypes.Result, bindVars map[string]*querypb.BindVariable) string { - var mids sqlparser.Values - for r, inputRow := range result.Rows { - row := sqlparser.ValTuple{} - for c, value := range inputRow { - bvName := insertVarOffset(r, c) - bindVars[bvName] = sqltypes.ValueBindVariable(value) - row = append(row, sqlparser.NewArgument(bvName)) - } - mids = append(mids, row) - } - return ins.Prefix + sqlparser.String(mids) + ins.Suffix + return ins.executeUnshardedTableQuery(ctx, vcursor, ins, bindVars, ins.Query, uint64(insertID)) } -func (ins *Insert) execInsertSharded(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - insertID, err := ins.processGenerateFromValues(ctx, vcursor, bindVars) +func (ins *Insert) insertIntoShardedTable( + ctx context.Context, + vcursor VCursor, + bindVars map[string]*querypb.BindVariable, +) (*sqltypes.Result, error) { + insertID, err := ins.processGenerateFromValues(ctx, vcursor, ins, bindVars) if err != nil { return nil, err } - rss, queries, err := ins.getInsertShardedRoute(ctx, vcursor, bindVars) + rss, queries, err := ins.getInsertShardedQueries(ctx, vcursor, bindVars) if err != nil { return nil, err } - return ins.executeInsertQueries(ctx, vcursor, rss, queries, insertID) + return ins.executeInsertQueries(ctx, vcursor, rss, queries, uint64(insertID)) } func (ins *Insert) executeInsertQueries( @@ -368,7 +163,7 @@ func (ins *Insert) executeInsertQueries( vcursor VCursor, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, - insertID int64, + insertID uint64, ) (*sqltypes.Result, error) { autocommit := (len(rss) == 1 || ins.MultiShardAutocommit) && vcursor.AutocommitApproval() err := allowOnlyPrimary(rss...) @@ -381,347 +176,51 @@ func (ins *Insert) executeInsertQueries( } if insertID != 0 { - result.InsertID = uint64(insertID) + result.InsertID = insertID } return result, nil } -func (ins *Insert) getInsertSelectQueries( - ctx context.Context, - vcursor VCursor, - bindVars map[string]*querypb.BindVariable, - rows []sqltypes.Row, -) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) { - colVindexes := ins.ColVindexes - if len(colVindexes) != len(ins.VindexValueOffset) { - return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex value offsets and vindex info do not match") - } - - // Here we go over the incoming rows and extract values for the vindexes we need to update - shardingCols := make([][]sqltypes.Row, len(colVindexes)) - for _, inputRow := range rows { - for colIdx := range colVindexes { - offsets := ins.VindexValueOffset[colIdx] - row := make(sqltypes.Row, 0, len(offsets)) - for _, offset := range offsets { - if offset == -1 { // value not provided from select query - row = append(row, sqltypes.NULL) - continue - } - row = append(row, inputRow[offset]) - } - shardingCols[colIdx] = append(shardingCols[colIdx], row) - } - } - - keyspaceIDs, err := ins.processPrimary(ctx, vcursor, shardingCols[0], colVindexes[0]) - if err != nil { - return nil, nil, err - } - - for vIdx := 1; vIdx < len(colVindexes); vIdx++ { - colVindex := colVindexes[vIdx] - var err error - if colVindex.Owned { - err = ins.processOwned(ctx, vcursor, shardingCols[vIdx], colVindex, keyspaceIDs) - } else { - err = ins.processUnowned(ctx, vcursor, shardingCols[vIdx], colVindex, keyspaceIDs) - } - if err != nil { - return nil, nil, err - } - } - - var indexes []*querypb.Value - var destinations []key.Destination - for i, ksid := range keyspaceIDs { - if ksid != nil { - indexes = append(indexes, &querypb.Value{ - Value: strconv.AppendInt(nil, int64(i), 10), - }) - destinations = append(destinations, key.DestinationKeyspaceID(ksid)) - } - } - if len(destinations) == 0 { - // In this case, all we have is nil KeyspaceIds, we don't do - // anything at all. - return nil, nil, nil - } - - rss, indexesPerRss, err := vcursor.ResolveDestinations(ctx, ins.Keyspace.Name, indexes, destinations) - if err != nil { - return nil, nil, err - } - - queries := make([]*querypb.BoundQuery, len(rss)) - for i := range rss { - bvs := sqltypes.CopyBindVariables(bindVars) // we don't want to create one huge bindvars for all values - var mids sqlparser.Values - for _, indexValue := range indexesPerRss[i] { - index, _ := strconv.Atoi(string(indexValue.Value)) - if keyspaceIDs[index] != nil { - row := sqlparser.ValTuple{} - for colOffset, value := range rows[index] { - bvName := insertVarOffset(index, colOffset) - bvs[bvName] = sqltypes.ValueBindVariable(value) - row = append(row, sqlparser.NewArgument(bvName)) - } - mids = append(mids, row) - } - } - rewritten := ins.Prefix + sqlparser.String(mids) + ins.Suffix - queries[i] = &querypb.BoundQuery{ - Sql: rewritten, - BindVariables: bvs, - } - } - - return rss, queries, nil -} - -func (ins *Insert) execInsertFromSelect(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - // run the SELECT query - if ins.Input == nil { - return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "something went wrong planning INSERT SELECT") - } - - result, err := vcursor.ExecutePrimitive(ctx, ins.Input, bindVars, false) - if err != nil { - return nil, err - } - if len(result.Rows) == 0 { - return &sqltypes.Result{}, nil - } - - _, qr, err := ins.insertIntoShardedTable(ctx, vcursor, bindVars, result) - return qr, err -} - -// shouldGenerate determines if a sequence value should be generated for a given value -func shouldGenerate(v sqltypes.Value) bool { - if v.IsNull() { - return true - } - - // Unless the NO_AUTO_VALUE_ON_ZERO sql mode is active in mysql, it also - // treats 0 as a value that should generate a new sequence. - n, err := v.ToCastUint64() - if err == nil && n == 0 { - return true - } - - return false -} - -// processGenerateFromValues generates new values using a sequence if necessary. -// If no value was generated, it returns 0. Values are generated only -// for cases where none are supplied. -func (ins *Insert) processGenerateFromValues( - ctx context.Context, - vcursor VCursor, - bindVars map[string]*querypb.BindVariable, -) (insertID int64, err error) { - if ins.Generate == nil { - return 0, nil - } - - // Scan input values to compute the number of values to generate, and - // keep track of where they should be filled. - env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) - resolved, err := env.Evaluate(ins.Generate.Values) - if err != nil { - return 0, err - } - count := int64(0) - values := resolved.TupleValues() - for _, val := range values { - if shouldGenerate(val) { - count++ - } - } - - // If generation is needed, generate the requested number of values (as one call). - if count != 0 { - rss, _, err := vcursor.ResolveDestinations(ctx, ins.Generate.Keyspace.Name, nil, []key.Destination{key.DestinationAnyShard{}}) - if err != nil { - return 0, err - } - if len(rss) != 1 { - return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "auto sequence generation can happen through single shard only, it is getting routed to %d shards", len(rss)) - } - bindVars := map[string]*querypb.BindVariable{"n": sqltypes.Int64BindVariable(count)} - qr, err := vcursor.ExecuteStandalone(ctx, ins, ins.Generate.Query, bindVars, rss[0]) - if err != nil { - return 0, err - } - // If no rows are returned, it's an internal error, and the code - // must panic, which will be caught and reported. - insertID, err = qr.Rows[0][0].ToCastInt64() - if err != nil { - return 0, err - } - } - - // Fill the holes where no value was supplied. - cur := insertID - for i, v := range values { - if shouldGenerate(v) { - bindVars[SeqVarName+strconv.Itoa(i)] = sqltypes.Int64BindVariable(cur) - cur++ - } else { - bindVars[SeqVarName+strconv.Itoa(i)] = sqltypes.ValueBindVariable(v) - } - } - return insertID, nil -} - -// processGenerateFromRows generates new values using a sequence if necessary. -// If no value was generated, it returns 0. Values are generated only -// for cases where none are supplied. -func (ins *Insert) processGenerateFromRows( - ctx context.Context, - vcursor VCursor, - rows []sqltypes.Row, -) (insertID int64, err error) { - if ins.Generate == nil { - return 0, nil - } - var count int64 - offset := ins.Generate.Offset - genColPresent := offset < len(rows[0]) - if genColPresent { - for _, val := range rows { - if val[offset].IsNull() { - count++ - } - } - } else { - count = int64(len(rows)) - } - - if count == 0 { - return 0, nil - } - - // If generation is needed, generate the requested number of values (as one call). - rss, _, err := vcursor.ResolveDestinations(ctx, ins.Generate.Keyspace.Name, nil, []key.Destination{key.DestinationAnyShard{}}) - if err != nil { - return 0, err - } - if len(rss) != 1 { - return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "auto sequence generation can happen through single shard only, it is getting routed to %d shards", len(rss)) - } - bindVars := map[string]*querypb.BindVariable{"n": sqltypes.Int64BindVariable(count)} - qr, err := vcursor.ExecuteStandalone(ctx, ins, ins.Generate.Query, bindVars, rss[0]) - if err != nil { - return 0, err - } - // If no rows are returned, it's an internal error, and the code - // must panic, which will be caught and reported. - insertID, err = qr.Rows[0][0].ToCastInt64() - if err != nil { - return 0, err - } - - used := insertID - for idx, val := range rows { - if genColPresent { - if val[offset].IsNull() { - val[offset] = sqltypes.NewInt64(used) - used++ - } - } else { - rows[idx] = append(val, sqltypes.NewInt64(used)) - used++ - } - } - - return insertID, nil -} - -// getInsertShardedRoute performs all the vindex related work +// getInsertShardedQueries performs all the vindex related work // and returns a map of shard to queries. // Using the primary vindex, it computes the target keyspace ids. // For owned vindexes, it creates entries. // For unowned vindexes with no input values, it reverse maps. // For unowned vindexes with values, it validates. // If it's an IGNORE or ON DUPLICATE key insert, it drops unroutable rows. -func (ins *Insert) getInsertShardedRoute( +func (ins *Insert) getInsertShardedQueries( ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, ) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) { + // vindexRowsValues builds the values of all vindex columns. // the 3-d structure indexes are colVindex, row, col. Note that // ins.Values indexes are colVindex, col, row. So, the conversion // involves a transpose. // The reason we need to transpose is that all the Vindex APIs // require inputs in that format. - vindexRowsValues := make([][]sqltypes.Row, len(ins.VindexValues)) - rowCount := 0 - env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) - colVindexes := ins.ColVindexes - for vIdx, vColValues := range ins.VindexValues { - if len(vColValues) != len(colVindexes[vIdx].Columns) { - return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] supplied vindex column values don't match vschema: %v %v", vColValues, colVindexes[vIdx].Columns) - } - for colIdx, colValues := range vColValues { - rowsResolvedValues := make(sqltypes.Row, 0, len(colValues)) - for _, colValue := range colValues { - result, err := env.Evaluate(colValue) - if err != nil { - return nil, nil, err - } - rowsResolvedValues = append(rowsResolvedValues, result.Value(vcursor.ConnCollation())) - } - // This is the first iteration: allocate for transpose. - if colIdx == 0 { - if len(rowsResolvedValues) == 0 { - return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] rowcount is zero for inserts: %v", rowsResolvedValues) - } - if rowCount == 0 { - rowCount = len(rowsResolvedValues) - } - if rowCount != len(rowsResolvedValues) { - return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] uneven row values for inserts: %d %d", rowCount, len(rowsResolvedValues)) - } - vindexRowsValues[vIdx] = make([]sqltypes.Row, rowCount) - } - // Perform the transpose. - for rowNum, colVal := range rowsResolvedValues { - vindexRowsValues[vIdx][rowNum] = append(vindexRowsValues[vIdx][rowNum], colVal) - } - } + vindexRowsValues, err := ins.buildVindexRowsValues(ctx, vcursor, bindVars) + if err != nil { + return nil, nil, err } // The output from the following 'process' functions is a list of // 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(colVindexes) == 0 { + if len(vindexRowsValues) == 0 || len(ins.ColVindexes) == 0 { return nil, nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.RequiresPrimaryKey, vterrors.PrimaryVindexNotSet, ins.TableName) } - keyspaceIDs, err := ins.processPrimary(ctx, vcursor, vindexRowsValues[0], colVindexes[0]) + + keyspaceIDs, err := ins.processVindexes(ctx, vcursor, vindexRowsValues) if err != nil { return nil, nil, err } - for vIdx := 1; vIdx < len(colVindexes); vIdx++ { - colVindex := colVindexes[vIdx] - var err error - if colVindex.Owned { - err = ins.processOwned(ctx, vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) - } else { - err = ins.processUnowned(ctx, vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) - } - if err != nil { - return nil, nil, err - } - } - // Build 3-d bindvars. Skip rows with nil keyspace ids in case // we're executing an insert ignore. - for vIdx, colVindex := range colVindexes { + for vIdx, colVindex := range ins.ColVindexes { for rowNum, rowColumnKeys := range vindexRowsValues[vIdx] { if keyspaceIDs[rowNum] == nil { // InsertIgnore: skip the row. @@ -794,174 +293,50 @@ func (ins *Insert) getInsertShardedRoute( return rss, queries, nil } -// processPrimary maps the primary vindex values to the keyspace ids. -func (ins *Insert) processPrimary(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex) ([]ksID, error) { - destinations, err := vindexes.Map(ctx, colVindex.Vindex, vcursor, vindexColumnsKeys) - if err != nil { - return nil, err - } - - keyspaceIDs := make([]ksID, len(destinations)) - for i, destination := range destinations { - switch d := destination.(type) { - case key.DestinationKeyspaceID: - // This is a single keyspace id, we're good. - keyspaceIDs[i] = d - case key.DestinationNone: - // No valid keyspace id, we may return an error. - if !ins.Ignore { - return nil, fmt.Errorf("could not map %v to a keyspace id", vindexColumnsKeys[i]) - } - default: - return nil, fmt.Errorf("could not map %v to a unique keyspace id: %v", vindexColumnsKeys[i], destination) - } - } - - return keyspaceIDs, nil -} - -// processOwned creates vindex entries for the values of an owned column. -func (ins *Insert) processOwned(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex, ksids []ksID) error { - if !ins.Ignore { - return colVindex.Vindex.(vindexes.Lookup).Create(ctx, vcursor, vindexColumnsKeys, ksids, false /* ignoreMode */) - } - - // InsertIgnore - var createIndexes []int - var createKeys []sqltypes.Row - var createKsids []ksID - - for rowNum, rowColumnKeys := range vindexColumnsKeys { - if ksids[rowNum] == nil { - continue - } - createIndexes = append(createIndexes, rowNum) - createKeys = append(createKeys, rowColumnKeys) - createKsids = append(createKsids, ksids[rowNum]) - } - if createKeys == nil { - return nil - } - - err := colVindex.Vindex.(vindexes.Lookup).Create(ctx, vcursor, createKeys, createKsids, true) - if err != nil { - return err - } - // After creation, verify that the keys map to the keyspace ids. If not, remove - // those that don't map. - verified, err := vindexes.Verify(ctx, colVindex.Vindex, vcursor, createKeys, createKsids) - if err != nil { - return err - } - for i, v := range verified { - if !v { - ksids[createIndexes[i]] = nil - } - } - return nil -} - -// processUnowned either reverse maps or validates the values for an unowned column. -func (ins *Insert) processUnowned(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex, ksids []ksID) error { - var reverseIndexes []int - var reverseKsids []ksID - - var verifyIndexes []int - var verifyKeys []sqltypes.Row - var verifyKsids []ksID - - // Check if this VIndex is reversible or not. - reversibleVindex, isReversible := colVindex.Vindex.(vindexes.Reversible) - - for rowNum, rowColumnKeys := range vindexColumnsKeys { - // If we weren't able to determine a keyspace id from the primary VIndex, skip this row - if ksids[rowNum] == nil { - continue +func (ins *Insert) buildVindexRowsValues(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([][]sqltypes.Row, error) { + vindexRowsValues := make([][]sqltypes.Row, len(ins.VindexValues)) + rowCount := 0 + env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) + colVindexes := ins.ColVindexes + for vIdx, vColValues := range ins.VindexValues { + if len(vColValues) != len(colVindexes[vIdx].Columns) { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] supplied vindex column values don't match vschema: %v %v", vColValues, colVindexes[vIdx].Columns) } - - if rowColumnKeys[0].IsNull() { - // If the value of the column is `NULL`, but this is a reversible VIndex, - // we will try to generate the value from the keyspace id generated by the primary VIndex. - if isReversible { - reverseIndexes = append(reverseIndexes, rowNum) - reverseKsids = append(reverseKsids, ksids[rowNum]) + for colIdx, colValues := range vColValues { + rowsResolvedValues := make(sqltypes.Row, 0, len(colValues)) + for _, colValue := range colValues { + result, err := env.Evaluate(colValue) + if err != nil { + return nil, err + } + rowsResolvedValues = append(rowsResolvedValues, result.Value(vcursor.ConnCollation())) } - - // Otherwise, don't do anything. Whether `NULL` is a valid value for this column will be - // handled by MySQL. - } else { - // If a value for this column was specified, the keyspace id values from the - // secondary VIndex need to be verified against the keyspace id from the primary VIndex - verifyIndexes = append(verifyIndexes, rowNum) - verifyKeys = append(verifyKeys, rowColumnKeys) - verifyKsids = append(verifyKsids, ksids[rowNum]) - } - } - - // Reverse map values for secondary VIndex columns from the primary VIndex's keyspace id. - if reverseKsids != nil { - reverseKeys, err := reversibleVindex.ReverseMap(vcursor, reverseKsids) - if err != nil { - return err - } - - for i, reverseKey := range reverseKeys { - // Fill the first column with the reverse-mapped value. - vindexColumnsKeys[reverseIndexes[i]][0] = reverseKey - } - } - - // Verify that the keyspace ids generated by the primary and secondary VIndexes match - if verifyIndexes != nil { - // If values were supplied, we validate against keyspace id. - verified, err := vindexes.Verify(ctx, colVindex.Vindex, vcursor, verifyKeys, verifyKsids) - if err != nil { - return err - } - - var mismatchVindexKeys []sqltypes.Row - for i, v := range verified { - rowNum := verifyIndexes[i] - if !v { - if !ins.Ignore { - mismatchVindexKeys = append(mismatchVindexKeys, vindexColumnsKeys[rowNum]) - continue + // This is the first iteration: allocate for transpose. + if colIdx == 0 { + if len(rowsResolvedValues) == 0 { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] rowcount is zero for inserts: %v", rowsResolvedValues) } - - // Skip the whole row if this is a `INSERT IGNORE` or `INSERT ... ON DUPLICATE KEY ...` statement - // but the keyspace ids didn't match. - ksids[verifyIndexes[i]] = nil + if rowCount == 0 { + rowCount = len(rowsResolvedValues) + } + if rowCount != len(rowsResolvedValues) { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] uneven row values for inserts: %d %d", rowCount, len(rowsResolvedValues)) + } + vindexRowsValues[vIdx] = make([]sqltypes.Row, rowCount) + } + // Perform the transpose. + for rowNum, colVal := range rowsResolvedValues { + vindexRowsValues[vIdx][rowNum] = append(vindexRowsValues[vIdx][rowNum], colVal) } - } - - if mismatchVindexKeys != nil { - return fmt.Errorf("values %v for column %v does not map to keyspace ids", mismatchVindexKeys, colVindex.Columns) } } - - return nil -} - -// InsertVarName returns a name for the bind var for this column. This method is used by the planner and engine, -// to make sure they both produce the same names -func InsertVarName(col sqlparser.IdentifierCI, rowNum int) string { - return fmt.Sprintf("_%s_%d", col.CompliantName(), rowNum) -} - -func insertVarOffset(rowNum, colOffset int) string { - return fmt.Sprintf("_c%d_%d", rowNum, colOffset) + return vindexRowsValues, nil } func (ins *Insert) description() PrimitiveDescription { - other := map[string]any{ - "Query": ins.Query, - "TableName": ins.GetTableName(), - "MultiShardAutocommit": ins.MultiShardAutocommit, - "QueryTimeout": ins.QueryTimeout, - "InsertIgnore": ins.Ignore, - "InputAsNonStreaming": ins.ForceNonStreaming, - "NoAutoCommit": ins.PreventAutoCommit, - } + other := ins.commonDesc() + other["Query"] = ins.Query + other["TableName"] = ins.GetTableName() if len(ins.VindexValues) > 0 { valuesOffsets := map[string]string{} @@ -984,35 +359,6 @@ func (ins *Insert) description() PrimitiveDescription { other["VindexValues"] = valuesOffsets } - if ins.Generate != nil { - if ins.Generate.Values == nil { - other["AutoIncrement"] = fmt.Sprintf("%s:Offset(%d)", ins.Generate.Query, ins.Generate.Offset) - } else { - other["AutoIncrement"] = fmt.Sprintf("%s:Values::%s", ins.Generate.Query, sqlparser.String(ins.Generate.Values)) - } - } - - if len(ins.VindexValueOffset) > 0 { - valuesOffsets := map[string]string{} - for idx, ints := range ins.VindexValueOffset { - if len(ins.ColVindexes) < idx { - panic("ins.ColVindexes and ins.VindexValueOffset do not line up") - } - vindex := ins.ColVindexes[idx] - marshal, _ := json.Marshal(ints) - valuesOffsets[vindex.Name] = string(marshal) - } - other["VindexOffsetFromSelect"] = valuesOffsets - } - if len(ins.Mid) > 0 { - mids := slice.Map(ins.Mid, func(from sqlparser.ValTuple) string { - return sqlparser.String(from) - }) - shardQuery := fmt.Sprintf("%s%s%s", ins.Prefix, strings.Join(mids, ", "), ins.Suffix) - if shardQuery != ins.Query { - other["ShardedQuery"] = shardQuery - } - } return PrimitiveDescription{ OperatorType: "Insert", Keyspace: ins.Keyspace, @@ -1022,41 +368,8 @@ func (ins *Insert) description() PrimitiveDescription { } } -func (ins *Insert) insertIntoUnshardedTable(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, result *sqltypes.Result) (int64, *sqltypes.Result, error) { - query := ins.getInsertQueryForUnsharded(result, bindVars) - return ins.executeUnshardedTableQuery(ctx, vcursor, bindVars, query) -} - -func (ins *Insert) executeUnshardedTableQuery(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, query string) (int64, *sqltypes.Result, error) { - insertID, err := ins.processGenerateFromValues(ctx, vcursor, bindVars) - if err != nil { - return 0, nil, err - } - - rss, _, err := vcursor.ResolveDestinations(ctx, ins.Keyspace.Name, nil, []key.Destination{key.DestinationAllShards{}}) - if err != nil { - return 0, nil, err - } - if len(rss) != 1 { - return 0, nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Keyspace does not have exactly one shard: %v", rss) - } - err = allowOnlyPrimary(rss...) - if err != nil { - return 0, nil, err - } - qr, err := execShard(ctx, ins, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */) - if err != nil { - return 0, nil, err - } - - // If processGenerateFromValues generated new values, it supersedes - // any ids that MySQL might have generated. If both generated - // values, we don't return an error because this behavior - // is required to support migration. - if insertID != 0 { - qr.InsertID = uint64(insertID) - } else { - insertID = int64(qr.InsertID) - } - return insertID, qr, nil +// InsertVarName returns a name for the bind var for this column. This method is used by the planner and engine, +// to make sure they both produce the same names +func InsertVarName(col sqlparser.IdentifierCI, rowNum int) string { + return fmt.Sprintf("_%s_%d", col.CompliantName(), rowNum) } diff --git a/go/vt/vtgate/engine/insert_common.go b/go/vt/vtgate/engine/insert_common.go new file mode 100644 index 00000000000..d0a14feec26 --- /dev/null +++ b/go/vt/vtgate/engine/insert_common.go @@ -0,0 +1,480 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "strings" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +type ( + InsertCommon struct { + // Opcode is the execution opcode. + Opcode InsertOpcode + + // Keyspace specifies the keyspace to send the query to. + Keyspace *vindexes.Keyspace + + // Ignore is for INSERT IGNORE and INSERT...ON DUPLICATE KEY constructs + // for sharded cases. + Ignore bool + + // TableName is the name of the table on which row will be inserted. + TableName string + + // Option to override the standard behavior and allow a multi-shard insert + // to use single round trip autocommit. + // + // This is a clear violation of the SQL semantics since it means the statement + // is not atomic in the presence of PK conflicts on one shard and not another. + // However, some application use cases would prefer that the statement partially + // succeed in order to get the performance benefits of autocommit. + MultiShardAutocommit bool + + // QueryTimeout contains the optional timeout (in milliseconds) to apply to this query + QueryTimeout int + + // ForceNonStreaming is true when the insert table and select table are same. + // This will avoid locking by the select table. + ForceNonStreaming bool + + PreventAutoCommit bool + + // Generate is only set for inserts where a sequence must be generated. + Generate *Generate + + // ColVindexes are the vindexes that will use the VindexValues + ColVindexes []*vindexes.ColumnVindex + + // Prefix, Suffix are for sharded insert plans. + Prefix string + Suffix string + + // Insert needs tx handling + txNeeded + } + + ksID = []byte + + // Generate represents the instruction to generate + // a value from a sequence. + Generate struct { + Keyspace *vindexes.Keyspace + Query string + // Values are the supplied values for the column, which + // will be stored as a list within the expression. New + // values will be generated based on how many were not + // supplied (NULL). + Values evalengine.Expr + // Insert using Select, offset for auto increment column + Offset int + } + + // InsertOpcode is a number representing the opcode + // for the Insert primitive. + InsertOpcode int +) + +const nextValBV = "n" + +const ( + // InsertUnsharded is for routing an insert statement + // to an unsharded keyspace. + InsertUnsharded = InsertOpcode(iota) + // InsertSharded is for routing an insert statement + // to individual shards. Requires: A list of Values, one + // for each ColVindex. If the table has an Autoinc column, + // A Generate subplan must be created. + InsertSharded +) + +var insName = map[InsertOpcode]string{ + InsertUnsharded: "InsertUnsharded", + InsertSharded: "InsertSharded", +} + +// String returns the opcode +func (code InsertOpcode) String() string { + return strings.ReplaceAll(insName[code], "Insert", "") +} + +// MarshalJSON serializes the InsertOpcode as a JSON string. +// It's used for testing and diagnostics. +func (code InsertOpcode) MarshalJSON() ([]byte, error) { + return json.Marshal(insName[code]) +} + +// GetKeyspaceName specifies the Keyspace that this primitive routes to. +func (ic *InsertCommon) GetKeyspaceName() string { + return ic.Keyspace.Name +} + +// GetTableName specifies the table that this primitive routes to. +func (ic *InsertCommon) GetTableName() string { + return ic.TableName +} + +// GetFields fetches the field info. +func (ic *InsertCommon) GetFields(context.Context, VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return nil, vterrors.VT13001("unexpected fields call for insert query") +} + +func (ins *InsertCommon) executeUnshardedTableQuery(ctx context.Context, vcursor VCursor, loggingPrimitive Primitive, bindVars map[string]*querypb.BindVariable, query string, insertID uint64) (*sqltypes.Result, error) { + rss, _, err := vcursor.ResolveDestinations(ctx, ins.Keyspace.Name, nil, []key.Destination{key.DestinationAllShards{}}) + if err != nil { + return nil, err + } + if len(rss) != 1 { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Keyspace does not have exactly one shard: %v", rss) + } + err = allowOnlyPrimary(rss...) + if err != nil { + return nil, err + } + qr, err := execShard(ctx, loggingPrimitive, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */) + if err != nil { + return nil, err + } + + // If processGenerateFromValues generated new values, it supersedes + // any ids that MySQL might have generated. If both generated + // values, we don't return an error because this behavior + // is required to support migration. + if insertID != 0 { + qr.InsertID = insertID + } + return qr, nil +} + +func (ins *InsertCommon) processVindexes(ctx context.Context, vcursor VCursor, vindexRowsValues [][]sqltypes.Row) ([]ksID, error) { + colVindexes := ins.ColVindexes + keyspaceIDs, err := ins.processPrimary(ctx, vcursor, vindexRowsValues[0], colVindexes[0]) + if err != nil { + return nil, err + } + + for vIdx := 1; vIdx < len(colVindexes); vIdx++ { + colVindex := colVindexes[vIdx] + if colVindex.Owned { + err = ins.processOwned(ctx, vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) + } else { + err = ins.processUnowned(ctx, vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) + } + if err != nil { + return nil, err + } + } + return keyspaceIDs, nil +} + +// processPrimary maps the primary vindex values to the keyspace ids. +func (ic *InsertCommon) processPrimary(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex) ([]ksID, error) { + destinations, err := vindexes.Map(ctx, colVindex.Vindex, vcursor, vindexColumnsKeys) + if err != nil { + return nil, err + } + + keyspaceIDs := make([]ksID, len(destinations)) + for i, destination := range destinations { + switch d := destination.(type) { + case key.DestinationKeyspaceID: + // This is a single keyspace id, we're good. + keyspaceIDs[i] = d + case key.DestinationNone: + // No valid keyspace id, we may return an error. + if !ic.Ignore { + return nil, fmt.Errorf("could not map %v to a keyspace id", vindexColumnsKeys[i]) + } + default: + return nil, fmt.Errorf("could not map %v to a unique keyspace id: %v", vindexColumnsKeys[i], destination) + } + } + + return keyspaceIDs, nil +} + +// processOwned creates vindex entries for the values of an owned column. +func (ic *InsertCommon) processOwned(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex, ksids []ksID) error { + if !ic.Ignore { + return colVindex.Vindex.(vindexes.Lookup).Create(ctx, vcursor, vindexColumnsKeys, ksids, false /* ignoreMode */) + } + + // InsertIgnore + var createIndexes []int + var createKeys []sqltypes.Row + var createKsids []ksID + + for rowNum, rowColumnKeys := range vindexColumnsKeys { + if ksids[rowNum] == nil { + continue + } + createIndexes = append(createIndexes, rowNum) + createKeys = append(createKeys, rowColumnKeys) + createKsids = append(createKsids, ksids[rowNum]) + } + if createKeys == nil { + return nil + } + + err := colVindex.Vindex.(vindexes.Lookup).Create(ctx, vcursor, createKeys, createKsids, true) + if err != nil { + return err + } + // After creation, verify that the keys map to the keyspace ids. If not, remove + // those that don't map. + verified, err := vindexes.Verify(ctx, colVindex.Vindex, vcursor, createKeys, createKsids) + if err != nil { + return err + } + for i, v := range verified { + if !v { + ksids[createIndexes[i]] = nil + } + } + return nil +} + +// processUnowned either reverse maps or validates the values for an unowned column. +func (ic *InsertCommon) processUnowned(ctx context.Context, vcursor VCursor, vindexColumnsKeys []sqltypes.Row, colVindex *vindexes.ColumnVindex, ksids []ksID) error { + var reverseIndexes []int + var reverseKsids []ksID + + var verifyIndexes []int + var verifyKeys []sqltypes.Row + var verifyKsids []ksID + + // Check if this VIndex is reversible or not. + reversibleVindex, isReversible := colVindex.Vindex.(vindexes.Reversible) + + for rowNum, rowColumnKeys := range vindexColumnsKeys { + // If we weren't able to determine a keyspace id from the primary VIndex, skip this row + if ksids[rowNum] == nil { + continue + } + + if rowColumnKeys[0].IsNull() { + // If the value of the column is `NULL`, but this is a reversible VIndex, + // we will try to generate the value from the keyspace id generated by the primary VIndex. + if isReversible { + reverseIndexes = append(reverseIndexes, rowNum) + reverseKsids = append(reverseKsids, ksids[rowNum]) + } + + // Otherwise, don't do anything. Whether `NULL` is a valid value for this column will be + // handled by MySQL. + } else { + // If a value for this column was specified, the keyspace id values from the + // secondary VIndex need to be verified against the keyspace id from the primary VIndex + verifyIndexes = append(verifyIndexes, rowNum) + verifyKeys = append(verifyKeys, rowColumnKeys) + verifyKsids = append(verifyKsids, ksids[rowNum]) + } + } + + // Reverse map values for secondary VIndex columns from the primary VIndex's keyspace id. + if reverseKsids != nil { + reverseKeys, err := reversibleVindex.ReverseMap(vcursor, reverseKsids) + if err != nil { + return err + } + + for i, reverseKey := range reverseKeys { + // Fill the first column with the reverse-mapped value. + vindexColumnsKeys[reverseIndexes[i]][0] = reverseKey + } + } + + // Verify that the keyspace ids generated by the primary and secondary VIndexes match + if verifyIndexes != nil { + // If values were supplied, we validate against keyspace id. + verified, err := vindexes.Verify(ctx, colVindex.Vindex, vcursor, verifyKeys, verifyKsids) + if err != nil { + return err + } + + var mismatchVindexKeys []sqltypes.Row + for i, v := range verified { + rowNum := verifyIndexes[i] + if !v { + if !ic.Ignore { + mismatchVindexKeys = append(mismatchVindexKeys, vindexColumnsKeys[rowNum]) + continue + } + + // Skip the whole row if this is a `INSERT IGNORE` or `INSERT ... ON DUPLICATE KEY ...` statement + // but the keyspace ids didn't match. + ksids[verifyIndexes[i]] = nil + } + } + + if mismatchVindexKeys != nil { + return fmt.Errorf("values %v for column %v does not map to keyspace ids", mismatchVindexKeys, colVindex.Columns) + } + } + + return nil +} + +// processGenerateFromSelect generates new values using a sequence if necessary. +// If no value was generated, it returns 0. Values are generated only +// for cases where none are supplied. +func (ic *InsertCommon) processGenerateFromSelect( + ctx context.Context, + vcursor VCursor, + loggingPrimitive Primitive, + rows []sqltypes.Row, +) (insertID int64, err error) { + if ic.Generate == nil { + return 0, nil + } + var count int64 + offset := ic.Generate.Offset + genColPresent := offset < len(rows[0]) + if genColPresent { + for _, row := range rows { + if shouldGenerate(row[offset], evalengine.ParseSQLMode(vcursor.SQLMode())) { + count++ + } + } + } else { + count = int64(len(rows)) + } + + if count == 0 { + return 0, nil + } + + insertID, err = ic.execGenerate(ctx, vcursor, loggingPrimitive, count) + if err != nil { + return 0, err + } + + used := insertID + for idx, val := range rows { + if genColPresent { + if shouldGenerate(val[offset], evalengine.ParseSQLMode(vcursor.SQLMode())) { + val[offset] = sqltypes.NewInt64(used) + used++ + } + } else { + rows[idx] = append(val, sqltypes.NewInt64(used)) + used++ + } + } + + return insertID, nil +} + +// processGenerateFromValues generates new values using a sequence if necessary. +// If no value was generated, it returns 0. Values are generated only +// for cases where none are supplied. +func (ic *InsertCommon) processGenerateFromValues( + ctx context.Context, + vcursor VCursor, + loggingPrimitive Primitive, + bindVars map[string]*querypb.BindVariable, +) (insertID int64, err error) { + if ic.Generate == nil { + return 0, nil + } + + // Scan input values to compute the number of values to generate, and + // keep track of where they should be filled. + env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) + resolved, err := env.Evaluate(ic.Generate.Values) + if err != nil { + return 0, err + } + count := int64(0) + values := resolved.TupleValues() + for _, val := range values { + if shouldGenerate(val, evalengine.ParseSQLMode(vcursor.SQLMode())) { + count++ + } + } + + // If generation is needed, generate the requested number of values (as one call). + if count != 0 { + insertID, err = ic.execGenerate(ctx, vcursor, loggingPrimitive, count) + if err != nil { + return 0, err + } + } + + // Fill the holes where no value was supplied. + cur := insertID + for i, v := range values { + if shouldGenerate(v, evalengine.ParseSQLMode(vcursor.SQLMode())) { + bindVars[SeqVarName+strconv.Itoa(i)] = sqltypes.Int64BindVariable(cur) + cur++ + } else { + bindVars[SeqVarName+strconv.Itoa(i)] = sqltypes.ValueBindVariable(v) + } + } + return insertID, nil +} + +func (ic *InsertCommon) execGenerate(ctx context.Context, vcursor VCursor, loggingPrimitive Primitive, count int64) (int64, error) { + // If generation is needed, generate the requested number of values (as one call). + rss, _, err := vcursor.ResolveDestinations(ctx, ic.Generate.Keyspace.Name, nil, []key.Destination{key.DestinationAnyShard{}}) + if err != nil { + return 0, err + } + if len(rss) != 1 { + return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "auto sequence generation can happen through single shard only, it is getting routed to %d shards", len(rss)) + } + bindVars := map[string]*querypb.BindVariable{nextValBV: sqltypes.Int64BindVariable(count)} + qr, err := vcursor.ExecuteStandalone(ctx, loggingPrimitive, ic.Generate.Query, bindVars, rss[0]) + if err != nil { + return 0, err + } + // If no rows are returned, it's an internal error, and the code + // must panic, which will be caught and reported. + return qr.Rows[0][0].ToCastInt64() +} + +// shouldGenerate determines if a sequence value should be generated for a given value +func shouldGenerate(v sqltypes.Value, sqlmode evalengine.SQLMode) bool { + if v.IsNull() { + return true + } + + // Unless the NO_AUTO_VALUE_ON_ZERO sql mode is active in mysql, it also + // treats 0 as a value that should generate a new sequence. + value, err := evalengine.CoerceTo(v, sqltypes.Uint64, sqlmode) + if err != nil { + return false + } + + id, err := value.ToCastUint64() + if err != nil { + return false + } + + return id == 0 +} diff --git a/go/vt/vtgate/engine/insert_select.go b/go/vt/vtgate/engine/insert_select.go new file mode 100644 index 00000000000..d36176922dc --- /dev/null +++ b/go/vt/vtgate/engine/insert_select.go @@ -0,0 +1,423 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "sync" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +var _ Primitive = (*InsertSelect)(nil) + +type ( + // InsertSelect represents the instructions to perform an insert operation with input rows from a select. + InsertSelect struct { + InsertCommon + + // Input is a select query plan to retrieve results for inserting data. + Input Primitive + + // VindexValueOffset stores the offset for each column in the ColumnVindex + // that will appear in the result set of the select query. + VindexValueOffset [][]int + } +) + +// newInsertSelect creates a new InsertSelect. +func newInsertSelect( + ignore bool, + keyspace *vindexes.Keyspace, + table *vindexes.Table, + prefix string, + suffix string, + vv [][]int, + input Primitive, +) *InsertSelect { + ins := &InsertSelect{ + InsertCommon: InsertCommon{ + Ignore: ignore, + Keyspace: keyspace, + Prefix: prefix, + Suffix: suffix, + }, + Input: input, + VindexValueOffset: vv, + } + if table != nil { + ins.TableName = table.Name.String() + for _, colVindex := range table.ColumnVindexes { + if colVindex.IsPartialVindex() { + continue + } + ins.ColVindexes = append(ins.ColVindexes, colVindex) + } + } + return ins +} + +func (ins *InsertSelect) Inputs() ([]Primitive, []map[string]any) { + return []Primitive{ins.Input}, nil +} + +// RouteType returns a description of the query routing type used by the primitive +func (ins *InsertSelect) RouteType() string { + return "InsertSelect" +} + +// TryExecute performs a non-streaming exec. +func (ins *InsertSelect) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { + ctx, cancelFunc := addQueryTimeout(ctx, vcursor, ins.QueryTimeout) + defer cancelFunc() + + if ins.Keyspace.Sharded { + return ins.execInsertSharded(ctx, vcursor, bindVars) + } + return ins.execInsertUnsharded(ctx, vcursor, bindVars) +} + +// TryStreamExecute performs a streaming exec. +func (ins *InsertSelect) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + if ins.ForceNonStreaming { + res, err := ins.TryExecute(ctx, vcursor, bindVars, wantfields) + if err != nil { + return err + } + return callback(res) + } + ctx, cancelFunc := addQueryTimeout(ctx, vcursor, ins.QueryTimeout) + defer cancelFunc() + + sharded := ins.Keyspace.Sharded + output := &sqltypes.Result{} + err := ins.execSelectStreaming(ctx, vcursor, bindVars, func(irr insertRowsResult) error { + if len(irr.rows) == 0 { + return nil + } + + var qr *sqltypes.Result + var err error + if sharded { + qr, err = ins.insertIntoShardedTable(ctx, vcursor, bindVars, irr) + } else { + qr, err = ins.insertIntoUnshardedTable(ctx, vcursor, bindVars, irr) + } + if err != nil { + return err + } + + output.RowsAffected += qr.RowsAffected + // InsertID needs to be updated to the least insertID value in sqltypes.Result + if output.InsertID == 0 || output.InsertID > qr.InsertID { + output.InsertID = qr.InsertID + } + return nil + }) + if err != nil { + return err + } + return callback(output) +} + +func (ins *InsertSelect) execInsertUnsharded(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + irr, err := ins.execSelect(ctx, vcursor, bindVars) + if err != nil { + return nil, err + } + if len(irr.rows) == 0 { + return &sqltypes.Result{}, nil + } + return ins.insertIntoUnshardedTable(ctx, vcursor, bindVars, irr) +} + +func (ins *InsertSelect) insertIntoUnshardedTable(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, irr insertRowsResult) (*sqltypes.Result, error) { + query := ins.getInsertUnshardedQuery(irr.rows, bindVars) + return ins.executeUnshardedTableQuery(ctx, vcursor, ins, bindVars, query, irr.insertID) +} + +func (ins *InsertSelect) getInsertUnshardedQuery(rows []sqltypes.Row, bindVars map[string]*querypb.BindVariable) string { + var mids sqlparser.Values + for r, inputRow := range rows { + row := sqlparser.ValTuple{} + for c, value := range inputRow { + bvName := insertVarOffset(r, c) + bindVars[bvName] = sqltypes.ValueBindVariable(value) + row = append(row, sqlparser.NewArgument(bvName)) + } + mids = append(mids, row) + } + return ins.Prefix + sqlparser.String(mids) + ins.Suffix +} + +func (ins *InsertSelect) insertIntoShardedTable( + ctx context.Context, + vcursor VCursor, + bindVars map[string]*querypb.BindVariable, + irr insertRowsResult, +) (*sqltypes.Result, error) { + rss, queries, err := ins.getInsertShardedQueries(ctx, vcursor, bindVars, irr.rows) + if err != nil { + return nil, err + } + + qr, err := ins.executeInsertQueries(ctx, vcursor, rss, queries, irr.insertID) + if err != nil { + return nil, err + } + qr.InsertID = uint64(irr.insertID) + return qr, nil +} + +func (ins *InsertSelect) executeInsertQueries( + ctx context.Context, + vcursor VCursor, + rss []*srvtopo.ResolvedShard, + queries []*querypb.BoundQuery, + insertID uint64, +) (*sqltypes.Result, error) { + autocommit := (len(rss) == 1 || ins.MultiShardAutocommit) && vcursor.AutocommitApproval() + err := allowOnlyPrimary(rss...) + if err != nil { + return nil, err + } + result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /* rollbackOnError */, autocommit) + if errs != nil { + return nil, vterrors.Aggregate(errs) + } + + if insertID != 0 { + result.InsertID = insertID + } + return result, nil +} + +func (ins *InsertSelect) getInsertShardedQueries( + ctx context.Context, + vcursor VCursor, + bindVars map[string]*querypb.BindVariable, + rows []sqltypes.Row, +) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) { + vindexRowsValues, err := ins.buildVindexRowsValues(rows) + if err != nil { + return nil, nil, err + } + + keyspaceIDs, err := ins.processVindexes(ctx, vcursor, vindexRowsValues) + if err != nil { + return nil, nil, err + } + + var indexes []*querypb.Value + var destinations []key.Destination + for i, ksid := range keyspaceIDs { + if ksid != nil { + indexes = append(indexes, &querypb.Value{ + Value: strconv.AppendInt(nil, int64(i), 10), + }) + destinations = append(destinations, key.DestinationKeyspaceID(ksid)) + } + } + if len(destinations) == 0 { + // In this case, all we have is nil KeyspaceIds, we don't do + // anything at all. + return nil, nil, nil + } + + rss, indexesPerRss, err := vcursor.ResolveDestinations(ctx, ins.Keyspace.Name, indexes, destinations) + if err != nil { + return nil, nil, err + } + + queries := make([]*querypb.BoundQuery, len(rss)) + for i := range rss { + bvs := sqltypes.CopyBindVariables(bindVars) // we don't want to create one huge bindvars for all values + var mids sqlparser.Values + for _, indexValue := range indexesPerRss[i] { + index, _ := strconv.Atoi(string(indexValue.Value)) + if keyspaceIDs[index] != nil { + row := sqlparser.ValTuple{} + for colOffset, value := range rows[index] { + bvName := insertVarOffset(index, colOffset) + bvs[bvName] = sqltypes.ValueBindVariable(value) + row = append(row, sqlparser.NewArgument(bvName)) + } + mids = append(mids, row) + } + } + rewritten := ins.Prefix + sqlparser.String(mids) + ins.Suffix + queries[i] = &querypb.BoundQuery{ + Sql: rewritten, + BindVariables: bvs, + } + } + + return rss, queries, nil +} + +func (ins *InsertSelect) buildVindexRowsValues(rows []sqltypes.Row) ([][]sqltypes.Row, error) { + colVindexes := ins.ColVindexes + if len(colVindexes) != len(ins.VindexValueOffset) { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex value offsets and vindex info do not match") + } + + // Here we go over the incoming rows and extract values for the vindexes we need to update + vindexRowsValues := make([][]sqltypes.Row, len(colVindexes)) + for _, inputRow := range rows { + for colIdx := range colVindexes { + offsets := ins.VindexValueOffset[colIdx] + row := make(sqltypes.Row, 0, len(offsets)) + for _, offset := range offsets { + if offset == -1 { // value not provided from select query + row = append(row, sqltypes.NULL) + continue + } + row = append(row, inputRow[offset]) + } + vindexRowsValues[colIdx] = append(vindexRowsValues[colIdx], row) + } + } + return vindexRowsValues, nil +} + +func (ins *InsertSelect) execInsertSharded(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + result, err := ins.execSelect(ctx, vcursor, bindVars) + if err != nil { + return nil, err + } + if len(result.rows) == 0 { + return &sqltypes.Result{}, nil + } + + return ins.insertIntoShardedTable(ctx, vcursor, bindVars, result) +} + +func (ins *InsertSelect) description() PrimitiveDescription { + other := ins.commonDesc() + other["TableName"] = ins.GetTableName() + + if len(ins.VindexValueOffset) > 0 { + valuesOffsets := map[string]string{} + for idx, ints := range ins.VindexValueOffset { + if len(ins.ColVindexes) < idx { + panic("ins.ColVindexes and ins.VindexValueOffset do not line up") + } + vindex := ins.ColVindexes[idx] + marshal, _ := json.Marshal(ints) + valuesOffsets[vindex.Name] = string(marshal) + } + other["VindexOffsetFromSelect"] = valuesOffsets + } + + return PrimitiveDescription{ + OperatorType: "Insert", + Keyspace: ins.Keyspace, + Variant: "Select", + TargetTabletType: topodatapb.TabletType_PRIMARY, + Other: other, + } +} + +func (ic *InsertCommon) commonDesc() map[string]any { + other := map[string]any{ + "MultiShardAutocommit": ic.MultiShardAutocommit, + "QueryTimeout": ic.QueryTimeout, + "InsertIgnore": ic.Ignore, + "InputAsNonStreaming": ic.ForceNonStreaming, + "NoAutoCommit": ic.PreventAutoCommit, + } + + if ic.Generate != nil { + if ic.Generate.Values == nil { + other["AutoIncrement"] = fmt.Sprintf("%s:Offset(%d)", ic.Generate.Query, ic.Generate.Offset) + } else { + other["AutoIncrement"] = fmt.Sprintf("%s:Values::%s", ic.Generate.Query, sqlparser.String(ic.Generate.Values)) + } + } + return other +} + +func insertVarOffset(rowNum, colOffset int) string { + return fmt.Sprintf("_c%d_%d", rowNum, colOffset) +} + +type insertRowsResult struct { + rows []sqltypes.Row + insertID uint64 +} + +func (ins *InsertSelect) execSelect( + ctx context.Context, + vcursor VCursor, + bindVars map[string]*querypb.BindVariable, +) (insertRowsResult, error) { + res, err := vcursor.ExecutePrimitive(ctx, ins.Input, bindVars, false) + if err != nil || len(res.Rows) == 0 { + return insertRowsResult{}, err + } + + insertID, err := ins.processGenerateFromSelect(ctx, vcursor, ins, res.Rows) + if err != nil { + return insertRowsResult{}, err + } + + return insertRowsResult{ + rows: res.Rows, + insertID: uint64(insertID), + }, nil +} + +func (ins *InsertSelect) execSelectStreaming( + ctx context.Context, + vcursor VCursor, + bindVars map[string]*querypb.BindVariable, + callback func(irr insertRowsResult) error, +) error { + var mu sync.Mutex + return vcursor.StreamExecutePrimitiveStandalone(ctx, ins.Input, bindVars, false, func(result *sqltypes.Result) error { + if len(result.Rows) == 0 { + return nil + } + + // should process only one chunk at a time. + // as parallel chunk insert will try to use the same transaction in the vttablet + // this will cause transaction in use error out with "transaction in use" error. + mu.Lock() + defer mu.Unlock() + + insertID, err := ins.processGenerateFromSelect(ctx, vcursor, ins, result.Rows) + if err != nil { + return err + } + + return callback(insertRowsResult{ + rows: result.Rows, + insertID: uint64(insertID), + }) + }) +} diff --git a/go/vt/vtgate/engine/insert_test.go b/go/vt/vtgate/engine/insert_test.go index d08ef856275..4ee8431f083 100644 --- a/go/vt/vtgate/engine/insert_test.go +++ b/go/vt/vtgate/engine/insert_test.go @@ -33,7 +33,7 @@ import ( ) func TestInsertUnsharded(t *testing.T) { - ins := NewQueryInsert( + ins := newQueryInsert( InsertUnsharded, &vindexes.Keyspace{ Name: "ks", @@ -68,7 +68,7 @@ func TestInsertUnsharded(t *testing.T) { } func TestInsertUnshardedGenerate(t *testing.T) { - ins := NewQueryInsert( + ins := newQueryInsert( InsertUnsharded, &vindexes.Keyspace{ Name: "ks", @@ -121,7 +121,7 @@ func TestInsertUnshardedGenerate(t *testing.T) { } func TestInsertUnshardedGenerate_Zeros(t *testing.T) { - ins := NewQueryInsert( + ins := newQueryInsert( InsertUnsharded, &vindexes.Keyspace{ Name: "ks", @@ -198,7 +198,7 @@ func TestInsertShardedSimple(t *testing.T) { ks := vs.Keyspaces["sharded"] // A single row insert should be autocommitted - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -232,7 +232,7 @@ func TestInsertShardedSimple(t *testing.T) { }) // Multiple rows are not autocommitted by default - ins = NewInsert( + ins = newInsert( InsertSharded, false, ks.Keyspace, @@ -272,7 +272,7 @@ func TestInsertShardedSimple(t *testing.T) { }) // Optional flag overrides autocommit - ins = NewInsert( + ins = newInsert( InsertSharded, false, ks.Keyspace, @@ -344,7 +344,7 @@ func TestInsertShardedFail(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -394,7 +394,7 @@ func TestInsertShardedGenerate(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -513,7 +513,7 @@ func TestInsertShardedOwned(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -623,7 +623,7 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -700,7 +700,7 @@ func TestInsertShardedGeo(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -806,7 +806,7 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, true, ks.Keyspace, @@ -962,7 +962,7 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, true, ks.Keyspace, @@ -1060,7 +1060,7 @@ func TestInsertShardedUnownedVerify(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -1188,7 +1188,7 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, true, ks.Keyspace, @@ -1294,7 +1294,7 @@ func TestInsertShardedIgnoreUnownedVerifyFail(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -1371,7 +1371,7 @@ func TestInsertShardedUnownedReverseMap(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -1485,7 +1485,7 @@ func TestInsertShardedUnownedReverseMapSuccess(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( + ins := newInsert( InsertSharded, false, ks.Keyspace, @@ -1533,21 +1533,13 @@ func TestInsertSelectSimple(t *testing.T) { ks := vs.Keyspaces["sharded"] // A single row insert should be autocommitted - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{{1}}, - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - - ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t1"].ColumnVindexes...) - ins.Prefix = "prefix " - ins.Suffix = " suffix" + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + ins := newInsertSelect(false, ks.Keyspace, ks.Tables["t1"], "prefix ", " suffix", [][]int{{1}}, rb) vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -1623,23 +1615,24 @@ func TestInsertSelectOwned(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{ + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t1"], + "prefix ", + " suffix", + [][]int{ {1}, // The primary vindex has a single column as sharding key {0}}, // the onecol vindex uses the 'name' column - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - - ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t1"].ColumnVindexes...) - ins.Prefix = "prefix " - ins.Suffix = " suffix" + rb, + ) vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -1723,24 +1716,22 @@ func TestInsertSelectGenerate(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := NewInsert( - InsertSelect, - false, - ks.Keyspace, - nil, - ks.Tables["t1"], - "prefix ", - nil, - " suffix") - ins.Query = "dummy_insert" - ins.VindexValueOffset = [][]int{{1}} // The primary vindex has a single column as sharding key - ins.Input = &Route{ + rb := &Route{ Query: "dummy_select", FieldQuery: "dummy_field_query", RoutingParameters: &RoutingParameters{ Opcode: Scatter, Keyspace: ks.Keyspace}} + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t1"], + "prefix ", + " suffix", + [][]int{{1}}, // The primary vindex has a single column as sharding key + rb, + ) ins.Generate = &Generate{ Keyspace: &vindexes.Keyspace{ Name: "ks2", @@ -1760,7 +1751,7 @@ func TestInsertSelectGenerate(t *testing.T) { "varchar|int64"), "a|1", "a|null", - "b|null"), + "b|0"), // This is the result for the sequence query sqltypes.MakeTestResult( sqltypes.MakeTestFields( @@ -1817,20 +1808,23 @@ func TestStreamingInsertSelectGenerate(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{ - {1}}, // The primary vindex has a single column as sharding key - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - ins.ColVindexes = ks.Tables["t1"].ColumnVindexes + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t1"], + "prefix ", + " suffix", + [][]int{ + {1}}, // The primary vindex has a single column as sharding key + rb, + ) ins.Generate = &Generate{ Keyspace: &vindexes.Keyspace{ Name: "ks2", @@ -1839,8 +1833,6 @@ func TestStreamingInsertSelectGenerate(t *testing.T) { Query: "dummy_generate", Offset: 1, } - ins.Prefix = "prefix " - ins.Suffix = " suffix" vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -1913,20 +1905,21 @@ func TestInsertSelectGenerateNotProvided(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{ - {1}}, // The primary vindex has a single column as sharding key - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - - ins.ColVindexes = ks.Tables["t1"].ColumnVindexes + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t1"], + "prefix ", + " suffix", + [][]int{{1}}, // The primary vindex has a single column as sharding key, + rb, + ) ins.Generate = &Generate{ Keyspace: &vindexes.Keyspace{ Name: "ks2", @@ -1935,8 +1928,6 @@ func TestInsertSelectGenerateNotProvided(t *testing.T) { Query: "dummy_generate", Offset: 2, } - ins.Prefix = "prefix " - ins.Suffix = " suffix" vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -2001,20 +1992,21 @@ func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{ - {1}}, // The primary vindex has a single column as sharding key - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - - ins.ColVindexes = ks.Tables["t1"].ColumnVindexes + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t1"], + "prefix ", + " suffix", + [][]int{{1}}, // The primary vindex has a single column as sharding key, + rb, + ) ins.Generate = &Generate{ Keyspace: &vindexes.Keyspace{ Name: "ks2", @@ -2023,8 +2015,6 @@ func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { Query: "dummy_generate", Offset: 2, } - ins.Prefix = "prefix " - ins.Suffix = " suffix" vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -2099,22 +2089,21 @@ func TestInsertSelectUnowned(t *testing.T) { vs := vindexes.BuildVSchema(invschema) ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: ks.Keyspace, - Query: "dummy_insert", - VindexValueOffset: [][]int{ - {0}}, // the onecol vindex as unowned lookup sharding column - Input: &Route{ - Query: "dummy_select", - FieldQuery: "dummy_field_query", - RoutingParameters: &RoutingParameters{ - Opcode: Scatter, - Keyspace: ks.Keyspace}}} - - ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t2"].ColumnVindexes...) - ins.Prefix = "prefix " - ins.Suffix = " suffix" + rb := &Route{ + Query: "dummy_select", + FieldQuery: "dummy_field_query", + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: ks.Keyspace}} + ins := newInsertSelect( + false, + ks.Keyspace, + ks.Tables["t2"], + "prefix ", + " suffix", + [][]int{{0}}, // // the onecol vindex as unowned lookup sharding column + rb, + ) vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -2220,16 +2209,15 @@ func TestInsertSelectShardingCases(t *testing.T) { RoutingParameters: &RoutingParameters{Opcode: Unsharded, Keyspace: uks2.Keyspace}} // sks1 and sks2 - ins := &Insert{ - Opcode: InsertSelect, - Keyspace: sks1.Keyspace, - Query: "dummy_insert", - Prefix: "prefix ", - Suffix: " suffix", - ColVindexes: sks1.Tables["s1"].ColumnVindexes, - VindexValueOffset: [][]int{{0}}, - Input: sRoute, - } + ins := newInsertSelect( + false, + sks1.Keyspace, + sks1.Tables["s1"], + "prefix ", + " suffix", + [][]int{{0}}, + sRoute, + ) vc := &loggingVCursor{ resolvedTargetTabletType: topodatapb.TabletType_PRIMARY, @@ -2298,14 +2286,15 @@ func TestInsertSelectShardingCases(t *testing.T) { `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) // uks1 and sks2 - ins = &Insert{ - Opcode: InsertUnsharded, - Keyspace: uks1.Keyspace, - Query: "dummy_insert", - Prefix: "prefix ", - Suffix: " suffix", - Input: sRoute, - } + ins = newInsertSelect( + false, + uks1.Keyspace, + nil, + "prefix ", + " suffix", + nil, + sRoute, + ) vc.Rewind() _, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 39144fc858d..173c0213073 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -22,7 +22,6 @@ import ( "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -91,28 +90,30 @@ func errOutIfPlanCannotBeConstructed(ctx *plancontext.PlanningContext, vTbl *vin } func insertUnshardedShortcut(stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { - eIns := &engine.Insert{} - eIns.Keyspace = ks - eIns.TableName = tables[0].Name.String() - eIns.Opcode = engine.InsertUnsharded + eIns := &engine.Insert{ + InsertCommon: engine.InsertCommon{ + Opcode: engine.InsertUnsharded, + Keyspace: ks, + TableName: tables[0].Name.String(), + }, + } eIns.Query = generateQuery(stmt) return &insert{eInsert: eIns} } type insert struct { - eInsert *engine.Insert - source logicalPlan + eInsert *engine.Insert + eInsertSelect *engine.InsertSelect + source logicalPlan } var _ logicalPlan = (*insert)(nil) func (i *insert) Primitive() engine.Primitive { - if i.source != nil { - i.eInsert.Input = i.source.Primitive() + if i.source == nil { + return i.eInsert } - return i.eInsert -} - -func (i *insert) ContainsTables() semantics.TableSet { - panic("does not expect insert to get contains tables call") + input := i.source.Primitive() + i.eInsertSelect.Input = input + return i.eInsertSelect } diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index d6732ada87d..5f965b55ad9 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -110,20 +110,20 @@ func transformInsertionSelection(ctx *plancontext.PlanningContext, op *operators } ins := dmlOp.(*operators.Insert) - eins := &engine.Insert{ - Opcode: mapToInsertOpCode(rb.Routing.OpCode(), true), - Keyspace: rb.Routing.Keyspace(), - TableName: ins.VTable.Name.String(), - Ignore: ins.Ignore, - ForceNonStreaming: op.ForceNonStreaming, - Generate: autoIncGenerate(ins.AutoIncrement), - ColVindexes: ins.ColVindexes, - VindexValues: ins.VindexValues, + eins := &engine.InsertSelect{ + InsertCommon: engine.InsertCommon{ + Keyspace: rb.Routing.Keyspace(), + TableName: ins.VTable.Name.String(), + Ignore: ins.Ignore, + ForceNonStreaming: op.ForceNonStreaming, + Generate: autoIncGenerate(ins.AutoIncrement), + ColVindexes: ins.ColVindexes, + }, VindexValueOffset: ins.VindexValueOffset, } - lp := &insert{eInsert: eins} + lp := &insert{eInsertSelect: eins} - eins.Prefix, eins.Mid, eins.Suffix = generateInsertShardedQuery(ins.AST) + eins.Prefix, _, eins.Suffix = generateInsertShardedQuery(ins.AST) selectionPlan, err := transformToLogicalPlan(ctx, op.Select) if err != nil { @@ -548,15 +548,23 @@ func buildInsertLogicalPlan( hints *queryHints, ) (logicalPlan, error) { ins := op.(*operators.Insert) + + ic := engine.InsertCommon{ + Opcode: mapToInsertOpCode(rb.Routing.OpCode()), + Keyspace: rb.Routing.Keyspace(), + TableName: ins.VTable.Name.String(), + Ignore: ins.Ignore, + Generate: autoIncGenerate(ins.AutoIncrement), + ColVindexes: ins.ColVindexes, + } + if hints != nil { + ic.MultiShardAutocommit = hints.multiShardAutocommit + ic.QueryTimeout = hints.queryTimeout + } + eins := &engine.Insert{ - Opcode: mapToInsertOpCode(rb.Routing.OpCode(), false), - Keyspace: rb.Routing.Keyspace(), - TableName: ins.VTable.Name.String(), - Ignore: ins.Ignore, - Generate: autoIncGenerate(ins.AutoIncrement), - ColVindexes: ins.ColVindexes, - VindexValues: ins.VindexValues, - VindexValueOffset: ins.VindexValueOffset, + InsertCommon: ic, + VindexValues: ins.VindexValues, } lp := &insert{eInsert: eins} @@ -566,22 +574,14 @@ func buildInsertLogicalPlan( eins.Prefix, eins.Mid, eins.Suffix = generateInsertShardedQuery(ins.AST) } - if hints != nil { - eins.MultiShardAutocommit = hints.multiShardAutocommit - eins.QueryTimeout = hints.queryTimeout - } - eins.Query = generateQuery(stmt) return lp, nil } -func mapToInsertOpCode(code engine.Opcode, insertSelect bool) engine.InsertOpcode { +func mapToInsertOpCode(code engine.Opcode) engine.InsertOpcode { if code == engine.Unsharded { return engine.InsertUnsharded } - if insertSelect { - return engine.InsertSelect - } return engine.InsertSharded } diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index 5ec8210b12d..ec39db0b158 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -4084,7 +4084,7 @@ "Original": "insert into unsharded(col) select col from unsharded_tab", "Instructions": { "OperatorType": "Insert", - "Variant": "Unsharded", + "Variant": "Select", "Keyspace": { "Name": "main", "Sharded": false @@ -4119,7 +4119,7 @@ "Original": "insert into unsharded(col) select col from t1", "Instructions": { "OperatorType": "Insert", - "Variant": "Unsharded", + "Variant": "Select", "Keyspace": { "Name": "main", "Sharded": false From 452c05ee968e5a419de7f6f412bb9ca94eb83ab0 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 30 Nov 2023 05:17:56 +0530 Subject: [PATCH 062/119] Add wait for reading mycnf to prevent race (#14626) Signed-off-by: Manan Gupta --- go/vt/mysqlctl/cmd.go | 2 +- go/vt/mysqlctl/mycnf.go | 19 +++++++++- go/vt/mysqlctl/mycnf_flag.go | 8 ++++- go/vt/mysqlctl/mycnf_test.go | 68 ++++++++++++++++++++++-------------- 4 files changed, 68 insertions(+), 29 deletions(-) diff --git a/go/vt/mysqlctl/cmd.go b/go/vt/mysqlctl/cmd.go index 5c3bda11437..222a39e26ee 100644 --- a/go/vt/mysqlctl/cmd.go +++ b/go/vt/mysqlctl/cmd.go @@ -55,7 +55,7 @@ func CreateMysqldAndMycnf(tabletUID uint32, mysqlSocket string, mysqlPort int) ( // of the MySQL instance. func OpenMysqldAndMycnf(tabletUID uint32) (*Mysqld, *Mycnf, error) { // We pass a port of 0, this will be read and overwritten from the path on disk - mycnf, err := ReadMycnf(NewMycnf(tabletUID, 0)) + mycnf, err := ReadMycnf(NewMycnf(tabletUID, 0), 0) if err != nil { return nil, nil, fmt.Errorf("couldn't read my.cnf file: %v", err) } diff --git a/go/vt/mysqlctl/mycnf.go b/go/vt/mysqlctl/mycnf.go index 3af6b8e8607..dad91e20fed 100644 --- a/go/vt/mysqlctl/mycnf.go +++ b/go/vt/mysqlctl/mycnf.go @@ -28,6 +28,7 @@ import ( "os" "path" "strconv" + "time" ) // Mycnf is a memory structure that contains a bunch of interesting @@ -112,6 +113,10 @@ type Mycnf struct { Path string // the actual path that represents this mycnf } +const ( + myCnfWaitRetryTime = 100 * time.Millisecond +) + // TabletDir returns the tablet directory. func (cnf *Mycnf) TabletDir() string { return path.Dir(cnf.DataDir) @@ -153,8 +158,20 @@ func normKey(bkey []byte) string { // ReadMycnf will read an existing my.cnf from disk, and update the passed in Mycnf object // with values from the my.cnf on disk. -func ReadMycnf(mycnf *Mycnf) (*Mycnf, error) { +func ReadMycnf(mycnf *Mycnf, waitTime time.Duration) (*Mycnf, error) { f, err := os.Open(mycnf.Path) + if waitTime != 0 { + timer := time.NewTimer(waitTime) + for err != nil { + select { + case <-timer.C: + return nil, err + default: + time.Sleep(myCnfWaitRetryTime) + f, err = os.Open(mycnf.Path) + } + } + } if err != nil { return nil, err } diff --git a/go/vt/mysqlctl/mycnf_flag.go b/go/vt/mysqlctl/mycnf_flag.go index 33a18d69940..8559e5c1431 100644 --- a/go/vt/mysqlctl/mycnf_flag.go +++ b/go/vt/mysqlctl/mycnf_flag.go @@ -17,6 +17,8 @@ limitations under the License. package mysqlctl import ( + "time" + "github.com/spf13/pflag" "vitess.io/vitess/go/vt/log" @@ -51,6 +53,10 @@ var ( flagMycnfFile string ) +const ( + waitForMyCnf = 10 * time.Second +) + // RegisterFlags registers the command line flags for // specifying the values of a mycnf config file. See NewMycnfFromFlags // to get the supported modes. @@ -129,5 +135,5 @@ func NewMycnfFromFlags(uid uint32) (mycnf *Mycnf, err error) { } mycnf = NewMycnf(uid, 0) mycnf.Path = flagMycnfFile - return ReadMycnf(mycnf) + return ReadMycnf(mycnf, waitForMyCnf) } diff --git a/go/vt/mysqlctl/mycnf_test.go b/go/vt/mysqlctl/mycnf_test.go index d422ed899c4..fc54f063618 100644 --- a/go/vt/mysqlctl/mycnf_test.go +++ b/go/vt/mysqlctl/mycnf_test.go @@ -20,7 +20,11 @@ import ( "bytes" "os" "strings" + "sync" "testing" + "time" + + "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/servenv" @@ -29,6 +33,9 @@ import ( var MycnfPath = "/tmp/my.cnf" func TestMycnf(t *testing.T) { + // Remove any my.cnf file if it already exists. + os.Remove(MycnfPath) + uid := uint32(11111) cnf := NewMycnf(uid, 6802) myTemplateSource := new(bytes.Buffer) @@ -39,36 +46,45 @@ func TestMycnf(t *testing.T) { f, _ := os.ReadFile("../../../config/mycnf/default.cnf") myTemplateSource.Write(f) data, err := cnf.makeMycnf(myTemplateSource.String()) - if err != nil { - t.Errorf("err: %v", err) - } else { - t.Logf("data: %v", data) - } - err = os.WriteFile(MycnfPath, []byte(data), 0666) - if err != nil { - t.Errorf("failed creating my.cnf %v", err) - } - _, err = os.ReadFile(MycnfPath) - if err != nil { - t.Errorf("failed reading, err %v", err) - return - } + require.NoError(t, err) + t.Logf("data: %v", data) + + // Since there is no my.cnf file, reading it should fail with a no such file error. mycnf := NewMycnf(uid, 0) mycnf.Path = MycnfPath - mycnf, err = ReadMycnf(mycnf) - if err != nil { - t.Errorf("failed reading, err %v", err) - } else { + _, err = ReadMycnf(mycnf, 0) + require.ErrorContains(t, err, "no such file or directory") + + // Next up we will spawn a go-routine to try and read the cnf file with a timeout. + // We will create the cnf file after some delay and verify that ReadMycnf does wait that long + // and ends up succeeding in reading the my.cnf file. + waitTime := 1 * time.Second + wg := sync.WaitGroup{} + wg.Add(1) + + go func() { + defer wg.Done() + startTime := time.Now() + var readErr error + mycnf, readErr = ReadMycnf(mycnf, 1*time.Minute) + require.NoError(t, readErr, "failed reading") t.Logf("socket file %v", mycnf.SocketFile) - } + totalTimeSpent := time.Since(startTime) + require.GreaterOrEqual(t, totalTimeSpent, waitTime) + }() + + time.Sleep(waitTime) + err = os.WriteFile(MycnfPath, []byte(data), 0666) + require.NoError(t, err, "failed creating my.cnf") + _, err = os.ReadFile(MycnfPath) + require.NoError(t, err, "failed reading") + + // Wait for ReadMycnf to finish and then verify that the data read is correct. + wg.Wait() // Tablet UID should be 11111, which determines tablet/data dir. - if got, want := mycnf.DataDir, "/vt_0000011111/"; !strings.Contains(got, want) { - t.Errorf("mycnf.DataDir = %v, want *%v*", got, want) - } + require.Contains(t, mycnf.DataDir, "/vt_0000011111/") // MySQL server-id should be 22222, different from Tablet UID. - if got, want := mycnf.ServerID, uint32(22222); got != want { - t.Errorf("mycnf.ServerID = %v, want %v", got, want) - } + require.EqualValues(t, uint32(22222), mycnf.ServerID) } // Run this test if any changes are made to hook handling / make_mycnf hook @@ -112,7 +128,7 @@ func NoTestMycnfHook(t *testing.T) { } mycnf := NewMycnf(uid, 0) mycnf.Path = cnf.Path - mycnf, err = ReadMycnf(mycnf) + mycnf, err = ReadMycnf(mycnf, 0) if err != nil { t.Errorf("failed reading, err %v", err) } else { From 217c2d776e109780fa29d098fa241f4c9c52344e Mon Sep 17 00:00:00 2001 From: jwangace <121262788+jwangace@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:03:16 -0800 Subject: [PATCH 063/119] increase vtctlclient backupShard command success rate (#14604) Signed-off-by: Jun Wang Signed-off-by: jwangace <121262788+jwangace@users.noreply.github.com> Co-authored-by: Jun Wang Co-authored-by: Andrew Mason --- go/vt/vtctl/grpcvtctldserver/server.go | 8 +- go/vt/vtctl/reparentutil/util.go | 12 +++ go/vt/vtctl/reparentutil/util_test.go | 102 +++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 21c4dc272f6..caa99d5e8c8 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -431,8 +431,14 @@ func (s *VtctldServer) BackupShard(req *vtctldatapb.BackupShardRequest, stream v span.Annotate("incremental_from_pos", req.IncrementalFromPos) tablets, stats, err := reparentutil.ShardReplicationStatuses(ctx, s.ts, s.tmc, req.Keyspace, req.Shard) + + // Instead of return on err directly, only return err when no tablets for backup at all if err != nil { - return err + tablets = reparentutil.GetBackupCandidates(tablets, stats) + // Only return err when no usable tablet + if len(tablets) == 0 { + return err + } } var ( diff --git a/go/vt/vtctl/reparentutil/util.go b/go/vt/vtctl/reparentutil/util.go index cfde8f34508..ac57e1230d1 100644 --- a/go/vt/vtctl/reparentutil/util.go +++ b/go/vt/vtctl/reparentutil/util.go @@ -343,3 +343,15 @@ func waitForCatchUp( } return nil } + +// GetBackupCandidates is used to get a list of healthy tablets for backup +func GetBackupCandidates(tablets []*topo.TabletInfo, stats []*replicationdatapb.Status) (res []*topo.TabletInfo) { + for i, stat := range stats { + // shardTablets[i] and stats[i] is 1:1 mapping + // Always include TabletType_PRIMARY. Healthy shardTablets[i] will be added to tablets + if tablets[i].Type == topodatapb.TabletType_PRIMARY || stat != nil { + res = append(res, tablets[i]) + } + } + return res +} diff --git a/go/vt/vtctl/reparentutil/util_test.go b/go/vt/vtctl/reparentutil/util_test.go index a9e6274d490..7b0d624590f 100644 --- a/go/vt/vtctl/reparentutil/util_test.go +++ b/go/vt/vtctl/reparentutil/util_test.go @@ -1218,3 +1218,105 @@ func Test_getTabletsWithPromotionRules(t *testing.T) { }) } } + +func TestGetBackupCandidates(t *testing.T) { + var ( + primaryTablet = &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 1, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + } + replicaTablet = &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 2, + }, + Type: topodatapb.TabletType_REPLICA, + }, + } + rdonlyTablet = &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 3, + }, + Type: topodatapb.TabletType_RDONLY, + }, + } + spareTablet = &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 4, + }, + Type: topodatapb.TabletType_SPARE, + }, + } + ) + tests := []struct { + name string + in []*topo.TabletInfo + expected []*topo.TabletInfo + status []*replicationdatapb.Status + }{ + { + name: "one primary tablet with status", + in: []*topo.TabletInfo{primaryTablet}, + expected: []*topo.TabletInfo{primaryTablet}, + status: []*replicationdatapb.Status{{}}, + }, + { + name: "one primary tablet with no status", + in: []*topo.TabletInfo{primaryTablet}, + expected: []*topo.TabletInfo{primaryTablet}, + status: []*replicationdatapb.Status{nil}, + }, + { + name: "4 tablets with no status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet}, + status: []*replicationdatapb.Status{nil, nil, nil, nil}, + }, + { + name: "4 tablets with full status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + status: []*replicationdatapb.Status{{}, {}, {}, {}}, + }, + { + name: "4 tablets with no primaryTablet status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + status: []*replicationdatapb.Status{nil, {}, {}, {}}, + }, + { + name: "4 tablets with no replicaTablet status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet, rdonlyTablet, spareTablet}, + status: []*replicationdatapb.Status{{}, nil, {}, {}}, + }, + { + name: "4 tablets with no rdonlyTablet status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet, replicaTablet, spareTablet}, + status: []*replicationdatapb.Status{{}, {}, nil, {}}, + }, + { + name: "4 tablets with no spareTablet status", + in: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet, spareTablet}, + expected: []*topo.TabletInfo{primaryTablet, replicaTablet, rdonlyTablet}, + status: []*replicationdatapb.Status{{}, {}, {}, nil}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res := GetBackupCandidates(tt.in, tt.status) + require.EqualValues(t, tt.expected, res) + }) + } +} From ffd7cc51bc6e5d40843dbdb13021c34bcbfaf3b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 30 Nov 2023 09:54:38 +0100 Subject: [PATCH 064/119] bugfix: do not rewrite an expression twice (#14641) --- .../planbuilder/operators/aggregator.go | 1 - .../planbuilder/testdata/aggr_cases.json | 75 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index 685a418339a..269c4616274 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -186,7 +186,6 @@ func (a *Aggregator) findColInternal(ctx *plancontext.PlanningContext, ae *sqlpa if offset >= 0 { return offset } - expr = a.DT.RewriteExpression(ctx, expr) // Aggregator is little special and cannot work if the input offset are not matched with the aggregation columns. // So, before pushing anything from above the aggregator offset planning needs to be completed. diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index 3302ca09fc7..2254baa36a6 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6297,5 +6297,80 @@ "user.user" ] } + }, + { + "comment": "Group by aggregated column should not be a problem", + "query": "SELECT b.col FROM music AS b JOIN (SELECT MIN(bb.id) AS min_id, MAX(bb.id) AS max_id FROM user AS bb) AS foobars WHERE b.id > foobars.min_id GROUP BY b.col", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT b.col FROM music AS b JOIN (SELECT MIN(bb.id) AS min_id, MAX(bb.id) AS max_id FROM user AS bb) AS foobars WHERE b.id > foobars.min_id GROUP BY b.col", + "Instructions": { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "GroupBy": "(0|1)", + "ResultColumns": 1, + "Inputs": [ + { + "OperatorType": "Sort", + "Variant": "Memory", + "OrderBy": "(0|1) ASC", + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0,R:1", + "JoinVars": { + "foobars_min_id": 0 + }, + "TableName": "`user`_music", + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "GroupBy": "0 COLLATE utf8mb4_0900_ai_ci", + "Inputs": [ + { + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "min(0|2) AS min_id, max(1|2) AS max_id", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select min(bb.id) as min_id, max(bb.id) as max_id, weight_string(bb.id) from `user` as bb where 1 != 1 group by weight_string(bb.id)", + "OrderBy": "0 ASC COLLATE utf8mb4_0900_ai_ci", + "Query": "select min(bb.id) as min_id, max(bb.id) as max_id, weight_string(bb.id) from `user` as bb group by weight_string(bb.id) order by min(bb.id) asc", + "Table": "`user`" + } + ] + } + ] + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select b.col, weight_string(b.col) from music as b where 1 != 1 group by b.col, weight_string(b.col)", + "Query": "select b.col, weight_string(b.col) from music as b where b.id > :foobars_min_id group by b.col, weight_string(b.col)", + "Table": "music" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.music", + "user.user" + ] + } } ] From c1790ddc49d1ea1af97f44a3bc208a6ea06eab88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 30 Nov 2023 13:13:30 +0100 Subject: [PATCH 065/119] refactor: minor cleanups in planner code (#14642) --- go/vt/vtgate/planbuilder/operators/aggregator.go | 2 +- go/vt/vtgate/planbuilder/operators/phases.go | 15 ++++++++++----- go/vt/vtgate/planbuilder/simplifier_test.go | 11 +++-------- go/vt/vtgate/simplifier/expression_simplifier.go | 5 +++-- go/vt/vtgate/simplifier/simplifier.go | 2 +- go/vt/vtgate/simplifier/simplifier_test.go | 8 +++----- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index 269c4616274..e1848752e75 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -201,7 +201,7 @@ func (a *Aggregator) findColInternal(ctx *plancontext.PlanningContext, ae *sqlpa } if addToGroupBy { - panic(vterrors.VT13001("did not expect to add group by here")) + panic(vterrors.VT13001(fmt.Sprintf("did not expect to add group by here: %s", sqlparser.String(expr)))) } return -1 diff --git a/go/vt/vtgate/planbuilder/operators/phases.go b/go/vt/vtgate/planbuilder/operators/phases.go index f180cfc2ce0..557124e9320 100644 --- a/go/vt/vtgate/planbuilder/operators/phases.go +++ b/go/vt/vtgate/planbuilder/operators/phases.go @@ -101,13 +101,18 @@ type phaser struct { } func (p *phaser) next(ctx *plancontext.PlanningContext) Phase { - for phas := p.current; phas < DONE; phas++ { - if phas.shouldRun(ctx.SemTable.QuerySignature) { - p.current = p.current + 1 - return phas + for { + curr := p.current + if curr == DONE { + return DONE + } + + p.current++ + + if curr.shouldRun(ctx.SemTable.QuerySignature) { + return curr } } - return DONE } func removePerformanceDistinctAboveRoute(_ *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { diff --git a/go/vt/vtgate/planbuilder/simplifier_test.go b/go/vt/vtgate/planbuilder/simplifier_test.go index 4c83af77933..56d310d2949 100644 --- a/go/vt/vtgate/planbuilder/simplifier_test.go +++ b/go/vt/vtgate/planbuilder/simplifier_test.go @@ -21,19 +21,14 @@ import ( "fmt" "testing" - "vitess.io/vitess/go/test/vschemawrapper" - - "vitess.io/vitess/go/vt/vterrors" - "github.com/stretchr/testify/assert" - - "vitess.io/vitess/go/vt/vtgate/simplifier" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/test/vschemawrapper" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/simplifier" ) // TestSimplifyBuggyQuery should be used to whenever we get a planner bug reported diff --git a/go/vt/vtgate/simplifier/expression_simplifier.go b/go/vt/vtgate/simplifier/expression_simplifier.go index 4537a137e76..5582ac3993d 100644 --- a/go/vt/vtgate/simplifier/expression_simplifier.go +++ b/go/vt/vtgate/simplifier/expression_simplifier.go @@ -21,7 +21,6 @@ import ( "strconv" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/sqlparser" ) @@ -44,10 +43,10 @@ func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { cursor.Replace(expr) valid := test(smallestKnown[0]) - log.Errorf("test: %t: simplified %s to %s, full expr: %s", valid, sqlparser.String(node), sqlparser.String(expr), sqlparser.String(smallestKnown)) if valid { break // we will still continue trying to simplify other expressions at this level } else { + log.Errorf("failed attempt: tried changing {%s} to {%s} in {%s}", sqlparser.String(node), sqlparser.String(expr), sqlparser.String(in)) // undo the change cursor.Replace(node) } @@ -105,6 +104,8 @@ func (s *shrinker) fillQueue() bool { s.queue = append(s.queue, e.Left, e.Right) case *sqlparser.BinaryExpr: s.queue = append(s.queue, e.Left, e.Right) + case *sqlparser.BetweenExpr: + s.queue = append(s.queue, e.Left, e.From, e.To) case *sqlparser.Literal: switch e.Type { case sqlparser.StrVal: diff --git a/go/vt/vtgate/simplifier/simplifier.go b/go/vt/vtgate/simplifier/simplifier.go index 0e19935caba..522da172557 100644 --- a/go/vt/vtgate/simplifier/simplifier.go +++ b/go/vt/vtgate/simplifier/simplifier.go @@ -201,7 +201,7 @@ func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.SelectStatement, simplified := removeTable(clone, searchedTS, currentDB, si) name, _ := tbl.Name() if simplified && test(clone) { - log.Errorf("removed table %s: %s -> %s", sqlparser.String(name), sqlparser.String(in), sqlparser.String(clone)) + log.Errorf("removed table `%s`: \n%s\n%s", sqlparser.String(name), sqlparser.String(in), sqlparser.String(clone)) return clone } } diff --git a/go/vt/vtgate/simplifier/simplifier_test.go b/go/vt/vtgate/simplifier/simplifier_test.go index c9edbbab8d8..e2270a551b5 100644 --- a/go/vt/vtgate/simplifier/simplifier_test.go +++ b/go/vt/vtgate/simplifier/simplifier_test.go @@ -20,14 +20,12 @@ import ( "fmt" "testing" - "vitess.io/vitess/go/vt/log" - - "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) func TestFindAllExpressions(t *testing.T) { From 06c8c54aa4a494cd95f15834c2ac428f64631d62 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:18:24 +0100 Subject: [PATCH 066/119] VReplication TableStreamer: Only stream tables in tablestreamer (ignore views) (#14646) Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/fk_config_test.go | 1 + go/vt/vttablet/tabletserver/vstreamer/tablestreamer.go | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/go/test/endtoend/vreplication/fk_config_test.go b/go/test/endtoend/vreplication/fk_config_test.go index 5b02aeb62bb..deda1a1b296 100644 --- a/go/test/endtoend/vreplication/fk_config_test.go +++ b/go/test/endtoend/vreplication/fk_config_test.go @@ -20,6 +20,7 @@ var ( initialFKSchema = ` create table parent(id int, name varchar(128), primary key(id)) engine=innodb; create table child(id int, parent_id int, name varchar(128), primary key(id), foreign key(parent_id) references parent(id) on delete cascade) engine=innodb; +create view vparent as select * from parent; ` initialFKData = ` insert into parent values(1, 'parent1'), (2, 'parent2'); diff --git a/go/vt/vttablet/tabletserver/vstreamer/tablestreamer.go b/go/vt/vttablet/tabletserver/vstreamer/tablestreamer.go index 0bbd265435b..80f850dae2e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/tablestreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/tablestreamer.go @@ -23,12 +23,12 @@ import ( "strings" "sync/atomic" - "vitess.io/vitess/go/vt/vttablet" - "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl/tmutils" + "vitess.io/vitess/go/vt/vttablet" "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -117,12 +117,16 @@ func (ts *tableStreamer) Stream() error { return err } - rs, err := conn.ExecuteFetch("show tables", -1, true) + rs, err := conn.ExecuteFetch("show full tables", -1, true) if err != nil { return err } for _, row := range rs.Rows { tableName := row[0].ToString() + tableType := row[1].ToString() + if tableType != tmutils.TableBaseTable { + continue + } if schema2.IsInternalOperationTableName(tableName) { log.Infof("Skipping internal table %s", tableName) continue From 4aebf1cc54ab6b5a21520e5067be31513ae3df63 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 30 Nov 2023 18:03:00 +0100 Subject: [PATCH 067/119] Allow for passing in the MySQL shutdown timeout (#14568) Signed-off-by: Dirkjan Bussink --- go/cmd/mysqlctl/command/shutdown.go | 5 +- go/cmd/mysqlctl/command/teardown.go | 5 +- go/cmd/mysqlctld/cli/mysqlctld.go | 13 +- go/cmd/vtbackup/cli/vtbackup.go | 68 +++-- go/cmd/vtcombo/cli/main.go | 14 +- go/flags/endtoend/mysqlctld.txt | 3 +- go/flags/endtoend/vtbackup.txt | 1 + go/flags/endtoend/vtcombo.txt | 1 + go/flags/endtoend/vttablet.txt | 1 + go/test/endtoend/utils/mysql.go | 5 +- go/vt/mysqlctl/backup.go | 2 +- go/vt/mysqlctl/backup_blackbox_test.go | 90 +++--- go/vt/mysqlctl/backup_test.go | 54 ++-- go/vt/mysqlctl/backupengine.go | 64 ++-- go/vt/mysqlctl/builtinbackupengine.go | 4 +- go/vt/mysqlctl/fakemysqldaemon.go | 2 +- go/vt/mysqlctl/grpcmysqlctlserver/server.go | 13 +- go/vt/mysqlctl/mysql_daemon.go | 3 +- go/vt/mysqlctl/mysqld.go | 8 +- go/vt/mysqlctl/xtrabackupengine.go | 2 +- go/vt/proto/mysqlctl/mysqlctl.pb.go | 317 ++++++++++---------- go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go | 53 +++- go/vt/vttablet/tabletmanager/restore.go | 32 +- go/vt/vttablet/tabletmanager/rpc_backup.go | 29 +- go/vt/vttablet/tabletmanager/tm_init.go | 4 +- go/vt/wrangler/testlib/backup_test.go | 14 +- proto/mysqlctl.proto | 1 + web/vtadmin/src/proto/vtadmin.d.ts | 6 + web/vtadmin/src/proto/vtadmin.js | 31 +- 29 files changed, 502 insertions(+), 343 deletions(-) diff --git a/go/cmd/mysqlctl/command/shutdown.go b/go/cmd/mysqlctl/command/shutdown.go index 41c804856eb..6e2e3a74a61 100644 --- a/go/cmd/mysqlctl/command/shutdown.go +++ b/go/cmd/mysqlctl/command/shutdown.go @@ -30,7 +30,6 @@ var Shutdown = &cobra.Command{ Use: "shutdown", Short: "Shuts down mysqld, without removing any files.", Long: "Stop a `mysqld` instance that was previously started with `init` or `start`.\n\n" + - "For large `mysqld` instances, you may need to extend the `wait_time` to shutdown cleanly.", Example: `mysqlctl --tablet_uid 101 --alsologtostderr shutdown`, Args: cobra.NoArgs, @@ -51,9 +50,9 @@ func commandShutdown(cmd *cobra.Command, args []string) error { } defer mysqld.Close() - ctx, cancel := context.WithTimeout(context.Background(), shutdownArgs.WaitTime) + ctx, cancel := context.WithTimeout(context.Background(), shutdownArgs.WaitTime+10*time.Second) defer cancel() - if err := mysqld.Shutdown(ctx, cnf, true); err != nil { + if err := mysqld.Shutdown(ctx, cnf, true, shutdownArgs.WaitTime); err != nil { return fmt.Errorf("failed shutdown mysql: %v", err) } return nil diff --git a/go/cmd/mysqlctl/command/teardown.go b/go/cmd/mysqlctl/command/teardown.go index 0d37a15cfdc..4ad0539bdd1 100644 --- a/go/cmd/mysqlctl/command/teardown.go +++ b/go/cmd/mysqlctl/command/teardown.go @@ -32,7 +32,6 @@ var Teardown = &cobra.Command{ Long: "{{< warning >}}\n" + "This is a destructive operation.\n" + "{{}}\n\n" + - "Shuts down a `mysqld` instance and removes its data directory.", Example: `mysqlctl --tablet_uid 101 --alsologtostderr teardown`, Args: cobra.NoArgs, @@ -54,9 +53,9 @@ func commandTeardown(cmd *cobra.Command, args []string) error { } defer mysqld.Close() - ctx, cancel := context.WithTimeout(context.Background(), teardownArgs.WaitTime) + ctx, cancel := context.WithTimeout(context.Background(), teardownArgs.WaitTime+10*time.Second) defer cancel() - if err := mysqld.Teardown(ctx, cnf, teardownArgs.Force); err != nil { + if err := mysqld.Teardown(ctx, cnf, teardownArgs.Force, teardownArgs.WaitTime); err != nil { return fmt.Errorf("failed teardown mysql (forced? %v): %v", teardownArgs.Force, err) } return nil diff --git a/go/cmd/mysqlctld/cli/mysqlctld.go b/go/cmd/mysqlctld/cli/mysqlctld.go index 6ebaa5dc422..51a0c47f56e 100644 --- a/go/cmd/mysqlctld/cli/mysqlctld.go +++ b/go/cmd/mysqlctld/cli/mysqlctld.go @@ -45,8 +45,9 @@ var ( mysqlSocket string // mysqlctl init flags - waitTime = 5 * time.Minute - initDBSQLFile string + waitTime = 5 * time.Minute + shutdownWaitTime = 5 * time.Minute + initDBSQLFile string Main = &cobra.Command{ Use: "mysqlctld", @@ -84,8 +85,9 @@ func init() { Main.Flags().IntVar(&mysqlPort, "mysql_port", mysqlPort, "MySQL port") Main.Flags().Uint32Var(&tabletUID, "tablet_uid", tabletUID, "Tablet UID") Main.Flags().StringVar(&mysqlSocket, "mysql_socket", mysqlSocket, "Path to the mysqld socket file") - Main.Flags().DurationVar(&waitTime, "wait_time", waitTime, "How long to wait for mysqld startup or shutdown") + Main.Flags().DurationVar(&waitTime, "wait_time", waitTime, "How long to wait for mysqld startup") Main.Flags().StringVar(&initDBSQLFile, "init_db_sql_file", initDBSQLFile, "Path to .sql file to run after mysqld initialization") + Main.Flags().DurationVar(&shutdownWaitTime, "shutdown-wait-time", shutdownWaitTime, "How long to wait for mysqld shutdown") acl.RegisterFlags(Main.Flags()) } @@ -154,8 +156,9 @@ func run(cmd *cobra.Command, args []string) error { // Take mysqld down with us on SIGTERM before entering lame duck. servenv.OnTermSync(func() { log.Infof("mysqlctl received SIGTERM, shutting down mysqld first") - ctx := context.Background() - if err := mysqld.Shutdown(ctx, cnf, true); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), shutdownWaitTime+10*time.Second) + defer cancel() + if err := mysqld.Shutdown(ctx, cnf, true, shutdownWaitTime); err != nil { log.Errorf("failed to shutdown mysqld: %v", err) } }) diff --git a/go/cmd/vtbackup/cli/vtbackup.go b/go/cmd/vtbackup/cli/vtbackup.go index 121ba39b8c5..560e9d21b2a 100644 --- a/go/cmd/vtbackup/cli/vtbackup.go +++ b/go/cmd/vtbackup/cli/vtbackup.go @@ -84,13 +84,14 @@ var ( incrementalFromPos string // mysqlctld-like flags - mysqlPort = 3306 - mysqlSocket string - mysqlTimeout = 5 * time.Minute - initDBSQLFile string - detachedMode bool - keepAliveTimeout time.Duration - disableRedoLog bool + mysqlPort = 3306 + mysqlSocket string + mysqlTimeout = 5 * time.Minute + mysqlShutdownTimeout = 5 * time.Minute + initDBSQLFile string + detachedMode bool + keepAliveTimeout time.Duration + disableRedoLog bool // Deprecated, use "Phase" instead. deprecatedDurationByPhase = stats.NewGaugesWithSingleLabel( @@ -207,6 +208,7 @@ func init() { Main.Flags().IntVar(&mysqlPort, "mysql_port", mysqlPort, "mysql port") Main.Flags().StringVar(&mysqlSocket, "mysql_socket", mysqlSocket, "path to the mysql socket") Main.Flags().DurationVar(&mysqlTimeout, "mysql_timeout", mysqlTimeout, "how long to wait for mysqld startup") + Main.Flags().DurationVar(&mysqlShutdownTimeout, "mysql-shutdown-timeout", mysqlShutdownTimeout, "how long to wait for mysqld startup") Main.Flags().StringVar(&initDBSQLFile, "init_db_sql_file", initDBSQLFile, "path to .sql file to run after mysql_install_db") Main.Flags().BoolVar(&detachedMode, "detach", detachedMode, "detached mode - run backups detached from the terminal") Main.Flags().DurationVar(&keepAliveTimeout, "keep-alive-timeout", keepAliveTimeout, "Wait until timeout elapses after a successful backup before shutting down.") @@ -340,9 +342,9 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back defer func() { // Be careful not to use the original context, because we don't want to // skip shutdown just because we timed out waiting for other things. - mysqlShutdownCtx, mysqlShutdownCancel := context.WithTimeout(context.Background(), 30*time.Second) + mysqlShutdownCtx, mysqlShutdownCancel := context.WithTimeout(context.Background(), mysqlShutdownTimeout+10*time.Second) defer mysqlShutdownCancel() - if err := mysqld.Shutdown(mysqlShutdownCtx, mycnf, false); err != nil { + if err := mysqld.Shutdown(mysqlShutdownCtx, mycnf, false, mysqlShutdownTimeout); err != nil { log.Errorf("failed to shutdown mysqld: %v", err) } }() @@ -356,18 +358,19 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back } backupParams := mysqlctl.BackupParams{ - Cnf: mycnf, - Mysqld: mysqld, - Logger: logutil.NewConsoleLogger(), - Concurrency: concurrency, - IncrementalFromPos: incrementalFromPos, - HookExtraEnv: extraEnv, - TopoServer: topoServer, - Keyspace: initKeyspace, - Shard: initShard, - TabletAlias: topoproto.TabletAliasString(tabletAlias), - Stats: backupstats.BackupStats(), - UpgradeSafe: upgradeSafe, + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: concurrency, + IncrementalFromPos: incrementalFromPos, + HookExtraEnv: extraEnv, + TopoServer: topoServer, + Keyspace: initKeyspace, + Shard: initShard, + TabletAlias: topoproto.TabletAliasString(tabletAlias), + Stats: backupstats.BackupStats(), + UpgradeSafe: upgradeSafe, + MysqlShutdownTimeout: mysqlShutdownTimeout, } // In initial_backup mode, just take a backup of this empty database. if initialBackup { @@ -416,16 +419,17 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back log.Infof("Restoring latest backup from directory %v", backupDir) restoreAt := time.Now() params := mysqlctl.RestoreParams{ - Cnf: mycnf, - Mysqld: mysqld, - Logger: logutil.NewConsoleLogger(), - Concurrency: concurrency, - HookExtraEnv: extraEnv, - DeleteBeforeRestore: true, - DbName: dbName, - Keyspace: initKeyspace, - Shard: initShard, - Stats: backupstats.RestoreStats(), + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: concurrency, + HookExtraEnv: extraEnv, + DeleteBeforeRestore: true, + DbName: dbName, + Keyspace: initKeyspace, + Shard: initShard, + Stats: backupstats.RestoreStats(), + MysqlShutdownTimeout: mysqlShutdownTimeout, } backupManifest, err := mysqlctl.Restore(ctx, params) var restorePos replication.Position @@ -583,7 +587,7 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back return fmt.Errorf("Could not prep for full shutdown: %v", err) } // Shutdown, waiting for it to finish - if err := mysqld.Shutdown(ctx, mycnf, true); err != nil { + if err := mysqld.Shutdown(ctx, mycnf, true, mysqlShutdownTimeout); err != nil { return fmt.Errorf("Something went wrong during full MySQL shutdown: %v", err) } // Start MySQL, waiting for it to come up diff --git a/go/cmd/vtcombo/cli/main.go b/go/cmd/vtcombo/cli/main.go index bfc0ad894fe..6912a886b18 100644 --- a/go/cmd/vtcombo/cli/main.go +++ b/go/cmd/vtcombo/cli/main.go @@ -147,6 +147,8 @@ func startMysqld(uid uint32) (mysqld *mysqlctl.Mysqld, cnf *mysqlctl.Mycnf, err return mysqld, cnf, nil } +const mysqlShutdownTimeout = 5 * time.Minute + func run(cmd *cobra.Command, args []string) (err error) { // Stash away a copy of the topology that vtcombo was started with. // @@ -195,7 +197,9 @@ func run(cmd *cobra.Command, args []string) (err error) { return err } servenv.OnClose(func() { - mysqld.Shutdown(context.TODO(), cnf, true) + ctx, cancel := context.WithTimeout(context.Background(), mysqlShutdownTimeout+10*time.Second) + defer cancel() + mysqld.Shutdown(ctx, cnf, true, mysqlShutdownTimeout) }) // We want to ensure we can write to this database mysqld.SetReadOnly(false) @@ -217,7 +221,9 @@ func run(cmd *cobra.Command, args []string) (err error) { if err != nil { // ensure we start mysql in the event we fail here if startMysql { - mysqld.Shutdown(context.TODO(), cnf, true) + ctx, cancel := context.WithTimeout(context.Background(), mysqlShutdownTimeout+10*time.Second) + defer cancel() + mysqld.Shutdown(ctx, cnf, true, mysqlShutdownTimeout) } return fmt.Errorf("initTabletMapProto failed: %w", err) @@ -264,7 +270,9 @@ func run(cmd *cobra.Command, args []string) (err error) { err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, ks.GetName(), tpb.Cells, false) if err != nil { if startMysql { - mysqld.Shutdown(context.TODO(), cnf, true) + ctx, cancel := context.WithTimeout(context.Background(), mysqlShutdownTimeout+10*time.Second) + defer cancel() + mysqld.Shutdown(ctx, cnf, true, mysqlShutdownTimeout) } return fmt.Errorf("Couldn't build srv keyspace for (%v: %v). Got error: %w", ks, tpb.Cells, err) diff --git a/go/flags/endtoend/mysqlctld.txt b/go/flags/endtoend/mysqlctld.txt index 141c6697070..ccb89f08bf5 100644 --- a/go/flags/endtoend/mysqlctld.txt +++ b/go/flags/endtoend/mysqlctld.txt @@ -110,6 +110,7 @@ Flags: --replication_connect_retry duration how long to wait in between replica reconnect attempts. Only precise to the second. (default 10s) --security_policy string the name of a registered security policy to use for controlling access to URLs - empty means allow all for anyone (built-in policies: deny-all, read-only) --service_map strings comma separated list of services to enable (or disable if prefixed with '-') Example: grpc-queryservice + --shutdown-wait-time duration How long to wait for mysqld shutdown (default 5m0s) --socket_file string Local unix socket file to listen on --stderrthreshold severityFlag logs at or above this threshold go to stderr (default 1) --table-refresh-interval int interval in milliseconds to refresh tables in status page with refreshRequired class @@ -118,4 +119,4 @@ Flags: --v Level log level for V logs -v, --version print binary version --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging - --wait_time duration How long to wait for mysqld startup or shutdown (default 5m0s) + --wait_time duration How long to wait for mysqld startup (default 5m0s) diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index 8610606eca2..3971472b74b 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -174,6 +174,7 @@ Flags: --mycnf_slow_log_path string mysql slow query log path --mycnf_socket_file string mysql socket file --mycnf_tmp_dir string mysql tmp directory + --mysql-shutdown-timeout duration how long to wait for mysqld startup (default 5m0s) --mysql_port int mysql port (default 3306) --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") --mysql_socket string path to the mysql socket diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index 40720e702b7..d32df437787 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -222,6 +222,7 @@ Flags: --mycnf_tmp_dir string mysql tmp directory --mysql-server-keepalive-period duration TCP period between keep-alives --mysql-server-pool-conn-read-buffers If set, the server will pool incoming connection read buffers + --mysql-shutdown-timeout duration timeout to use when MySQL is being shut down. (default 5m0s) --mysql_allow_clear_text_without_tls If set, the server will allow the use of a clear text password over non-SSL connections. --mysql_auth_server_impl string Which auth server implementation to use. Options: none, ldap, clientcert, static, vault. (default "static") --mysql_default_workload string Default session workload (OLTP, OLAP, DBA) (default "OLTP") diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index 7dc29a140b1..f3085f71d2f 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -242,6 +242,7 @@ Flags: --mycnf_slow_log_path string mysql slow query log path --mycnf_socket_file string mysql socket file --mycnf_tmp_dir string mysql tmp directory + --mysql-shutdown-timeout duration timeout to use when MySQL is being shut down. (default 5m0s) --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") --mysqlctl_mycnf_template string template file to use for generating the my.cnf file during server init --mysqlctl_socket string socket file to use for remote mysqlctl actions (empty for local actions) diff --git a/go/test/endtoend/utils/mysql.go b/go/test/endtoend/utils/mysql.go index de8ce40f992..888c0cc8959 100644 --- a/go/test/endtoend/utils/mysql.go +++ b/go/test/endtoend/utils/mysql.go @@ -23,6 +23,7 @@ import ( "os" "path" "testing" + "time" "github.com/stretchr/testify/assert" @@ -35,6 +36,8 @@ import ( "vitess.io/vitess/go/vt/mysqlctl" ) +const mysqlShutdownTimeout = 1 * time.Minute + // NewMySQL creates a new MySQL server using the local mysqld binary. The name of the database // will be set to `dbName`. SQL queries that need to be executed on the new MySQL instance // can be passed through the `schemaSQL` argument. @@ -96,7 +99,7 @@ func NewMySQLWithMysqld(port int, hostname, dbName string, schemaSQL ...string) } return params, mysqld, func() { ctx := context.Background() - _ = mysqld.Teardown(ctx, mycnf, true) + _ = mysqld.Teardown(ctx, mycnf, true, mysqlShutdownTimeout) }, nil } diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index e9f0b19d54a..5a9706b07f8 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -453,7 +453,7 @@ func Restore(ctx context.Context, params RestoreParams) (*BackupManifest, error) // The MySQL manual recommends restarting mysqld after running mysql_upgrade, // so that any changes made to system tables take effect. params.Logger.Infof("Restore: restarting mysqld after mysql_upgrade") - if err := params.Mysqld.Shutdown(context.Background(), params.Cnf, true); err != nil { + if err := params.Mysqld.Shutdown(context.Background(), params.Cnf, true, params.MysqlShutdownTimeout); err != nil { return nil, err } if err := params.Mysqld.Start(context.Background(), params.Cnf); err != nil { diff --git a/go/vt/mysqlctl/backup_blackbox_test.go b/go/vt/mysqlctl/backup_blackbox_test.go index 8de6a8679fa..b174b60ed1d 100644 --- a/go/vt/mysqlctl/backup_blackbox_test.go +++ b/go/vt/mysqlctl/backup_blackbox_test.go @@ -47,6 +47,8 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" ) +const mysqlShutdownTimeout = 1 * time.Minute + func setBuiltinBackupMysqldDeadline(t time.Duration) time.Duration { old := mysqlctl.BuiltinBackupMysqldTimeout mysqlctl.BuiltinBackupMysqldTimeout = t @@ -154,12 +156,13 @@ func TestExecuteBackup(t *testing.T) { InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), DataDir: path.Join(backupRoot, "datadir"), }, - Concurrency: 2, - HookExtraEnv: map[string]string{}, - TopoServer: ts, - Keyspace: keyspace, - Shard: shard, - Stats: fakeStats, + Concurrency: 2, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + Stats: fakeStats, + MysqlShutdownTimeout: mysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -213,10 +216,11 @@ func TestExecuteBackup(t *testing.T) { InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), DataDir: path.Join(backupRoot, "datadir"), }, - HookExtraEnv: map[string]string{}, - TopoServer: ts, - Keyspace: keyspace, - Shard: shard, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: mysqlShutdownTimeout, }, bh) assert.Error(t, err) @@ -299,12 +303,13 @@ func TestExecuteBackupWithSafeUpgrade(t *testing.T) { InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), DataDir: path.Join(backupRoot, "datadir"), }, - Concurrency: 2, - TopoServer: ts, - Keyspace: keyspace, - Shard: shard, - Stats: backupstats.NewFakeStats(), - UpgradeSafe: true, + Concurrency: 2, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + Stats: backupstats.NewFakeStats(), + UpgradeSafe: true, + MysqlShutdownTimeout: mysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -385,12 +390,13 @@ func TestExecuteBackupWithCanceledContext(t *testing.T) { InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), DataDir: path.Join(backupRoot, "datadir"), }, - Stats: backupstats.NewFakeStats(), - Concurrency: 2, - HookExtraEnv: map[string]string{}, - TopoServer: ts, - Keyspace: keyspace, - Shard: shard, + Stats: backupstats.NewFakeStats(), + Concurrency: 2, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: mysqlShutdownTimeout, }, bh) require.Error(t, err) @@ -469,12 +475,13 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), DataDir: path.Join(backupRoot, "datadir"), }, - Stats: backupstats.NewFakeStats(), - Concurrency: 2, - HookExtraEnv: map[string]string{}, - TopoServer: ts, - Keyspace: keyspace, - Shard: shard, + Stats: backupstats.NewFakeStats(), + Concurrency: 2, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: mysqlShutdownTimeout, }, bh) require.NoError(t, err) @@ -500,19 +507,20 @@ func TestExecuteRestoreWithTimedOutContext(t *testing.T) { RelayLogIndexPath: path.Join(backupRoot, "relaylogindex"), RelayLogInfoPath: path.Join(backupRoot, "relayloginfo"), }, - Logger: logutil.NewConsoleLogger(), - Mysqld: mysqld, - Concurrency: 2, - HookExtraEnv: map[string]string{}, - DeleteBeforeRestore: false, - DbName: "test", - Keyspace: "test", - Shard: "-", - StartTime: time.Now(), - RestoreToPos: replication.Position{}, - RestoreToTimestamp: time.Time{}, - DryRun: false, - Stats: fakeStats, + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Concurrency: 2, + HookExtraEnv: map[string]string{}, + DeleteBeforeRestore: false, + DbName: "test", + Keyspace: "test", + Shard: "-", + StartTime: time.Now(), + RestoreToPos: replication.Position{}, + RestoreToTimestamp: time.Time{}, + DryRun: false, + Stats: fakeStats, + MysqlShutdownTimeout: mysqlShutdownTimeout, } // Successful restore. diff --git a/go/vt/mysqlctl/backup_test.go b/go/vt/mysqlctl/backup_test.go index 5b97f709c2f..ad7e0faab98 100644 --- a/go/vt/mysqlctl/backup_test.go +++ b/go/vt/mysqlctl/backup_test.go @@ -42,6 +42,8 @@ import ( "vitess.io/vitess/go/vt/mysqlctl/backupstorage" ) +const mysqlShutdownTimeout = 1 * time.Minute + // TestBackupExecutesBackupWithScopedParams tests that Backup passes // a Scope()-ed stats to backupengine ExecuteBackup. func TestBackupExecutesBackupWithScopedParams(t *testing.T) { @@ -563,7 +565,7 @@ func createFakeBackupRestoreEnv(t *testing.T) *fakeBackupRestoreEnv { sqldb := fakesqldb.New(t) sqldb.SetNeverFail(true) mysqld := NewFakeMysqlDaemon(sqldb) - require.Nil(t, mysqld.Shutdown(ctx, nil, false)) + require.Nil(t, mysqld.Shutdown(ctx, nil, false, mysqlShutdownTimeout)) dirName, err := os.MkdirTemp("", "vt_backup_test") require.Nil(t, err) @@ -575,33 +577,35 @@ func createFakeBackupRestoreEnv(t *testing.T) *fakeBackupRestoreEnv { stats := backupstats.NewFakeStats() backupParams := BackupParams{ - Cnf: cnf, - Logger: logger, - Mysqld: mysqld, - Concurrency: 1, - HookExtraEnv: map[string]string{}, - TopoServer: nil, - Keyspace: "test", - Shard: "-", - BackupTime: time.Now(), - IncrementalFromPos: "", - Stats: stats, + Cnf: cnf, + Logger: logger, + Mysqld: mysqld, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: nil, + Keyspace: "test", + Shard: "-", + BackupTime: time.Now(), + IncrementalFromPos: "", + Stats: stats, + MysqlShutdownTimeout: mysqlShutdownTimeout, } restoreParams := RestoreParams{ - Cnf: cnf, - Logger: logger, - Mysqld: mysqld, - Concurrency: 1, - HookExtraEnv: map[string]string{}, - DeleteBeforeRestore: false, - DbName: "test", - Keyspace: "test", - Shard: "-", - StartTime: time.Now(), - RestoreToPos: replication.Position{}, - DryRun: false, - Stats: stats, + Cnf: cnf, + Logger: logger, + Mysqld: mysqld, + Concurrency: 1, + HookExtraEnv: map[string]string{}, + DeleteBeforeRestore: false, + DbName: "test", + Keyspace: "test", + Shard: "-", + StartTime: time.Now(), + RestoreToPos: replication.Position{}, + DryRun: false, + Stats: stats, + MysqlShutdownTimeout: mysqlShutdownTimeout, } manifest := BackupManifest{ diff --git a/go/vt/mysqlctl/backupengine.go b/go/vt/mysqlctl/backupengine.go index 5a79edbdde0..cf6065cd733 100644 --- a/go/vt/mysqlctl/backupengine.go +++ b/go/vt/mysqlctl/backupengine.go @@ -77,23 +77,26 @@ type BackupParams struct { Stats backupstats.Stats // UpgradeSafe indicates whether the backup is safe for upgrade and created with innodb_fast_shutdown=0 UpgradeSafe bool + // MysqlShutdownTimeout defines how long we wait during MySQL shutdown if that is part of the backup process. + MysqlShutdownTimeout time.Duration } func (b *BackupParams) Copy() BackupParams { return BackupParams{ - Cnf: b.Cnf, - Mysqld: b.Mysqld, - Logger: b.Logger, - Concurrency: b.Concurrency, - HookExtraEnv: b.HookExtraEnv, - TopoServer: b.TopoServer, - Keyspace: b.Keyspace, - Shard: b.Shard, - TabletAlias: b.TabletAlias, - BackupTime: b.BackupTime, - IncrementalFromPos: b.IncrementalFromPos, - Stats: b.Stats, - UpgradeSafe: b.UpgradeSafe, + Cnf: b.Cnf, + Mysqld: b.Mysqld, + Logger: b.Logger, + Concurrency: b.Concurrency, + HookExtraEnv: b.HookExtraEnv, + TopoServer: b.TopoServer, + Keyspace: b.Keyspace, + Shard: b.Shard, + TabletAlias: b.TabletAlias, + BackupTime: b.BackupTime, + IncrementalFromPos: b.IncrementalFromPos, + Stats: b.Stats, + UpgradeSafe: b.UpgradeSafe, + MysqlShutdownTimeout: b.MysqlShutdownTimeout, } } @@ -130,24 +133,27 @@ type RestoreParams struct { DryRun bool // Stats let's restore engines report detailed restore timings. Stats backupstats.Stats + // MysqlShutdownTimeout defines how long we wait during MySQL shutdown if that is part of the backup process. + MysqlShutdownTimeout time.Duration } func (p *RestoreParams) Copy() RestoreParams { return RestoreParams{ - Cnf: p.Cnf, - Mysqld: p.Mysqld, - Logger: p.Logger, - Concurrency: p.Concurrency, - HookExtraEnv: p.HookExtraEnv, - DeleteBeforeRestore: p.DeleteBeforeRestore, - DbName: p.DbName, - Keyspace: p.Keyspace, - Shard: p.Shard, - StartTime: p.StartTime, - RestoreToPos: p.RestoreToPos, - RestoreToTimestamp: p.RestoreToTimestamp, - DryRun: p.DryRun, - Stats: p.Stats, + Cnf: p.Cnf, + Mysqld: p.Mysqld, + Logger: p.Logger, + Concurrency: p.Concurrency, + HookExtraEnv: p.HookExtraEnv, + DeleteBeforeRestore: p.DeleteBeforeRestore, + DbName: p.DbName, + Keyspace: p.Keyspace, + Shard: p.Shard, + StartTime: p.StartTime, + RestoreToPos: p.RestoreToPos, + RestoreToTimestamp: p.RestoreToTimestamp, + DryRun: p.DryRun, + Stats: p.Stats, + MysqlShutdownTimeout: p.MysqlShutdownTimeout, } } @@ -584,10 +590,10 @@ func validateMySQLVersionUpgradeCompatible(to string, from string, upgradeSafe b return fmt.Errorf("running MySQL version %q is newer than backup MySQL version %q which is not safe to upgrade", to, from) } -func prepareToRestore(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger) error { +func prepareToRestore(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, mysqlShutdownTimeout time.Duration) error { // shutdown mysqld if it is running logger.Infof("Restore: shutdown mysqld") - if err := mysqld.Shutdown(ctx, cnf, true); err != nil { + if err := mysqld.Shutdown(ctx, cnf, true, mysqlShutdownTimeout); err != nil { return err } diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index e46932bcd51..57f55cefb2f 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -468,7 +468,7 @@ func (be *BuiltinBackupEngine) executeFullBackup(ctx context.Context, params Bac // shutdown mysqld shutdownCtx, cancel := context.WithTimeout(ctx, BuiltinBackupMysqldTimeout) - err = params.Mysqld.Shutdown(shutdownCtx, params.Cnf, true) + err = params.Mysqld.Shutdown(shutdownCtx, params.Cnf, true, params.MysqlShutdownTimeout) defer cancel() if err != nil { return false, vterrors.Wrap(err, "can't shutdown mysqld") @@ -886,7 +886,7 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara // executeRestoreFullBackup restores the files from a full backup. The underlying mysql database service is expected to be stopped. func (be *BuiltinBackupEngine) executeRestoreFullBackup(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, bm builtinBackupManifest) error { - if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger); err != nil { + if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger, params.MysqlShutdownTimeout); err != nil { return err } diff --git a/go/vt/mysqlctl/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon.go index 791b43da583..521a839bf78 100644 --- a/go/vt/mysqlctl/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon.go @@ -220,7 +220,7 @@ func (fmd *FakeMysqlDaemon) Start(ctx context.Context, cnf *Mycnf, mysqldArgs .. } // Shutdown is part of the MysqlDaemon interface. -func (fmd *FakeMysqlDaemon) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool) error { +func (fmd *FakeMysqlDaemon) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool, mysqlShutdownTimeout time.Duration) error { if !fmd.Running { return fmt.Errorf("fake mysql daemon not running") } diff --git a/go/vt/mysqlctl/grpcmysqlctlserver/server.go b/go/vt/mysqlctl/grpcmysqlctlserver/server.go index ac3b5092f19..38ce4b2b2df 100644 --- a/go/vt/mysqlctl/grpcmysqlctlserver/server.go +++ b/go/vt/mysqlctl/grpcmysqlctlserver/server.go @@ -22,9 +22,11 @@ package grpcmysqlctlserver import ( "context" + "time" "google.golang.org/grpc" + "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/vt/mysqlctl" mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" ) @@ -41,9 +43,18 @@ func (s *server) Start(ctx context.Context, request *mysqlctlpb.StartRequest) (* return &mysqlctlpb.StartResponse{}, s.mysqld.Start(ctx, s.cnf, request.MysqldArgs...) } +const mysqlShutdownTimeout = 5 * time.Minute + // Shutdown implements the server side of the MysqlctlClient interface. func (s *server) Shutdown(ctx context.Context, request *mysqlctlpb.ShutdownRequest) (*mysqlctlpb.ShutdownResponse, error) { - return &mysqlctlpb.ShutdownResponse{}, s.mysqld.Shutdown(ctx, s.cnf, request.WaitForMysqld) + timeout, ok, err := protoutil.DurationFromProto(request.MysqlShutdownTimeout) + if err != nil { + return nil, err + } + if !ok { + timeout = mysqlShutdownTimeout + } + return &mysqlctlpb.ShutdownResponse{}, s.mysqld.Shutdown(ctx, s.cnf, request.WaitForMysqld, timeout) } // RunMysqlUpgrade implements the server side of the MysqlctlClient interface. diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index f50d368ed7d..66454e8b8a8 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -18,6 +18,7 @@ package mysqlctl import ( "context" + "time" "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/sqltypes" @@ -33,7 +34,7 @@ import ( type MysqlDaemon interface { // methods related to mysql running or not Start(ctx context.Context, cnf *Mycnf, mysqldArgs ...string) error - Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool) error + Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool, mysqlShutdownTimeout time.Duration) error RunMysqlUpgrade(ctx context.Context) error ApplyBinlogFile(ctx context.Context, req *mysqlctlpb.ApplyBinlogFileRequest) error ReadBinlogFilesTimestamps(ctx context.Context, req *mysqlctlpb.ReadBinlogFilesTimestampsRequest) (*mysqlctlpb.ReadBinlogFilesTimestampsResponse, error) diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 52f806fe29b..9864d909b2f 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -522,7 +522,7 @@ func (mysqld *Mysqld) wait(ctx context.Context, cnf *Mycnf, params *mysql.ConnPa // flushed - on the order of 20-30 minutes. // // If a mysqlctld address is provided in a flag, Shutdown will run remotely. -func (mysqld *Mysqld) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool) error { +func (mysqld *Mysqld) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bool, shutdownTimeout time.Duration) error { log.Infof("Mysqld.Shutdown") // Execute as remote action on mysqlctld if requested. @@ -581,7 +581,7 @@ func (mysqld *Mysqld) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bo defer os.Remove(cnf) args := []string{ "--defaults-extra-file=" + cnf, - "--shutdown-timeout=300", + fmt.Sprintf("--shutdown-timeout=%d", int(shutdownTimeout.Seconds())), "--connect-timeout=30", "--wait=10", "shutdown", @@ -1024,9 +1024,9 @@ func (mysqld *Mysqld) createTopDir(cnf *Mycnf, dir string) error { } // Teardown will shutdown the running daemon, and delete the root directory. -func (mysqld *Mysqld) Teardown(ctx context.Context, cnf *Mycnf, force bool) error { +func (mysqld *Mysqld) Teardown(ctx context.Context, cnf *Mycnf, force bool, shutdownTimeout time.Duration) error { log.Infof("mysqlctl.Teardown") - if err := mysqld.Shutdown(ctx, cnf, true); err != nil { + if err := mysqld.Shutdown(ctx, cnf, true, shutdownTimeout); err != nil { log.Warningf("failed mysqld shutdown: %v", err.Error()) if !force { return err diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index d11699167d9..a61551c3dcf 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -484,7 +484,7 @@ func (be *XtrabackupEngine) ExecuteRestore(ctx context.Context, params RestorePa return nil, err } - if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger); err != nil { + if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger, params.MysqlShutdownTimeout); err != nil { return nil, err } diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index 87d07442c8c..90c120243ec 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -190,7 +190,8 @@ type ShutdownRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - WaitForMysqld bool `protobuf:"varint,1,opt,name=wait_for_mysqld,json=waitForMysqld,proto3" json:"wait_for_mysqld,omitempty"` + WaitForMysqld bool `protobuf:"varint,1,opt,name=wait_for_mysqld,json=waitForMysqld,proto3" json:"wait_for_mysqld,omitempty"` + MysqlShutdownTimeout *vttime.Duration `protobuf:"bytes,2,opt,name=mysql_shutdown_timeout,json=mysqlShutdownTimeout,proto3" json:"mysql_shutdown_timeout,omitempty"` } func (x *ShutdownRequest) Reset() { @@ -232,6 +233,13 @@ func (x *ShutdownRequest) GetWaitForMysqld() bool { return false } +func (x *ShutdownRequest) GetMysqlShutdownTimeout() *vttime.Duration { + if x != nil { + return x.MysqlShutdownTimeout + } + return nil +} + type ShutdownResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -922,129 +930,134 @@ var file_mysqlctl_proto_rawDesc = []byte{ 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, 0xc0, - 0x01, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x17, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x64, 0x61, - 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, - 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x15, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, - 0x65, 0x22, 0x19, 0x0a, 0x17, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x20, + 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x81, 0x01, 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, 0x12, 0x46, 0x0a, 0x16, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, + 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x53, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 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, 0xc0, 0x01, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x17, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x17, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x52, 0x15, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x44, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0f, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x12, 0x33, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, + 0x6c, 0x61, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x32, 0x0a, + 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, 0x61, + 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x69, 0x6e, 0x6c, 0x6f, + 0x67, 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, 0x16, 0x0a, 0x14, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0xb0, 0x05, 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, 0x58, 0x0a, + 0x0f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x20, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x19, 0x52, 0x65, 0x61, 0x64, 0x42, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x73, 0x12, 0x2a, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xf9, 0x01, 0x0a, - 0x21, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x66, 0x69, 0x72, - 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x12, - 0x33, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 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, 0x16, 0x0a, 0x14, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x31, 0x0a, 0x15, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 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, 0xb0, 0x05, 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, 0x58, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, - 0x74, 0x6c, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x79, 0x73, 0x71, - 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, - 0x0a, 0x19, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x12, 0x2a, 0x2e, 0x6d, 0x79, - 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, - 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 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, 0x12, 0x52, 0x0a, 0x0d, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x6d, - 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, - 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 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, + 0x1a, 0x2b, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x73, 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, 0x12, 0x52, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, + 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, + 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 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 ( @@ -1080,37 +1093,39 @@ var file_mysqlctl_proto_goTypes = []interface{}{ (*VersionStringRequest)(nil), // 15: mysqlctl.VersionStringRequest (*VersionStringResponse)(nil), // 16: mysqlctl.VersionStringResponse (*BackupInfo)(nil), // 17: mysqlctl.BackupInfo - (*vttime.Time)(nil), // 18: vttime.Time - (*topodata.TabletAlias)(nil), // 19: topodata.TabletAlias + (*vttime.Duration)(nil), // 18: vttime.Duration + (*vttime.Time)(nil), // 19: vttime.Time + (*topodata.TabletAlias)(nil), // 20: topodata.TabletAlias } var file_mysqlctl_proto_depIdxs = []int32{ - 18, // 0: mysqlctl.ApplyBinlogFileRequest.binlog_restore_datetime:type_name -> vttime.Time - 18, // 1: mysqlctl.ReadBinlogFilesTimestampsResponse.first_timestamp:type_name -> vttime.Time - 18, // 2: mysqlctl.ReadBinlogFilesTimestampsResponse.last_timestamp:type_name -> vttime.Time - 19, // 3: mysqlctl.BackupInfo.tablet_alias:type_name -> topodata.TabletAlias - 18, // 4: mysqlctl.BackupInfo.time:type_name -> vttime.Time - 0, // 5: mysqlctl.BackupInfo.status:type_name -> mysqlctl.BackupInfo.Status - 1, // 6: mysqlctl.MysqlCtl.Start:input_type -> mysqlctl.StartRequest - 3, // 7: mysqlctl.MysqlCtl.Shutdown:input_type -> mysqlctl.ShutdownRequest - 5, // 8: mysqlctl.MysqlCtl.RunMysqlUpgrade:input_type -> mysqlctl.RunMysqlUpgradeRequest - 7, // 9: mysqlctl.MysqlCtl.ApplyBinlogFile:input_type -> mysqlctl.ApplyBinlogFileRequest - 9, // 10: mysqlctl.MysqlCtl.ReadBinlogFilesTimestamps:input_type -> mysqlctl.ReadBinlogFilesTimestampsRequest - 11, // 11: mysqlctl.MysqlCtl.ReinitConfig:input_type -> mysqlctl.ReinitConfigRequest - 13, // 12: mysqlctl.MysqlCtl.RefreshConfig:input_type -> mysqlctl.RefreshConfigRequest - 15, // 13: mysqlctl.MysqlCtl.VersionString:input_type -> mysqlctl.VersionStringRequest - 2, // 14: mysqlctl.MysqlCtl.Start:output_type -> mysqlctl.StartResponse - 4, // 15: mysqlctl.MysqlCtl.Shutdown:output_type -> mysqlctl.ShutdownResponse - 6, // 16: mysqlctl.MysqlCtl.RunMysqlUpgrade:output_type -> mysqlctl.RunMysqlUpgradeResponse - 8, // 17: mysqlctl.MysqlCtl.ApplyBinlogFile:output_type -> mysqlctl.ApplyBinlogFileResponse - 10, // 18: mysqlctl.MysqlCtl.ReadBinlogFilesTimestamps:output_type -> mysqlctl.ReadBinlogFilesTimestampsResponse - 12, // 19: mysqlctl.MysqlCtl.ReinitConfig:output_type -> mysqlctl.ReinitConfigResponse - 14, // 20: mysqlctl.MysqlCtl.RefreshConfig:output_type -> mysqlctl.RefreshConfigResponse - 16, // 21: mysqlctl.MysqlCtl.VersionString:output_type -> mysqlctl.VersionStringResponse - 14, // [14:22] is the sub-list for method output_type - 6, // [6:14] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 18, // 0: mysqlctl.ShutdownRequest.mysql_shutdown_timeout:type_name -> vttime.Duration + 19, // 1: mysqlctl.ApplyBinlogFileRequest.binlog_restore_datetime:type_name -> vttime.Time + 19, // 2: mysqlctl.ReadBinlogFilesTimestampsResponse.first_timestamp:type_name -> vttime.Time + 19, // 3: mysqlctl.ReadBinlogFilesTimestampsResponse.last_timestamp:type_name -> vttime.Time + 20, // 4: mysqlctl.BackupInfo.tablet_alias:type_name -> topodata.TabletAlias + 19, // 5: mysqlctl.BackupInfo.time:type_name -> vttime.Time + 0, // 6: mysqlctl.BackupInfo.status:type_name -> mysqlctl.BackupInfo.Status + 1, // 7: mysqlctl.MysqlCtl.Start:input_type -> mysqlctl.StartRequest + 3, // 8: mysqlctl.MysqlCtl.Shutdown:input_type -> mysqlctl.ShutdownRequest + 5, // 9: mysqlctl.MysqlCtl.RunMysqlUpgrade:input_type -> mysqlctl.RunMysqlUpgradeRequest + 7, // 10: mysqlctl.MysqlCtl.ApplyBinlogFile:input_type -> mysqlctl.ApplyBinlogFileRequest + 9, // 11: mysqlctl.MysqlCtl.ReadBinlogFilesTimestamps:input_type -> mysqlctl.ReadBinlogFilesTimestampsRequest + 11, // 12: mysqlctl.MysqlCtl.ReinitConfig:input_type -> mysqlctl.ReinitConfigRequest + 13, // 13: mysqlctl.MysqlCtl.RefreshConfig:input_type -> mysqlctl.RefreshConfigRequest + 15, // 14: mysqlctl.MysqlCtl.VersionString:input_type -> mysqlctl.VersionStringRequest + 2, // 15: mysqlctl.MysqlCtl.Start:output_type -> mysqlctl.StartResponse + 4, // 16: mysqlctl.MysqlCtl.Shutdown:output_type -> mysqlctl.ShutdownResponse + 6, // 17: mysqlctl.MysqlCtl.RunMysqlUpgrade:output_type -> mysqlctl.RunMysqlUpgradeResponse + 8, // 18: mysqlctl.MysqlCtl.ApplyBinlogFile:output_type -> mysqlctl.ApplyBinlogFileResponse + 10, // 19: mysqlctl.MysqlCtl.ReadBinlogFilesTimestamps:output_type -> mysqlctl.ReadBinlogFilesTimestampsResponse + 12, // 20: mysqlctl.MysqlCtl.ReinitConfig:output_type -> mysqlctl.ReinitConfigResponse + 14, // 21: mysqlctl.MysqlCtl.RefreshConfig:output_type -> mysqlctl.RefreshConfigResponse + 16, // 22: mysqlctl.MysqlCtl.VersionString:output_type -> mysqlctl.VersionStringResponse + 15, // [15:23] is the sub-list for method output_type + 7, // [7:15] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_mysqlctl_proto_init() } diff --git a/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go b/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go index bb2ec78e03a..fab1af2f471 100644 --- a/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go @@ -63,7 +63,8 @@ func (m *ShutdownRequest) CloneVT() *ShutdownRequest { return (*ShutdownRequest)(nil) } r := &ShutdownRequest{ - WaitForMysqld: m.WaitForMysqld, + WaitForMysqld: m.WaitForMysqld, + MysqlShutdownTimeout: m.MysqlShutdownTimeout.CloneVT(), } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -430,6 +431,16 @@ func (m *ShutdownRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MysqlShutdownTimeout != nil { + size, err := m.MysqlShutdownTimeout.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } if m.WaitForMysqld { i-- if m.WaitForMysqld { @@ -1085,6 +1096,10 @@ func (m *ShutdownRequest) SizeVT() (n int) { if m.WaitForMysqld { n += 2 } + if m.MysqlShutdownTimeout != nil { + l = m.MysqlShutdownTimeout.SizeVT() + n += 1 + l + sov(uint64(l)) + } n += len(m.unknownFields) return n } @@ -1487,6 +1502,42 @@ func (m *ShutdownRequest) UnmarshalVT(dAtA []byte) error { } } m.WaitForMysqld = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MysqlShutdownTimeout", 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.MysqlShutdownTimeout == nil { + m.MysqlShutdownTimeout = &vttime.Duration{} + } + if err := m.MysqlShutdownTimeout.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 032b7357d43..e606e71a267 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -131,7 +131,8 @@ func (tm *TabletManager) RestoreData( deleteBeforeRestore bool, backupTime time.Time, restoreToTimetamp time.Time, - restoreToPos string) error { + restoreToPos string, + mysqlShutdownTimeout time.Duration) error { if err := tm.lock(ctx); err != nil { return err } @@ -180,14 +181,14 @@ func (tm *TabletManager) RestoreData( RestoreToPos: restoreToPos, RestoreToTimestamp: protoutil.TimeToProto(restoreToTimetamp), } - err = tm.restoreDataLocked(ctx, logger, waitForBackupInterval, deleteBeforeRestore, req) + err = tm.restoreDataLocked(ctx, logger, waitForBackupInterval, deleteBeforeRestore, req, mysqlShutdownTimeout) if err != nil { return err } return nil } -func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.Logger, waitForBackupInterval time.Duration, deleteBeforeRestore bool, request *tabletmanagerdatapb.RestoreFromBackupRequest) error { +func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.Logger, waitForBackupInterval time.Duration, deleteBeforeRestore bool, request *tabletmanagerdatapb.RestoreFromBackupRequest, mysqlShutdownTimeout time.Duration) error { tablet := tm.Tablet() originalType := tablet.Type @@ -217,18 +218,19 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L } params := mysqlctl.RestoreParams{ - Cnf: tm.Cnf, - Mysqld: tm.MysqlDaemon, - Logger: logger, - Concurrency: restoreConcurrency, - HookExtraEnv: tm.hookExtraEnv(), - DeleteBeforeRestore: deleteBeforeRestore, - DbName: topoproto.TabletDbName(tablet), - Keyspace: keyspace, - Shard: tablet.Shard, - StartTime: startTime, - DryRun: request.DryRun, - Stats: backupstats.RestoreStats(), + Cnf: tm.Cnf, + Mysqld: tm.MysqlDaemon, + Logger: logger, + Concurrency: restoreConcurrency, + HookExtraEnv: tm.hookExtraEnv(), + DeleteBeforeRestore: deleteBeforeRestore, + DbName: topoproto.TabletDbName(tablet), + Keyspace: keyspace, + Shard: tablet.Shard, + StartTime: startTime, + DryRun: request.DryRun, + Stats: backupstats.RestoreStats(), + MysqlShutdownTimeout: mysqlShutdownTimeout, } restoreToTimestamp := protoutil.TimeFromProto(request.RestoreToTimestamp).UTC() if request.RestoreToPos != "" && !restoreToTimestamp.IsZero() { diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index b3d2e2794f6..9c361eac400 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -149,19 +149,20 @@ func (tm *TabletManager) Backup(ctx context.Context, logger logutil.Logger, req // Now we can run the backup. backupParams := mysqlctl.BackupParams{ - Cnf: tm.Cnf, - Mysqld: tm.MysqlDaemon, - Logger: l, - Concurrency: int(req.Concurrency), - IncrementalFromPos: req.IncrementalFromPos, - HookExtraEnv: tm.hookExtraEnv(), - TopoServer: tm.TopoServer, - Keyspace: tablet.Keyspace, - Shard: tablet.Shard, - TabletAlias: topoproto.TabletAliasString(tablet.Alias), - BackupTime: time.Now(), - Stats: backupstats.BackupStats(), - UpgradeSafe: req.UpgradeSafe, + Cnf: tm.Cnf, + Mysqld: tm.MysqlDaemon, + Logger: l, + Concurrency: int(req.Concurrency), + IncrementalFromPos: req.IncrementalFromPos, + HookExtraEnv: tm.hookExtraEnv(), + TopoServer: tm.TopoServer, + Keyspace: tablet.Keyspace, + Shard: tablet.Shard, + TabletAlias: topoproto.TabletAliasString(tablet.Alias), + BackupTime: time.Now(), + Stats: backupstats.BackupStats(), + UpgradeSafe: req.UpgradeSafe, + MysqlShutdownTimeout: mysqlShutdownTimeout, } returnErr := mysqlctl.Backup(ctx, backupParams) @@ -189,7 +190,7 @@ func (tm *TabletManager) RestoreFromBackup(ctx context.Context, logger logutil.L l := logutil.NewTeeLogger(logutil.NewConsoleLogger(), logger) // Now we can run restore. - err = tm.restoreDataLocked(ctx, l, 0 /* waitForBackupInterval */, true /* deleteBeforeRestore */, request) + err = tm.restoreDataLocked(ctx, l, 0 /* waitForBackupInterval */, true /* deleteBeforeRestore */, request, mysqlShutdownTimeout) // Re-run health check to be sure to capture any replication delay. tm.QueryServiceControl.BroadcastHealth() diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 2873c3a1d5e..c1b6c837d50 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -88,6 +88,7 @@ var ( initPopulateMetadata bool initTimeout = 1 * time.Minute + mysqlShutdownTimeout = 5 * time.Minute ) func registerInitFlags(fs *pflag.FlagSet) { @@ -99,6 +100,7 @@ func registerInitFlags(fs *pflag.FlagSet) { fs.StringVar(&skipBuildInfoTags, "vttablet_skip_buildinfo_tags", skipBuildInfoTags, "comma-separated list of buildinfo tags to skip from merging with --init_tags. each tag is either an exact match or a regular expression of the form '/regexp/'.") fs.Var(&initTags, "init_tags", "(init parameter) comma separated list of key:value pairs used to tag the tablet") fs.DurationVar(&initTimeout, "init_timeout", initTimeout, "(init parameter) timeout to use for the init phase.") + fs.DurationVar(&mysqlShutdownTimeout, "mysql-shutdown-timeout", mysqlShutdownTimeout, "timeout to use when MySQL is being shut down.") } var ( @@ -798,7 +800,7 @@ func (tm *TabletManager) handleRestore(ctx context.Context) (bool, error) { } // restoreFromBackup will just be a regular action // (same as if it was triggered remotely) - if err := tm.RestoreData(ctx, logutil.NewConsoleLogger(), waitForBackupInterval, false /* deleteBeforeRestore */, backupTime, restoreToTimestamp, restoreToPos); err != nil { + if err := tm.RestoreData(ctx, logutil.NewConsoleLogger(), waitForBackupInterval, false /* deleteBeforeRestore */, backupTime, restoreToTimestamp, restoreToPos, mysqlShutdownTimeout); err != nil { log.Exitf("RestoreFromBackup failed: %v", err) } }() diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index 787e4ce1946..0ba8adc9a06 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -47,6 +47,8 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) +const mysqlShutdownTimeout = 1 * time.Minute + type compressionDetails struct { CompressionEngineName string ExternalCompressorCmd string @@ -263,7 +265,7 @@ func testBackupRestore(t *testing.T, cDetails *compressionDetails) error { RelayLogInfoPath: path.Join(root, "relay-log.info"), } - err = destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* backupTime */, time.Time{} /* restoreToTimestamp */, "") + err = destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* backupTime */, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout) if err != nil { return err } @@ -302,7 +304,7 @@ func testBackupRestore(t *testing.T, cDetails *compressionDetails) error { primary.FakeMysqlDaemon.SetReplicationPositionPos = primary.FakeMysqlDaemon.CurrentPrimaryPosition // restore primary from latest backup - require.NoError(t, primary.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, ""), + require.NoError(t, primary.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout), "RestoreData failed") // tablet was created as PRIMARY, so it's baseTabletType is PRIMARY assert.Equal(t, topodatapb.TabletType_PRIMARY, primary.Tablet.Type) @@ -318,7 +320,7 @@ func testBackupRestore(t *testing.T, cDetails *compressionDetails) error { } // Test restore with the backup timestamp - require.NoError(t, primary.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, backupTime, time.Time{} /* restoreToTimestamp */, ""), + require.NoError(t, primary.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, backupTime, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout), "RestoreData with backup timestamp failed") assert.Equal(t, topodatapb.TabletType_PRIMARY, primary.Tablet.Type) assert.False(t, primary.FakeMysqlDaemon.Replicating) @@ -519,7 +521,7 @@ func TestBackupRestoreLagged(t *testing.T) { errCh = make(chan error, 1) go func(ctx context.Context, tablet *FakeTablet) { - errCh <- tablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "") + errCh <- tablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout) }(ctx, destTablet) timer = time.NewTicker(1 * time.Second) @@ -713,7 +715,7 @@ func TestRestoreUnreachablePrimary(t *testing.T) { // set a short timeout so that we don't have to wait 30 seconds topo.RemoteOperationTimeout = 2 * time.Second // Restore should still succeed - require.NoError(t, destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "")) + require.NoError(t, destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout)) // verify the full status require.NoError(t, destTablet.FakeMysqlDaemon.CheckSuperQueryList(), "destTablet.FakeMysqlDaemon.CheckSuperQueryList failed") assert.True(t, destTablet.FakeMysqlDaemon.Replicating) @@ -867,7 +869,7 @@ func TestDisableActiveReparents(t *testing.T) { RelayLogInfoPath: path.Join(root, "relay-log.info"), } - require.NoError(t, destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "")) + require.NoError(t, destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */, time.Time{} /* restoreFromBackupTs */, time.Time{} /* restoreToTimestamp */, "", mysqlShutdownTimeout)) // verify the full status require.NoError(t, destTablet.FakeMysqlDaemon.CheckSuperQueryList(), "destTablet.FakeMysqlDaemon.CheckSuperQueryList failed") assert.False(t, destTablet.FakeMysqlDaemon.Replicating) diff --git a/proto/mysqlctl.proto b/proto/mysqlctl.proto index bc67cef07c1..7e5fe13b991 100644 --- a/proto/mysqlctl.proto +++ b/proto/mysqlctl.proto @@ -33,6 +33,7 @@ message StartResponse{} message ShutdownRequest{ bool wait_for_mysqld = 1; + vttime.Duration mysql_shutdown_timeout = 2; } message ShutdownResponse{} diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index f5f7c100cc5..11489a0acc2 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -12649,6 +12649,9 @@ export namespace mysqlctl { /** ShutdownRequest wait_for_mysqld */ wait_for_mysqld?: (boolean|null); + + /** ShutdownRequest mysql_shutdown_timeout */ + mysql_shutdown_timeout?: (vttime.IDuration|null); } /** Represents a ShutdownRequest. */ @@ -12663,6 +12666,9 @@ export namespace mysqlctl { /** ShutdownRequest wait_for_mysqld. */ public wait_for_mysqld: boolean; + /** ShutdownRequest mysql_shutdown_timeout. */ + public mysql_shutdown_timeout?: (vttime.IDuration|null); + /** * Creates a new ShutdownRequest instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index a7fcd29e3f7..71d67a61ed1 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -29336,6 +29336,7 @@ export const mysqlctl = $root.mysqlctl = (() => { * @memberof mysqlctl * @interface IShutdownRequest * @property {boolean|null} [wait_for_mysqld] ShutdownRequest wait_for_mysqld + * @property {vttime.IDuration|null} [mysql_shutdown_timeout] ShutdownRequest mysql_shutdown_timeout */ /** @@ -29361,6 +29362,14 @@ export const mysqlctl = $root.mysqlctl = (() => { */ ShutdownRequest.prototype.wait_for_mysqld = false; + /** + * ShutdownRequest mysql_shutdown_timeout. + * @member {vttime.IDuration|null|undefined} mysql_shutdown_timeout + * @memberof mysqlctl.ShutdownRequest + * @instance + */ + ShutdownRequest.prototype.mysql_shutdown_timeout = null; + /** * Creates a new ShutdownRequest instance using the specified properties. * @function create @@ -29387,6 +29396,8 @@ export const mysqlctl = $root.mysqlctl = (() => { writer = $Writer.create(); if (message.wait_for_mysqld != null && Object.hasOwnProperty.call(message, "wait_for_mysqld")) writer.uint32(/* id 1, wireType 0 =*/8).bool(message.wait_for_mysqld); + if (message.mysql_shutdown_timeout != null && Object.hasOwnProperty.call(message, "mysql_shutdown_timeout")) + $root.vttime.Duration.encode(message.mysql_shutdown_timeout, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); return writer; }; @@ -29425,6 +29436,10 @@ export const mysqlctl = $root.mysqlctl = (() => { message.wait_for_mysqld = reader.bool(); break; } + case 2: { + message.mysql_shutdown_timeout = $root.vttime.Duration.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -29463,6 +29478,11 @@ export const mysqlctl = $root.mysqlctl = (() => { if (message.wait_for_mysqld != null && message.hasOwnProperty("wait_for_mysqld")) if (typeof message.wait_for_mysqld !== "boolean") return "wait_for_mysqld: boolean expected"; + if (message.mysql_shutdown_timeout != null && message.hasOwnProperty("mysql_shutdown_timeout")) { + let error = $root.vttime.Duration.verify(message.mysql_shutdown_timeout); + if (error) + return "mysql_shutdown_timeout." + error; + } return null; }; @@ -29480,6 +29500,11 @@ export const mysqlctl = $root.mysqlctl = (() => { let message = new $root.mysqlctl.ShutdownRequest(); if (object.wait_for_mysqld != null) message.wait_for_mysqld = Boolean(object.wait_for_mysqld); + if (object.mysql_shutdown_timeout != null) { + if (typeof object.mysql_shutdown_timeout !== "object") + throw TypeError(".mysqlctl.ShutdownRequest.mysql_shutdown_timeout: object expected"); + message.mysql_shutdown_timeout = $root.vttime.Duration.fromObject(object.mysql_shutdown_timeout); + } return message; }; @@ -29496,10 +29521,14 @@ export const mysqlctl = $root.mysqlctl = (() => { if (!options) options = {}; let object = {}; - if (options.defaults) + if (options.defaults) { object.wait_for_mysqld = false; + object.mysql_shutdown_timeout = null; + } if (message.wait_for_mysqld != null && message.hasOwnProperty("wait_for_mysqld")) object.wait_for_mysqld = message.wait_for_mysqld; + if (message.mysql_shutdown_timeout != null && message.hasOwnProperty("mysql_shutdown_timeout")) + object.mysql_shutdown_timeout = $root.vttime.Duration.toObject(message.mysql_shutdown_timeout, options); return object; }; From c5ee4880809fd48d15c9818528ced254a34f2448 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 30 Nov 2023 18:31:02 +0100 Subject: [PATCH 068/119] mysqlctl: Error out on stale socket (#14650) Signed-off-by: Dirkjan Bussink --- go/vt/mysqlctl/mysqld.go | 6 +++--- go/vt/mysqlctl/mysqld_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 9864d909b2f..731e608a2c0 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -461,13 +461,13 @@ func cleanupLockfile(socket string, ts string) error { if err == nil { // If the process still exists, it's not safe to // remove the lock file, so we have to keep it around. - log.Warningf("%v: not removing socket lock file: %v", ts, lockPath) - return nil + log.Errorf("%v: not removing socket lock file: %v with pid %v", ts, lockPath, p) + return fmt.Errorf("process %v is still running", p) } if !errors.Is(err, os.ErrProcessDone) { // Any errors except for the process being done // is unexpected here. - log.Errorf("%v: error checking process: %v", ts, err) + log.Errorf("%v: error checking process %v: %v", ts, p, err) return err } diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index b45ab5bd6d8..0caba8c904d 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -195,6 +195,6 @@ func TestCleanupLockfile(t *testing.T) { // If the lockfile exists, and the process is found, we don't clean it up. os.WriteFile("mysql.sock.lock", []byte(strconv.Itoa(os.Getpid())), 0o600) - assert.NoError(t, cleanupLockfile("mysql.sock", ts)) + assert.Error(t, cleanupLockfile("mysql.sock", ts)) assert.FileExists(t, "mysql.sock.lock") } From 0fbae2ecd26658f4e3e7e45183b16e29ba855de0 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 30 Nov 2023 12:46:46 -0500 Subject: [PATCH 069/119] Flakes: Shutdown vttablet before mysqld in backup tests (#14647) Signed-off-by: Matt Lord --- .../endtoend/backup/vtbackup/backup_only_test.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/go/test/endtoend/backup/vtbackup/backup_only_test.go b/go/test/endtoend/backup/vtbackup/backup_only_test.go index 5e80d5d3cc3..3cce3053406 100644 --- a/go/test/endtoend/backup/vtbackup/backup_only_test.go +++ b/go/test/endtoend/backup/vtbackup/backup_only_test.go @@ -300,11 +300,12 @@ func resetTabletDirectory(t *testing.T, tablet cluster.Vttablet, initMysql bool) extraArgs := []string{"--db-credentials-file", dbCredentialFile} tablet.MysqlctlProcess.ExtraArgs = extraArgs - // Shutdown Mysql - err := tablet.MysqlctlProcess.Stop() - require.Nil(t, err) // Teardown Tablet - err = tablet.VttabletProcess.TearDown() + err := tablet.VttabletProcess.TearDown() + require.Nil(t, err) + + // Shutdown Mysql + err = tablet.MysqlctlProcess.Stop() require.Nil(t, err) // Clear out the previous data @@ -335,13 +336,7 @@ func tearDown(t *testing.T, initMysql bool) { require.Nil(t, err) } - // TODO: Ideally we should not be resetting the mysql. - // So in below code we will have to uncomment the commented code and remove resetTabletDirectory for _, tablet := range []cluster.Vttablet{*primary, *replica1, *replica2} { - //Tear down Tablet - //err := tablet.VttabletProcess.TearDown() - //require.Nil(t, err) - resetTabletDirectory(t, tablet, initMysql) // DeleteTablet on a primary will cause tablet to shutdown, so should only call it after tablet is already shut down err := localCluster.VtctlclientProcess.ExecuteCommand("DeleteTablet", "--", "--allow_primary", tablet.Alias) From 48a6690c69c5e298a21dcb6dd05e7f22eaf920b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Mon, 4 Dec 2023 11:34:01 +0100 Subject: [PATCH 070/119] planbuilder: clean up code (#14657) Signed-off-by: Andres Taylor --- .../planbuilder/operator_transformers.go | 33 +- .../planbuilder/operators/SQL_builder.go | 9 +- .../operators/aggregation_pushing.go | 168 ++++----- .../planbuilder/operators/aggregator.go | 29 +- .../planbuilder/operators/apply_join.go | 54 ++- .../vtgate/planbuilder/operators/ast_to_op.go | 151 ++++---- .../vtgate/planbuilder/operators/comments.go | 15 +- go/vt/vtgate/planbuilder/operators/delete.go | 81 ++--- .../vtgate/planbuilder/operators/distinct.go | 17 +- .../planbuilder/operators/dml_planning.go | 34 +- .../planbuilder/operators/expressions.go | 5 +- go/vt/vtgate/planbuilder/operators/filter.go | 28 +- .../planbuilder/operators/fk_cascade.go | 19 +- .../vtgate/planbuilder/operators/fk_verify.go | 17 +- .../vtgate/planbuilder/operators/hash_join.go | 39 +- go/vt/vtgate/planbuilder/operators/helpers.go | 54 +-- go/vt/vtgate/planbuilder/operators/horizon.go | 32 +- .../operators/horizon_expanding.go | 68 ++-- .../operators/info_schema_planning.go | 15 +- go/vt/vtgate/planbuilder/operators/insert.go | 155 ++++---- .../planbuilder/operators/insert_selection.go | 17 +- go/vt/vtgate/planbuilder/operators/join.go | 51 ++- .../planbuilder/operators/join_merging.go | 5 +- go/vt/vtgate/planbuilder/operators/joins.go | 15 +- go/vt/vtgate/planbuilder/operators/limit.go | 15 +- .../planbuilder/operators/misc_routing.go | 36 +- .../planbuilder/operators/offset_planning.go | 46 ++- .../vtgate/planbuilder/operators/operator.go | 155 ++------ .../planbuilder/operators/operator_funcs.go | 3 +- go/vt/vtgate/planbuilder/operators/ops/op.go | 77 ---- .../vtgate/planbuilder/operators/ordering.go | 21 +- go/vt/vtgate/planbuilder/operators/phases.go | 68 ++-- .../planbuilder/operators/plan_query.go | 165 +++++++++ .../planbuilder/operators/projection.go | 102 +++--- .../planbuilder/operators/query_planning.go | 333 ++++++++---------- .../planbuilder/operators/querygraph.go | 9 +- .../planbuilder/operators/queryprojection.go | 53 +-- .../operators/queryprojection_test.go | 9 +- .../operators/{rewrite => }/rewriters.go | 138 +++----- go/vt/vtgate/planbuilder/operators/route.go | 106 ++---- .../planbuilder/operators/route_planning.go | 186 ++++------ .../planbuilder/operators/sequential.go | 11 +- .../planbuilder/operators/sharded_routing.go | 57 ++- .../vtgate/planbuilder/operators/subquery.go | 59 ++-- .../planbuilder/operators/subquery_builder.go | 119 ++----- .../operators/subquery_container.go | 17 +- .../operators/subquery_planning.go | 155 ++++---- go/vt/vtgate/planbuilder/operators/table.go | 7 +- .../operators/{ops => }/to_json.go | 2 +- go/vt/vtgate/planbuilder/operators/union.go | 15 +- .../planbuilder/operators/union_merging.go | 56 ++- go/vt/vtgate/planbuilder/operators/update.go | 131 +++---- .../planbuilder/operators/utils_test.go | 15 +- go/vt/vtgate/planbuilder/operators/vindex.go | 7 +- go/vt/vtgate/planbuilder/plan_test.go | 6 +- go/vt/vtgate/planbuilder/select.go | 3 +- 56 files changed, 1345 insertions(+), 1948 deletions(-) delete mode 100644 go/vt/vtgate/planbuilder/operators/ops/op.go create mode 100644 go/vt/vtgate/planbuilder/operators/plan_query.go rename go/vt/vtgate/planbuilder/operators/{rewrite => }/rewriters.go (67%) rename go/vt/vtgate/planbuilder/operators/{ops => }/to_json.go (98%) diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 5f965b55ad9..3974a307e71 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -30,13 +30,11 @@ import ( "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) -func transformToLogicalPlan(ctx *plancontext.PlanningContext, op ops.Operator) (logicalPlan, error) { +func transformToLogicalPlan(ctx *plancontext.PlanningContext, op operators.Operator) (logicalPlan, error) { switch op := op.(type) { case *operators.Route: return transformRoutePlan(ctx, op) @@ -190,10 +188,7 @@ func transformSubQuery(ctx *plancontext.PlanningContext, op *operators.SubQuery) return newUncorrelatedSubquery(op.FilterType, op.SubqueryValueName, op.HasValuesName, inner, outer), nil } - lhsCols, err := op.OuterExpressionsNeeded(ctx, op.Outer) - if err != nil { - return nil, err - } + lhsCols := op.OuterExpressionsNeeded(ctx, op.Outer) return newSemiJoin(outer, inner, op.Vars, lhsCols), nil } @@ -251,7 +246,7 @@ func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggrega oa.groupByKeys = append(oa.groupByKeys, &engine.GroupByParams{ KeyCol: groupBy.ColOffset, WeightStringCol: groupBy.WSOffset, - Expr: groupBy.AsAliasedExpr().Expr, + Expr: groupBy.SimplifiedExpr, Type: typ, }) } @@ -435,7 +430,7 @@ func routeToEngineRoute(ctx *plancontext.PlanningContext, op *operators.Route, h } rp := newRoutingParams(ctx, op.Routing.OpCode()) - err = op.Routing.UpdateRoutingParams(ctx, rp) + op.Routing.UpdateRoutingParams(ctx, rp) if err != nil { return nil, err } @@ -544,7 +539,7 @@ func buildRouteLogicalPlan(ctx *plancontext.PlanningContext, op *operators.Route } func buildInsertLogicalPlan( - rb *operators.Route, op ops.Operator, stmt *sqlparser.Insert, + rb *operators.Route, op operators.Operator, stmt *sqlparser.Insert, hints *queryHints, ) (logicalPlan, error) { ins := op.(*operators.Insert) @@ -635,16 +630,13 @@ func dmlFormatter(buf *sqlparser.TrackedBuffer, node sqlparser.SQLNode) { func buildUpdateLogicalPlan( ctx *plancontext.PlanningContext, rb *operators.Route, - dmlOp ops.Operator, + dmlOp operators.Operator, stmt *sqlparser.Update, hints *queryHints, ) (logicalPlan, error) { upd := dmlOp.(*operators.Update) rp := newRoutingParams(ctx, rb.Routing.OpCode()) - err := rb.Routing.UpdateRoutingParams(ctx, rp) - if err != nil { - return nil, err - } + rb.Routing.UpdateRoutingParams(ctx, rp) edml := &engine.DML{ Query: generateQuery(stmt), TableNames: []string{upd.VTable.Name.String()}, @@ -670,15 +662,12 @@ func buildUpdateLogicalPlan( func buildDeleteLogicalPlan( ctx *plancontext.PlanningContext, rb *operators.Route, - dmlOp ops.Operator, + dmlOp operators.Operator, hints *queryHints, ) (logicalPlan, error) { del := dmlOp.(*operators.Delete) rp := newRoutingParams(ctx, rb.Routing.OpCode()) - err := rb.Routing.UpdateRoutingParams(ctx, rp) - if err != nil { - return nil, err - } + rb.Routing.UpdateRoutingParams(ctx, rp) edml := &engine.DML{ Query: generateQuery(del.AST), TableNames: []string{del.VTable.Name.String()}, @@ -739,7 +728,7 @@ func updateSelectedVindexPredicate(op *operators.Route) sqlparser.Expr { func getAllTableNames(op *operators.Route) ([]string, error) { tableNameMap := map[string]any{} - err := rewrite.Visit(op, func(op ops.Operator) error { + err := operators.Visit(op, func(op operators.Operator) error { tbl, isTbl := op.(*operators.Table) var name string if isTbl { @@ -764,7 +753,7 @@ func getAllTableNames(op *operators.Route) ([]string, error) { } func transformUnionPlan(ctx *plancontext.PlanningContext, op *operators.Union) (logicalPlan, error) { - sources, err := slice.MapWithError(op.Sources, func(src ops.Operator) (logicalPlan, error) { + sources, err := slice.MapWithError(op.Sources, func(src operators.Operator) (logicalPlan, error) { plan, err := transformToLogicalPlan(ctx, src) if err != nil { return nil, err diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index 5201818951d..961a7d252ff 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -23,7 +23,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -33,7 +32,7 @@ type ( ctx *plancontext.PlanningContext stmt sqlparser.Statement tableNames []string - dmlOperator ops.Operator + dmlOperator Operator } ) @@ -41,7 +40,7 @@ func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { return qb.stmt.(sqlparser.SelectStatement) } -func ToSQL(ctx *plancontext.PlanningContext, op ops.Operator) (_ sqlparser.Statement, _ ops.Operator, err error) { +func ToSQL(ctx *plancontext.PlanningContext, op Operator) (_ sqlparser.Statement, _ Operator, err error) { defer PanicHandler(&err) q := &queryBuilder{ctx: ctx} @@ -347,7 +346,7 @@ func stripDownQuery(from, to sqlparser.SelectStatement) { } // buildQuery recursively builds the query into an AST, from an operator tree -func buildQuery(op ops.Operator, qb *queryBuilder) { +func buildQuery(op Operator, qb *queryBuilder) { switch op := op.(type) { case *Table: buildTable(op, qb) @@ -415,7 +414,7 @@ func buildUpdate(op *Update, qb *queryBuilder) { } type OpWithAST interface { - ops.Operator + Operator Statement() sqlparser.Statement } diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index edba5c51256..e50483ce8d2 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -24,25 +24,23 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) -func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) (output ops.Operator, applyResult *rewrite.ApplyResult, err error) { +func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) (output Operator, applyResult *ApplyResult) { if aggregator.Pushed { - return aggregator, rewrite.SameTree, nil + return aggregator, NoRewrite } // this rewrite is always valid, and we should do it whenever possible if route, ok := aggregator.Source.(*Route); ok && (route.IsSingleShard() || overlappingUniqueVindex(ctx, aggregator.Grouping)) { - return rewrite.Swap(aggregator, route, "push down aggregation under route - remove original") + return Swap(aggregator, route, "push down aggregation under route - remove original") } // other rewrites require us to have reached this phase before we can consider them if !reachedPhase(ctx, delegateAggregation) { - return aggregator, rewrite.SameTree, nil + return aggregator, NoRewrite } // if we have not yet been able to push this aggregation down, @@ -54,23 +52,19 @@ func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) switch src := aggregator.Source.(type) { case *Route: // if we have a single sharded route, we can push it down - output, applyResult, err = pushAggregationThroughRoute(ctx, aggregator, src) + output, applyResult = pushAggregationThroughRoute(ctx, aggregator, src) case *ApplyJoin: - output, applyResult, err = pushAggregationThroughJoin(ctx, aggregator, src) + output, applyResult = pushAggregationThroughJoin(ctx, aggregator, src) case *Filter: - output, applyResult, err = pushAggregationThroughFilter(ctx, aggregator, src) + output, applyResult = pushAggregationThroughFilter(ctx, aggregator, src) case *SubQueryContainer: - output, applyResult, err = pushAggregationThroughSubquery(ctx, aggregator, src) + output, applyResult = pushAggregationThroughSubquery(ctx, aggregator, src) default: - return aggregator, rewrite.SameTree, nil - } - - if err != nil { - return nil, nil, err + return aggregator, NoRewrite } if output == nil { - return aggregator, rewrite.SameTree, nil + return aggregator, NoRewrite } aggregator.Pushed = true @@ -92,16 +86,13 @@ func pushAggregationThroughSubquery( ctx *plancontext.PlanningContext, rootAggr *Aggregator, src *SubQueryContainer, -) (ops.Operator, *rewrite.ApplyResult, error) { - pushedAggr := rootAggr.Clone([]ops.Operator{src.Outer}).(*Aggregator) +) (Operator, *ApplyResult) { + pushedAggr := rootAggr.Clone([]Operator{src.Outer}).(*Aggregator) pushedAggr.Original = false pushedAggr.Pushed = false for _, subQuery := range src.Inner { - lhsCols, err := subQuery.OuterExpressionsNeeded(ctx, src.Outer) - if err != nil { - return nil, nil, err - } + lhsCols := subQuery.OuterExpressionsNeeded(ctx, src.Outer) for _, colName := range lhsCols { idx := slices.IndexFunc(pushedAggr.Columns, func(ae *sqlparser.AliasedExpr) bool { return ctx.SemTable.EqualsExpr(ae.Expr, colName) @@ -116,12 +107,12 @@ func pushAggregationThroughSubquery( src.Outer = pushedAggr if !rootAggr.Original { - return src, rewrite.NewTree("push Aggregation under subquery - keep original"), nil + return src, Rewrote("push Aggregation under subquery - keep original") } rootAggr.aggregateTheAggregates() - return rootAggr, rewrite.NewTree("push Aggregation under subquery"), nil + return rootAggr, Rewrote("push Aggregation under subquery") } func (a *Aggregator) aggregateTheAggregates() { @@ -145,15 +136,12 @@ func pushAggregationThroughRoute( ctx *plancontext.PlanningContext, aggregator *Aggregator, route *Route, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { // Create a new aggregator to be placed below the route. aggrBelowRoute := aggregator.SplitAggregatorBelowRoute(route.Inputs()) aggrBelowRoute.Aggregations = nil - err := pushAggregations(ctx, aggregator, aggrBelowRoute) - if err != nil { - return nil, nil, err - } + pushAggregations(ctx, aggregator, aggrBelowRoute) // Set the source of the route to the new aggregator placed below the route. route.Source = aggrBelowRoute @@ -161,18 +149,15 @@ func pushAggregationThroughRoute( if !aggregator.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return aggregator.Source, rewrite.NewTree("push aggregation under route - remove original"), nil + return aggregator.Source, Rewrote("push aggregation under route - remove original") } - return aggregator, rewrite.NewTree("push aggregation under route - keep original"), nil + return aggregator, Rewrote("push aggregation under route - keep original") } // pushAggregations splits aggregations between the original aggregator and the one we are pushing down -func pushAggregations(ctx *plancontext.PlanningContext, aggregator *Aggregator, aggrBelowRoute *Aggregator) error { - canPushDistinctAggr, distinctExpr, err := checkIfWeCanPush(ctx, aggregator) - if err != nil { - return err - } +func pushAggregations(ctx *plancontext.PlanningContext, aggregator *Aggregator, aggrBelowRoute *Aggregator) { + canPushDistinctAggr, distinctExpr := checkIfWeCanPush(ctx, aggregator) distinctAggrGroupByAdded := false @@ -192,7 +177,7 @@ func pushAggregations(ctx *plancontext.PlanningContext, aggregator *Aggregator, // doing the aggregating on the vtgate level instead // Adding to group by can be done only once even though there are multiple distinct aggregation with same expression. if !distinctAggrGroupByAdded { - groupBy := NewGroupBy(distinctExpr, distinctExpr, aeDistinctExpr) + groupBy := NewGroupBy(distinctExpr, distinctExpr) groupBy.ColOffset = aggr.ColOffset aggrBelowRoute.Grouping = append(aggrBelowRoute.Grouping, groupBy) distinctAggrGroupByAdded = true @@ -202,11 +187,9 @@ func pushAggregations(ctx *plancontext.PlanningContext, aggregator *Aggregator, if !canPushDistinctAggr { aggregator.DistinctExpr = distinctExpr } - - return nil } -func checkIfWeCanPush(ctx *plancontext.PlanningContext, aggregator *Aggregator) (bool, sqlparser.Expr, error) { +func checkIfWeCanPush(ctx *plancontext.PlanningContext, aggregator *Aggregator) (bool, sqlparser.Expr) { canPush := true var distinctExpr sqlparser.Expr var differentExpr *sqlparser.AliasedExpr @@ -229,22 +212,22 @@ func checkIfWeCanPush(ctx *plancontext.PlanningContext, aggregator *Aggregator) } if !canPush && differentExpr != nil { - return false, nil, vterrors.VT12001(fmt.Sprintf("only one DISTINCT aggregation is allowed in a SELECT: %s", sqlparser.String(differentExpr))) + panic(vterrors.VT12001(fmt.Sprintf("only one DISTINCT aggregation is allowed in a SELECT: %s", sqlparser.String(differentExpr)))) } - return canPush, distinctExpr, nil + return canPush, distinctExpr } func pushAggregationThroughFilter( ctx *plancontext.PlanningContext, aggregator *Aggregator, filter *Filter, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { columnsNeeded := collectColNamesNeeded(ctx, filter) // Create a new aggregator to be placed below the route. - pushedAggr := aggregator.Clone([]ops.Operator{filter.Source}).(*Aggregator) + pushedAggr := aggregator.Clone([]Operator{filter.Source}).(*Aggregator) pushedAggr.Pushed = false pushedAggr.Original = false @@ -264,10 +247,10 @@ withNextColumn: if !aggregator.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return aggregator.Source, rewrite.NewTree("push aggregation under filter - remove original"), nil + return aggregator.Source, Rewrote("push aggregation under filter - remove original") } aggregator.aggregateTheAggregates() - return aggregator, rewrite.NewTree("push aggregation under filter - keep original"), nil + return aggregator, Rewrote("push aggregation under filter - keep original") } func collectColNamesNeeded(ctx *plancontext.PlanningContext, f *Filter) (columnsNeeded []*sqlparser.ColName) { @@ -363,7 +346,7 @@ Transformed: / \ R1 R2 */ -func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin) (ops.Operator, *rewrite.ApplyResult, error) { +func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin) (Operator, *ApplyResult) { lhs := &joinPusher{ orig: rootAggr, pushed: &Aggregator{ @@ -387,23 +370,17 @@ func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggr if err != nil { // if we get this error, we just abort the splitting and fall back on simpler ways of solving the same query if errors.Is(err, errAbortAggrPushing) { - return nil, nil, nil + return nil, nil } - return nil, nil, err + panic(err) } - groupingJCs, err := splitGroupingToLeftAndRight(ctx, rootAggr, lhs, rhs) - if err != nil { - return nil, nil, err - } + groupingJCs := splitGroupingToLeftAndRight(ctx, rootAggr, lhs, rhs) joinColumns = append(joinColumns, groupingJCs...) // We need to add any columns coming from the lhs of the join to the group by on that side // If we don't, the LHS will not be able to return the column, and it can't be used to send down to the RHS - err = addColumnsFromLHSInJoinPredicates(ctx, rootAggr, join, lhs) - if err != nil { - return nil, nil, err - } + addColumnsFromLHSInJoinPredicates(ctx, rootAggr, join, lhs) join.LHS, join.RHS = lhs.pushed, rhs.pushed join.JoinColumns = joinColumns @@ -411,23 +388,23 @@ func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggr if !rootAggr.Original { // we only keep the root aggregation, if this aggregator was created // by splitting one and pushing under a join, we can get rid of this one - return output, rewrite.NewTree("push Aggregation under join - keep original"), nil + return output, Rewrote("push Aggregation under join - keep original") } rootAggr.aggregateTheAggregates() rootAggr.Source = output - return rootAggr, rewrite.NewTree("push Aggregation under join"), nil + return rootAggr, Rewrote("push Aggregation under join") } var errAbortAggrPushing = fmt.Errorf("abort aggregation pushing") -func addColumnsFromLHSInJoinPredicates(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin, lhs *joinPusher) error { +func addColumnsFromLHSInJoinPredicates(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin, lhs *joinPusher) { for _, pred := range join.JoinPredicates { for _, bve := range pred.LHSExprs { expr := bve.Expr wexpr, err := rootAggr.QP.GetSimplifiedExpr(ctx, expr) if err != nil { - return err + panic(err) } idx, found := canReuseColumn(ctx, lhs.pushed.Columns, expr, extractExpr) if !found { @@ -450,10 +427,9 @@ func addColumnsFromLHSInJoinPredicates(ctx *plancontext.PlanningContext, rootAgg }) } } - return nil } -func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Aggregator, lhs, rhs *joinPusher) ([]JoinColumn, error) { +func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Aggregator, lhs, rhs *joinPusher) []JoinColumn { var groupingJCs []JoinColumn for _, groupBy := range rootAggr.Grouping { @@ -463,30 +439,27 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg case deps.IsSolvedBy(lhs.tableID): lhs.addGrouping(ctx, groupBy) groupingJCs = append(groupingJCs, JoinColumn{ - Original: aeWrap(groupBy.Inner), + Original: groupBy.Inner, LHSExprs: []BindVarExpr{{Expr: expr}}, }) case deps.IsSolvedBy(rhs.tableID): rhs.addGrouping(ctx, groupBy) groupingJCs = append(groupingJCs, JoinColumn{ - Original: aeWrap(groupBy.Inner), + Original: groupBy.Inner, RHSExpr: expr, }) case deps.IsSolvedBy(lhs.tableID.Merge(rhs.tableID)): - jc, err := breakExpressionInLHSandRHSForApplyJoin(ctx, groupBy.SimplifiedExpr, lhs.tableID) - if err != nil { - return nil, err - } + jc := breakExpressionInLHSandRHSForApplyJoin(ctx, groupBy.SimplifiedExpr, lhs.tableID) for _, lhsExpr := range jc.LHSExprs { e := lhsExpr.Expr - lhs.addGrouping(ctx, NewGroupBy(e, e, aeWrap(e))) + lhs.addGrouping(ctx, NewGroupBy(e, e)) } - rhs.addGrouping(ctx, NewGroupBy(jc.RHSExpr, jc.RHSExpr, aeWrap(jc.RHSExpr))) + rhs.addGrouping(ctx, NewGroupBy(jc.RHSExpr, jc.RHSExpr)) default: - return nil, vterrors.VT13001(fmt.Sprintf("grouping with bad dependencies %s", groupBy.SimplifiedExpr)) + panic(vterrors.VT13001(fmt.Sprintf("grouping with bad dependencies %s", groupBy.SimplifiedExpr))) } } - return groupingJCs, nil + return groupingJCs } // splitAggrColumnsToLeftAndRight pushes all aggregations on the aggregator above a join and @@ -497,7 +470,7 @@ func splitAggrColumnsToLeftAndRight( aggregator *Aggregator, join *ApplyJoin, lhs, rhs *joinPusher, -) ([]JoinColumn, ops.Operator, error) { +) ([]JoinColumn, Operator, error) { proj := newAliasedProjection(join) proj.FromAggr = true builder := &aggBuilder{ @@ -507,10 +480,7 @@ func splitAggrColumnsToLeftAndRight( outerJoin: join.LeftJoin, } - canPushDistinctAggr, distinctExpr, err := checkIfWeCanPush(ctx, aggregator) - if err != nil { - return nil, nil, err - } + canPushDistinctAggr, distinctExpr := checkIfWeCanPush(ctx, aggregator) // Distinct aggregation cannot be pushed down in the join. // We keep node of the distinct aggregation expression to be used later for ordering. @@ -531,10 +501,7 @@ outer: continue outer } } - _, err := builder.proj.addUnexploredExpr(col, col.Expr) - if err != nil { - return nil, nil, err - } + builder.proj.addUnexploredExpr(col, col.Expr) } return builder.joinColumns, builder.proj, nil } @@ -566,7 +533,7 @@ func (ab *aggBuilder) leftCountStar(ctx *plancontext.PlanningContext) *sqlparser ae, created := ab.lhs.countStar(ctx) if created { ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: ae, + Original: ae.Expr, LHSExprs: []BindVarExpr{{Expr: ae.Expr}}, }) } @@ -577,7 +544,7 @@ func (ab *aggBuilder) rightCountStar(ctx *plancontext.PlanningContext) *sqlparse ae, created := ab.rhs.countStar(ctx) if created { ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: ae, + Original: ae.Expr, RHSExpr: ae.Expr, }) } @@ -599,7 +566,8 @@ func (p *joinPusher) countStar(ctx *plancontext.PlanningContext) (*sqlparser.Ali func (ab *aggBuilder) handleAggr(ctx *plancontext.PlanningContext, aggr Aggr) error { switch aggr.OpCode { case opcode.AggregateCountStar: - return ab.handleCountStar(ctx, aggr) + ab.handleCountStar(ctx, aggr) + return nil case opcode.AggregateCount, opcode.AggregateSum: return ab.handleAggrWithCountStarMultiplier(ctx, aggr) case opcode.AggregateMax, opcode.AggregateMin, opcode.AggregateAnyValue: @@ -632,7 +600,7 @@ func (ab *aggBuilder) handleAggr(ctx *plancontext.PlanningContext, aggr Aggr) er func (ab *aggBuilder) pushThroughLeft(aggr Aggr) { ab.lhs.pushThroughAggr(aggr) ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: aggr.Original, + Original: aggr.Original.Expr, LHSExprs: []BindVarExpr{{Expr: aggr.Original.Expr}}, }) } @@ -640,16 +608,13 @@ func (ab *aggBuilder) pushThroughLeft(aggr Aggr) { func (ab *aggBuilder) pushThroughRight(aggr Aggr) { ab.rhs.pushThroughAggr(aggr) ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: aggr.Original, + Original: aggr.Original.Expr, RHSExpr: aggr.Original.Expr, }) } func (ab *aggBuilder) handlePushThroughAggregation(ctx *plancontext.PlanningContext, aggr Aggr) error { - _, err := ab.proj.addUnexploredExpr(aggr.Original, aggr.Original.Expr) - if err != nil { - return err - } + ab.proj.addUnexploredExpr(aggr.Original, aggr.Original.Expr) deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr) switch { @@ -663,12 +628,12 @@ func (ab *aggBuilder) handlePushThroughAggregation(ctx *plancontext.PlanningCont return nil } -func (ab *aggBuilder) handleCountStar(ctx *plancontext.PlanningContext, aggr Aggr) error { +func (ab *aggBuilder) handleCountStar(ctx *plancontext.PlanningContext, aggr Aggr) { // Add the aggregate to both sides of the join. lhsAE := ab.leftCountStar(ctx) rhsAE := ab.rightCountStar(ctx) - return ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, true) + ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, true) } func (ab *aggBuilder) handleAggrWithCountStarMultiplier(ctx *plancontext.PlanningContext, aggr Aggr) error { @@ -694,10 +659,11 @@ func (ab *aggBuilder) handleAggrWithCountStarMultiplier(ctx *plancontext.Plannin return errAbortAggrPushing } - return ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, addCoalesce) + ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, addCoalesce) + return nil } -func (ab *aggBuilder) buildProjectionForAggr(lhsAE *sqlparser.AliasedExpr, rhsAE *sqlparser.AliasedExpr, aggr Aggr, coalesce bool) error { +func (ab *aggBuilder) buildProjectionForAggr(lhsAE *sqlparser.AliasedExpr, rhsAE *sqlparser.AliasedExpr, aggr Aggr, coalesce bool) { // We expect the expressions to be different on each side of the join, otherwise it's an error. if lhsAE.Expr == rhsAE.Expr { panic(fmt.Sprintf("Need the two produced expressions to be different. %T %T", lhsAE, rhsAE)) @@ -726,8 +692,7 @@ func (ab *aggBuilder) buildProjectionForAggr(lhsAE *sqlparser.AliasedExpr, rhsAE As: sqlparser.NewIdentifierCI(aggr.Original.ColumnName()), } - _, err := ab.proj.addUnexploredExpr(projAE, projExpr) - return err + ab.proj.addUnexploredExpr(projAE, projExpr) } func coalesceFunc(e sqlparser.Expr) sqlparser.Expr { @@ -820,7 +785,7 @@ func needAvgBreaking(aggrs []Aggr) bool { // splitAvgAggregations takes an aggregator that has AVG aggregations in it and splits // these into sum/count expressions that can be spread out to shards -func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (ops.Operator, *rewrite.ApplyResult, error) { +func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (Operator, *ApplyResult) { proj := newAliasedProjection(aggr) var columns []*sqlparser.AliasedExpr @@ -848,10 +813,7 @@ func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (o outputColumn := aeWrap(col.Expr) outputColumn.As = sqlparser.NewIdentifierCI(col.ColumnName()) - _, err := proj.addUnexploredExpr(sqlparser.CloneRefOfAliasedExpr(col), calcExpr) - if err != nil { - return nil, nil, err - } + proj.addUnexploredExpr(sqlparser.CloneRefOfAliasedExpr(col), calcExpr) col.Expr = sumExpr found := false for aggrOffset, aggregation := range aggr.Aggregations { @@ -877,5 +839,5 @@ func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (o aggr.Columns = append(aggr.Columns, columns...) aggr.Aggregations = append(aggr.Aggregations, aggregations...) - return proj, rewrite.NewTree("split avg aggregation"), nil + return proj, Rewrote("split avg aggregation") } diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index e1848752e75..6c07343498b 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -35,7 +34,7 @@ type ( // Both all aggregations and no grouping, and the inverse // of all grouping and no aggregations are valid configurations of this operator Aggregator struct { - Source ops.Operator + Source Operator Columns []*sqlparser.AliasedExpr Grouping []GroupBy @@ -60,7 +59,7 @@ type ( } ) -func (a *Aggregator) Clone(inputs []ops.Operator) ops.Operator { +func (a *Aggregator) Clone(inputs []Operator) Operator { kopy := *a kopy.Source = inputs[0] kopy.Columns = slices.Clone(a.Columns) @@ -69,18 +68,18 @@ func (a *Aggregator) Clone(inputs []ops.Operator) ops.Operator { return &kopy } -func (a *Aggregator) Inputs() []ops.Operator { - return []ops.Operator{a.Source} +func (a *Aggregator) Inputs() []Operator { + return []Operator{a.Source} } -func (a *Aggregator) SetInputs(operators []ops.Operator) { +func (a *Aggregator) SetInputs(operators []Operator) { if len(operators) != 1 { panic(fmt.Sprintf("unexpected number of operators as input in aggregator: %d", len(operators))) } a.Source = operators[0] } -func (a *Aggregator) AddPredicate(_ *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (a *Aggregator) AddPredicate(_ *plancontext.PlanningContext, expr sqlparser.Expr) Operator { return &Filter{ Source: a, Predicates: []sqlparser.Expr{expr}, @@ -92,7 +91,7 @@ func (a *Aggregator) addColumnWithoutPushing(ctx *plancontext.PlanningContext, e a.Columns = append(a.Columns, expr) if addToGroupBy { - groupBy := NewGroupBy(expr.Expr, expr.Expr, expr) + groupBy := NewGroupBy(expr.Expr, expr.Expr) groupBy.ColOffset = offset a.Grouping = append(a.Grouping, groupBy) } else { @@ -193,12 +192,6 @@ func (a *Aggregator) findColInternal(ctx *plancontext.PlanningContext, ae *sqlpa if offset, found := canReuseColumn(ctx, a.Columns, expr, extractExpr); found { return offset } - colName, isColName := expr.(*sqlparser.ColName) - for i, col := range a.Columns { - if isColName && colName.Name.EqualString(col.As.String()) { - return i - } - } if addToGroupBy { panic(vterrors.VT13001(fmt.Sprintf("did not expect to add group by here: %s", sqlparser.String(expr)))) @@ -254,11 +247,11 @@ func (a *Aggregator) ShortDescription() string { return fmt.Sprintf("%s%s group by %s", org, strings.Join(columns, ", "), strings.Join(grouping, ",")) } -func (a *Aggregator) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (a *Aggregator) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return a.Source.GetOrdering(ctx) } -func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) Operator { if a.offsetPlanned { return nil } @@ -408,7 +401,7 @@ func (a *Aggregator) internalAddColumn(ctx *plancontext.PlanningContext, aliased // SplitAggregatorBelowRoute returns the aggregator that will live under the Route. // This is used when we are splitting the aggregation so one part is done // at the mysql level and one part at the vtgate level -func (a *Aggregator) SplitAggregatorBelowRoute(input []ops.Operator) *Aggregator { +func (a *Aggregator) SplitAggregatorBelowRoute(input []Operator) *Aggregator { newOp := a.Clone(input).(*Aggregator) newOp.Pushed = false newOp.Original = false @@ -420,4 +413,4 @@ func (a *Aggregator) introducesTableID() semantics.TableSet { return a.DT.introducesTableID() } -var _ ops.Operator = (*Aggregator)(nil) +var _ Operator = (*Aggregator)(nil) diff --git a/go/vt/vtgate/planbuilder/operators/apply_join.go b/go/vt/vtgate/planbuilder/operators/apply_join.go index 95d7d962738..7e2c100c944 100644 --- a/go/vt/vtgate/planbuilder/operators/apply_join.go +++ b/go/vt/vtgate/planbuilder/operators/apply_join.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -33,7 +32,7 @@ type ( // ApplyJoin is a nested loop join - for each row on the LHS, // we'll execute the plan on the RHS, feeding data from left to right ApplyJoin struct { - LHS, RHS ops.Operator + LHS, RHS Operator // LeftJoin will be true in the case of an outer join LeftJoin bool @@ -72,7 +71,7 @@ type ( // so they can be used for the result of this expression that is using data from both sides. // All fields will be used for these JoinColumn struct { - Original *sqlparser.AliasedExpr // this is the original expression being passed through + Original sqlparser.Expr // this is the original expression being passed through LHSExprs []BindVarExpr RHSExpr sqlparser.Expr GroupBy bool // if this is true, we need to push this down to our inputs with addToGroupBy set to true @@ -86,7 +85,7 @@ type ( } ) -func NewApplyJoin(lhs, rhs ops.Operator, predicate sqlparser.Expr, leftOuterJoin bool) *ApplyJoin { +func NewApplyJoin(lhs, rhs Operator, predicate sqlparser.Expr, leftOuterJoin bool) *ApplyJoin { return &ApplyJoin{ LHS: lhs, RHS: rhs, @@ -97,7 +96,7 @@ func NewApplyJoin(lhs, rhs ops.Operator, predicate sqlparser.Expr, leftOuterJoin } // Clone implements the Operator interface -func (aj *ApplyJoin) Clone(inputs []ops.Operator) ops.Operator { +func (aj *ApplyJoin) Clone(inputs []Operator) Operator { kopy := *aj kopy.LHS = inputs[0] kopy.RHS = inputs[1] @@ -110,33 +109,33 @@ func (aj *ApplyJoin) Clone(inputs []ops.Operator) ops.Operator { return &kopy } -func (aj *ApplyJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (aj *ApplyJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { return AddPredicate(ctx, aj, expr, false, newFilter) } // Inputs implements the Operator interface -func (aj *ApplyJoin) Inputs() []ops.Operator { - return []ops.Operator{aj.LHS, aj.RHS} +func (aj *ApplyJoin) Inputs() []Operator { + return []Operator{aj.LHS, aj.RHS} } // SetInputs implements the Operator interface -func (aj *ApplyJoin) SetInputs(inputs []ops.Operator) { +func (aj *ApplyJoin) SetInputs(inputs []Operator) { aj.LHS, aj.RHS = inputs[0], inputs[1] } -func (aj *ApplyJoin) GetLHS() ops.Operator { +func (aj *ApplyJoin) GetLHS() Operator { return aj.LHS } -func (aj *ApplyJoin) GetRHS() ops.Operator { +func (aj *ApplyJoin) GetRHS() Operator { return aj.RHS } -func (aj *ApplyJoin) SetLHS(operator ops.Operator) { +func (aj *ApplyJoin) SetLHS(operator Operator) { aj.LHS = operator } -func (aj *ApplyJoin) SetRHS(operator ops.Operator) { +func (aj *ApplyJoin) SetRHS(operator Operator) { aj.RHS = operator } @@ -151,10 +150,7 @@ func (aj *ApplyJoin) IsInner() bool { func (aj *ApplyJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) { aj.Predicate = ctx.SemTable.AndExpressions(expr, aj.Predicate) - col, err := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, TableID(aj.LHS)) - if err != nil { - panic(err) - } + col := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, TableID(aj.LHS)) aj.JoinPredicates = append(aj.JoinPredicates, col) rhs := aj.RHS.AddPredicate(ctx, col.RHSExpr) aj.RHS = rhs @@ -173,21 +169,21 @@ func (aj *ApplyJoin) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser. return transformColumnsToSelectExprs(ctx, aj) } -func (aj *ApplyJoin) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (aj *ApplyJoin) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return aj.LHS.GetOrdering(ctx) } func joinColumnToAliasedExpr(c JoinColumn) *sqlparser.AliasedExpr { - return c.Original + return aeWrap(c.Original) } func joinColumnToExpr(column JoinColumn) sqlparser.Expr { - return column.Original.Expr + return column.Original } -func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sqlparser.AliasedExpr, e sqlparser.Expr, addToGroupBy bool) (col JoinColumn, err error) { +func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sqlparser.AliasedExpr, e sqlparser.Expr, addToGroupBy bool) (col JoinColumn) { defer func() { - col.Original = orig + col.Original = orig.Expr }() lhs := TableID(aj.LHS) rhs := TableID(aj.RHS) @@ -201,12 +197,9 @@ func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sq case deps.IsSolvedBy(rhs): col.RHSExpr = e case deps.IsSolvedBy(both): - col, err = breakExpressionInLHSandRHSForApplyJoin(ctx, e, TableID(aj.LHS)) - if err != nil { - return JoinColumn{}, err - } + col = breakExpressionInLHSandRHSForApplyJoin(ctx, e, TableID(aj.LHS)) default: - return JoinColumn{}, vterrors.VT13002(sqlparser.String(e)) + panic(vterrors.VT13002(sqlparser.String(e))) } return @@ -232,16 +225,13 @@ func (aj *ApplyJoin) AddColumn( return offset } } - col, err := aj.getJoinColumnFor(ctx, expr, expr.Expr, groupBy) - if err != nil { - panic(err) - } + col := aj.getJoinColumnFor(ctx, expr, expr.Expr, groupBy) offset := len(aj.JoinColumns) aj.JoinColumns = append(aj.JoinColumns, col) return offset } -func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { for _, col := range aj.JoinColumns { // Read the type description for JoinColumn to understand the following code for _, lhsExpr := range col.LHSExprs { diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index f6acbadd35a..f8c8891f8f9 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -21,7 +21,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -31,39 +30,28 @@ const foreignKeyConstraintValues = "fkc_vals" const foreignKeyUpdateExpr = "fkc_upd" // translateQueryToOp creates an operator tree that represents the input SELECT or UNION query -func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) (op ops.Operator, err error) { +func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) Operator { switch node := selStmt.(type) { case *sqlparser.Select: - op, err = createOperatorFromSelect(ctx, node) + return createOperatorFromSelect(ctx, node) case *sqlparser.Union: - op, err = createOperatorFromUnion(ctx, node) + return createOperatorFromUnion(ctx, node) case *sqlparser.Update: - op, err = createOperatorFromUpdate(ctx, node) + return createOperatorFromUpdate(ctx, node) case *sqlparser.Delete: - op, err = createOperatorFromDelete(ctx, node) + return createOperatorFromDelete(ctx, node) case *sqlparser.Insert: - op, err = createOperatorFromInsert(ctx, node) + return createOperatorFromInsert(ctx, node) default: - err = vterrors.VT12001(fmt.Sprintf("operator: %T", selStmt)) + panic(vterrors.VT12001(fmt.Sprintf("operator: %T", selStmt))) } - if err != nil { - return nil, err - } - - return op, nil } -func createOperatorFromSelect(ctx *plancontext.PlanningContext, sel *sqlparser.Select) (ops.Operator, error) { - op, err := crossJoin(ctx, sel.From) - if err != nil { - return nil, err - } +func createOperatorFromSelect(ctx *plancontext.PlanningContext, sel *sqlparser.Select) Operator { + op := crossJoin(ctx, sel.From) if sel.Where != nil { - op, err = addWherePredicates(ctx, sel.Where.Expr, op) - if err != nil { - return nil, err - } + op = addWherePredicates(ctx, sel.Where.Expr, op) } if sel.Comments != nil || sel.Lock != sqlparser.NoLock { @@ -76,26 +64,23 @@ func createOperatorFromSelect(ctx *plancontext.PlanningContext, sel *sqlparser.S op = newHorizon(op, sel) - return op, nil + return op } -func addWherePredicates(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op ops.Operator) (ops.Operator, error) { +func addWherePredicates(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op Operator) Operator { sqc := &SubQueryBuilder{} outerID := TableID(op) exprs := sqlparser.SplitAndExpression(nil, expr) for _, expr := range exprs { sqlparser.RemoveKeyspaceFromColName(expr) - subq, err := sqc.handleSubquery(ctx, expr, outerID) - if err != nil { - return nil, err - } + subq := sqc.handleSubquery(ctx, expr, outerID) if subq != nil { continue } op = op.AddPredicate(ctx, expr) addColumnEquality(ctx, expr) } - return sqc.getRootOperator(op, nil), nil + return sqc.getRootOperator(op, nil) } // cloneASTAndSemState clones the AST and the semantic state of the input node. @@ -158,56 +143,44 @@ type joinPredicateCollector struct { func (jpc *joinPredicateCollector) inspectPredicate( ctx *plancontext.PlanningContext, predicate sqlparser.Expr, -) error { +) { pred := predicate deps := ctx.SemTable.RecursiveDeps(predicate) // if the subquery is not enough, but together we have all we need, // then we can use this predicate to connect the subquery to the outer query if !deps.IsSolvedBy(jpc.subqID) && deps.IsSolvedBy(jpc.totalID) { jpc.predicates = append(jpc.predicates, predicate) - jc, err := breakExpressionInLHSandRHSForApplyJoin(ctx, predicate, jpc.outerID) - if err != nil { - return err - } + jc := breakExpressionInLHSandRHSForApplyJoin(ctx, predicate, jpc.outerID) jpc.joinColumns = append(jpc.joinColumns, jc) pred = jc.RHSExpr } jpc.remainingPredicates = append(jpc.remainingPredicates, pred) - return nil } -func createOperatorFromUnion(ctx *plancontext.PlanningContext, node *sqlparser.Union) (ops.Operator, error) { - opLHS, err := translateQueryToOp(ctx, node.Left) - if err != nil { - return nil, err - } - +func createOperatorFromUnion(ctx *plancontext.PlanningContext, node *sqlparser.Union) Operator { _, isRHSUnion := node.Right.(*sqlparser.Union) if isRHSUnion { - return nil, vterrors.VT12001("nesting of UNIONs on the right-hand side") + panic(vterrors.VT12001("nesting of UNIONs on the right-hand side")) } - opRHS, err := translateQueryToOp(ctx, node.Right) - if err != nil { - return nil, err - } - + opLHS := translateQueryToOp(ctx, node.Left) + opRHS := translateQueryToOp(ctx, node.Right) lexprs := ctx.SemTable.SelectExprs(node.Left) rexprs := ctx.SemTable.SelectExprs(node.Right) unionCols := ctx.SemTable.SelectExprs(node) - union := newUnion([]ops.Operator{opLHS, opRHS}, []sqlparser.SelectExprs{lexprs, rexprs}, unionCols, node.Distinct) - return newHorizon(union, node), nil + union := newUnion([]Operator{opLHS, opRHS}, []sqlparser.SelectExprs{lexprs, rexprs}, unionCols, node.Distinct) + return newHorizon(union, node) } // createOpFromStmt creates an operator from the given statement. It takes in two additional arguments— // 1. verifyAllFKs: For this given statement, do we need to verify validity of all the foreign keys on the vtgate level. // 2. fkToIgnore: The foreign key constraint to specifically ignore while planning the statement. This field is used in UPDATE CASCADE planning, wherein while planning the child update // query, we need to ignore the parent foreign key constraint that caused the cascade in question. -func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement, verifyAllFKs bool, fkToIgnore string) (ops.Operator, error) { +func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement, verifyAllFKs bool, fkToIgnore string) Operator { var err error ctx, err = plancontext.CreatePlanningContext(stmt, ctx.ReservedVars, ctx.VSchema, ctx.PlannerVersion) if err != nil { - return nil, err + panic(err) } // TODO (@GuptaManan100, @harshit-gangal): When we add cross-shard foreign keys support, @@ -222,7 +195,7 @@ func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement // From all the parent foreign keys involved, we should remove the one that we need to ignore. err = ctx.SemTable.RemoveParentForeignKey(fkToIgnore) if err != nil { - return nil, err + panic(err) } // Now, we can filter the foreign keys further based on the planning context, specifically whether we are running @@ -236,13 +209,17 @@ func createOpFromStmt(ctx *plancontext.PlanningContext, stmt sqlparser.Statement err = ctx.SemTable.RemoveNonRequiredForeignKeys(ctx.VerifyAllFKs, vindexes.DeleteAction) } if err != nil { - return nil, err + panic(err) } - return PlanQuery(ctx, stmt) + op, err := PlanQuery(ctx, stmt) + if err != nil { + panic(err) + } + return op } -func getOperatorFromTableExpr(ctx *plancontext.PlanningContext, tableExpr sqlparser.TableExpr, onlyTable bool) (ops.Operator, error) { +func getOperatorFromTableExpr(ctx *plancontext.PlanningContext, tableExpr sqlparser.TableExpr, onlyTable bool) Operator { switch tableExpr := tableExpr.(type) { case *sqlparser.AliasedTableExpr: return getOperatorFromAliasedTableExpr(ctx, tableExpr, onlyTable) @@ -251,19 +228,13 @@ func getOperatorFromTableExpr(ctx *plancontext.PlanningContext, tableExpr sqlpar case *sqlparser.ParenTableExpr: return crossJoin(ctx, tableExpr.Exprs) default: - return nil, vterrors.VT13001(fmt.Sprintf("unable to use: %T table type", tableExpr)) + panic(vterrors.VT13001(fmt.Sprintf("unable to use: %T table type", tableExpr))) } } -func getOperatorFromJoinTableExpr(ctx *plancontext.PlanningContext, tableExpr *sqlparser.JoinTableExpr) (ops.Operator, error) { - lhs, err := getOperatorFromTableExpr(ctx, tableExpr.LeftExpr, false) - if err != nil { - return nil, err - } - rhs, err := getOperatorFromTableExpr(ctx, tableExpr.RightExpr, false) - if err != nil { - return nil, err - } +func getOperatorFromJoinTableExpr(ctx *plancontext.PlanningContext, tableExpr *sqlparser.JoinTableExpr) Operator { + lhs := getOperatorFromTableExpr(ctx, tableExpr.LeftExpr, false) + rhs := getOperatorFromTableExpr(ctx, tableExpr.RightExpr, false) switch tableExpr.Join { case sqlparser.NormalJoinType: @@ -271,17 +242,17 @@ func getOperatorFromJoinTableExpr(ctx *plancontext.PlanningContext, tableExpr *s case sqlparser.LeftJoinType, sqlparser.RightJoinType: return createOuterJoin(tableExpr, lhs, rhs) default: - return nil, vterrors.VT13001("unsupported: %s", tableExpr.Join.ToString()) + panic(vterrors.VT13001("unsupported: %s", tableExpr.Join.ToString())) } } -func getOperatorFromAliasedTableExpr(ctx *plancontext.PlanningContext, tableExpr *sqlparser.AliasedTableExpr, onlyTable bool) (ops.Operator, error) { +func getOperatorFromAliasedTableExpr(ctx *plancontext.PlanningContext, tableExpr *sqlparser.AliasedTableExpr, onlyTable bool) Operator { tableID := ctx.SemTable.TableSetFor(tableExpr) switch tbl := tableExpr.Expr.(type) { case sqlparser.TableName: tableInfo, err := ctx.SemTable.TableInfoFor(tableID) if err != nil { - return nil, err + panic(err) } if vt, isVindex := tableInfo.(*semantics.VindexTable); isVindex { @@ -295,73 +266,71 @@ func getOperatorFromAliasedTableExpr(ctx *plancontext.PlanningContext, tableExpr }, Vindex: vt.Vindex, Solved: solves, - }, nil + } } qg := newQueryGraph() isInfSchema := tableInfo.IsInfSchema() qt := &QueryTable{Alias: tableExpr, Table: tbl, ID: tableID, IsInfSchema: isInfSchema} qg.Tables = append(qg.Tables, qt) - return qg, nil + return qg case *sqlparser.DerivedTable: if onlyTable && tbl.Select.GetLimit() == nil { tbl.Select.SetOrderBy(nil) } - inner, err := translateQueryToOp(ctx, tbl.Select) - if err != nil { - return nil, err - } + inner := translateQueryToOp(ctx, tbl.Select) if horizon, ok := inner.(*Horizon); ok { horizon.TableId = &tableID horizon.Alias = tableExpr.As.String() horizon.ColumnAliases = tableExpr.Columns qp, err := CreateQPFromSelectStatement(ctx, tbl.Select) if err != nil { - return nil, err + panic(err) } horizon.QP = qp } - return inner, nil + return inner default: - return nil, vterrors.VT13001(fmt.Sprintf("unable to use: %T", tbl)) + panic(vterrors.VT13001(fmt.Sprintf("unable to use: %T", tbl))) } } -func crossJoin(ctx *plancontext.PlanningContext, exprs sqlparser.TableExprs) (ops.Operator, error) { - var output ops.Operator +func crossJoin(ctx *plancontext.PlanningContext, exprs sqlparser.TableExprs) Operator { + var output Operator for _, tableExpr := range exprs { - op, err := getOperatorFromTableExpr(ctx, tableExpr, len(exprs) == 1) - if err != nil { - return nil, err - } + op := getOperatorFromTableExpr(ctx, tableExpr, len(exprs) == 1) if output == nil { output = op } else { output = createJoin(ctx, output, op) } } - return output, nil + return output } -func createQueryTableForDML(ctx *plancontext.PlanningContext, tableExpr sqlparser.TableExpr, whereClause *sqlparser.Where) (semantics.TableInfo, *QueryTable, error) { +func createQueryTableForDML( + ctx *plancontext.PlanningContext, + tableExpr sqlparser.TableExpr, + whereClause *sqlparser.Where, +) (semantics.TableInfo, *QueryTable) { alTbl, ok := tableExpr.(*sqlparser.AliasedTableExpr) if !ok { - return nil, nil, vterrors.VT13001("expected AliasedTableExpr") + panic(vterrors.VT13001("expected AliasedTableExpr")) } tblName, ok := alTbl.Expr.(sqlparser.TableName) if !ok { - return nil, nil, vterrors.VT13001("expected TableName") + panic(vterrors.VT13001("expected TableName")) } tableID := ctx.SemTable.TableSetFor(alTbl) tableInfo, err := ctx.SemTable.TableInfoFor(tableID) if err != nil { - return nil, nil, err + panic(err) } if tableInfo.IsInfSchema() { - return nil, nil, vterrors.VT12001("update information schema tables") + panic(vterrors.VT12001("update information schema tables")) } var predicates []sqlparser.Expr @@ -374,7 +343,7 @@ func createQueryTableForDML(ctx *plancontext.PlanningContext, tableExpr sqlparse Table: tblName, Predicates: predicates, } - return tableInfo, qt, nil + return tableInfo, qt } func addColumnEquality(ctx *plancontext.PlanningContext, expr sqlparser.Expr) { @@ -404,7 +373,7 @@ func createSelectionOp( orderBy sqlparser.OrderBy, limit *sqlparser.Limit, lock sqlparser.Lock, -) (ops.Operator, error) { +) Operator { selectionStmt := &sqlparser.Select{ SelectExprs: selectExprs, From: tableExprs, diff --git a/go/vt/vtgate/planbuilder/operators/comments.go b/go/vt/vtgate/planbuilder/operators/comments.go index 9ede4b9e0da..912fa4138d9 100644 --- a/go/vt/vtgate/planbuilder/operators/comments.go +++ b/go/vt/vtgate/planbuilder/operators/comments.go @@ -21,32 +21,31 @@ import ( "strings" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // LockAndComment contains any comments or locking directives we want on all queries down from this operator type LockAndComment struct { - Source ops.Operator + Source Operator Comments *sqlparser.ParsedComments Lock sqlparser.Lock } -func (l *LockAndComment) Clone(inputs []ops.Operator) ops.Operator { +func (l *LockAndComment) Clone(inputs []Operator) Operator { klon := *l klon.Source = inputs[0] return &klon } -func (l *LockAndComment) Inputs() []ops.Operator { - return []ops.Operator{l.Source} +func (l *LockAndComment) Inputs() []Operator { + return []Operator{l.Source} } -func (l *LockAndComment) SetInputs(operators []ops.Operator) { +func (l *LockAndComment) SetInputs(operators []Operator) { l.Source = operators[0] } -func (l *LockAndComment) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (l *LockAndComment) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { l.Source = l.Source.AddPredicate(ctx, expr) return l } @@ -76,6 +75,6 @@ func (l *LockAndComment) ShortDescription() string { return strings.Join(s, " ") } -func (l *LockAndComment) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (l *LockAndComment) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return l.Source.GetOrdering(ctx) } diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index 8b7841bdcdd..17f6125992f 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -22,7 +22,6 @@ import ( "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/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -45,7 +44,7 @@ func (d *Delete) introducesTableID() semantics.TableSet { } // Clone implements the Operator interface -func (d *Delete) Clone([]ops.Operator) ops.Operator { +func (d *Delete) Clone([]Operator) Operator { return &Delete{ QTable: d.QTable, VTable: d.VTable, @@ -61,7 +60,7 @@ func (d *Delete) TablesUsed() []string { return nil } -func (d *Delete) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (d *Delete) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } @@ -73,24 +72,13 @@ func (d *Delete) Statement() sqlparser.Statement { return d.AST } -func createOperatorFromDelete(ctx *plancontext.PlanningContext, deleteStmt *sqlparser.Delete) (ops.Operator, error) { - tableInfo, qt, err := createQueryTableForDML(ctx, deleteStmt.TableExprs[0], deleteStmt.Where) - if err != nil { - return nil, err - } - - vindexTable, routing, err := buildVindexTableForDML(ctx, tableInfo, qt, "delete") - if err != nil { - return nil, err - } +func createOperatorFromDelete(ctx *plancontext.PlanningContext, deleteStmt *sqlparser.Delete) Operator { + tableInfo, qt := createQueryTableForDML(ctx, deleteStmt.TableExprs[0], deleteStmt.Where) + vindexTable, routing := buildVindexTableForDML(ctx, tableInfo, qt, "delete") delClone := sqlparser.CloneRefOfDelete(deleteStmt) // Create the delete operator first. - delOp, err := createDeleteOperator(ctx, deleteStmt, qt, vindexTable, routing) - if err != nil { - return nil, err - } - + delOp := createDeleteOperator(ctx, deleteStmt, qt, vindexTable, routing) if deleteStmt.Comments != nil { delOp = &LockAndComment{ Source: delOp, @@ -101,11 +89,11 @@ func createOperatorFromDelete(ctx *plancontext.PlanningContext, deleteStmt *sqlp childFks := ctx.SemTable.GetChildForeignKeysList() // If there are no foreign key constraints, then we don't need to do anything. if len(childFks) == 0 { - return delOp, nil + return delOp } // If the delete statement has a limit, we don't support it yet. if deleteStmt.Limit != nil { - return nil, vterrors.VT12001("foreign keys management at vitess with limit") + panic(vterrors.VT12001("foreign keys management at vitess with limit")) } return createFkCascadeOpForDelete(ctx, delOp, delClone, childFks) @@ -116,7 +104,7 @@ func createDeleteOperator( deleteStmt *sqlparser.Delete, qt *QueryTable, vindexTable *vindexes.Table, - routing Routing) (ops.Operator, error) { + routing Routing) Operator { del := &Delete{ QTable: qt, VTable: vindexTable, @@ -128,13 +116,10 @@ func createDeleteOperator( } if !vindexTable.Keyspace.Sharded { - return route, nil + return route } - primaryVindex, vindexAndPredicates, err := getVindexInformation(qt.ID, vindexTable) - if err != nil { - return nil, err - } + primaryVindex, vindexAndPredicates := getVindexInformation(qt.ID, vindexTable) tr, ok := routing.(*ShardedRouting) if ok { @@ -151,58 +136,49 @@ func createDeleteOperator( sqc := &SubQueryBuilder{} for _, predicate := range qt.Predicates { - if subq, err := sqc.handleSubquery(ctx, predicate, qt.ID); err != nil { - return nil, err - } else if subq != nil { + subq := sqc.handleSubquery(ctx, predicate, qt.ID) + if subq != nil { continue } - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + + routing = UpdateRoutingLogic(ctx, predicate, routing) } if routing.OpCode() == engine.Scatter && deleteStmt.Limit != nil { // TODO systay: we should probably check for other op code types - IN could also hit multiple shards (2022-04-07) - return nil, vterrors.VT12001("multi shard DELETE with LIMIT") + panic(vterrors.VT12001("multi shard DELETE with LIMIT")) } - return sqc.getRootOperator(route, nil), nil + return sqc.getRootOperator(route, nil) } -func createFkCascadeOpForDelete(ctx *plancontext.PlanningContext, parentOp ops.Operator, delStmt *sqlparser.Delete, childFks []vindexes.ChildFKInfo) (ops.Operator, error) { +func createFkCascadeOpForDelete(ctx *plancontext.PlanningContext, parentOp Operator, delStmt *sqlparser.Delete, childFks []vindexes.ChildFKInfo) Operator { var fkChildren []*FkChild var selectExprs []sqlparser.SelectExpr for _, fk := range childFks { // Any RESTRICT type foreign keys that arrive here, // are cross-shard/cross-keyspace RESTRICT cases, which we don't currently support. if fk.OnDelete.IsRestrict() { - return nil, vterrors.VT12002() + panic(vterrors.VT12002()) } // We need to select all the parent columns for the foreign key constraint, to use in the update of the child table. var offsets []int offsets, selectExprs = addColumns(ctx, fk.ParentColumns, selectExprs) - fkChild, err := createFkChildForDelete(ctx, fk, offsets) - if err != nil { - return nil, err - } - fkChildren = append(fkChildren, fkChild) - } - selectionOp, err := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, nil, sqlparser.ForUpdateLockNoWait) - if err != nil { - return nil, err + fkChildren = append(fkChildren, + createFkChildForDelete(ctx, fk, offsets)) } + selectionOp := createSelectionOp(ctx, selectExprs, delStmt.TableExprs, delStmt.Where, nil, nil, sqlparser.ForUpdateLockNoWait) return &FkCascade{ Selection: selectionOp, Children: fkChildren, Parent: parentOp, - }, nil + } } -func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, cols []int) (*FkChild, error) { +func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, cols []int) *FkChild { bvName := ctx.ReservedVars.ReserveVariable(foreignKeyConstraintValues) parsedComments := getParsedCommentsForFkChecks(ctx) var childStmt sqlparser.Statement @@ -240,18 +216,15 @@ func createFkChildForDelete(ctx *plancontext.PlanningContext, fk vindexes.ChildF Where: &sqlparser.Where{Type: sqlparser.WhereClause, Expr: compExpr}, } case sqlparser.SetDefault: - return nil, vterrors.VT09016() + panic(vterrors.VT09016()) } // For the child statement of a DELETE query, we don't need to verify all the FKs on VTgate or ignore any foreign key explicitly. - childOp, err := createOpFromStmt(ctx, childStmt, false /* verifyAllFKs */, "" /* fkToIgnore */) - if err != nil { - return nil, err - } + childOp := createOpFromStmt(ctx, childStmt, false /* verifyAllFKs */, "" /* fkToIgnore */) return &FkChild{ BVName: bvName, Cols: cols, Op: childOp, - }, nil + } } diff --git a/go/vt/vtgate/planbuilder/operators/distinct.go b/go/vt/vtgate/planbuilder/operators/distinct.go index d7aad08d206..74f4495374c 100644 --- a/go/vt/vtgate/planbuilder/operators/distinct.go +++ b/go/vt/vtgate/planbuilder/operators/distinct.go @@ -21,13 +21,12 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type ( Distinct struct { - Source ops.Operator + Source Operator QP *QueryProjection // When we go from AST to operator, we place DISTINCT ops in the required places in the op tree @@ -46,7 +45,7 @@ type ( } ) -func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) Operator { columns := d.GetColumns(ctx) for idx, col := range columns { e, err := d.QP.GetSimplifiedExpr(ctx, col.Expr) @@ -71,7 +70,7 @@ func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { return nil } -func (d *Distinct) Clone(inputs []ops.Operator) ops.Operator { +func (d *Distinct) Clone(inputs []Operator) Operator { return &Distinct{ Required: d.Required, Source: inputs[0], @@ -82,15 +81,15 @@ func (d *Distinct) Clone(inputs []ops.Operator) ops.Operator { } } -func (d *Distinct) Inputs() []ops.Operator { - return []ops.Operator{d.Source} +func (d *Distinct) Inputs() []Operator { + return []Operator{d.Source} } -func (d *Distinct) SetInputs(operators []ops.Operator) { +func (d *Distinct) SetInputs(operators []Operator) { d.Source = operators[0] } -func (d *Distinct) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (d *Distinct) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { d.Source = d.Source.AddPredicate(ctx, expr) return d } @@ -118,7 +117,7 @@ func (d *Distinct) ShortDescription() string { return "Performance" } -func (d *Distinct) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (d *Distinct) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return d.Source.GetOrdering(ctx) } diff --git a/go/vt/vtgate/planbuilder/operators/dml_planning.go b/go/vt/vtgate/planbuilder/operators/dml_planning.go index 8f87a71c95f..3140142858c 100644 --- a/go/vt/vtgate/planbuilder/operators/dml_planning.go +++ b/go/vt/vtgate/planbuilder/operators/dml_planning.go @@ -19,12 +19,11 @@ package operators import ( "fmt" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "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" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -33,12 +32,11 @@ import ( // If it cannot find a unique vindex match, it returns an error. func getVindexInformation(id semantics.TableSet, table *vindexes.Table) ( *vindexes.ColumnVindex, - []*VindexPlusPredicates, - error) { + []*VindexPlusPredicates) { // Check that we have a primary vindex which is valid if len(table.ColumnVindexes) == 0 || !table.ColumnVindexes[0].IsUnique() { - return nil, nil, vterrors.VT09001(table.Name) + panic(vterrors.VT09001(table.Name)) } primaryVindex := table.ColumnVindexes[0] @@ -55,10 +53,16 @@ func getVindexInformation(id semantics.TableSet, table *vindexes.Table) ( TableID: id, }) } - return primaryVindex, vindexesAndPredicates, nil + return primaryVindex, vindexesAndPredicates } -func buildChangedVindexesValues(ctx *plancontext.PlanningContext, update *sqlparser.Update, table *vindexes.Table, ksidCols []sqlparser.IdentifierCI, assignments []SetExpr) (vv map[string]*engine.VindexValues, ownedVindexQuery string, subQueriesArgOnChangedVindex []string, err error) { +func buildChangedVindexesValues( + ctx *plancontext.PlanningContext, + update *sqlparser.Update, + table *vindexes.Table, + ksidCols []sqlparser.IdentifierCI, + assignments []SetExpr, +) (vv map[string]*engine.VindexValues, ownedVindexQuery string, subQueriesArgOnChangedVindex []string) { changedVindexes := make(map[string]*engine.VindexValues) buf, offset := initialQuery(ksidCols, table) for i, vindex := range table.ColumnVindexes { @@ -72,7 +76,7 @@ func buildChangedVindexesValues(ctx *plancontext.PlanningContext, update *sqlpar continue } if found { - return nil, "", nil, vterrors.VT03015(assignment.Name.Name) + panic(vterrors.VT03015(assignment.Name.Name)) } found = true pv, err := evalengine.Translate(assignment.Expr.EvalExpr, &evalengine.Config{ @@ -80,7 +84,7 @@ func buildChangedVindexesValues(ctx *plancontext.PlanningContext, update *sqlpar Collation: ctx.SemTable.Collation, }) if err != nil { - return nil, "", nil, invalidUpdateExpr(assignment.Name.Name.String(), assignment.Expr.EvalExpr) + panic(invalidUpdateExpr(assignment.Name.Name.String(), assignment.Expr.EvalExpr)) } if assignment.Expr.Info != nil { @@ -107,13 +111,13 @@ func buildChangedVindexesValues(ctx *plancontext.PlanningContext, update *sqlpar } if update.Limit != nil && len(update.OrderBy) == 0 { - return nil, "", nil, vterrors.VT12001(fmt.Sprintf("you need to provide the ORDER BY clause when using LIMIT; invalid update on vindex: %v", vindex.Name)) + panic(vterrors.VT12001(fmt.Sprintf("you need to provide the ORDER BY clause when using LIMIT; invalid update on vindex: %v", vindex.Name))) } if i == 0 { - return nil, "", nil, vterrors.VT12001(fmt.Sprintf("you cannot UPDATE primary vindex columns; invalid update on vindex: %v", vindex.Name)) + panic(vterrors.VT12001(fmt.Sprintf("you cannot UPDATE primary vindex columns; invalid update on vindex: %v", vindex.Name))) } if _, ok := vindex.Vindex.(vindexes.Lookup); !ok { - return nil, "", nil, vterrors.VT12001(fmt.Sprintf("you can only UPDATE lookup vindexes; invalid update on vindex: %v", vindex.Name)) + panic(vterrors.VT12001(fmt.Sprintf("you can only UPDATE lookup vindexes; invalid update on vindex: %v", vindex.Name))) } changedVindexes[vindex.Name] = &engine.VindexValues{ EvalExprMap: vindexValueMap, @@ -122,16 +126,16 @@ func buildChangedVindexesValues(ctx *plancontext.PlanningContext, update *sqlpar offset++ } if len(changedVindexes) == 0 { - return nil, "", nil, nil + return nil, "", nil } // generate rest of the owned vindex query. aTblExpr, ok := update.TableExprs[0].(*sqlparser.AliasedTableExpr) if !ok { - return nil, "", nil, vterrors.VT12001("UPDATE on complex table expression") + panic(vterrors.VT12001("UPDATE on complex table expression")) } tblExpr := &sqlparser.AliasedTableExpr{Expr: sqlparser.TableName{Name: table.Name}, As: aTblExpr.As} buf.Myprintf(" from %v%v%v%v for update", tblExpr, update.Where, update.OrderBy, update.Limit) - return changedVindexes, buf.String(), subQueriesArgOnChangedVindex, nil + return changedVindexes, buf.String(), subQueriesArgOnChangedVindex } func initialQuery(ksidCols []sqlparser.IdentifierCI, table *vindexes.Table) (*sqlparser.TrackedBuffer, int) { diff --git a/go/vt/vtgate/planbuilder/operators/expressions.go b/go/vt/vtgate/planbuilder/operators/expressions.go index 0df875a6fbd..65600155631 100644 --- a/go/vt/vtgate/planbuilder/operators/expressions.go +++ b/go/vt/vtgate/planbuilder/operators/expressions.go @@ -28,7 +28,7 @@ func breakExpressionInLHSandRHSForApplyJoin( ctx *plancontext.PlanningContext, expr sqlparser.Expr, lhs semantics.TableSet, -) (col JoinColumn, err error) { +) (col JoinColumn) { rewrittenExpr := sqlparser.CopyOnRewrite(expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) { nodeExpr, ok := cursor.Node().(sqlparser.Expr) if !ok || !fetchByOffset(nodeExpr) { @@ -51,9 +51,6 @@ func breakExpressionInLHSandRHSForApplyJoin( cursor.Replace(arg) }, nil).(sqlparser.Expr) - if err != nil { - return JoinColumn{}, err - } ctx.JoinPredicates[expr] = append(ctx.JoinPredicates[expr], rewrittenExpr) col.RHSExpr = rewrittenExpr return diff --git a/go/vt/vtgate/planbuilder/operators/filter.go b/go/vt/vtgate/planbuilder/operators/filter.go index cee57c74943..f2171c43a1b 100644 --- a/go/vt/vtgate/planbuilder/operators/filter.go +++ b/go/vt/vtgate/planbuilder/operators/filter.go @@ -24,14 +24,12 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) type Filter struct { - Source ops.Operator + Source Operator Predicates []sqlparser.Expr // PredicateWithOffsets is the evalengine expression that will finally be used. @@ -41,14 +39,14 @@ type Filter struct { Truncate int } -func newFilter(op ops.Operator, expr sqlparser.Expr) ops.Operator { +func newFilter(op Operator, expr sqlparser.Expr) Operator { return &Filter{ Source: op, Predicates: []sqlparser.Expr{expr}, } } // Clone implements the Operator interface -func (f *Filter) Clone(inputs []ops.Operator) ops.Operator { +func (f *Filter) Clone(inputs []Operator) Operator { return &Filter{ Source: inputs[0], Predicates: slices.Clone(f.Predicates), @@ -58,12 +56,12 @@ func (f *Filter) Clone(inputs []ops.Operator) ops.Operator { } // Inputs implements the Operator interface -func (f *Filter) Inputs() []ops.Operator { - return []ops.Operator{f.Source} +func (f *Filter) Inputs() []Operator { + return []Operator{f.Source} } // SetInputs implements the Operator interface -func (f *Filter) SetInputs(ops []ops.Operator) { +func (f *Filter) SetInputs(ops []Operator) { f.Source = ops[0] } @@ -80,7 +78,7 @@ func (f *Filter) UnsolvedPredicates(st *semantics.SemTable) []sqlparser.Expr { return result } -func (f *Filter) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (f *Filter) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { f.Source = f.Source.AddPredicate(ctx, expr) return f } @@ -101,25 +99,25 @@ func (f *Filter) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Sele return f.Source.GetSelectExprs(ctx) } -func (f *Filter) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (f *Filter) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return f.Source.GetOrdering(ctx) } -func (f *Filter) Compact(*plancontext.PlanningContext) (ops.Operator, *rewrite.ApplyResult, error) { +func (f *Filter) Compact(*plancontext.PlanningContext) (Operator, *ApplyResult) { if len(f.Predicates) == 0 { - return f.Source, rewrite.NewTree("filter with no predicates removed"), nil + return f.Source, Rewrote("filter with no predicates removed") } other, isFilter := f.Source.(*Filter) if !isFilter { - return f, rewrite.SameTree, nil + return f, NoRewrite } f.Source = other.Source f.Predicates = append(f.Predicates, other.Predicates...) - return f, rewrite.NewTree("two filters merged into one"), nil + return f, Rewrote("two filters merged into one") } -func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) Operator { cfg := &evalengine.Config{ ResolveType: ctx.SemTable.TypeForExpr, Collation: ctx.SemTable.Collation, diff --git a/go/vt/vtgate/planbuilder/operators/fk_cascade.go b/go/vt/vtgate/planbuilder/operators/fk_cascade.go index 73b902a4980..f24b59ca5ab 100644 --- a/go/vt/vtgate/planbuilder/operators/fk_cascade.go +++ b/go/vt/vtgate/planbuilder/operators/fk_cascade.go @@ -20,7 +20,6 @@ import ( "slices" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -29,7 +28,7 @@ type FkChild struct { BVName string Cols []int // indexes NonLiteralInfo []engine.NonLiteralUpdateInfo - Op ops.Operator + Op Operator noColumns noPredicates @@ -39,19 +38,19 @@ type FkChild struct { // as an operator. This operator is created for DML queries that require // cascades (for example, ON DELETE CASCADE). type FkCascade struct { - Selection ops.Operator + Selection Operator Children []*FkChild - Parent ops.Operator + Parent Operator noColumns noPredicates } -var _ ops.Operator = (*FkCascade)(nil) +var _ Operator = (*FkCascade)(nil) // Inputs implements the Operator interface -func (fkc *FkCascade) Inputs() []ops.Operator { - var inputs []ops.Operator +func (fkc *FkCascade) Inputs() []Operator { + var inputs []Operator inputs = append(inputs, fkc.Parent) inputs = append(inputs, fkc.Selection) for _, child := range fkc.Children { @@ -61,7 +60,7 @@ func (fkc *FkCascade) Inputs() []ops.Operator { } // SetInputs implements the Operator interface -func (fkc *FkCascade) SetInputs(operators []ops.Operator) { +func (fkc *FkCascade) SetInputs(operators []Operator) { if len(operators) < 2 { panic("incorrect count of inputs for FkCascade") } @@ -76,7 +75,7 @@ func (fkc *FkCascade) SetInputs(operators []ops.Operator) { } // Clone implements the Operator interface -func (fkc *FkCascade) Clone(inputs []ops.Operator) ops.Operator { +func (fkc *FkCascade) Clone(inputs []Operator) Operator { if len(inputs) < 2 { panic("incorrect count of inputs for FkCascade") } @@ -100,7 +99,7 @@ func (fkc *FkCascade) Clone(inputs []ops.Operator) ops.Operator { } // GetOrdering implements the Operator interface -func (fkc *FkCascade) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (fkc *FkCascade) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } diff --git a/go/vt/vtgate/planbuilder/operators/fk_verify.go b/go/vt/vtgate/planbuilder/operators/fk_verify.go index 39e1092c8d9..8275a8d462f 100644 --- a/go/vt/vtgate/planbuilder/operators/fk_verify.go +++ b/go/vt/vtgate/planbuilder/operators/fk_verify.go @@ -17,14 +17,13 @@ limitations under the License. package operators import ( - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // VerifyOp keeps the information about the foreign key verification operation. // It is a Parent verification or a Child verification. type VerifyOp struct { - Op ops.Operator + Op Operator Typ string } @@ -33,17 +32,17 @@ type VerifyOp struct { // verifications on the existence of the rows in the parent table (for example, INSERT and UPDATE). type FkVerify struct { Verify []*VerifyOp - Input ops.Operator + Input Operator noColumns noPredicates } -var _ ops.Operator = (*FkVerify)(nil) +var _ Operator = (*FkVerify)(nil) // Inputs implements the Operator interface -func (fkv *FkVerify) Inputs() []ops.Operator { - inputs := []ops.Operator{fkv.Input} +func (fkv *FkVerify) Inputs() []Operator { + inputs := []Operator{fkv.Input} for _, v := range fkv.Verify { inputs = append(inputs, v.Op) } @@ -51,7 +50,7 @@ func (fkv *FkVerify) Inputs() []ops.Operator { } // SetInputs implements the Operator interface -func (fkv *FkVerify) SetInputs(operators []ops.Operator) { +func (fkv *FkVerify) SetInputs(operators []Operator) { fkv.Input = operators[0] if len(fkv.Verify) != len(operators)-1 { panic("mismatched number of verify inputs") @@ -62,7 +61,7 @@ func (fkv *FkVerify) SetInputs(operators []ops.Operator) { } // Clone implements the Operator interface -func (fkv *FkVerify) Clone(inputs []ops.Operator) ops.Operator { +func (fkv *FkVerify) Clone(inputs []Operator) Operator { newFkv := &FkVerify{ Verify: fkv.Verify, } @@ -71,7 +70,7 @@ func (fkv *FkVerify) Clone(inputs []ops.Operator) ops.Operator { } // GetOrdering implements the Operator interface -func (fkv *FkVerify) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (fkv *FkVerify) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } diff --git a/go/vt/vtgate/planbuilder/operators/hash_join.go b/go/vt/vtgate/planbuilder/operators/hash_join.go index e9cfeb7d107..ce23e510c09 100644 --- a/go/vt/vtgate/planbuilder/operators/hash_join.go +++ b/go/vt/vtgate/planbuilder/operators/hash_join.go @@ -25,14 +25,13 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) type ( HashJoin struct { - LHS, RHS ops.Operator + LHS, RHS Operator // LeftJoin will be true in the case of an outer join LeftJoin bool @@ -62,10 +61,10 @@ type ( } ) -var _ ops.Operator = (*HashJoin)(nil) +var _ Operator = (*HashJoin)(nil) var _ JoinOp = (*HashJoin)(nil) -func NewHashJoin(lhs, rhs ops.Operator, outerJoin bool) *HashJoin { +func NewHashJoin(lhs, rhs Operator, outerJoin bool) *HashJoin { hj := &HashJoin{ LHS: lhs, RHS: rhs, @@ -74,7 +73,7 @@ func NewHashJoin(lhs, rhs ops.Operator, outerJoin bool) *HashJoin { return hj } -func (hj *HashJoin) Clone(inputs []ops.Operator) ops.Operator { +func (hj *HashJoin) Clone(inputs []Operator) Operator { kopy := *hj kopy.LHS, kopy.RHS = inputs[0], inputs[1] kopy.columns = slices.Clone(hj.columns) @@ -83,15 +82,15 @@ func (hj *HashJoin) Clone(inputs []ops.Operator) ops.Operator { return &kopy } -func (hj *HashJoin) Inputs() []ops.Operator { - return []ops.Operator{hj.LHS, hj.RHS} +func (hj *HashJoin) Inputs() []Operator { + return []Operator{hj.LHS, hj.RHS} } -func (hj *HashJoin) SetInputs(operators []ops.Operator) { +func (hj *HashJoin) SetInputs(operators []Operator) { hj.LHS, hj.RHS = operators[0], operators[1] } -func (hj *HashJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (hj *HashJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { return AddPredicate(ctx, hj, expr, false, newFilter) } @@ -107,7 +106,7 @@ func (hj *HashJoin) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bo return len(hj.columns) - 1 } -func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { if hj.offset { return nil } @@ -124,15 +123,11 @@ func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { }) proj := newAliasedProjection(hj) - _, err := proj.addProjExpr(eexprs...) - if err != nil { - panic(err) - } - + proj.addProjExpr(eexprs...) return proj } -func (hj *HashJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int { +func (hj *HashJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, _ bool) int { for offset, col := range hj.columns { if ctx.SemTable.EqualsExprWithDeps(expr, col) { return offset @@ -162,23 +157,23 @@ func (hj *HashJoin) ShortDescription() string { return cmp } -func (hj *HashJoin) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (hj *HashJoin) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return nil // hash joins will never promise an output order } -func (hj *HashJoin) GetLHS() ops.Operator { +func (hj *HashJoin) GetLHS() Operator { return hj.LHS } -func (hj *HashJoin) GetRHS() ops.Operator { +func (hj *HashJoin) GetRHS() Operator { return hj.RHS } -func (hj *HashJoin) SetLHS(op ops.Operator) { +func (hj *HashJoin) SetLHS(op Operator) { hj.LHS = op } -func (hj *HashJoin) SetRHS(op ops.Operator) { +func (hj *HashJoin) SetRHS(op Operator) { hj.RHS = op } @@ -239,7 +234,7 @@ func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Exp return true } deps := ctx.SemTable.RecursiveDeps(expr) - check := func(id semantics.TableSet, op ops.Operator, offsetter func(int) int) int { + check := func(id semantics.TableSet, op Operator, offsetter func(int) int) int { if !deps.IsSolvedBy(id) { return -1 } diff --git a/go/vt/vtgate/planbuilder/operators/helpers.go b/go/vt/vtgate/planbuilder/operators/helpers.go index 21be634d7d8..e5801f6b36f 100644 --- a/go/vt/vtgate/planbuilder/operators/helpers.go +++ b/go/vt/vtgate/planbuilder/operators/helpers.go @@ -21,36 +21,34 @@ import ( "sort" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) // compact will optimise the operator tree into a smaller but equivalent version -func compact(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { +func compact(ctx *plancontext.PlanningContext, op Operator) Operator { type compactable interface { // Compact implement this interface for operators that have easy to see optimisations - Compact(ctx *plancontext.PlanningContext) (ops.Operator, *rewrite.ApplyResult, error) + Compact(ctx *plancontext.PlanningContext) (Operator, *ApplyResult) } - newOp, err := rewrite.BottomUp(op, TableID, func(op ops.Operator, _ semantics.TableSet, _ bool) (ops.Operator, *rewrite.ApplyResult, error) { + newOp := BottomUp(op, TableID, func(op Operator, _ semantics.TableSet, _ bool) (Operator, *ApplyResult) { newOp, ok := op.(compactable) if !ok { - return op, rewrite.SameTree, nil + return op, NoRewrite } return newOp.Compact(ctx) }, stopAtRoute) - return newOp, err + return newOp } -func checkValid(op ops.Operator) error { +func checkValid(op Operator) error { type checkable interface { CheckValid() error } - return rewrite.Visit(op, func(this ops.Operator) error { + return Visit(op, func(this Operator) error { if chk, ok := this.(checkable); ok { return chk.CheckValid() } @@ -58,9 +56,9 @@ func checkValid(op ops.Operator) error { }) } -func Clone(op ops.Operator) ops.Operator { +func Clone(op Operator) Operator { inputs := op.Inputs() - clones := make([]ops.Operator, len(inputs)) + clones := make([]Operator, len(inputs)) for i, input := range inputs { clones[i] = Clone(input) } @@ -72,8 +70,8 @@ type tableIDIntroducer interface { introducesTableID() semantics.TableSet } -func TableID(op ops.Operator) (result semantics.TableSet) { - _ = rewrite.Visit(op, func(this ops.Operator) error { +func TableID(op Operator) (result semantics.TableSet) { + _ = Visit(op, func(this Operator) error { if tbl, ok := this.(tableIDIntroducer); ok { result = result.Merge(tbl.introducesTableID()) } @@ -87,9 +85,9 @@ type TableUser interface { TablesUsed() []string } -func TablesUsed(op ops.Operator) []string { +func TablesUsed(op Operator) []string { addString, collect := collectSortedUniqueStrings() - _ = rewrite.Visit(op, func(this ops.Operator) error { + _ = Visit(op, func(this Operator) error { if tbl, ok := this.(TableUser); ok { for _, u := range tbl.TablesUsed() { addString(u) @@ -100,29 +98,7 @@ func TablesUsed(op ops.Operator) []string { return collect() } -func UnresolvedPredicates(op ops.Operator, st *semantics.SemTable) (result []sqlparser.Expr) { - type unresolved interface { - // UnsolvedPredicates returns any predicates that have dependencies on the given Operator and - // on the outside of it (a parent Select expression, any other table not used by Operator, etc.). - // This is used for sub-queries. An example query could be: - // SELECT * FROM tbl WHERE EXISTS (SELECT 1 FROM otherTbl WHERE tbl.col = otherTbl.col) - // The subquery would have one unsolved predicate: `tbl.col = otherTbl.col` - // It's a predicate that belongs to the inner query, but it needs data from the outer query - // These predicates dictate which data we have to send from the outer side to the inner - UnsolvedPredicates(semTable *semantics.SemTable) []sqlparser.Expr - } - - _ = rewrite.Visit(op, func(this ops.Operator) error { - if tbl, ok := this.(unresolved); ok { - result = append(result, tbl.UnsolvedPredicates(st)...) - } - - return nil - }) - return -} - -func CostOf(op ops.Operator) (cost int) { +func CostOf(op Operator) (cost int) { type costly interface { // Cost returns the cost for this operator. All the costly operators in the tree are summed together to get the // total cost of the operator tree. @@ -131,7 +107,7 @@ func CostOf(op ops.Operator) (cost int) { Cost() int } - _ = rewrite.Visit(op, func(op ops.Operator) error { + _ = Visit(op, func(op Operator) error { if costlyOp, ok := op.(costly); ok { cost += costlyOp.Cost() } diff --git a/go/vt/vtgate/planbuilder/operators/horizon.go b/go/vt/vtgate/planbuilder/operators/horizon.go index c58db4f3964..1a6fc6331ea 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon.go +++ b/go/vt/vtgate/planbuilder/operators/horizon.go @@ -22,7 +22,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -35,7 +34,7 @@ import ( // Project/Aggregate/Sort/Limit operations, some which can be pushed down, // and some that have to be evaluated at the vtgate level. type Horizon struct { - Source ops.Operator + Source Operator // If this is a derived table, the two following fields will contain the tableID and name of it TableId *semantics.TableSet @@ -52,12 +51,12 @@ type Horizon struct { ColumnsOffset []int } -func newHorizon(src ops.Operator, query sqlparser.SelectStatement) *Horizon { +func newHorizon(src Operator, query sqlparser.SelectStatement) *Horizon { return &Horizon{Source: src, Query: query} } // Clone implements the Operator interface -func (h *Horizon) Clone(inputs []ops.Operator) ops.Operator { +func (h *Horizon) Clone(inputs []Operator) Operator { klone := *h klone.Source = inputs[0] klone.ColumnAliases = sqlparser.CloneColumns(h.ColumnAliases) @@ -77,16 +76,16 @@ func (h *Horizon) IsMergeable(ctx *plancontext.PlanningContext) bool { } // Inputs implements the Operator interface -func (h *Horizon) Inputs() []ops.Operator { - return []ops.Operator{h.Source} +func (h *Horizon) Inputs() []Operator { + return []Operator{h.Source} } // SetInputs implements the Operator interface -func (h *Horizon) SetInputs(ops []ops.Operator) { +func (h *Horizon) SetInputs(ops []Operator) { h.Source = ops[0] } -func (h *Horizon) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (h *Horizon) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { if _, isUNion := h.Source.(*Union); isUNion { // If we have a derived table on top of a UNION, we can let the UNION do the expression rewriting h.Source = h.Source.AddPredicate(ctx, expr) @@ -181,12 +180,9 @@ func (h *Horizon) GetSelectExprs(*plancontext.PlanningContext) sqlparser.SelectE return sqlparser.GetFirstSelect(h.Query).SelectExprs } -func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { if h.QP == nil { - _, err := h.getQP(ctx) - if err != nil { - panic(err) - } + h.getQP(ctx) } return h.QP.OrderExprs } @@ -196,20 +192,20 @@ func (h *Horizon) selectStatement() sqlparser.SelectStatement { return h.Query } -func (h *Horizon) src() ops.Operator { +func (h *Horizon) src() Operator { return h.Source } -func (h *Horizon) getQP(ctx *plancontext.PlanningContext) (*QueryProjection, error) { +func (h *Horizon) getQP(ctx *plancontext.PlanningContext) *QueryProjection { if h.QP != nil { - return h.QP, nil + return h.QP } qp, err := CreateQPFromSelectStatement(ctx, h.Query) if err != nil { - return nil, err + panic(err) } h.QP = qp - return h.QP, nil + return h.QP } func (h *Horizon) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go index 06bcf2aaeb5..e3ddc5d9232 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go +++ b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go @@ -23,12 +23,10 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) -func expandHorizon(ctx *plancontext.PlanningContext, horizon *Horizon) (ops.Operator, *rewrite.ApplyResult, error) { +func expandHorizon(ctx *plancontext.PlanningContext, horizon *Horizon) (Operator, *ApplyResult) { statement := horizon.selectStatement() switch sel := statement.(type) { case *sqlparser.Select: @@ -36,16 +34,13 @@ func expandHorizon(ctx *plancontext.PlanningContext, horizon *Horizon) (ops.Oper case *sqlparser.Union: return expandUnionHorizon(ctx, horizon, sel) } - return nil, nil, vterrors.VT13001(fmt.Sprintf("unexpected statement type %T", statement)) + panic(vterrors.VT13001(fmt.Sprintf("unexpected statement type %T", statement))) } -func expandUnionHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, union *sqlparser.Union) (ops.Operator, *rewrite.ApplyResult, error) { +func expandUnionHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, union *sqlparser.Union) (Operator, *ApplyResult) { op := horizon.Source - qp, err := horizon.getQP(ctx) - if err != nil { - return nil, nil, err - } + qp := horizon.getQP(ctx) if len(qp.OrderExprs) > 0 { op = &Ordering{ @@ -72,20 +67,15 @@ func expandUnionHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, unio } if op == horizon.Source { - return op, rewrite.NewTree("removed UNION horizon not used"), nil + return op, Rewrote("removed UNION horizon not used") } - return op, rewrite.NewTree("expand UNION horizon into smaller components"), nil + return op, Rewrote("expand UNION horizon into smaller components") } -func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel *sqlparser.Select) (ops.Operator, *rewrite.ApplyResult, error) { +func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel *sqlparser.Select) (Operator, *ApplyResult) { op := createProjectionFromSelect(ctx, horizon) - - qp, err := horizon.getQP(ctx) - if err != nil { - return nil, nil, err - } - + qp := horizon.getQP(ctx) var extracted []string if qp.HasAggr { extracted = append(extracted, "Aggregation") @@ -103,10 +93,7 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel } if sel.Having != nil { - op, err = addWherePredicates(ctx, sel.Having.Expr, op) - if err != nil { - return nil, nil, err - } + op = addWherePredicates(ctx, sel.Having.Expr, op) extracted = append(extracted, "Filter") } @@ -126,14 +113,11 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel extracted = append(extracted, "Limit") } - return op, rewrite.NewTree(fmt.Sprintf("expand SELECT horizon into (%s)", strings.Join(extracted, ", "))), nil + return op, Rewrote(fmt.Sprintf("expand SELECT horizon into (%s)", strings.Join(extracted, ", "))) } -func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horizon) (out ops.Operator) { - qp, err := horizon.getQP(ctx) - if err != nil { - panic(err) - } +func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horizon) (out Operator) { + qp := horizon.getQP(ctx) var dt *DerivedTable if horizon.TableId != nil { @@ -172,7 +156,7 @@ func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horiz return createProjectionForSimpleAggregation(ctx, a, qp) } -func createProjectionForSimpleAggregation(ctx *plancontext.PlanningContext, a *Aggregator, qp *QueryProjection) ops.Operator { +func createProjectionForSimpleAggregation(ctx *plancontext.PlanningContext, a *Aggregator, qp *QueryProjection) Operator { outer: for colIdx, expr := range qp.SelectExprs { ae, err := expr.GetAliasedExpr() @@ -206,7 +190,7 @@ outer: return a } -func createProjectionForComplexAggregation(a *Aggregator, qp *QueryProjection) ops.Operator { +func createProjectionForComplexAggregation(a *Aggregator, qp *QueryProjection) Operator { p := newAliasedProjection(a) p.DT = a.DT for _, expr := range qp.SelectExprs { @@ -215,10 +199,7 @@ func createProjectionForComplexAggregation(a *Aggregator, qp *QueryProjection) o panic(err) } - _, err = p.addProjExpr(newProjExpr(ae)) - if err != nil { - panic(err) - } + p.addProjExpr(newProjExpr(ae)) } for i, by := range a.Grouping { a.Grouping[i].ColOffset = len(a.Columns) @@ -231,7 +212,7 @@ func createProjectionForComplexAggregation(a *Aggregator, qp *QueryProjection) o return p } -func createProjectionWithoutAggr(ctx *plancontext.PlanningContext, qp *QueryProjection, src ops.Operator) *Projection { +func createProjectionWithoutAggr(ctx *plancontext.PlanningContext, qp *QueryProjection, src Operator) *Projection { // first we need to check if we have all columns or there are still unexpanded stars aes, err := slice.MapWithError(qp.SelectExprs, func(from SelectExpr) (*sqlparser.AliasedExpr, error) { ae, ok := from.Col.(*sqlparser.AliasedExpr) @@ -252,28 +233,19 @@ func createProjectionWithoutAggr(ctx *plancontext.PlanningContext, qp *QueryProj for _, ae := range aes { org := sqlparser.CloneRefOfAliasedExpr(ae) expr := ae.Expr - newExpr, subqs, err := sqc.pullOutValueSubqueries(ctx, expr, outerID, false) - if err != nil { - panic(err) - } + newExpr, subqs := sqc.pullOutValueSubqueries(ctx, expr, outerID, false) if newExpr == nil { // there was no subquery in this expression - _, err := proj.addUnexploredExpr(org, expr) - if err != nil { - panic(err) - } + proj.addUnexploredExpr(org, expr) } else { - err := proj.addSubqueryExpr(org, newExpr, subqs...) - if err != nil { - panic(err) - } + proj.addSubqueryExpr(org, newExpr, subqs...) } } proj.Source = sqc.getRootOperator(src, nil) return proj } -func newStarProjection(src ops.Operator, qp *QueryProjection) *Projection { +func newStarProjection(src Operator, qp *QueryProjection) *Projection { cols := sqlparser.SelectExprs{} for _, expr := range qp.SelectExprs { diff --git a/go/vt/vtgate/planbuilder/operators/info_schema_planning.go b/go/vt/vtgate/planbuilder/operators/info_schema_planning.go index 4f096e1ac65..f7de09c4857 100644 --- a/go/vt/vtgate/planbuilder/operators/info_schema_planning.go +++ b/go/vt/vtgate/planbuilder/operators/info_schema_planning.go @@ -41,7 +41,7 @@ type InfoSchemaRouting struct { Table *QueryTable } -func (isr *InfoSchemaRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (isr *InfoSchemaRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.SysTableTableSchema = nil for _, expr := range isr.SysTableTableSchema { eexpr, err := evalengine.Translate(expr, &evalengine.Config{ @@ -49,7 +49,7 @@ func (isr *InfoSchemaRouting) UpdateRoutingParams(_ *plancontext.PlanningContext ResolveColumn: NotImplementedSchemaInfoResolver, }) if err != nil { - return err + panic(err) } rp.SysTableTableSchema = append(rp.SysTableTableSchema, eexpr) } @@ -61,12 +61,11 @@ func (isr *InfoSchemaRouting) UpdateRoutingParams(_ *plancontext.PlanningContext ResolveColumn: NotImplementedSchemaInfoResolver, }) if err != nil { - return err + panic(err) } rp.SysTableTableName[k] = eexpr } - return nil } func (isr *InfoSchemaRouting) Clone() Routing { @@ -77,10 +76,10 @@ func (isr *InfoSchemaRouting) Clone() Routing { } } -func (isr *InfoSchemaRouting) updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) (Routing, error) { +func (isr *InfoSchemaRouting) updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Routing { isTableSchema, bvName, out := extractInfoSchemaRoutingPredicate(ctx, expr) if out == nil { - return isr, nil + return isr } if isr.SysTableTableName == nil { @@ -92,14 +91,14 @@ func (isr *InfoSchemaRouting) updateRoutingLogic(ctx *plancontext.PlanningContex if sqlparser.Equals.Expr(out, s) { // we already have this expression in the list // stating it again does not add value - return isr, nil + return isr } } isr.SysTableTableSchema = append(isr.SysTableTableSchema, out) } else { isr.SysTableTableName[bvName] = out } - return isr, nil + return isr } func (isr *InfoSchemaRouting) Cost() int { diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index fa2f60dcecc..f783ac7a5bc 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -24,7 +24,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -79,13 +78,13 @@ func (i *Insert) ShortDescription() string { return i.VTable.String() } -func (i *Insert) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (i *Insert) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -var _ ops.Operator = (*Insert)(nil) +var _ Operator = (*Insert)(nil) -func (i *Insert) Clone([]ops.Operator) ops.Operator { +func (i *Insert) Clone([]Operator) Operator { return &Insert{ VTable: i.VTable, AST: i.AST, @@ -105,16 +104,10 @@ func (i *Insert) Statement() sqlparser.Statement { return i.AST } -func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.Insert) (ops.Operator, error) { - tableInfo, qt, err := createQueryTableForDML(ctx, ins.Table, nil) - if err != nil { - return nil, err - } +func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.Insert) Operator { + tableInfo, qt := createQueryTableForDML(ctx, ins.Table, nil) - vTbl, routing, err := buildVindexTableForDML(ctx, tableInfo, qt, "insert") - if err != nil { - return nil, err - } + vTbl, routing := buildVindexTableForDML(ctx, tableInfo, qt, "insert") deleteBeforeInsert := false if ins.Action == sqlparser.ReplaceAct && @@ -125,37 +118,27 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I deleteBeforeInsert = true } - insOp, err := checkAndCreateInsertOperator(ctx, ins, vTbl, routing) - if err != nil { - return nil, err - } + insOp := checkAndCreateInsertOperator(ctx, ins, vTbl, routing) if !deleteBeforeInsert { - return insOp, nil + return insOp } rows, isRows := ins.Rows.(sqlparser.Values) if !isRows { - return nil, vterrors.VT12001("REPLACE INTO using select statement") + panic(vterrors.VT12001("REPLACE INTO using select statement")) } pkCompExpr := pkCompExpression(vTbl, ins, rows) - uniqKeyCompExprs, err := uniqKeyCompExpressions(vTbl, ins, rows) - if err != nil { - return nil, err - } - + uniqKeyCompExprs := uniqKeyCompExpressions(vTbl, ins, rows) whereExpr := getWhereCondExpr(append(uniqKeyCompExprs, pkCompExpr)) delStmt := &sqlparser.Delete{ TableExprs: sqlparser.TableExprs{sqlparser.CloneRefOfAliasedTableExpr(ins.Table)}, Where: sqlparser.NewWhere(sqlparser.WhereClause, whereExpr), } - delOp, err := createOpFromStmt(ctx, delStmt, false, "") - if err != nil { - return nil, err - } - return &Sequential{Sources: []ops.Operator{delOp, insOp}}, nil + delOp := createOpFromStmt(ctx, delStmt, false, "") + return &Sequential{Sources: []Operator{delOp, insOp}} } func getWhereCondExpr(compExprs []*sqlparser.ComparisonExpr) sqlparser.Expr { @@ -229,10 +212,10 @@ type uComp struct { def sqlparser.Expr } -func uniqKeyCompExpressions(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparser.Values) (comps []*sqlparser.ComparisonExpr, err error) { +func uniqKeyCompExpressions(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparser.Values) (comps []*sqlparser.ComparisonExpr) { noOfUniqKeys := len(vTbl.UniqueKeys) if noOfUniqKeys == 0 { - return nil, nil + return nil } type uIdx struct { @@ -248,10 +231,7 @@ func uniqKeyCompExpressions(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sq skipKey := false for _, expr := range uniqKey { var offsets []uComp - offsets, skipKey, err = createUniqueKeyComp(ins, expr, vTbl) - if err != nil { - return nil, err - } + offsets, skipKey = createUniqueKeyComp(ins, expr, vTbl) if skipKey { break } @@ -293,10 +273,10 @@ func uniqKeyCompExpressions(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sq for i, valTuple := range allValTuples { compExprs = append(compExprs, sqlparser.NewComparisonExpr(sqlparser.InOp, allColTuples[i], valTuple, nil)) } - return compExprs, nil + return compExprs } -func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vindexes.Table) ([]uComp, bool, error) { +func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vindexes.Table) ([]uComp, bool) { col, isCol := expr.(*sqlparser.ColName) if isCol { var def sqlparser.Expr @@ -305,13 +285,13 @@ func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vinde def = findDefault(vTbl, col.Name) if def == nil { // default value is empty, nothing to compare as it will always be false. - return nil, true, nil + return nil, true } } - return []uComp{{idx, def}}, false, nil + return []uComp{{idx, def}}, false } var offsets []uComp - err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { col, ok := node.(*sqlparser.ColName) if !ok { return true, nil @@ -328,14 +308,11 @@ func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vinde offsets = append(offsets, uComp{idx, def}) return false, nil }, expr) - return offsets, false, err + return offsets, false } -func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) (ops.Operator, error) { - insOp, err := createInsertOperator(ctx, ins, vTbl, routing) - if err != nil { - return nil, err - } +func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) Operator { + insOp := createInsertOperator(ctx, ins, vTbl, routing) if ins.Comments != nil { insOp = &LockAndComment{ @@ -347,31 +324,31 @@ func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlpars // Find the foreign key mode and for unmanaged foreign-key-mode, we don't need to do anything. ksMode, err := ctx.VSchema.ForeignKeyMode(vTbl.Keyspace.Name) if err != nil { - return nil, err + return nil } if ksMode != vschemapb.Keyspace_managed { - return insOp, nil + return insOp } parentFKs := ctx.SemTable.GetParentForeignKeysList() childFks := ctx.SemTable.GetChildForeignKeysList() if len(parentFKs) > 0 { - return nil, vterrors.VT12002() + panic(vterrors.VT12002()) } if len(childFks) > 0 { if ins.Action == sqlparser.ReplaceAct { - return nil, vterrors.VT12001("REPLACE INTO with foreign keys") + panic(vterrors.VT12001("REPLACE INTO with foreign keys")) } if len(ins.OnDup) > 0 { - return nil, vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys") + panic(vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys")) } } - return insOp, nil + return insOp } -func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) (ops.Operator, error) { +func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) Operator { if _, target := routing.(*TargetedRouting); target { - return nil, vterrors.VT09017("INSERT with a target destination is not allowed") + panic(vterrors.VT09017("INSERT with a target destination is not allowed")) } insOp := &Insert{ @@ -390,15 +367,12 @@ func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.I if vTbl.ColumnListAuthoritative { insStmt = populateInsertColumnlist(insStmt, vTbl) } else { - return nil, vterrors.VT09004() + panic(vterrors.VT09004()) } } // modify column list or values for autoincrement column. - autoIncGen, err := modifyForAutoinc(ctx, insStmt, vTbl) - if err != nil { - return nil, err - } + autoIncGen := modifyForAutoinc(ctx, insStmt, vTbl) insOp.AutoIncrement = autoIncGen // set insert ignore. @@ -407,24 +381,27 @@ func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.I insOp.ColVindexes = getColVindexes(insOp) switch rows := insStmt.Rows.(type) { case sqlparser.Values: - route.Source, err = insertRowsPlan(ctx, insOp, insStmt, rows) - if err != nil { - return nil, err - } + route.Source = insertRowsPlan(ctx, insOp, insStmt, rows) case sqlparser.SelectStatement: return insertSelectPlan(ctx, insOp, route, insStmt, rows) } - return route, nil + return route } -func insertSelectPlan(ctx *plancontext.PlanningContext, insOp *Insert, routeOp *Route, ins *sqlparser.Insert, sel sqlparser.SelectStatement) (*InsertSelection, error) { +func insertSelectPlan( + ctx *plancontext.PlanningContext, + insOp *Insert, + routeOp *Route, + ins *sqlparser.Insert, + sel sqlparser.SelectStatement, +) *InsertSelection { if columnMismatch(insOp.AutoIncrement, ins, sel) { - return nil, vterrors.VT03006() + panic(vterrors.VT03006()) } selOp, err := PlanQuery(ctx, sel) if err != nil { - return nil, err + panic(err) } // output of the select plan will be used to insert rows into the table. @@ -449,28 +426,24 @@ func insertSelectPlan(ctx *plancontext.PlanningContext, insOp *Insert, routeOp * } if len(insOp.ColVindexes) == 0 { - return insertSelect, nil + return insertSelect } colVindexes := insOp.ColVindexes vv := make([][]int, len(colVindexes)) for idx, colVindex := range colVindexes { for _, col := range colVindex.Columns { - err := checkAndErrIfVindexChanging(sqlparser.UpdateExprs(ins.OnDup), col) - if err != nil { - return nil, err - } - + checkAndErrIfVindexChanging(sqlparser.UpdateExprs(ins.OnDup), col) colNum := findColumn(ins, col) // sharding column values should be provided in the insert. if colNum == -1 && idx == 0 { - return nil, vterrors.VT09003(col) + panic(vterrors.VT09003(col)) } vv[idx] = append(vv[idx], colNum) } } insOp.VindexValueOffset = vv - return insertSelect, nil + return insertSelect } func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectStatement) bool { @@ -498,15 +471,15 @@ func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectSt return false } -func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlparser.Insert, rows sqlparser.Values) (*Insert, error) { +func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlparser.Insert, rows sqlparser.Values) *Insert { for _, row := range rows { if len(ins.Columns) != len(row) { - return nil, vterrors.VT03006() + panic(vterrors.VT03006()) } } if len(insOp.ColVindexes) == 0 { - return insOp, nil + return insOp } colVindexes := insOp.ColVindexes @@ -514,10 +487,7 @@ func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlpar for vIdx, colVindex := range colVindexes { routeValues[vIdx] = make([][]evalengine.Expr, len(colVindex.Columns)) for colIdx, col := range colVindex.Columns { - err := checkAndErrIfVindexChanging(sqlparser.UpdateExprs(ins.OnDup), col) - if err != nil { - return nil, err - } + checkAndErrIfVindexChanging(sqlparser.UpdateExprs(ins.OnDup), col) routeValues[vIdx][colIdx] = make([]evalengine.Expr, len(rows)) colNum, _ := findOrAddColumn(ins, col) for rowNum, row := range rows { @@ -526,7 +496,7 @@ func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlpar Collation: ctx.SemTable.Collation, }) if err != nil { - return nil, err + panic(err) } routeValues[vIdx][colIdx][rowNum] = innerpv } @@ -543,7 +513,7 @@ func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlpar } } insOp.VindexValues = routeValues - return insOp, nil + return insOp } func valuesProvided(rows sqlparser.InsertRows) bool { @@ -571,18 +541,17 @@ func getColVindexes(insOp *Insert) (colVindexes []*vindexes.ColumnVindex) { return } -func checkAndErrIfVindexChanging(setClauses sqlparser.UpdateExprs, col sqlparser.IdentifierCI) error { +func checkAndErrIfVindexChanging(setClauses sqlparser.UpdateExprs, col sqlparser.IdentifierCI) { for _, assignment := range setClauses { if col.Equal(assignment.Name.Name) { valueExpr, isValuesFuncExpr := assignment.Expr.(*sqlparser.ValuesFuncExpr) // update on duplicate key is changing the vindex column, not supported. if !isValuesFuncExpr || !valueExpr.Name.Name.Equal(assignment.Name.Name) { - return vterrors.VT12001("DML cannot update vindex column") + panic(vterrors.VT12001("DML cannot update vindex column")) } - return nil + return } } - return nil } // findOrAddColumn finds the position of a column in the insert. If it's @@ -625,9 +594,9 @@ func populateInsertColumnlist(ins *sqlparser.Insert, table *vindexes.Table) *sql // modifyForAutoinc modifies the AST and the plan to generate necessary autoinc values. // For row values cases, bind variable names are generated using baseName. -func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTable *vindexes.Table) (*Generate, error) { +func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTable *vindexes.Table) *Generate { if vTable.AutoIncrement == nil { - return nil, nil + return nil } gen := &Generate{ Keyspace: vTable.AutoIncrement.Sequence.Keyspace, @@ -642,7 +611,7 @@ func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, v autoIncValues := make(sqlparser.ValTuple, 0, len(rows)) for rowNum, row := range rows { if len(ins.Columns) != len(row) { - return nil, vterrors.VT03006() + panic(vterrors.VT03006()) } // Support the DEFAULT keyword by treating it as null if _, ok := row[colNum].(*sqlparser.Default); ok { @@ -657,8 +626,8 @@ func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, v Collation: ctx.SemTable.Collation, }) if err != nil { - return nil, err + panic(err) } } - return gen, nil + return gen } diff --git a/go/vt/vtgate/planbuilder/operators/insert_selection.go b/go/vt/vtgate/planbuilder/operators/insert_selection.go index 5ae49ee2c55..70bda0a990a 100644 --- a/go/vt/vtgate/planbuilder/operators/insert_selection.go +++ b/go/vt/vtgate/planbuilder/operators/insert_selection.go @@ -17,15 +17,14 @@ limitations under the License. package operators import ( - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // InsertSelection operator represents an INSERT into SELECT FROM query. // It holds the operators for running the selection and insertion. type InsertSelection struct { - Select ops.Operator - Insert ops.Operator + Select Operator + Insert Operator // ForceNonStreaming when true, select first then insert, this is to avoid locking rows by select for insert. ForceNonStreaming bool @@ -34,7 +33,7 @@ type InsertSelection struct { noPredicates } -func (is *InsertSelection) Clone(inputs []ops.Operator) ops.Operator { +func (is *InsertSelection) Clone(inputs []Operator) Operator { return &InsertSelection{ Select: inputs[0], Insert: inputs[1], @@ -42,11 +41,11 @@ func (is *InsertSelection) Clone(inputs []ops.Operator) ops.Operator { } } -func (is *InsertSelection) Inputs() []ops.Operator { - return []ops.Operator{is.Select, is.Insert} +func (is *InsertSelection) Inputs() []Operator { + return []Operator{is.Select, is.Insert} } -func (is *InsertSelection) SetInputs(inputs []ops.Operator) { +func (is *InsertSelection) SetInputs(inputs []Operator) { is.Select = inputs[0] is.Insert = inputs[1] } @@ -58,8 +57,8 @@ func (is *InsertSelection) ShortDescription() string { return "" } -func (is *InsertSelection) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (is *InsertSelection) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -var _ ops.Operator = (*InsertSelection)(nil) +var _ Operator = (*InsertSelection)(nil) diff --git a/go/vt/vtgate/planbuilder/operators/join.go b/go/vt/vtgate/planbuilder/operators/join.go index 1d50a688df4..35bf26f9793 100644 --- a/go/vt/vtgate/planbuilder/operators/join.go +++ b/go/vt/vtgate/planbuilder/operators/join.go @@ -19,24 +19,22 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // Join represents a join. If we have a predicate, this is an inner join. If no predicate exists, it is a cross join type Join struct { - LHS, RHS ops.Operator + LHS, RHS Operator Predicate sqlparser.Expr LeftJoin bool noColumns } -var _ ops.Operator = (*Join)(nil) +var _ Operator = (*Join)(nil) // Clone implements the Operator interface -func (j *Join) Clone(inputs []ops.Operator) ops.Operator { +func (j *Join) Clone(inputs []Operator) Operator { clone := *j clone.LHS = inputs[0] clone.RHS = inputs[1] @@ -48,30 +46,30 @@ func (j *Join) Clone(inputs []ops.Operator) ops.Operator { } } -func (j *Join) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (j *Join) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } // Inputs implements the Operator interface -func (j *Join) Inputs() []ops.Operator { - return []ops.Operator{j.LHS, j.RHS} +func (j *Join) Inputs() []Operator { + return []Operator{j.LHS, j.RHS} } // SetInputs implements the Operator interface -func (j *Join) SetInputs(ops []ops.Operator) { +func (j *Join) SetInputs(ops []Operator) { j.LHS, j.RHS = ops[0], ops[1] } -func (j *Join) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *rewrite.ApplyResult, error) { +func (j *Join) Compact(ctx *plancontext.PlanningContext) (Operator, *ApplyResult) { if j.LeftJoin { // we can't merge outer joins into a single QG - return j, rewrite.SameTree, nil + return j, NoRewrite } lqg, lok := j.LHS.(*QueryGraph) rqg, rok := j.RHS.(*QueryGraph) if !lok || !rok { - return j, rewrite.SameTree, nil + return j, NoRewrite } newOp := &QueryGraph{ @@ -82,23 +80,23 @@ func (j *Join) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *rewrite if j.Predicate != nil { newOp.collectPredicate(ctx, j.Predicate) } - return newOp, rewrite.NewTree("merge querygraphs into a single one"), nil + return newOp, Rewrote("merge querygraphs into a single one") } -func createOuterJoin(tableExpr *sqlparser.JoinTableExpr, lhs, rhs ops.Operator) (ops.Operator, error) { +func createOuterJoin(tableExpr *sqlparser.JoinTableExpr, lhs, rhs Operator) Operator { if tableExpr.Join == sqlparser.RightJoinType { lhs, rhs = rhs, lhs } subq, _ := getSubQuery(tableExpr.Condition.On) if subq != nil { - return nil, vterrors.VT12001("subquery in outer join predicate") + panic(vterrors.VT12001("subquery in outer join predicate")) } predicate := tableExpr.Condition.On sqlparser.RemoveKeyspaceFromColName(predicate) - return &Join{LHS: lhs, RHS: rhs, LeftJoin: true, Predicate: predicate}, nil + return &Join{LHS: lhs, RHS: rhs, LeftJoin: true, Predicate: predicate} } -func createJoin(ctx *plancontext.PlanningContext, LHS, RHS ops.Operator) ops.Operator { +func createJoin(ctx *plancontext.PlanningContext, LHS, RHS Operator) Operator { lqg, lok := LHS.(*QueryGraph) rqg, rok := RHS.(*QueryGraph) if lok && rok { @@ -112,7 +110,7 @@ func createJoin(ctx *plancontext.PlanningContext, LHS, RHS ops.Operator) ops.Ope return &Join{LHS: LHS, RHS: RHS} } -func createInnerJoin(ctx *plancontext.PlanningContext, tableExpr *sqlparser.JoinTableExpr, lhs, rhs ops.Operator) (ops.Operator, error) { +func createInnerJoin(ctx *plancontext.PlanningContext, tableExpr *sqlparser.JoinTableExpr, lhs, rhs Operator) Operator { op := createJoin(ctx, lhs, rhs) sqc := &SubQueryBuilder{} outerID := TableID(op) @@ -120,37 +118,34 @@ func createInnerJoin(ctx *plancontext.PlanningContext, tableExpr *sqlparser.Join sqlparser.RemoveKeyspaceFromColName(joinPredicate) exprs := sqlparser.SplitAndExpression(nil, joinPredicate) for _, pred := range exprs { - subq, err := sqc.handleSubquery(ctx, pred, outerID) - if err != nil { - return nil, err - } + subq := sqc.handleSubquery(ctx, pred, outerID) if subq != nil { continue } op = op.AddPredicate(ctx, pred) } - return sqc.getRootOperator(op, nil), nil + return sqc.getRootOperator(op, nil) } -func (j *Join) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (j *Join) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { return AddPredicate(ctx, j, expr, false, newFilter) } var _ JoinOp = (*Join)(nil) -func (j *Join) GetLHS() ops.Operator { +func (j *Join) GetLHS() Operator { return j.LHS } -func (j *Join) GetRHS() ops.Operator { +func (j *Join) GetRHS() Operator { return j.RHS } -func (j *Join) SetLHS(operator ops.Operator) { +func (j *Join) SetLHS(operator Operator) { j.LHS = operator } -func (j *Join) SetRHS(operator ops.Operator) { +func (j *Join) SetRHS(operator Operator) { j.RHS = operator } diff --git a/go/vt/vtgate/planbuilder/operators/join_merging.go b/go/vt/vtgate/planbuilder/operators/join_merging.go index 52c9c4e5837..dfd89013e94 100644 --- a/go/vt/vtgate/planbuilder/operators/join_merging.go +++ b/go/vt/vtgate/planbuilder/operators/join_merging.go @@ -21,14 +21,13 @@ import ( "reflect" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // mergeJoinInputs checks whether two operators can be merged into a single one. // If they can be merged, a new operator with the merged routing is returned // If they cannot be merged, nil is returned. -func mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPredicates []sqlparser.Expr, m merger) *Route { +func mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredicates []sqlparser.Expr, m merger) *Route { lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(lhs, rhs) if lhsRoute == nil { return nil @@ -66,7 +65,7 @@ func mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, jo } } -func prepareInputRoutes(lhs ops.Operator, rhs ops.Operator) (*Route, *Route, Routing, Routing, routingType, routingType, bool) { +func prepareInputRoutes(lhs Operator, rhs Operator) (*Route, *Route, Routing, Routing, routingType, routingType, bool) { lhsRoute, rhsRoute := operatorsToRoutes(lhs, rhs) if lhsRoute == nil || rhsRoute == nil { return nil, nil, nil, nil, 0, 0, false diff --git a/go/vt/vtgate/planbuilder/operators/joins.go b/go/vt/vtgate/planbuilder/operators/joins.go index ad61a6c5a00..266b9b8288f 100644 --- a/go/vt/vtgate/planbuilder/operators/joins.go +++ b/go/vt/vtgate/planbuilder/operators/joins.go @@ -18,17 +18,16 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) type JoinOp interface { - ops.Operator - GetLHS() ops.Operator - GetRHS() ops.Operator - SetLHS(ops.Operator) - SetRHS(ops.Operator) + Operator + GetLHS() Operator + GetRHS() Operator + SetLHS(Operator) + SetRHS(Operator) MakeInner() IsInner() bool AddJoinPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) @@ -39,8 +38,8 @@ func AddPredicate( join JoinOp, expr sqlparser.Expr, joinPredicates bool, - newFilter func(ops.Operator, sqlparser.Expr) ops.Operator, -) ops.Operator { + newFilter func(Operator, sqlparser.Expr) Operator, +) Operator { deps := ctx.SemTable.RecursiveDeps(expr) switch { case deps.IsSolvedBy(TableID(join.GetLHS())): diff --git a/go/vt/vtgate/planbuilder/operators/limit.go b/go/vt/vtgate/planbuilder/operators/limit.go index a6ea925b135..1ba6b61149d 100644 --- a/go/vt/vtgate/planbuilder/operators/limit.go +++ b/go/vt/vtgate/planbuilder/operators/limit.go @@ -18,12 +18,11 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type Limit struct { - Source ops.Operator + Source Operator AST *sqlparser.Limit // Pushed marks whether the limit has been pushed down to the inputs but still need to keep the operator around. @@ -32,22 +31,22 @@ type Limit struct { Pushed bool } -func (l *Limit) Clone(inputs []ops.Operator) ops.Operator { +func (l *Limit) Clone(inputs []Operator) Operator { return &Limit{ Source: inputs[0], AST: sqlparser.CloneRefOfLimit(l.AST), } } -func (l *Limit) Inputs() []ops.Operator { - return []ops.Operator{l.Source} +func (l *Limit) Inputs() []Operator { + return []Operator{l.Source} } -func (l *Limit) SetInputs(operators []ops.Operator) { +func (l *Limit) SetInputs(operators []Operator) { l.Source = operators[0] } -func (l *Limit) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (l *Limit) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { l.Source = l.Source.AddPredicate(ctx, expr) return l } @@ -68,7 +67,7 @@ func (l *Limit) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Selec return l.Source.GetSelectExprs(ctx) } -func (l *Limit) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (l *Limit) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return l.Source.GetOrdering(ctx) } diff --git a/go/vt/vtgate/planbuilder/operators/misc_routing.go b/go/vt/vtgate/planbuilder/operators/misc_routing.go index 81301f975b4..575aa7b4e9a 100644 --- a/go/vt/vtgate/planbuilder/operators/misc_routing.go +++ b/go/vt/vtgate/planbuilder/operators/misc_routing.go @@ -64,10 +64,9 @@ var ( _ Routing = (*SequenceRouting)(nil) ) -func (tr *TargetedRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (tr *TargetedRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.Keyspace = tr.keyspace rp.TargetDestination = tr.TargetDestination - return nil } func (tr *TargetedRouting) Clone() Routing { @@ -75,8 +74,8 @@ func (tr *TargetedRouting) Clone() Routing { return &newTr } -func (tr *TargetedRouting) updateRoutingLogic(_ *plancontext.PlanningContext, _ sqlparser.Expr) (Routing, error) { - return tr, nil +func (tr *TargetedRouting) updateRoutingLogic(_ *plancontext.PlanningContext, _ sqlparser.Expr) Routing { + return tr } func (tr *TargetedRouting) Cost() int { @@ -91,17 +90,16 @@ func (tr *TargetedRouting) Keyspace() *vindexes.Keyspace { return tr.keyspace } -func (n *NoneRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (n *NoneRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.Keyspace = n.keyspace - return nil } func (n *NoneRouting) Clone() Routing { return n } -func (n *NoneRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) (Routing, error) { - return n, nil +func (n *NoneRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) Routing { + return n } func (n *NoneRouting) Cost() int { @@ -116,9 +114,8 @@ func (n *NoneRouting) Keyspace() *vindexes.Keyspace { return n.keyspace } -func (rr *AnyShardRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (rr *AnyShardRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.Keyspace = rr.keyspace - return nil } func (rr *AnyShardRouting) Clone() Routing { @@ -128,8 +125,8 @@ func (rr *AnyShardRouting) Clone() Routing { } } -func (rr *AnyShardRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) (Routing, error) { - return rr, nil +func (rr *AnyShardRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) Routing { + return rr } func (rr *AnyShardRouting) Cost() int { @@ -159,16 +156,14 @@ func (rr *AnyShardRouting) AlternateInKeyspace(keyspace *vindexes.Keyspace) *Rou return nil } -func (dr *DualRouting) UpdateRoutingParams(*plancontext.PlanningContext, *engine.RoutingParameters) error { - return nil -} +func (dr *DualRouting) UpdateRoutingParams(*plancontext.PlanningContext, *engine.RoutingParameters) {} func (dr *DualRouting) Clone() Routing { return &DualRouting{} } -func (dr *DualRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) (Routing, error) { - return dr, nil +func (dr *DualRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) Routing { + return dr } func (dr *DualRouting) Cost() int { @@ -183,18 +178,17 @@ func (dr *DualRouting) Keyspace() *vindexes.Keyspace { return nil } -func (sr *SequenceRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (sr *SequenceRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.Opcode = engine.Next rp.Keyspace = sr.keyspace - return nil } func (sr *SequenceRouting) Clone() Routing { return &SequenceRouting{keyspace: sr.keyspace} } -func (sr *SequenceRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) (Routing, error) { - return sr, nil +func (sr *SequenceRouting) updateRoutingLogic(*plancontext.PlanningContext, sqlparser.Expr) Routing { + return sr } func (sr *SequenceRouting) Cost() int { diff --git a/go/vt/vtgate/planbuilder/operators/offset_planning.go b/go/vt/vtgate/planbuilder/operators/offset_planning.go index d2fc266790c..6de7a2be2b0 100644 --- a/go/vt/vtgate/planbuilder/operators/offset_planning.go +++ b/go/vt/vtgate/planbuilder/operators/offset_planning.go @@ -21,36 +21,30 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) // planOffsets will walk the tree top down, adding offset information to columns in the tree for use in further optimization, -func planOffsets(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { +func planOffsets(ctx *plancontext.PlanningContext, root Operator) Operator { type offsettable interface { - planOffsets(ctx *plancontext.PlanningContext) ops.Operator + planOffsets(ctx *plancontext.PlanningContext) Operator } - visitor := func(in ops.Operator, _ semantics.TableSet, _ bool) (ops.Operator, *rewrite.ApplyResult, error) { - var err error + visitor := func(in Operator, _ semantics.TableSet, _ bool) (Operator, *ApplyResult) { switch op := in.(type) { case *Horizon: - return nil, nil, vterrors.VT13001(fmt.Sprintf("should not see %T here", in)) + panic(vterrors.VT13001(fmt.Sprintf("should not see %T here", in))) case offsettable: newOp := op.planOffsets(ctx) if newOp != nil { - return newOp, rewrite.NewTree("new operator after offset planning"), nil + return newOp, Rewrote("new operator after offset planning") } } - if err != nil { - return nil, nil, err - } - return in, rewrite.SameTree, nil + return in, NoRewrite } - return rewrite.TopDown(root, TableID, visitor, stopAtRoute) + return TopDown(root, TableID, visitor, stopAtRoute) } func fetchByOffset(e sqlparser.SQLNode) bool { @@ -63,7 +57,7 @@ func fetchByOffset(e sqlparser.SQLNode) bool { } // useOffsets rewrites an expression to use values from the input -func useOffsets(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op ops.Operator) sqlparser.Expr { +func useOffsets(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op Operator) sqlparser.Expr { var exprOffset *sqlparser.Offset in := op.Inputs()[0] @@ -93,17 +87,17 @@ func useOffsets(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op ops.Op // addColumnsToInput adds columns needed by an operator to its input. // This happens only when the filter expression can be retrieved as an offset from the underlying mysql. -func addColumnsToInput(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { - visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func addColumnsToInput(ctx *plancontext.PlanningContext, root Operator) Operator { + visitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { filter, ok := in.(*Filter) if !ok { - return in, rewrite.SameTree, nil + return in, NoRewrite } proj, areOnTopOfProj := filter.Source.(selectExpressions) if !areOnTopOfProj { // not much we can do here - return in, rewrite.SameTree, nil + return in, NoRewrite } addedColumns := false found := func(expr sqlparser.Expr, i int) {} @@ -119,22 +113,22 @@ func addColumnsToInput(ctx *plancontext.PlanningContext, root ops.Operator) (ops _ = sqlparser.CopyOnRewrite(expr, visitor, nil, ctx.SemTable.CopySemanticInfo) } if addedColumns { - return in, rewrite.NewTree("added columns because filter needs it"), nil + return in, Rewrote("added columns because filter needs it") } - return in, rewrite.SameTree, nil + return in, NoRewrite } - return rewrite.TopDown(root, TableID, visitor, stopAtRoute) + return TopDown(root, TableID, visitor, stopAtRoute) } // addColumnsToInput adds columns needed by an operator to its input. // This happens only when the filter expression can be retrieved as an offset from the underlying mysql. -func pullDistinctFromUNION(_ *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { - visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func pullDistinctFromUNION(_ *plancontext.PlanningContext, root Operator) Operator { + visitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { union, ok := in.(*Union) if !ok || !union.distinct { - return in, rewrite.SameTree, nil + return in, NoRewrite } union.distinct = false @@ -143,10 +137,10 @@ func pullDistinctFromUNION(_ *plancontext.PlanningContext, root ops.Operator) (o Required: true, Source: union, } - return distinct, rewrite.NewTree("pulled out DISTINCT from union"), nil + return distinct, Rewrote("pulled out DISTINCT from union") } - return rewrite.TopDown(root, TableID, visitor, stopAtRoute) + return TopDown(root, TableID, visitor, stopAtRoute) } func getOffsetRewritingVisitor( diff --git a/go/vt/vtgate/planbuilder/operators/operator.go b/go/vt/vtgate/planbuilder/operators/operator.go index b165c5345b0..d639643dda1 100644 --- a/go/vt/vtgate/planbuilder/operators/operator.go +++ b/go/vt/vtgate/planbuilder/operators/operator.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2022 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. @@ -36,138 +36,61 @@ The operators go through a few phases while planning: package operators import ( - "fmt" - - "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type ( - // helper type that implements Inputs() returning nil - noInputs struct{} + // Operator forms the tree of operators, representing the declarative query provided. + // The operator tree is no actually runnable, it's an intermediate representation used + // while query planning + // The mental model are operators that pull data from each other, the root being the + // full query output, and the leaves are most often `Route`s, representing communication + // with one or more shards. We want to push down as much work as possible under these Routes + Operator interface { + // Clone will return a copy of this operator, protected so changed to the original will not impact the clone + Clone(inputs []Operator) Operator - // helper type that implements AddColumn() returning an error - noColumns struct{} + // Inputs returns the inputs for this operator + Inputs() []Operator - // helper type that implements AddPredicate() returning an error - noPredicates struct{} -) + // SetInputs changes the inputs for this op + SetInputs([]Operator) -// PlanQuery creates a query plan for a given SQL statement -func PlanQuery(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) (result ops.Operator, err error) { - defer PanicHandler(&err) + // AddPredicate is used to push predicates. It pushed it as far down as is possible in the tree. + // If we encounter a join and the predicate depends on both sides of the join, the predicate will be split into two parts, + // where data is fetched from the LHS of the join to be used in the evaluation on the RHS + // TODO: we should remove this and replace it with rewriters + AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator - op, err := translateQueryToOp(ctx, stmt) - if err != nil { - return nil, err - } + AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int - if rewrite.DebugOperatorTree { - fmt.Println("Initial tree:") - fmt.Println(ops.ToTree(op)) - } + FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int - if op, err = compact(ctx, op); err != nil { - return nil, err - } + GetColumns(ctx *plancontext.PlanningContext) []*sqlparser.AliasedExpr + GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs - if err = checkValid(op); err != nil { - return nil, err - } - - if op, err = planQuery(ctx, op); err != nil { - return nil, err - } + ShortDescription() string - _, isRoute := op.(*Route) - if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { - // If we got here, we don't have a single shard plan - return nil, ctx.SemTable.NotSingleRouteErr + GetOrdering(ctx *plancontext.PlanningContext) []OrderBy } - return op, err -} + // OrderBy contains the expression to used in order by and also if ordering is needed at VTGate level then what the weight_string function expression to be sent down for evaluation. + OrderBy struct { + Inner *sqlparser.Order -func PanicHandler(err *error) { - if r := recover(); r != nil { - badness, ok := r.(error) - if !ok { - panic(r) - } - - *err = badness - } -} - -// Inputs implements the Operator interface -func (noInputs) Inputs() []ops.Operator { - return nil -} - -// SetInputs implements the Operator interface -func (noInputs) SetInputs(ops []ops.Operator) { - if len(ops) > 0 { - panic("the noInputs operator does not have inputs") - } -} - -// AddColumn implements the Operator interface -func (noColumns) AddColumn(*plancontext.PlanningContext, bool, bool, *sqlparser.AliasedExpr) int { - panic(vterrors.VT13001("noColumns operators have no column")) -} - -func (noColumns) GetColumns(*plancontext.PlanningContext) []*sqlparser.AliasedExpr { - panic(vterrors.VT13001("noColumns operators have no column")) -} - -func (noColumns) FindCol(*plancontext.PlanningContext, sqlparser.Expr, bool) int { - panic(vterrors.VT13001("noColumns operators have no column")) -} - -func (noColumns) GetSelectExprs(*plancontext.PlanningContext) sqlparser.SelectExprs { - panic(vterrors.VT13001("noColumns operators have no column")) -} - -// AddPredicate implements the Operator interface -func (noPredicates) AddPredicate(*plancontext.PlanningContext, sqlparser.Expr) ops.Operator { - panic(vterrors.VT13001("the noColumns operator cannot accept predicates")) -} - -// tryTruncateColumnsAt will see if we can truncate the columns by just asking the operator to do it for us -func tryTruncateColumnsAt(op ops.Operator, truncateAt int) bool { - type columnTruncator interface { - setTruncateColumnCount(offset int) - } - - truncator, ok := op.(columnTruncator) - if ok { - truncator.setTruncateColumnCount(truncateAt) - return true + // See GroupBy#SimplifiedExpr for more details about this + SimplifiedExpr sqlparser.Expr } +) - switch op := op.(type) { - case *Limit: - return tryTruncateColumnsAt(op.Source, truncateAt) - case *SubQuery: - for _, offset := range op.Vars { - if offset >= truncateAt { - return false - } - } - return tryTruncateColumnsAt(op.Outer, truncateAt) - default: - return false +// Map takes in a mapping function and applies it to both the expression in OrderBy. +func (ob OrderBy) Map(mappingFunc func(sqlparser.Expr) sqlparser.Expr) OrderBy { + return OrderBy{ + Inner: &sqlparser.Order{ + Expr: mappingFunc(ob.Inner.Expr), + Direction: ob.Inner.Direction, + }, + SimplifiedExpr: mappingFunc(ob.SimplifiedExpr), } } - -func transformColumnsToSelectExprs(ctx *plancontext.PlanningContext, op ops.Operator) sqlparser.SelectExprs { - columns := op.GetColumns(ctx) - selExprs := slice.Map(columns, func(from *sqlparser.AliasedExpr) sqlparser.SelectExpr { - return from - }) - return selExprs -} diff --git a/go/vt/vtgate/planbuilder/operators/operator_funcs.go b/go/vt/vtgate/planbuilder/operators/operator_funcs.go index 7f7aaff29c5..cc3007438fa 100644 --- a/go/vt/vtgate/planbuilder/operators/operator_funcs.go +++ b/go/vt/vtgate/planbuilder/operators/operator_funcs.go @@ -21,13 +21,12 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // RemovePredicate is used when we turn a predicate into a plan operator, // and the predicate needs to be removed as an AST construct -func RemovePredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op ops.Operator) (ops.Operator, error) { +func RemovePredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op Operator) (Operator, error) { switch op := op.(type) { case *Route: newSrc, err := RemovePredicate(ctx, expr, op.Source) diff --git a/go/vt/vtgate/planbuilder/operators/ops/op.go b/go/vt/vtgate/planbuilder/operators/ops/op.go deleted file mode 100644 index 1117b947814..00000000000 --- a/go/vt/vtgate/planbuilder/operators/ops/op.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2022 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 ops - -import ( - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" -) - -type ( - // Operator forms the tree of operators, representing the declarative query provided. - // The operator tree is no actually runnable, it's an intermediate representation used - // while query planning - // The mental model are operators that pull data from each other, the root being the - // full query output, and the leaves are most often `Route`s, representing communication - // with one or more shards. We want to push down as much work as possible under these Routes - Operator interface { - // Clone will return a copy of this operator, protected so changed to the original will not impact the clone - Clone(inputs []Operator) Operator - - // Inputs returns the inputs for this operator - Inputs() []Operator - - // SetInputs changes the inputs for this op - SetInputs([]Operator) - - // AddPredicate is used to push predicates. It pushed it as far down as is possible in the tree. - // If we encounter a join and the predicate depends on both sides of the join, the predicate will be split into two parts, - // where data is fetched from the LHS of the join to be used in the evaluation on the RHS - // TODO: we should remove this and replace it with rewriters - AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator - - AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int - - FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int - - GetColumns(ctx *plancontext.PlanningContext) []*sqlparser.AliasedExpr - GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs - - ShortDescription() string - - GetOrdering(ctx *plancontext.PlanningContext) []OrderBy - } - - // OrderBy contains the expression to used in order by and also if ordering is needed at VTGate level then what the weight_string function expression to be sent down for evaluation. - OrderBy struct { - Inner *sqlparser.Order - - // See GroupBy#SimplifiedExpr for more details about this - SimplifiedExpr sqlparser.Expr - } -) - -// Map takes in a mapping function and applies it to both the expression in OrderBy. -func (ob OrderBy) Map(mappingFunc func(sqlparser.Expr) sqlparser.Expr) OrderBy { - return OrderBy{ - Inner: &sqlparser.Order{ - Expr: mappingFunc(ob.Inner.Expr), - Direction: ob.Inner.Direction, - }, - SimplifiedExpr: mappingFunc(ob.SimplifiedExpr), - } -} diff --git a/go/vt/vtgate/planbuilder/operators/ordering.go b/go/vt/vtgate/planbuilder/operators/ordering.go index 66436f6a47d..bc088ca2220 100644 --- a/go/vt/vtgate/planbuilder/operators/ordering.go +++ b/go/vt/vtgate/planbuilder/operators/ordering.go @@ -22,20 +22,19 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type Ordering struct { - Source ops.Operator + Source Operator Offset []int WOffset []int - Order []ops.OrderBy + Order []OrderBy ResultColumns int } -func (o *Ordering) Clone(inputs []ops.Operator) ops.Operator { +func (o *Ordering) Clone(inputs []Operator) Operator { return &Ordering{ Source: inputs[0], Offset: slices.Clone(o.Offset), @@ -45,15 +44,15 @@ func (o *Ordering) Clone(inputs []ops.Operator) ops.Operator { } } -func (o *Ordering) Inputs() []ops.Operator { - return []ops.Operator{o.Source} +func (o *Ordering) Inputs() []Operator { + return []Operator{o.Source} } -func (o *Ordering) SetInputs(operators []ops.Operator) { +func (o *Ordering) SetInputs(operators []Operator) { o.Source = operators[0] } -func (o *Ordering) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (o *Ordering) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { o.Source = o.Source.AddPredicate(ctx, expr) return o } @@ -74,11 +73,11 @@ func (o *Ordering) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Se return o.Source.GetSelectExprs(ctx) } -func (o *Ordering) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (o *Ordering) GetOrdering(*plancontext.PlanningContext) []OrderBy { return o.Order } -func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) Operator { for _, order := range o.Order { offset := o.Source.AddColumn(ctx, true, false, aeWrap(order.SimplifiedExpr)) o.Offset = append(o.Offset, offset) @@ -96,7 +95,7 @@ func (o *Ordering) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { } func (o *Ordering) ShortDescription() string { - ordering := slice.Map(o.Order, func(o ops.OrderBy) string { + ordering := slice.Map(o.Order, func(o OrderBy) string { return sqlparser.String(o.SimplifiedExpr) }) return strings.Join(ordering, ", ") diff --git a/go/vt/vtgate/planbuilder/operators/phases.go b/go/vt/vtgate/planbuilder/operators/phases.go index 557124e9320..8a47507a526 100644 --- a/go/vt/vtgate/planbuilder/operators/phases.go +++ b/go/vt/vtgate/planbuilder/operators/phases.go @@ -20,8 +20,6 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -79,7 +77,7 @@ func (p Phase) shouldRun(s semantics.QuerySignature) bool { } } -func (p Phase) act(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { +func (p Phase) act(ctx *plancontext.PlanningContext, op Operator) Operator { switch p { case pullDistinctFromUnion: return pullDistinctFromUNION(ctx, op) @@ -90,9 +88,9 @@ func (p Phase) act(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Opera case cleanOutPerfDistinct: return removePerformanceDistinctAboveRoute(ctx, op) case subquerySettling: - return settleSubqueries(ctx, op), nil + return settleSubqueries(ctx, op) default: - return op, nil + return op } } @@ -115,51 +113,47 @@ func (p *phaser) next(ctx *plancontext.PlanningContext) Phase { } } -func removePerformanceDistinctAboveRoute(_ *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { - return rewrite.BottomUp(op, TableID, func(innerOp ops.Operator, _ semantics.TableSet, _ bool) (ops.Operator, *rewrite.ApplyResult, error) { +func removePerformanceDistinctAboveRoute(_ *plancontext.PlanningContext, op Operator) Operator { + return BottomUp(op, TableID, func(innerOp Operator, _ semantics.TableSet, _ bool) (Operator, *ApplyResult) { d, ok := innerOp.(*Distinct) if !ok || d.Required { - return innerOp, rewrite.SameTree, nil + return innerOp, NoRewrite } - return d.Source, rewrite.NewTree("removed distinct not required that was not pushed under route"), nil + return d.Source, Rewrote("removed distinct not required that was not pushed under route") }, stopAtRoute) } -func enableDelegateAggregation(ctx *plancontext.PlanningContext, op ops.Operator) (ops.Operator, error) { +func enableDelegateAggregation(ctx *plancontext.PlanningContext, op Operator) Operator { return addColumnsToInput(ctx, op) } // addOrderingForAllAggregations is run we have pushed down Aggregators as far down as possible. -func addOrderingForAllAggregations(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { - visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func addOrderingForAllAggregations(ctx *plancontext.PlanningContext, root Operator) Operator { + visitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { aggrOp, ok := in.(*Aggregator) if !ok { - return in, rewrite.SameTree, nil + return in, NoRewrite } - requireOrdering, err := needsOrdering(ctx, aggrOp) - if err != nil { - return nil, nil, err - } - - var res *rewrite.ApplyResult + requireOrdering := needsOrdering(ctx, aggrOp) + var res *ApplyResult if requireOrdering { addOrderingFor(aggrOp) - res = rewrite.NewTree("added ordering before aggregation") + res = Rewrote("added ordering before aggregation") } - return in, res, nil + return in, res } - return rewrite.BottomUp(root, TableID, visitor, stopAtRoute) + return BottomUp(root, TableID, visitor, stopAtRoute) } func addOrderingFor(aggrOp *Aggregator) { - orderBys := slice.Map(aggrOp.Grouping, func(from GroupBy) ops.OrderBy { + orderBys := slice.Map(aggrOp.Grouping, func(from GroupBy) OrderBy { return from.AsOrderBy() }) if aggrOp.DistinctExpr != nil { - orderBys = append(orderBys, ops.OrderBy{ + orderBys = append(orderBys, OrderBy{ Inner: &sqlparser.Order{ Expr: aggrOp.DistinctExpr, }, @@ -172,7 +166,7 @@ func addOrderingFor(aggrOp *Aggregator) { } } -func needsOrdering(ctx *plancontext.PlanningContext, in *Aggregator) (bool, error) { +func needsOrdering(ctx *plancontext.PlanningContext, in *Aggregator) bool { requiredOrder := slice.Map(in.Grouping, func(from GroupBy) sqlparser.Expr { return from.SimplifiedExpr }) @@ -180,44 +174,44 @@ func needsOrdering(ctx *plancontext.PlanningContext, in *Aggregator) (bool, erro requiredOrder = append(requiredOrder, in.DistinctExpr) } if len(requiredOrder) == 0 { - return false, nil + return false } srcOrdering := in.Source.GetOrdering(ctx) if len(srcOrdering) < len(requiredOrder) { - return true, nil + return true } for idx, gb := range requiredOrder { if !ctx.SemTable.EqualsExprWithDeps(srcOrdering[idx].SimplifiedExpr, gb) { - return true, nil + return true } } - return false, nil + return false } -func addGroupByOnRHSOfJoin(root ops.Operator) (ops.Operator, error) { - visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func addGroupByOnRHSOfJoin(root Operator) Operator { + visitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { join, ok := in.(*ApplyJoin) if !ok { - return in, rewrite.SameTree, nil + return in, NoRewrite } return addLiteralGroupingToRHS(join) } - return rewrite.TopDown(root, TableID, visitor, stopAtRoute) + return TopDown(root, TableID, visitor, stopAtRoute) } -func addLiteralGroupingToRHS(in *ApplyJoin) (ops.Operator, *rewrite.ApplyResult, error) { - _ = rewrite.Visit(in.RHS, func(op ops.Operator) error { +func addLiteralGroupingToRHS(in *ApplyJoin) (Operator, *ApplyResult) { + _ = Visit(in.RHS, func(op Operator) error { aggr, isAggr := op.(*Aggregator) if !isAggr { return nil } if len(aggr.Grouping) == 0 { gb := sqlparser.NewIntLiteral(".0") - aggr.Grouping = append(aggr.Grouping, NewGroupBy(gb, gb, aeWrap(gb))) + aggr.Grouping = append(aggr.Grouping, NewGroupBy(gb, gb)) } return nil }) - return in, rewrite.SameTree, nil + return in, NoRewrite } diff --git a/go/vt/vtgate/planbuilder/operators/plan_query.go b/go/vt/vtgate/planbuilder/operators/plan_query.go new file mode 100644 index 00000000000..811f0c8dc76 --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/plan_query.go @@ -0,0 +1,165 @@ +/* +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 operators contains the operators used to plan queries. +/* +The operators go through a few phases while planning: +1. Initial plan + In this first pass, we build an operator tree from the incoming parsed query. + At the leaves, it will contain QueryGraphs - these are the tables in the FROM clause + that we can easily do join ordering on because they are all inner joins. + All the post-processing - aggregations, sorting, limit etc. are at this stage + contained in Horizon structs. We try to push these down under routes, and expand + the ones that can't be pushed down into individual operators such as Projection, + Agreggation, Limit, etc. +2. Planning + Once the initial plan has been fully built, we go through a number of phases. + recursively running rewriters on the tree in a fixed point fashion, until we've gone + over all phases and the tree has stop changing. +3. Offset planning + Now is the time to stop working with AST objects and transform remaining expressions being + used on top of vtgate to either offsets on inputs or evalengine expressions. +*/ +package operators + +import ( + "fmt" + + "vitess.io/vitess/go/slice" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" +) + +type ( + // helper type that implements Inputs() returning nil + noInputs struct{} + + // helper type that implements AddColumn() returning an error + noColumns struct{} + + // helper type that implements AddPredicate() returning an error + noPredicates struct{} +) + +// PlanQuery creates a query plan for a given SQL statement +func PlanQuery(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) (result Operator, err error) { + defer PanicHandler(&err) + + op := translateQueryToOp(ctx, stmt) + + if DebugOperatorTree { + fmt.Println("Initial tree:") + fmt.Println(ToTree(op)) + } + + op = compact(ctx, op) + if err = checkValid(op); err != nil { + return nil, err + } + + if op, err = planQuery(ctx, op); err != nil { + return nil, err + } + + _, isRoute := op.(*Route) + if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { + // If we got here, we don't have a single shard plan + return nil, ctx.SemTable.NotSingleRouteErr + } + + return op, err +} + +func PanicHandler(err *error) { + if r := recover(); r != nil { + badness, ok := r.(error) + if !ok { + panic(r) + } + + *err = badness + } +} + +// Inputs implements the Operator interface +func (noInputs) Inputs() []Operator { + return nil +} + +// SetInputs implements the Operator interface +func (noInputs) SetInputs(ops []Operator) { + if len(ops) > 0 { + panic("the noInputs operator does not have inputs") + } +} + +// AddColumn implements the Operator interface +func (noColumns) AddColumn(*plancontext.PlanningContext, bool, bool, *sqlparser.AliasedExpr) int { + panic(vterrors.VT13001("noColumns operators have no column")) +} + +func (noColumns) GetColumns(*plancontext.PlanningContext) []*sqlparser.AliasedExpr { + panic(vterrors.VT13001("noColumns operators have no column")) +} + +func (noColumns) FindCol(*plancontext.PlanningContext, sqlparser.Expr, bool) int { + panic(vterrors.VT13001("noColumns operators have no column")) +} + +func (noColumns) GetSelectExprs(*plancontext.PlanningContext) sqlparser.SelectExprs { + panic(vterrors.VT13001("noColumns operators have no column")) +} + +// AddPredicate implements the Operator interface +func (noPredicates) AddPredicate(*plancontext.PlanningContext, sqlparser.Expr) Operator { + panic(vterrors.VT13001("the noColumns operator cannot accept predicates")) +} + +// tryTruncateColumnsAt will see if we can truncate the columns by just asking the operator to do it for us +func tryTruncateColumnsAt(op Operator, truncateAt int) bool { + type columnTruncator interface { + setTruncateColumnCount(offset int) + } + + truncator, ok := op.(columnTruncator) + if ok { + truncator.setTruncateColumnCount(truncateAt) + return true + } + + switch op := op.(type) { + case *Limit: + return tryTruncateColumnsAt(op.Source, truncateAt) + case *SubQuery: + for _, offset := range op.Vars { + if offset >= truncateAt { + return false + } + } + return tryTruncateColumnsAt(op.Outer, truncateAt) + default: + return false + } +} + +func transformColumnsToSelectExprs(ctx *plancontext.PlanningContext, op Operator) sqlparser.SelectExprs { + columns := op.GetColumns(ctx) + selExprs := slice.Map(columns, func(from *sqlparser.AliasedExpr) sqlparser.SelectExpr { + return from + }) + return selExprs +} diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 7e9f2d71a71..12b70d3e4ef 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -25,8 +25,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -34,7 +32,7 @@ import ( // Projection is used when we need to evaluate expressions on the vtgate // It uses the evalengine to accomplish its goal type Projection struct { - Source ops.Operator + Source Operator // Columns contain the expressions as viewed from the outside of this operator Columns ProjCols @@ -128,7 +126,7 @@ func newProjExprWithInner(ae *sqlparser.AliasedExpr, in sqlparser.Expr) *ProjExp } } -func newAliasedProjection(src ops.Operator) *Projection { +func newAliasedProjection(src Operator) *Projection { return &Projection{ Source: src, Columns: AliasedProjections{}, @@ -194,22 +192,19 @@ var _ selectExpressions = (*Projection)(nil) // createSimpleProjection returns a projection where all columns are offsets. // used to change the name and order of the columns in the final output -func createSimpleProjection(ctx *plancontext.PlanningContext, qp *QueryProjection, src ops.Operator) (*Projection, error) { +func createSimpleProjection(ctx *plancontext.PlanningContext, qp *QueryProjection, src Operator) *Projection { p := newAliasedProjection(src) for _, e := range qp.SelectExprs { ae, err := e.GetAliasedExpr() if err != nil { - return nil, err + panic(err) } offset := p.Source.AddColumn(ctx, true, false, ae) expr := newProjExpr(ae) expr.Info = Offset(offset) - _, err = p.addProjExpr(expr) - if err != nil { - return nil, err - } + p.addProjExpr(expr) } - return p, nil + return p } // canPush returns false if the projection has subquery expressions in it and the subqueries have not yet @@ -263,57 +258,45 @@ func (p *Projection) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Ex return -1 } -func (p *Projection) addProjExpr(pe ...*ProjExpr) (int, error) { +func (p *Projection) addProjExpr(pe ...*ProjExpr) int { ap, err := p.GetAliasedProjections() if err != nil { - return 0, err + panic(err) } offset := len(ap) ap = append(ap, pe...) p.Columns = ap - return offset, nil + return offset } -func (p *Projection) addUnexploredExpr(ae *sqlparser.AliasedExpr, e sqlparser.Expr) (int, error) { +func (p *Projection) addUnexploredExpr(ae *sqlparser.AliasedExpr, e sqlparser.Expr) int { return p.addProjExpr(newProjExprWithInner(ae, e)) } -func (p *Projection) addSubqueryExpr(ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) error { +func (p *Projection) addSubqueryExpr(ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) { pe := newProjExprWithInner(ae, expr) pe.Info = SubQueryExpression(sqs) - _, err := p.addProjExpr(pe) - return err + _ = p.addProjExpr(pe) } func (p *Projection) addColumnWithoutPushing(ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, _ bool) int { - column, err := p.addColumn(ctx, true, false, expr, false) - if err != nil { - panic(err) - } - return column + return p.addColumn(ctx, true, false, expr, false) } func (p *Projection) addColumnsWithoutPushing(ctx *plancontext.PlanningContext, reuse bool, _ []bool, exprs []*sqlparser.AliasedExpr) []int { offsets := make([]int, len(exprs)) for idx, expr := range exprs { - offset, err := p.addColumn(ctx, reuse, false, expr, false) - if err != nil { - panic(err) - } + offset := p.addColumn(ctx, reuse, false, expr, false) offsets[idx] = offset } return offsets } func (p *Projection) AddColumn(ctx *plancontext.PlanningContext, reuse bool, addToGroupBy bool, ae *sqlparser.AliasedExpr) int { - column, err := p.addColumn(ctx, reuse, addToGroupBy, ae, true) - if err != nil { - panic(err) - } - return column + return p.addColumn(ctx, reuse, addToGroupBy, ae, true) } func (p *Projection) addColumn( @@ -322,13 +305,13 @@ func (p *Projection) addColumn( addToGroupBy bool, ae *sqlparser.AliasedExpr, push bool, -) (int, error) { +) int { expr := p.DT.RewriteExpression(ctx, ae.Expr) if reuse { offset := p.FindCol(ctx, expr, false) if offset >= 0 { - return offset, nil + return offset } } @@ -337,7 +320,7 @@ func (p *Projection) addColumn( if ok { cols, ok := p.Columns.(AliasedProjections) if !ok { - return 0, vterrors.VT09015() + panic(vterrors.VT09015()) } for _, projExpr := range cols { if ctx.SemTable.EqualsExprWithDeps(ws.Expr, projExpr.ColExpr) { @@ -364,7 +347,7 @@ func (po Offset) expr() {} func (po *EvalEngine) expr() {} func (po SubQueryExpression) expr() {} -func (p *Projection) Clone(inputs []ops.Operator) ops.Operator { +func (p *Projection) Clone(inputs []Operator) Operator { return &Projection{ Source: inputs[0], Columns: p.Columns, // TODO don't think we need to deep clone here @@ -373,15 +356,15 @@ func (p *Projection) Clone(inputs []ops.Operator) ops.Operator { } } -func (p *Projection) Inputs() []ops.Operator { - return []ops.Operator{p.Source} +func (p *Projection) Inputs() []Operator { + return []Operator{p.Source} } -func (p *Projection) SetInputs(operators []ops.Operator) { +func (p *Projection) SetInputs(operators []Operator) { p.Source = operators[0] } -func (p *Projection) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (p *Projection) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { // we just pass through the predicate to our source p.Source = p.Source.AddPredicate(ctx, expr) return p @@ -412,7 +395,7 @@ func (p *Projection) GetSelectExprs(*plancontext.PlanningContext) sqlparser.Sele } } -func (p *Projection) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (p *Projection) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return p.Source.GetOrdering(ctx) } @@ -454,10 +437,10 @@ func (p *Projection) ShortDescription() string { return strings.Join(result, ", ") } -func (p *Projection) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *rewrite.ApplyResult, error) { +func (p *Projection) Compact(ctx *plancontext.PlanningContext) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } // for projections that are not derived tables, we can check if it is safe to remove or not @@ -471,7 +454,7 @@ func (p *Projection) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *r } if !needed { - return p.Source, rewrite.NewTree("removed projection only passing through the input"), nil + return p.Source, Rewrote("removed projection only passing through the input") } switch src := p.Source.(type) { @@ -480,13 +463,13 @@ func (p *Projection) Compact(ctx *plancontext.PlanningContext) (ops.Operator, *r case *ApplyJoin: return p.compactWithJoin(ctx, src) } - return p, rewrite.SameTree, nil + return p, NoRewrite } -func (p *Projection) compactWithJoin(ctx *plancontext.PlanningContext, join *ApplyJoin) (ops.Operator, *rewrite.ApplyResult, error) { +func (p *Projection) compactWithJoin(ctx *plancontext.PlanningContext, join *ApplyJoin) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } var newColumns []int @@ -499,49 +482,46 @@ func (p *Projection) compactWithJoin(ctx *plancontext.PlanningContext, join *App case nil: if !ctx.SemTable.EqualsExprWithDeps(col.EvalExpr, col.ColExpr) { // the inner expression is different from what we are presenting to the outside - this means we need to evaluate - return p, rewrite.SameTree, nil + return p, NoRewrite } offset := slices.IndexFunc(join.JoinColumns, func(jc JoinColumn) bool { - return ctx.SemTable.EqualsExprWithDeps(jc.Original.Expr, col.ColExpr) + return ctx.SemTable.EqualsExprWithDeps(jc.Original, col.ColExpr) }) if offset < 0 { - return p, rewrite.SameTree, nil + return p, NoRewrite } if len(join.Columns) > 0 { newColumns = append(newColumns, join.Columns[offset]) } newColumnsAST = append(newColumnsAST, join.JoinColumns[offset]) default: - return p, rewrite.SameTree, nil + return p, NoRewrite } } join.Columns = newColumns join.JoinColumns = newColumnsAST - return join, rewrite.NewTree("remove projection from before join"), nil + return join, Rewrote("remove projection from before join") } -func (p *Projection) compactWithRoute(ctx *plancontext.PlanningContext, rb *Route) (ops.Operator, *rewrite.ApplyResult, error) { +func (p *Projection) compactWithRoute(ctx *plancontext.PlanningContext, rb *Route) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } for i, col := range ap { offset, ok := col.Info.(Offset) if !ok || int(offset) != i { - return p, rewrite.SameTree, nil + return p, NoRewrite } } columns := rb.GetColumns(ctx) - if err != nil { - return nil, nil, err - } if len(columns) == len(ap) { - return rb, rewrite.NewTree("remove projection from before route"), nil + return rb, Rewrote("remove projection from before route") } rb.ResultColumns = len(columns) - return rb, rewrite.SameTree, nil + return rb, NoRewrite } // needsEvaluation finds the expression given by this argument and checks if the inside and outside expressions match @@ -561,7 +541,7 @@ func (p *Projection) needsEvaluation(ctx *plancontext.PlanningContext, e sqlpars return false } -func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) Operator { ap, err := p.GetAliasedProjections() if err != nil { panic(err) diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index ab140faf9b9..0994ee4402a 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -21,8 +21,6 @@ import ( "io" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -35,26 +33,20 @@ type ( } ) -func planQuery(ctx *plancontext.PlanningContext, root ops.Operator) (output ops.Operator, err error) { +func planQuery(ctx *plancontext.PlanningContext, root Operator) (output Operator, err error) { output, err = runPhases(ctx, root) if err != nil { return nil, err } - output, err = planOffsets(ctx, output) - if err != nil { - return nil, err - } + output = planOffsets(ctx, output) - if rewrite.DebugOperatorTree { + if DebugOperatorTree { fmt.Println("After offset planning:") - fmt.Println(ops.ToTree(output)) + fmt.Println(ToTree(output)) } - output, err = compact(ctx, output) - if err != nil { - return nil, err - } + output = compact(ctx, output) return addTruncationOrProjectionToReturnOutput(ctx, root, output) } @@ -63,17 +55,17 @@ func planQuery(ctx *plancontext.PlanningContext, root ops.Operator) (output ops. // If we can push it under a route - done. // If we can't, we will instead expand the Horizon into // smaller operators and try to push these down as far as possible -func runPhases(ctx *plancontext.PlanningContext, root ops.Operator) (op ops.Operator, err error) { +func runPhases(ctx *plancontext.PlanningContext, root Operator) (op Operator, err error) { op = root p := phaser{} for phase := p.next(ctx); phase != DONE; phase = p.next(ctx) { ctx.CurrentPhase = int(phase) - if rewrite.DebugOperatorTree { + if DebugOperatorTree { fmt.Printf("PHASE: %s\n", phase.String()) } - op, err = phase.act(ctx, op) + op = phase.act(ctx, op) if err != nil { return nil, err } @@ -83,17 +75,17 @@ func runPhases(ctx *plancontext.PlanningContext, root ops.Operator) (op ops.Oper return nil, err } - op, err = compact(ctx, op) + op = compact(ctx, op) if err != nil { return nil, err } } - return addGroupByOnRHSOfJoin(op) + return addGroupByOnRHSOfJoin(op), nil } -func runRewriters(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Operator, error) { - visitor := func(in ops.Operator, _ semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func runRewriters(ctx *plancontext.PlanningContext, root Operator) (Operator, error) { + visitor := func(in Operator, _ semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { switch in := in.(type) { case *Horizon: return pushOrExpandHorizon(ctx, in) @@ -120,23 +112,23 @@ func runRewriters(ctx *plancontext.PlanningContext, root ops.Operator) (ops.Oper case *LockAndComment: return pushLockAndComment(in) default: - return in, rewrite.SameTree, nil + return in, NoRewrite } } - return rewrite.FixedPointBottomUp(root, TableID, visitor, stopAtRoute) + return FixedPointBottomUp(root, TableID, visitor, stopAtRoute), nil } -func pushLockAndComment(l *LockAndComment) (ops.Operator, *rewrite.ApplyResult, error) { +func pushLockAndComment(l *LockAndComment) (Operator, *ApplyResult) { switch src := l.Source.(type) { case *Horizon, *QueryGraph: // we want to wait until the horizons have been pushed under a route or expanded // that way we know that we've replaced the QueryGraphs with Routes - return l, rewrite.SameTree, nil + return l, NoRewrite case *Route: src.Comments = l.Comments src.Lock = l.Lock - return src, rewrite.NewTree("put lock and comment into route"), nil + return src, Rewrote("put lock and comment into route") default: inputs := src.Inputs() for i, op := range inputs { @@ -147,23 +139,20 @@ func pushLockAndComment(l *LockAndComment) (ops.Operator, *rewrite.ApplyResult, } } src.SetInputs(inputs) - return src, rewrite.NewTree("pushed down lock and comments"), nil + return src, Rewrote("pushed down lock and comments") } } -func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (ops.Operator, *rewrite.ApplyResult, error) { +func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (Operator, *ApplyResult) { if in.IsDerived() { - newOp, result, err := pushDerived(ctx, in) - if err != nil { - return nil, nil, err - } - if result != rewrite.SameTree { - return newOp, result, nil + newOp, result := pushDerived(ctx, in) + if result != NoRewrite { + return newOp, result } } if !reachedPhase(ctx, initialPlanning) { - return in, rewrite.SameTree, nil + return in, NoRewrite } if ctx.SemTable.QuerySignature.SubQueries { @@ -172,15 +161,12 @@ func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (ops.Ope rb, isRoute := in.src().(*Route) if isRoute && rb.IsSingleShard() { - return rewrite.Swap(in, rb, "push horizon into route") + return Swap(in, rb, "push horizon into route") } sel, isSel := in.selectStatement().(*sqlparser.Select) - qp, err := in.getQP(ctx) - if err != nil { - return nil, nil, err - } + qp := in.getQP(ctx) needsOrdering := len(qp.OrderExprs) > 0 hasHaving := isSel && sel.Having != nil @@ -193,7 +179,7 @@ func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (ops.Ope in.selectStatement().GetLimit() == nil if canPush { - return rewrite.Swap(in, rb, "push horizon into route") + return Swap(in, rb, "push horizon into route") } return expandHorizon(ctx, in) @@ -202,42 +188,42 @@ func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (ops.Ope func tryPushProjection( ctx *plancontext.PlanningContext, p *Projection, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { switch src := p.Source.(type) { case *Route: - return rewrite.Swap(p, src, "push projection under route") + return Swap(p, src, "push projection under route") case *ApplyJoin: if p.FromAggr || !p.canPush(ctx) { - return p, rewrite.SameTree, nil + return p, NoRewrite } return pushProjectionInApplyJoin(ctx, p, src) case *Vindex: if !p.canPush(ctx) { - return p, rewrite.SameTree, nil + return p, NoRewrite } return pushProjectionInVindex(ctx, p, src) case *SubQueryContainer: if !p.canPush(ctx) { - return p, rewrite.SameTree, nil + return p, NoRewrite } return pushProjectionToOuterContainer(ctx, p, src) case *SubQuery: return pushProjectionToOuter(ctx, p, src) case *Limit: - return rewrite.Swap(p, src, "push projection under limit") + return Swap(p, src, "push projection under limit") default: - return p, rewrite.SameTree, nil + return p, NoRewrite } } -func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq *SubQuery) (ops.Operator, *rewrite.ApplyResult, error) { +func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq *SubQuery) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } if !reachedPhase(ctx, subquerySettling) || err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } outer := TableID(sq.Outer) @@ -248,7 +234,7 @@ func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq * } if !ctx.SemTable.RecursiveDeps(pe.EvalExpr).IsSolvedBy(outer) { - return p, rewrite.SameTree, nil + return p, NoRewrite } se, ok := pe.Info.(SubQueryExpression) @@ -258,22 +244,22 @@ func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq * } // all projections can be pushed to the outer sq.Outer, p.Source = p, sq.Outer - return sq, rewrite.NewTree("push projection into outer side of subquery"), nil + return sq, Rewrote("push projection into outer side of subquery") } func pushProjectionInVindex( ctx *plancontext.PlanningContext, p *Projection, src *Vindex, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return nil, nil, err + panic(err) } for _, pe := range ap { src.AddColumn(ctx, true, false, aeWrap(pe.EvalExpr)) } - return src, rewrite.NewTree("push projection into vindex"), nil + return src, Rewrote("push projection into vindex") } func (p *projector) add(pe *ProjExpr, col *sqlparser.IdentifierCI) { @@ -291,11 +277,11 @@ func pushProjectionInApplyJoin( ctx *plancontext.PlanningContext, p *Projection, src *ApplyJoin, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if src.LeftJoin || err != nil { // we can't push down expression evaluation to the rhs if we are not sure if it will even be executed - return p, rewrite.SameTree, nil + return p, NoRewrite } lhs, rhs := &projector{}, &projector{} if p.DT != nil && len(p.DT.Columns) > 0 { @@ -309,31 +295,18 @@ func pushProjectionInApplyJoin( if p.DT != nil && idx < len(p.DT.Columns) { col = &p.DT.Columns[idx] } - err := splitProjectionAcrossJoin(ctx, src, lhs, rhs, pe, col) - if err != nil { - return nil, nil, err - } + splitProjectionAcrossJoin(ctx, src, lhs, rhs, pe, col) } if p.isDerived() { - err := exposeColumnsThroughDerivedTable(ctx, p, src, lhs) - if err != nil { - return nil, nil, err - } + exposeColumnsThroughDerivedTable(ctx, p, src, lhs) } // Create and update the Projection operators for the left and right children, if needed. - src.LHS, err = createProjectionWithTheseColumns(ctx, src.LHS, lhs, p.DT) - if err != nil { - return nil, nil, err - } + src.LHS = createProjectionWithTheseColumns(ctx, src.LHS, lhs, p.DT) + src.RHS = createProjectionWithTheseColumns(ctx, src.RHS, rhs, p.DT) - src.RHS, err = createProjectionWithTheseColumns(ctx, src.RHS, rhs, p.DT) - if err != nil { - return nil, nil, err - } - - return src, rewrite.NewTree("split projection to either side of join"), nil + return src, Rewrote("split projection to either side of join") } // splitProjectionAcrossJoin creates JoinPredicates for all projections, @@ -344,21 +317,16 @@ func splitProjectionAcrossJoin( lhs, rhs *projector, pe *ProjExpr, colAlias *sqlparser.IdentifierCI, -) error { +) { // Check if the current expression can reuse an existing column in the ApplyJoin. if _, found := canReuseColumn(ctx, join.JoinColumns, pe.EvalExpr, joinColumnToExpr); found { - return nil - } - - col, err := splitUnexploredExpression(ctx, join, lhs, rhs, pe, colAlias) - if err != nil { - return err + return } // Add the new JoinColumn to the ApplyJoin's JoinPredicates. - join.JoinColumns = append(join.JoinColumns, col) - return nil + join.JoinColumns = append(join.JoinColumns, + splitUnexploredExpression(ctx, join, lhs, rhs, pe, colAlias)) } func splitUnexploredExpression( @@ -367,12 +335,9 @@ func splitUnexploredExpression( lhs, rhs *projector, pe *ProjExpr, colAlias *sqlparser.IdentifierCI, -) (JoinColumn, error) { +) JoinColumn { // Get a JoinColumn for the current expression. - col, err := join.getJoinColumnFor(ctx, pe.Original, pe.ColExpr, false) - if err != nil { - return JoinColumn{}, err - } + col := join.getJoinColumnFor(ctx, pe.Original, pe.ColExpr, false) // Update the left and right child columns and names based on the JoinColumn type. switch { @@ -395,7 +360,7 @@ func splitUnexploredExpression( innerPE.Info = pe.Info rhs.add(innerPE, colAlias) } - return col, nil + return col } // exposeColumnsThroughDerivedTable rewrites expressions within a join that is inside a derived table @@ -410,25 +375,25 @@ func splitUnexploredExpression( // The function iterates through each join predicate, rewriting the expressions in the predicate's // LHS expressions to include the derived table. This allows the expressions to be accessed outside // the derived table. -func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Projection, src *ApplyJoin, lhs *projector) error { +func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Projection, src *ApplyJoin, lhs *projector) { derivedTbl, err := ctx.SemTable.TableInfoFor(p.DT.TableID) if err != nil { - return err + panic(err) } derivedTblName, err := derivedTbl.Name() if err != nil { - return err + panic(err) } for _, predicate := range src.JoinPredicates { for idx, bve := range predicate.LHSExprs { expr := bve.Expr tbl, err := ctx.SemTable.TableInfoForExpr(expr) if err != nil { - return err + panic(err) } tblName, err := tbl.Name() if err != nil { - return err + panic(err) } expr = semantics.RewriteDerivedTableExpression(expr, derivedTbl) @@ -445,7 +410,6 @@ func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Proje lhs.add(projExpr, colAlias) } } - return nil } // prefixColNames adds qualifier prefixes to all ColName:s. @@ -462,17 +426,14 @@ func prefixColNames(ctx *plancontext.PlanningContext, tblName sqlparser.TableNam func createProjectionWithTheseColumns( ctx *plancontext.PlanningContext, - src ops.Operator, + src Operator, p *projector, dt *DerivedTable, -) (ops.Operator, error) { +) Operator { if len(p.columns) == 0 { - return src, nil - } - proj, err := createProjection(ctx, src) - if err != nil { - return nil, err + return src } + proj := createProjection(ctx, src) proj.Columns = AliasedProjections(p.columns) if dt != nil { kopy := *dt @@ -480,42 +441,42 @@ func createProjectionWithTheseColumns( proj.DT = &kopy } - return proj, nil + return proj } -func tryPushLimit(in *Limit) (ops.Operator, *rewrite.ApplyResult, error) { +func tryPushLimit(in *Limit) (Operator, *ApplyResult) { switch src := in.Source.(type) { case *Route: return tryPushingDownLimitInRoute(in, src) case *Aggregator: - return in, rewrite.SameTree, nil + return in, NoRewrite default: return setUpperLimit(in) } } -func tryPushingDownLimitInRoute(in *Limit, src *Route) (ops.Operator, *rewrite.ApplyResult, error) { +func tryPushingDownLimitInRoute(in *Limit, src *Route) (Operator, *ApplyResult) { if src.IsSingleShard() { - return rewrite.Swap(in, src, "push limit under route") + return Swap(in, src, "push limit under route") } return setUpperLimit(in) } -func setUpperLimit(in *Limit) (ops.Operator, *rewrite.ApplyResult, error) { +func setUpperLimit(in *Limit) (Operator, *ApplyResult) { if in.Pushed { - return in, rewrite.SameTree, nil + return in, NoRewrite } in.Pushed = true - visitor := func(op ops.Operator, _ semantics.TableSet, _ bool) (ops.Operator, *rewrite.ApplyResult, error) { - return op, rewrite.SameTree, nil + visitor := func(op Operator, _ semantics.TableSet, _ bool) (Operator, *ApplyResult) { + return op, NoRewrite } - var result *rewrite.ApplyResult - shouldVisit := func(op ops.Operator) rewrite.VisitRule { + var result *ApplyResult + shouldVisit := func(op Operator) VisitRule { switch op := op.(type) { case *Join, *ApplyJoin, *SubQueryContainer, *SubQuery: // we can't push limits down on either side - return rewrite.SkipChildren + return SkipChildren case *Route: newSrc := &Limit{ Source: op.Source, @@ -523,48 +484,46 @@ func setUpperLimit(in *Limit) (ops.Operator, *rewrite.ApplyResult, error) { Pushed: false, } op.Source = newSrc - result = result.Merge(rewrite.NewTree("push limit under route")) - return rewrite.SkipChildren + result = result.Merge(Rewrote("push limit under route")) + return SkipChildren default: - return rewrite.VisitChildren + return VisitChildren } } - _, err := rewrite.TopDown(in.Source, TableID, visitor, shouldVisit) - if err != nil { - return nil, nil, err - } - return in, result, nil + TopDown(in.Source, TableID, visitor, shouldVisit) + + return in, result } -func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operator, *rewrite.ApplyResult, error) { +func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (Operator, *ApplyResult) { switch src := in.Source.(type) { case *Route: - return rewrite.Swap(in, src, "push ordering under route") + return Swap(in, src, "push ordering under route") case *Filter: - return rewrite.Swap(in, src, "push ordering under filter") + return Swap(in, src, "push ordering under filter") case *ApplyJoin: if canPushLeft(ctx, src, in.Order) { // ApplyJoin is stable in regard to the columns coming from the LHS, // so if all the ordering columns come from the LHS, we can push down the Ordering there src.LHS, in.Source = in, src.LHS - return src, rewrite.NewTree("push down ordering on the LHS of a join"), nil + return src, Rewrote("push down ordering on the LHS of a join") } case *Ordering: // we'll just remove the order underneath. The top order replaces whatever was incoming in.Source = src.Source - return in, rewrite.NewTree("remove double ordering"), nil + return in, Rewrote("remove double ordering") case *Projection: // we can move ordering under a projection if it's not introducing a column we're sorting by for _, by := range in.Order { if !fetchByOffset(by.SimplifiedExpr) { - return in, rewrite.SameTree, nil + return in, NoRewrite } } - return rewrite.Swap(in, src, "push ordering under projection") + return Swap(in, src, "push ordering under projection") case *Aggregator: if !src.QP.AlignGroupByAndOrderBy(ctx) && !overlaps(ctx, in.Order, src.Grouping) { - return in, rewrite.SameTree, nil + return in, NoRewrite } return pushOrderingUnderAggr(ctx, in, src) @@ -573,26 +532,26 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (ops.Operat for _, order := range in.Order { deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) if !deps.IsSolvedBy(outerTableID) { - return in, rewrite.SameTree, nil + return in, NoRewrite } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push ordering into outer side of subquery"), nil + return src, Rewrote("push ordering into outer side of subquery") case *SubQuery: outerTableID := TableID(src.Outer) for _, order := range in.Order { deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) if !deps.IsSolvedBy(outerTableID) { - return in, rewrite.SameTree, nil + return in, NoRewrite } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push ordering into outer side of subquery"), nil + return src, Rewrote("push ordering into outer side of subquery") } - return in, rewrite.SameTree, nil + return in, NoRewrite } -func overlaps(ctx *plancontext.PlanningContext, order []ops.OrderBy, grouping []GroupBy) bool { +func overlaps(ctx *plancontext.PlanningContext, order []OrderBy, grouping []GroupBy) bool { ordering: for _, orderBy := range order { for _, groupBy := range grouping { @@ -606,13 +565,13 @@ ordering: return true } -func pushOrderingUnderAggr(ctx *plancontext.PlanningContext, order *Ordering, aggregator *Aggregator) (ops.Operator, *rewrite.ApplyResult, error) { +func pushOrderingUnderAggr(ctx *plancontext.PlanningContext, order *Ordering, aggregator *Aggregator) (Operator, *ApplyResult) { // If Aggregator is a derived table, then we should rewrite the ordering before pushing. if aggregator.isDerived() { for idx, orderExpr := range order.Order { ti, err := ctx.SemTable.TableInfoFor(aggregator.DT.TableID) if err != nil { - return nil, nil, err + panic(err) } newOrderExpr := orderExpr.Map(func(expr sqlparser.Expr) sqlparser.Expr { return semantics.RewriteDerivedTableExpression(expr, ti) @@ -666,12 +625,12 @@ func pushOrderingUnderAggr(ctx *plancontext.PlanningContext, order *Ordering, ag order.Source = aggrSource.Source aggrSource.Source = nil // removing from plan tree aggregator.Source = order - return aggregator, rewrite.NewTree("push ordering under aggregation, removing extra ordering"), nil + return aggregator, Rewrote("push ordering under aggregation, removing extra ordering") } - return rewrite.Swap(order, aggregator, "push ordering under aggregation") + return Swap(order, aggregator, "push ordering under aggregation") } -func canPushLeft(ctx *plancontext.PlanningContext, aj *ApplyJoin, order []ops.OrderBy) bool { +func canPushLeft(ctx *plancontext.PlanningContext, aj *ApplyJoin, order []OrderBy) bool { lhs := TableID(aj.LHS) for _, order := range order { deps := ctx.SemTable.DirectDeps(order.Inner.Expr) @@ -682,7 +641,7 @@ func canPushLeft(ctx *plancontext.PlanningContext, aj *ApplyJoin, order []ops.Or return true } -func isOuterTable(op ops.Operator, ts semantics.TableSet) bool { +func isOuterTable(op Operator, ts semantics.TableSet) bool { aj, ok := op.(*ApplyJoin) if ok && aj.LeftJoin && TableID(aj.RHS).IsOverlapping(ts) { return true @@ -697,39 +656,35 @@ func isOuterTable(op ops.Operator, ts semantics.TableSet) bool { return false } -func tryPushFilter(ctx *plancontext.PlanningContext, in *Filter) (ops.Operator, *rewrite.ApplyResult, error) { +func tryPushFilter(ctx *plancontext.PlanningContext, in *Filter) (Operator, *ApplyResult) { switch src := in.Source.(type) { case *Projection: return pushFilterUnderProjection(ctx, in, src) case *Route: for _, pred := range in.Predicates { - var err error deps := ctx.SemTable.RecursiveDeps(pred) if !isOuterTable(src, deps) { // we can only update based on predicates on inner tables - src.Routing, err = src.Routing.updateRoutingLogic(ctx, pred) - if err != nil { - return nil, nil, err - } + src.Routing = src.Routing.updateRoutingLogic(ctx, pred) } } - return rewrite.Swap(in, src, "push filter into Route") + return Swap(in, src, "push filter into Route") case *SubQuery: outerTableID := TableID(src.Outer) for _, pred := range in.Predicates { deps := ctx.SemTable.RecursiveDeps(pred) if !deps.IsSolvedBy(outerTableID) { - return in, rewrite.SameTree, nil + return in, NoRewrite } } src.Outer, in.Source = in, src.Outer - return src, rewrite.NewTree("push filter to outer query in subquery container"), nil + return src, Rewrote("push filter to outer query in subquery container") } - return in, rewrite.SameTree, nil + return in, NoRewrite } -func pushFilterUnderProjection(ctx *plancontext.PlanningContext, filter *Filter, projection *Projection) (ops.Operator, *rewrite.ApplyResult, error) { +func pushFilterUnderProjection(ctx *plancontext.PlanningContext, filter *Filter, projection *Projection) (Operator, *ApplyResult) { for _, p := range filter.Predicates { cantPush := false _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { @@ -746,64 +701,64 @@ func pushFilterUnderProjection(ctx *plancontext.PlanningContext, filter *Filter, }, p) if cantPush { - return filter, rewrite.SameTree, nil + return filter, NoRewrite } } - return rewrite.Swap(filter, projection, "push filter under projection") + return Swap(filter, projection, "push filter under projection") } -func tryPushDistinct(in *Distinct) (ops.Operator, *rewrite.ApplyResult, error) { +func tryPushDistinct(in *Distinct) (Operator, *ApplyResult) { if in.Required && in.PushedPerformance { - return in, rewrite.SameTree, nil + return in, NoRewrite } switch src := in.Source.(type) { case *Route: if isDistinct(src.Source) && src.IsSingleShard() { - return src, rewrite.NewTree("distinct not needed"), nil + return src, Rewrote("distinct not needed") } if src.IsSingleShard() || !in.Required { - return rewrite.Swap(in, src, "push distinct under route") + return Swap(in, src, "push distinct under route") } if isDistinct(src.Source) { - return in, rewrite.SameTree, nil + return in, NoRewrite } src.Source = &Distinct{Source: src.Source} in.PushedPerformance = true - return in, rewrite.NewTree("added distinct under route - kept original"), nil + return in, Rewrote("added distinct under route - kept original") case *Distinct: src.Required = false src.PushedPerformance = false - return src, rewrite.NewTree("remove double distinct"), nil + return src, Rewrote("remove double distinct") case *Union: for i := range src.Sources { src.Sources[i] = &Distinct{Source: src.Sources[i]} } in.PushedPerformance = true - return in, rewrite.NewTree("push down distinct under union"), nil + return in, Rewrote("push down distinct under union") case *ApplyJoin: src.LHS = &Distinct{Source: src.LHS} src.RHS = &Distinct{Source: src.RHS} in.PushedPerformance = true if in.Required { - return in, rewrite.NewTree("push distinct under join - kept original"), nil + return in, Rewrote("push distinct under join - kept original") } - return in.Source, rewrite.NewTree("push distinct under join"), nil + return in.Source, Rewrote("push distinct under join") case *Ordering: in.Source = src.Source - return in, rewrite.NewTree("remove ordering under distinct"), nil + return in, Rewrote("remove ordering under distinct") } - return in, rewrite.SameTree, nil + return in, NoRewrite } -func isDistinct(op ops.Operator) bool { +func isDistinct(op Operator) bool { switch op := op.(type) { case *Distinct: return true @@ -818,44 +773,40 @@ func isDistinct(op ops.Operator) bool { } } -func tryPushUnion(ctx *plancontext.PlanningContext, op *Union) (ops.Operator, *rewrite.ApplyResult, error) { - if res := compactUnion(op); res != rewrite.SameTree { - return op, res, nil +func tryPushUnion(ctx *plancontext.PlanningContext, op *Union) (Operator, *ApplyResult) { + if res := compactUnion(op); res != NoRewrite { + return op, res } - var sources []ops.Operator + var sources []Operator var selects []sqlparser.SelectExprs - var err error if op.distinct { - sources, selects, err = mergeUnionInputInAnyOrder(ctx, op) + sources, selects = mergeUnionInputInAnyOrder(ctx, op) } else { - sources, selects, err = mergeUnionInputsInOrder(ctx, op) - } - if err != nil { - return nil, nil, err + sources, selects = mergeUnionInputsInOrder(ctx, op) } if len(sources) == 1 { result := sources[0].(*Route) if result.IsSingleShard() || !op.distinct { - return result, rewrite.NewTree("push union under route"), nil + return result, Rewrote("push union under route") } return &Distinct{ Source: result, Required: true, - }, rewrite.NewTree("push union under route"), nil + }, Rewrote("push union under route") } if len(sources) == len(op.Sources) { - return op, rewrite.SameTree, nil + return op, NoRewrite } - return newUnion(sources, selects, op.unionColumns, op.distinct), rewrite.NewTree("merge union inputs"), nil + return newUnion(sources, selects, op.unionColumns, op.distinct), Rewrote("merge union inputs") } // addTruncationOrProjectionToReturnOutput uses the original Horizon to make sure that the output columns line up with what the user asked for -func addTruncationOrProjectionToReturnOutput(ctx *plancontext.PlanningContext, oldHorizon ops.Operator, output ops.Operator) (ops.Operator, error) { +func addTruncationOrProjectionToReturnOutput(ctx *plancontext.PlanningContext, oldHorizon Operator, output Operator) (Operator, error) { horizon, ok := oldHorizon.(*Horizon) if !ok { return output, nil @@ -871,20 +822,14 @@ func addTruncationOrProjectionToReturnOutput(ctx *plancontext.PlanningContext, o return output, nil } - qp, err := horizon.getQP(ctx) - if err != nil { - return nil, err - } - proj, err := createSimpleProjection(ctx, qp, output) - if err != nil { - return nil, err - } + qp := horizon.getQP(ctx) + proj := createSimpleProjection(ctx, qp, output) return proj, nil } -func stopAtRoute(operator ops.Operator) rewrite.VisitRule { +func stopAtRoute(operator Operator) VisitRule { _, isRoute := operator.(*Route) - return rewrite.VisitRule(!isRoute) + return VisitRule(!isRoute) } func aeWrap(e sqlparser.Expr) *sqlparser.AliasedExpr { diff --git a/go/vt/vtgate/planbuilder/operators/querygraph.go b/go/vt/vtgate/planbuilder/operators/querygraph.go index b0e6b4440be..bc731f29df6 100644 --- a/go/vt/vtgate/planbuilder/operators/querygraph.go +++ b/go/vt/vtgate/planbuilder/operators/querygraph.go @@ -20,7 +20,6 @@ import ( "strings" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -63,7 +62,7 @@ type ( } ) -var _ ops.Operator = (*QueryGraph)(nil) +var _ Operator = (*QueryGraph)(nil) // Introduces implements the tableIDIntroducer interface func (qg *QueryGraph) introducesTableID() semantics.TableSet { @@ -163,7 +162,7 @@ func (qg *QueryGraph) UnsolvedPredicates(_ *semantics.SemTable) []sqlparser.Expr } // Clone implements the Operator interface -func (qg *QueryGraph) Clone([]ops.Operator) ops.Operator { +func (qg *QueryGraph) Clone([]Operator) Operator { result := &QueryGraph{ Tables: nil, innerJoins: nil, @@ -176,11 +175,11 @@ func (qg *QueryGraph) Clone([]ops.Operator) ops.Operator { return result } -func (qg *QueryGraph) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (qg *QueryGraph) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -func (qg *QueryGraph) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (qg *QueryGraph) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { for _, e := range sqlparser.SplitAndExpression(nil, expr) { qg.collectPredicate(ctx, e) } diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index 1cef6706a9f..f9f6f7fa15d 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -28,7 +28,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -47,7 +46,7 @@ type ( HasAggr bool Distinct bool groupByExprs []GroupBy - OrderExprs []ops.OrderBy + OrderExprs []OrderBy HasStar bool // AddedColumn keeps a counter for expressions added to solve HAVING expressions the user is not selecting @@ -72,9 +71,6 @@ type ( // The index at which the user expects to see this column. Set to nil, if the user does not ask for it InnerIndex *int - // The original aliased expression that this group by is referring - aliasedExpr *sqlparser.AliasedExpr - // points to the column on the same aggregator ColOffset int WSOffset int @@ -127,11 +123,10 @@ func (aggr Aggr) GetTypeCollation(ctx *plancontext.PlanningContext) evalengine.T } // NewGroupBy creates a new group by from the given fields. -func NewGroupBy(inner, simplified sqlparser.Expr, aliasedExpr *sqlparser.AliasedExpr) GroupBy { +func NewGroupBy(inner, simplified sqlparser.Expr) GroupBy { return GroupBy{ Inner: inner, SimplifiedExpr: simplified, - aliasedExpr: aliasedExpr, ColOffset: -1, WSOffset: -1, } @@ -148,8 +143,8 @@ func NewAggr(opCode opcode.AggregateOpcode, f sqlparser.AggrFunc, original *sqlp } } -func (b GroupBy) AsOrderBy() ops.OrderBy { - return ops.OrderBy{ +func (b GroupBy) AsOrderBy() OrderBy { + return OrderBy{ Inner: &sqlparser.Order{ Expr: b.Inner, Direction: sqlparser.AscOrder, @@ -158,26 +153,6 @@ func (b GroupBy) AsOrderBy() ops.OrderBy { } } -func (b GroupBy) AsAliasedExpr() *sqlparser.AliasedExpr { - if b.aliasedExpr != nil { - return b.aliasedExpr - } - col, isColName := b.Inner.(*sqlparser.ColName) - if isColName && b.SimplifiedExpr != b.Inner { - return &sqlparser.AliasedExpr{ - Expr: b.SimplifiedExpr, - As: col.Name, - } - } - if !isColName && b.SimplifiedExpr != b.Inner { - panic("this should not happen - different inner and weighStringExpr and not a column alias") - } - - return &sqlparser.AliasedExpr{ - Expr: b.SimplifiedExpr, - } -} - // GetExpr returns the underlying sqlparser.Expr of our SelectExpr func (s SelectExpr) GetExpr() (sqlparser.Expr, error) { switch sel := s.Col.(type) { @@ -316,7 +291,7 @@ func containsAggr(e sqlparser.SQLNode) (hasAggr bool) { _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { switch node.(type) { case *sqlparser.Offset: - // offsets here indicate that a possible aggregation has already been handled by an input + // offsets here indicate that a possible aggregation has already been handled by an input, // so we don't need to worry about aggregation in the original return false, nil case sqlparser.AggrFunc: @@ -381,7 +356,7 @@ func (qp *QueryProjection) addOrderBy(ctx *plancontext.PlanningContext, orderBy if !es.add(ctx, simpleExpr) { continue } - qp.OrderExprs = append(qp.OrderExprs, ops.OrderBy{ + qp.OrderExprs = append(qp.OrderExprs, OrderBy{ Inner: sqlparser.CloneRefOfOrder(order), SimplifiedExpr: simpleExpr, }) @@ -436,7 +411,7 @@ func (qp *QueryProjection) calculateDistinct(ctx *plancontext.PlanningContext) e func (qp *QueryProjection) addGroupBy(ctx *plancontext.PlanningContext, groupBy sqlparser.GroupBy) error { es := &expressionSet{} for _, group := range groupBy { - selectExprIdx, aliasExpr := qp.FindSelectExprIndexForExpr(ctx, group) + selectExprIdx := qp.FindSelectExprIndexForExpr(ctx, group) simpleExpr, err := qp.GetSimplifiedExpr(ctx, group) if err != nil { return err @@ -450,7 +425,7 @@ func (qp *QueryProjection) addGroupBy(ctx *plancontext.PlanningContext, groupBy continue } - groupBy := NewGroupBy(group, simpleExpr, aliasExpr) + groupBy := NewGroupBy(group, simpleExpr) groupBy.InnerIndex = selectExprIdx qp.groupByExprs = append(qp.groupByExprs, groupBy) @@ -809,7 +784,7 @@ func createAggrFromAggrFunc(fnc sqlparser.AggrFunc, aliasedExpr *sqlparser.Alias // FindSelectExprIndexForExpr returns the index of the given expression in the select expressions, if it is part of it // returns -1 otherwise. -func (qp *QueryProjection) FindSelectExprIndexForExpr(ctx *plancontext.PlanningContext, expr sqlparser.Expr) (*int, *sqlparser.AliasedExpr) { +func (qp *QueryProjection) FindSelectExprIndexForExpr(ctx *plancontext.PlanningContext, expr sqlparser.Expr) *int { colExpr, isCol := expr.(*sqlparser.ColName) for idx, selectExpr := range qp.SelectExprs { @@ -820,14 +795,14 @@ func (qp *QueryProjection) FindSelectExprIndexForExpr(ctx *plancontext.PlanningC if isCol { isAliasExpr := aliasedExpr.As.NotEmpty() if isAliasExpr && colExpr.Name.Equal(aliasedExpr.As) { - return &idx, aliasedExpr + return &idx } } if ctx.SemTable.EqualsExprWithDeps(aliasedExpr.Expr, expr) { - return &idx, aliasedExpr + return &idx } } - return nil, nil + return nil } // OldAlignGroupByAndOrderBy TODO Remove once all of horizon planning is done on the operators @@ -920,7 +895,7 @@ func (qp *QueryProjection) GetColumnCount() int { func (qp *QueryProjection) orderByOverlapWithSelectExpr(ctx *plancontext.PlanningContext) bool { for _, expr := range qp.OrderExprs { - idx, _ := qp.FindSelectExprIndexForExpr(ctx, expr.SimplifiedExpr) + idx := qp.FindSelectExprIndexForExpr(ctx, expr.SimplifiedExpr) if idx != nil { return true } @@ -950,7 +925,7 @@ func (qp *QueryProjection) useGroupingOverDistinct(ctx *plancontext.PlanningCont if found != -1 { continue } - groupBy := NewGroupBy(ae.Expr, sExpr, ae) + groupBy := NewGroupBy(ae.Expr, sExpr) selectExprIdx := idx groupBy.InnerIndex = &selectExprIdx diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection_test.go b/go/vt/vtgate/planbuilder/operators/queryprojection_test.go index 7c92b716d7c..1319ad7f9f6 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection_test.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection_test.go @@ -23,7 +23,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -33,7 +32,7 @@ func TestQP(t *testing.T) { sql string expErr string - expOrder []ops.OrderBy + expOrder []OrderBy }{ { sql: "select * from user", @@ -46,20 +45,20 @@ func TestQP(t *testing.T) { }, { sql: "select 1, count(1) from user order by 1", - expOrder: []ops.OrderBy{ + expOrder: []OrderBy{ {Inner: &sqlparser.Order{Expr: sqlparser.NewIntLiteral("1")}, SimplifiedExpr: sqlparser.NewIntLiteral("1")}, }, }, { sql: "select id from user order by col, id, 1", - expOrder: []ops.OrderBy{ + expOrder: []OrderBy{ {Inner: &sqlparser.Order{Expr: sqlparser.NewColName("col")}, SimplifiedExpr: sqlparser.NewColName("col")}, {Inner: &sqlparser.Order{Expr: sqlparser.NewColName("id")}, SimplifiedExpr: sqlparser.NewColName("id")}, }, }, { sql: "SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name", // alias in order not supported - expOrder: []ops.OrderBy{ + expOrder: []OrderBy{ { Inner: &sqlparser.Order{Expr: sqlparser.NewColName("full_name")}, SimplifiedExpr: &sqlparser.FuncExpr{ diff --git a/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go b/go/vt/vtgate/planbuilder/operators/rewriters.go similarity index 67% rename from go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go rename to go/vt/vtgate/planbuilder/operators/rewriters.go index 1ecc0cd8e76..6a329860b4b 100644 --- a/go/vt/vtgate/planbuilder/operators/rewrite/rewriters.go +++ b/go/vt/vtgate/planbuilder/operators/rewriters.go @@ -14,27 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -package rewrite +package operators import ( "fmt" "slices" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/semantics" ) type ( // VisitF is the visitor that walks an operator tree VisitF func( - op ops.Operator, // op is the operator being visited + op Operator, // op is the operator being visited lhsTables semantics.TableSet, // lhsTables contains the TableSet for all table on the LHS of our parent isRoot bool, // isRoot will be true for the root of the operator tree - ) (ops.Operator, *ApplyResult, error) + ) (Operator, *ApplyResult) // ShouldVisit is used when we want to control which nodes and ancestors to visit and which to skip - ShouldVisit func(ops.Operator) VisitRule + ShouldVisit func(Operator) VisitRule // ApplyResult tracks modifications to node and expression trees. // Only return SameTree when it is acceptable to return the original @@ -52,7 +51,7 @@ type ( ) var ( - SameTree *ApplyResult = nil + NoRewrite *ApplyResult = nil ) const ( @@ -60,7 +59,7 @@ const ( SkipChildren VisitRule = false ) -func NewTree(message string) *ApplyResult { +func Rewrote(message string) *ApplyResult { if DebugOperatorTree { fmt.Println(">>>>>>>> " + message) } @@ -82,13 +81,13 @@ func (ar *ApplyResult) Changed() bool { } // Visit allows for the walking of the operator tree. If any error is returned, the walk is aborted -func Visit(root ops.Operator, visitor func(ops.Operator) error) error { - _, _, err := breakableTopDown(root, func(op ops.Operator) (ops.Operator, *ApplyResult, VisitRule, error) { +func Visit(root Operator, visitor func(Operator) error) error { + _, _, err := breakableTopDown(root, func(op Operator) (Operator, *ApplyResult, VisitRule, error) { err := visitor(op) if err != nil { - return nil, SameTree, SkipChildren, err + return nil, NoRewrite, SkipChildren, err } - return op, SameTree, VisitChildren, nil + return op, NoRewrite, VisitChildren, nil }) return err } @@ -97,16 +96,13 @@ func Visit(root ops.Operator, visitor func(ops.Operator) error) error { // the given operator tree from the bottom up. Each callback [f] returns a ApplyResult that is aggregated // into a final output indicating whether the operator tree was changed. func BottomUp( - root ops.Operator, - resolveID func(ops.Operator) semantics.TableSet, + root Operator, + resolveID func(Operator) semantics.TableSet, visit VisitF, shouldVisit ShouldVisit, -) (ops.Operator, error) { - op, _, err := bottomUp(root, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) - if err != nil { - return nil, err - } - return op, nil +) Operator { + op, _ := bottomUp(root, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) + return op } var DebugOperatorTree = false @@ -122,26 +118,23 @@ func EnableDebugPrinting() (reset func()) { // FixedPointBottomUp rewrites an operator tree much like BottomUp does, // but does the rewriting repeatedly, until a tree walk is done with no changes to the tree. func FixedPointBottomUp( - root ops.Operator, - resolveID func(ops.Operator) semantics.TableSet, + root Operator, + resolveID func(Operator) semantics.TableSet, visit VisitF, shouldVisit ShouldVisit, -) (op ops.Operator, err error) { +) (op Operator) { var id *ApplyResult op = root // will loop while the rewriting changes anything - for ok := true; ok; ok = id != SameTree { + for ok := true; ok; ok = id != NoRewrite { if DebugOperatorTree { - fmt.Println(ops.ToTree(op)) + fmt.Println(ToTree(op)) } // Continue the top-down rewriting process as long as changes were made during the last traversal - op, id, err = bottomUp(op, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) - if err != nil { - return nil, err - } + op, id = bottomUp(op, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) } - return op, nil + return op } // TopDown rewrites an operator tree from the bottom up. BottomUp applies a transformation function to @@ -155,31 +148,28 @@ func FixedPointBottomUp( // - shouldVisit: The ShouldVisit function to control which nodes and ancestors to visit and which to skip. // // Returns: -// - ops.Operator: The root of the (potentially) transformed operator tree. +// - Operator: The root of the (potentially) transformed operator tree. // - error: An error if any occurred during the traversal. func TopDown( - root ops.Operator, - resolveID func(ops.Operator) semantics.TableSet, + root Operator, + resolveID func(Operator) semantics.TableSet, visit VisitF, shouldVisit ShouldVisit, -) (op ops.Operator, err error) { - op, _, err = topDown(root, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) - if err != nil { - return nil, err - } +) Operator { + op, _ := topDown(root, semantics.EmptyTableSet(), resolveID, visit, shouldVisit, true) - return op, nil + return op } // Swap takes a tree like a->b->c and swaps `a` and `b`, so we end up with b->a->c -func Swap(parent, child ops.Operator, message string) (ops.Operator, *ApplyResult, error) { +func Swap(parent, child Operator, message string) (Operator, *ApplyResult) { c := child.Inputs() if len(c) != 1 { - return nil, nil, vterrors.VT13001("Swap can only be used on single input operators") + panic(vterrors.VT13001("Swap can only be used on single input operators")) } aInputs := slices.Clone(parent.Inputs()) - var tmp ops.Operator + var tmp Operator for i, in := range aInputs { if in == child { tmp = aInputs[i] @@ -188,30 +178,30 @@ func Swap(parent, child ops.Operator, message string) (ops.Operator, *ApplyResul } } if tmp == nil { - return nil, nil, vterrors.VT13001("Swap can only be used when the second argument is an input to the first") + panic(vterrors.VT13001("Swap can only be used when the second argument is an input to the first")) } - child.SetInputs([]ops.Operator{parent}) + child.SetInputs([]Operator{parent}) parent.SetInputs(aInputs) - return child, NewTree(message), nil + return child, Rewrote(message) } func bottomUp( - root ops.Operator, + root Operator, rootID semantics.TableSet, - resolveID func(ops.Operator) semantics.TableSet, + resolveID func(Operator) semantics.TableSet, rewriter VisitF, shouldVisit ShouldVisit, isRoot bool, -) (ops.Operator, *ApplyResult, error) { +) (Operator, *ApplyResult) { if shouldVisit != nil && !shouldVisit(root) { - return root, SameTree, nil + return root, NoRewrite } oldInputs := root.Inputs() var anythingChanged *ApplyResult - newInputs := make([]ops.Operator, len(oldInputs)) + newInputs := make([]Operator, len(oldInputs)) childID := rootID // noLHSTableSet is used to mark which operators that do not send data from the LHS to the RHS @@ -227,10 +217,7 @@ func bottomUp( if _, isUnion := root.(noLHSTableSet); !isUnion && i > 0 { childID = childID.Merge(resolveID(oldInputs[0])) } - in, changed, err := bottomUp(operator, childID, resolveID, rewriter, shouldVisit, false) - if err != nil { - return nil, nil, err - } + in, changed := bottomUp(operator, childID, resolveID, rewriter, shouldVisit, false) anythingChanged = anythingChanged.Merge(changed) newInputs[i] = in } @@ -239,18 +226,15 @@ func bottomUp( root = root.Clone(newInputs) } - newOp, treeIdentity, err := rewriter(root, rootID, isRoot) - if err != nil { - return nil, nil, err - } + newOp, treeIdentity := rewriter(root, rootID, isRoot) anythingChanged = anythingChanged.Merge(treeIdentity) - return newOp, anythingChanged, nil + return newOp, anythingChanged } func breakableTopDown( - in ops.Operator, - rewriter func(ops.Operator) (ops.Operator, *ApplyResult, VisitRule, error), -) (ops.Operator, *ApplyResult, error) { + in Operator, + rewriter func(Operator) (Operator, *ApplyResult, VisitRule, error), +) (Operator, *ApplyResult, error) { newOp, identity, visit, err := rewriter(in) if err != nil || visit == SkipChildren { return newOp, identity, err @@ -259,17 +243,17 @@ func breakableTopDown( var anythingChanged *ApplyResult oldInputs := newOp.Inputs() - newInputs := make([]ops.Operator, len(oldInputs)) + newInputs := make([]Operator, len(oldInputs)) for i, oldInput := range oldInputs { newInputs[i], identity, err = breakableTopDown(oldInput, rewriter) anythingChanged = anythingChanged.Merge(identity) if err != nil { - return nil, SameTree, err + return nil, NoRewrite, err } } if anythingChanged.Changed() { - return newOp, SameTree, nil + return newOp, NoRewrite, nil } return newOp.Clone(newInputs), anythingChanged, nil @@ -279,20 +263,17 @@ func breakableTopDown( // top down and applies the given transformation function. It also returns the ApplyResult // indicating whether the tree was changed func topDown( - root ops.Operator, + root Operator, rootID semantics.TableSet, - resolveID func(ops.Operator) semantics.TableSet, + resolveID func(Operator) semantics.TableSet, rewriter VisitF, shouldVisit ShouldVisit, isRoot bool, -) (ops.Operator, *ApplyResult, error) { - newOp, anythingChanged, err := rewriter(root, rootID, isRoot) - if err != nil { - return nil, nil, err - } +) (Operator, *ApplyResult) { + newOp, anythingChanged := rewriter(root, rootID, isRoot) if !shouldVisit(root) { - return newOp, anythingChanged, nil + return newOp, anythingChanged } if anythingChanged.Changed() { @@ -300,7 +281,7 @@ func topDown( } oldInputs := root.Inputs() - newInputs := make([]ops.Operator, len(oldInputs)) + newInputs := make([]Operator, len(oldInputs)) childID := rootID type noLHSTableSet interface{ NoLHSTableSet() } @@ -309,17 +290,14 @@ func topDown( if _, isUnion := root.(noLHSTableSet); !isUnion && i > 0 { childID = childID.Merge(resolveID(oldInputs[0])) } - in, changed, err := topDown(operator, childID, resolveID, rewriter, shouldVisit, false) - if err != nil { - return nil, nil, err - } + in, changed := topDown(operator, childID, resolveID, rewriter, shouldVisit, false) anythingChanged = anythingChanged.Merge(changed) newInputs[i] = in } - if anythingChanged != SameTree { - return root.Clone(newInputs), anythingChanged, nil + if anythingChanged != NoRewrite { + return root.Clone(newInputs), anythingChanged } - return root, SameTree, nil + return root, NoRewrite } diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go index acbc28553dd..d5eee19e5dd 100644 --- a/go/vt/vtgate/planbuilder/operators/route.go +++ b/go/vt/vtgate/planbuilder/operators/route.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -33,7 +32,7 @@ import ( type ( Route struct { - Source ops.Operator + Source Operator // Routes that have been merged into this one. MergedWith []*Route @@ -89,7 +88,7 @@ type ( Routing interface { // UpdateRoutingParams allows a Routing to control the routing params that will be used by the engine Route // OpCode is already set, and the default keyspace is set for read queries - UpdateRoutingParams(ctx *plancontext.PlanningContext, rp *engine.RoutingParameters) error + UpdateRoutingParams(ctx *plancontext.PlanningContext, rp *engine.RoutingParameters) // Clone returns a copy of the routing. Since we are trying different variation of merging, // one Routing can be used in different constellations. @@ -103,27 +102,27 @@ type ( // updateRoutingLogic updates the routing to take predicates into account. This can be used for routing // using vindexes or for figuring out which keyspace an information_schema query should be sent to. - updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) (Routing, error) + updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Routing } ) // UpdateRoutingLogic first checks if we are dealing with a predicate that -func UpdateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr, r Routing) (Routing, error) { +func UpdateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr, r Routing) Routing { ks := r.Keyspace() if ks == nil { var err error ks, err = ctx.VSchema.AnyKeyspace() if err != nil { - return nil, err + panic(err) } } nr := &NoneRouting{keyspace: ks} if isConstantFalse(expr) { - return nr, nil + return nr } - exit := func() (Routing, error) { + exit := func() Routing { return r.updateRoutingLogic(ctx, expr) } @@ -135,7 +134,7 @@ func UpdateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr, r if cmp.Operator != sqlparser.NullSafeEqualOp && (sqlparser.IsNull(cmp.Left) || sqlparser.IsNull(cmp.Right)) { // any comparison against a literal null, except a null safe equality (<=>), will return null - return nr, nil + return nr } tuples, ok := cmp.Right.(sqlparser.ValTuple) @@ -148,13 +147,13 @@ func UpdateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr, r for _, n := range tuples { // If any of the values in the tuple is a literal null, we know that this comparison will always return NULL if sqlparser.IsNull(n) { - return nr, nil + return nr } } case sqlparser.InOp: // WHERE col IN (null) if len(tuples) == 1 && sqlparser.IsNull(tuples[0]) { - return nr, nil + return nr } } @@ -189,7 +188,7 @@ func (r *Route) Cost() int { } // Clone implements the Operator interface -func (r *Route) Clone(inputs []ops.Operator) ops.Operator { +func (r *Route) Clone(inputs []Operator) Operator { cloneRoute := *r cloneRoute.Source = inputs[0] cloneRoute.Routing = r.Routing.Clone() @@ -197,12 +196,12 @@ func (r *Route) Clone(inputs []ops.Operator) ops.Operator { } // Inputs implements the Operator interface -func (r *Route) Inputs() []ops.Operator { - return []ops.Operator{r.Source} +func (r *Route) Inputs() []Operator { + return []Operator{r.Source} } // SetInputs implements the Operator interface -func (r *Route) SetInputs(ops []ops.Operator) { +func (r *Route) SetInputs(ops []Operator) { r.Source = ops[0] } @@ -357,7 +356,7 @@ func createRoute( ctx *plancontext.PlanningContext, queryTable *QueryTable, solves semantics.TableSet, -) (ops.Operator, error) { +) Operator { if queryTable.IsInfSchema { return createInfSchemaRoute(ctx, queryTable) } @@ -372,13 +371,13 @@ func findVSchemaTableAndCreateRoute( tableName sqlparser.TableName, solves semantics.TableSet, planAlternates bool, -) (*Route, error) { +) *Route { vschemaTable, _, _, _, target, err := ctx.VSchema.FindTableOrVindex(tableName) if target != nil { - return nil, vterrors.VT09017("SELECT with a target destination is not allowed") + panic(vterrors.VT09017("SELECT with a target destination is not allowed")) } if err != nil { - return nil, err + panic(err) } return createRouteFromVSchemaTable( @@ -397,7 +396,7 @@ func createRouteFromVSchemaTable( vschemaTable *vindexes.Table, solves semantics.TableSet, planAlternates bool, -) (*Route, error) { +) *Route { if vschemaTable.Name.String() != queryTable.Table.Name.String() { // we are dealing with a routed table queryTable = queryTable.Clone() @@ -405,7 +404,7 @@ func createRouteFromVSchemaTable( queryTable.Table.Name = vschemaTable.Name astTable, ok := queryTable.Alias.Expr.(sqlparser.TableName) if !ok { - return nil, vterrors.VT13001("a derived table should never be a routed table") + panic(vterrors.VT13001("a derived table should never be a routed table")) } realTableName := sqlparser.NewIdentifierCS(vschemaTable.Name.String()) astTable.Name = realTableName @@ -424,11 +423,7 @@ func createRouteFromVSchemaTable( // We create the appropiate Routing struct here, depending on the type of table we are dealing with. routing := createRoutingForVTable(vschemaTable, solves) for _, predicate := range queryTable.Predicates { - var err error - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, predicate, routing) } plan.Routing = routing @@ -436,24 +431,16 @@ func createRouteFromVSchemaTable( switch routing := routing.(type) { case *ShardedRouting: if routing.isScatter() && len(queryTable.Predicates) > 0 { - var err error // If we have a scatter query, it's worth spending a little extra time seeing if we can't improve it - plan.Routing, err = routing.tryImprove(ctx, queryTable) - if err != nil { - return nil, err - } + plan.Routing = routing.tryImprove(ctx, queryTable) } case *AnyShardRouting: if planAlternates { - alternates, err := createAlternateRoutesFromVSchemaTable(ctx, queryTable, vschemaTable, solves) - if err != nil { - return nil, err - } - routing.Alternates = alternates + routing.Alternates = createAlternateRoutesFromVSchemaTable(ctx, queryTable, vschemaTable, solves) } } - return plan, nil + return plan } func createRoutingForVTable(vschemaTable *vindexes.Table, id semantics.TableSet) Routing { @@ -474,13 +461,13 @@ func createAlternateRoutesFromVSchemaTable( queryTable *QueryTable, vschemaTable *vindexes.Table, solves semantics.TableSet, -) (map[*vindexes.Keyspace]*Route, error) { +) map[*vindexes.Keyspace]*Route { routes := make(map[*vindexes.Keyspace]*Route) switch vschemaTable.Type { case "", vindexes.TypeReference: for ksName, referenceTable := range vschemaTable.ReferencedBy { - route, err := findVSchemaTableAndCreateRoute( + route := findVSchemaTableAndCreateRoute( ctx, queryTable, sqlparser.TableName{ @@ -490,23 +477,17 @@ func createAlternateRoutesFromVSchemaTable( solves, false, /*planAlternates*/ ) - if err != nil { - return nil, err - } routes[referenceTable.Keyspace] = route } if vschemaTable.Source != nil { - route, err := findVSchemaTableAndCreateRoute( + route := findVSchemaTableAndCreateRoute( ctx, queryTable, vschemaTable.Source.TableName, solves, false, /*planAlternates*/ ) - if err != nil { - return nil, err - } keyspace := route.Routing.Keyspace() if keyspace != nil { routes[keyspace] = route @@ -514,15 +495,12 @@ func createAlternateRoutesFromVSchemaTable( } } - return routes, nil + return routes } -func (r *Route) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (r *Route) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { // first we see if the predicate changes how we route - newRouting, err := UpdateRoutingLogic(ctx, expr, r.Routing) - if err != nil { - panic(err) - } + newRouting := UpdateRoutingLogic(ctx, expr, r.Routing) r.Routing = newRouting // we also need to push the predicate down into the query @@ -530,16 +508,13 @@ func (r *Route) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex return r } -func createProjection(ctx *plancontext.PlanningContext, src ops.Operator) (*Projection, error) { +func createProjection(ctx *plancontext.PlanningContext, src Operator) *Projection { proj := newAliasedProjection(src) cols := src.GetColumns(ctx) for _, col := range cols { - _, err := proj.addUnexploredExpr(col, col.Expr) - if err != nil { - return nil, err - } + proj.addUnexploredExpr(col, col.Expr) } - return proj, nil + return proj } func (r *Route) AddColumn(ctx *plancontext.PlanningContext, reuse bool, gb bool, expr *sqlparser.AliasedExpr) int { @@ -561,10 +536,7 @@ func (r *Route) AddColumn(ctx *plancontext.PlanningContext, reuse bool, gb bool, } // If no-one could be found, we probably don't have one yet, so we add one here - src, err := createProjection(ctx, r.Source) - if err != nil { - panic(err) - } + src := createProjection(ctx, r.Source) r.Source = src offsets = src.addColumnsWithoutPushing(ctx, reuse, []bool{gb}, []*sqlparser.AliasedExpr{expr}) @@ -572,7 +544,7 @@ func (r *Route) AddColumn(ctx *plancontext.PlanningContext, reuse bool, gb bool, } type selectExpressions interface { - ops.Operator + Operator addColumnWithoutPushing(ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, addToGroupBy bool) int addColumnsWithoutPushing(ctx *plancontext.PlanningContext, reuse bool, addToGroupBy []bool, exprs []*sqlparser.AliasedExpr) []int isDerived() bool @@ -581,7 +553,7 @@ type selectExpressions interface { // addColumnToInput adds a column to an operator without pushing it down. // It will return a bool indicating whether the addition was successful or not, // and an offset to where the column can be found -func addMultipleColumnsToInput(ctx *plancontext.PlanningContext, operator ops.Operator, reuse bool, addToGroupBy []bool, exprs []*sqlparser.AliasedExpr) (ops.Operator, bool, []int) { +func addMultipleColumnsToInput(ctx *plancontext.PlanningContext, operator Operator, reuse bool, addToGroupBy []bool, exprs []*sqlparser.AliasedExpr) (Operator, bool, []int) { switch op := operator.(type) { case *SubQuery: src, added, offset := addMultipleColumnsToInput(ctx, op.Outer, reuse, addToGroupBy, exprs) @@ -657,7 +629,7 @@ func (r *Route) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Selec return r.Source.GetSelectExprs(ctx) } -func (r *Route) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (r *Route) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return r.Source.GetOrdering(ctx) } @@ -673,7 +645,7 @@ func (r *Route) TablesUsed() []string { return collect() } -func isSpecialOrderBy(o ops.OrderBy) bool { +func isSpecialOrderBy(o OrderBy) bool { if sqlparser.IsNull(o.Inner.Expr) { return true } @@ -681,7 +653,7 @@ func isSpecialOrderBy(o ops.OrderBy) bool { return isFunction && f.Name.Lowered() == "rand" } -func (r *Route) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (r *Route) planOffsets(ctx *plancontext.PlanningContext) Operator { // if operator is returning data from a single shard, we don't need to do anything more if r.IsSingleShard() { return nil diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index 5bce334a609..30c187ac955 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -26,8 +26,6 @@ import ( "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/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -38,34 +36,34 @@ type ( left, right semantics.TableSet } - opCacheMap map[tableSetPair]ops.Operator + opCacheMap map[tableSetPair]Operator ) -func pushDerived(ctx *plancontext.PlanningContext, op *Horizon) (ops.Operator, *rewrite.ApplyResult, error) { +func pushDerived(ctx *plancontext.PlanningContext, op *Horizon) (Operator, *ApplyResult) { innerRoute, ok := op.Source.(*Route) if !ok { - return op, rewrite.SameTree, nil + return op, NoRewrite } if !(innerRoute.Routing.OpCode() == engine.EqualUnique) && !op.IsMergeable(ctx) { // no need to check anything if we are sure that we will only hit a single shard - return op, rewrite.SameTree, nil + return op, NoRewrite } - return rewrite.Swap(op, op.Source, "push derived under route") + return Swap(op, op.Source, "push derived under route") } -func optimizeJoin(ctx *plancontext.PlanningContext, op *Join) (ops.Operator, *rewrite.ApplyResult, error) { +func optimizeJoin(ctx *plancontext.PlanningContext, op *Join) (Operator, *ApplyResult) { return mergeOrJoin(ctx, op.LHS, op.RHS, sqlparser.SplitAndExpression(nil, op.Predicate), !op.LeftJoin) } -func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (result ops.Operator, changed *rewrite.ApplyResult, err error) { +func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (result Operator, changed *ApplyResult) { switch { case ctx.PlannerVersion == querypb.ExecuteOptions_Gen4Left2Right: - result, err = leftToRightSolve(ctx, op) + result = leftToRightSolve(ctx, op) default: - result, err = greedySolve(ctx, op) + result = greedySolve(ctx, op) } unresolved := op.UnsolvedPredicates(ctx.SemTable) @@ -75,7 +73,7 @@ func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (resul result = newFilter(result, ctx.SemTable.AndExpressions(unresolved...)) } - changed = rewrite.NewTree("solved query graph") + changed = Rewrote("solved query graph") return } @@ -84,18 +82,18 @@ func buildVindexTableForDML( tableInfo semantics.TableInfo, table *QueryTable, dmlType string, -) (*vindexes.Table, Routing, error) { +) (*vindexes.Table, Routing) { vindexTable := tableInfo.GetVindexTable() if vindexTable.Source != nil { sourceTable, _, _, _, _, err := ctx.VSchema.FindTableOrVindex(vindexTable.Source.TableName) if err != nil { - return nil, nil, err + panic(err) } vindexTable = sourceTable } if !vindexTable.Keyspace.Sharded { - return vindexTable, &AnyShardRouting{keyspace: vindexTable.Keyspace}, nil + return vindexTable, &AnyShardRouting{keyspace: vindexTable.Keyspace} } var dest key.Destination @@ -103,23 +101,23 @@ func buildVindexTableForDML( var err error tblName, ok := table.Alias.Expr.(sqlparser.TableName) if !ok { - return nil, nil, vterrors.VT12001("multi shard UPDATE with LIMIT") + panic(vterrors.VT12001("multi shard UPDATE with LIMIT")) } _, _, _, typ, dest, err = ctx.VSchema.FindTableOrVindex(tblName) if err != nil { - return nil, nil, err + panic(err) } if dest == nil { routing := &ShardedRouting{ keyspace: vindexTable.Keyspace, RouteOpCode: engine.Scatter, } - return vindexTable, routing, nil + return vindexTable, routing } if typ != topodatapb.TabletType_PRIMARY { - return nil, nil, vterrors.VT09002(dmlType) + panic(vterrors.VT09002(dmlType)) } // we are dealing with an explicitly targeted DML @@ -127,7 +125,7 @@ func buildVindexTableForDML( keyspace: vindexTable.Keyspace, TargetDestination: dest, } - return vindexTable, routing, nil + return vindexTable, routing } func generateOwnedVindexQuery(tblExpr sqlparser.TableExpr, del *sqlparser.Delete, table *vindexes.Table, ksidCols []sqlparser.IdentifierCI) string { @@ -154,21 +152,14 @@ func getUpdateVindexInformation( vindexTable *vindexes.Table, tableID semantics.TableSet, assignments []SetExpr, -) ([]*VindexPlusPredicates, map[string]*engine.VindexValues, string, []string, error) { +) ([]*VindexPlusPredicates, map[string]*engine.VindexValues, string, []string) { if !vindexTable.Keyspace.Sharded { - return nil, nil, "", nil, nil + return nil, nil, "", nil } - primaryVindex, vindexAndPredicates, err := getVindexInformation(tableID, vindexTable) - if err != nil { - return nil, nil, "", nil, err - } - - changedVindexValues, ownedVindexQuery, subQueriesArgOnChangedVindex, err := buildChangedVindexesValues(ctx, updStmt, vindexTable, primaryVindex.Columns, assignments) - if err != nil { - return nil, nil, "", nil, err - } - return vindexAndPredicates, changedVindexValues, ownedVindexQuery, subQueriesArgOnChangedVindex, nil + primaryVindex, vindexAndPredicates := getVindexInformation(tableID, vindexTable) + changedVindexValues, ownedVindexQuery, subQueriesArgOnChangedVindex := buildChangedVindexesValues(ctx, updStmt, vindexTable, primaryVindex.Columns, assignments) + return vindexAndPredicates, changedVindexValues, ownedVindexQuery, subQueriesArgOnChangedVindex } /* @@ -177,67 +168,51 @@ func getUpdateVindexInformation( and removes the two inputs to this cheapest plan and instead adds the join. As an optimization, it first only considers joining tables that have predicates defined between them */ -func greedySolve(ctx *plancontext.PlanningContext, qg *QueryGraph) (ops.Operator, error) { - routeOps, err := seedOperatorList(ctx, qg) +func greedySolve(ctx *plancontext.PlanningContext, qg *QueryGraph) Operator { + routeOps := seedOperatorList(ctx, qg) planCache := opCacheMap{} - if err != nil { - return nil, err - } - op, err := mergeRoutes(ctx, qg, routeOps, planCache, false) - if err != nil { - return nil, err - } - return op, nil + return mergeRoutes(ctx, qg, routeOps, planCache, false) } -func leftToRightSolve(ctx *plancontext.PlanningContext, qg *QueryGraph) (ops.Operator, error) { - plans, err := seedOperatorList(ctx, qg) - if err != nil { - return nil, err - } +func leftToRightSolve(ctx *plancontext.PlanningContext, qg *QueryGraph) Operator { + plans := seedOperatorList(ctx, qg) - var acc ops.Operator + var acc Operator for _, plan := range plans { if acc == nil { acc = plan continue } joinPredicates := qg.GetPredicates(TableID(acc), TableID(plan)) - acc, _, err = mergeOrJoin(ctx, acc, plan, joinPredicates, true) - if err != nil { - return nil, err - } + acc, _ = mergeOrJoin(ctx, acc, plan, joinPredicates, true) } - return acc, nil + return acc } // seedOperatorList returns a route for each table in the qg -func seedOperatorList(ctx *plancontext.PlanningContext, qg *QueryGraph) ([]ops.Operator, error) { - plans := make([]ops.Operator, len(qg.Tables)) +func seedOperatorList(ctx *plancontext.PlanningContext, qg *QueryGraph) []Operator { + plans := make([]Operator, len(qg.Tables)) // we start by seeding the table with the single routes for i, table := range qg.Tables { solves := ctx.SemTable.TableSetFor(table.Alias) - plan, err := createRoute(ctx, table, solves) - if err != nil { - return nil, err - } + plan := createRoute(ctx, table, solves) if qg.NoDeps != nil { plan = plan.AddPredicate(ctx, qg.NoDeps) } plans[i] = plan } - return plans, nil + return plans } -func createInfSchemaRoute(ctx *plancontext.PlanningContext, table *QueryTable) (ops.Operator, error) { +func createInfSchemaRoute(ctx *plancontext.PlanningContext, table *QueryTable) Operator { ks, err := ctx.VSchema.AnyKeyspace() if err != nil { - return nil, err + panic(err) } - var src ops.Operator = &Table{ + var src Operator = &Table{ QTable: table, VTable: &vindexes.Table{ Name: table.Table.Name, @@ -246,26 +221,20 @@ func createInfSchemaRoute(ctx *plancontext.PlanningContext, table *QueryTable) ( } var routing Routing = &InfoSchemaRouting{} for _, pred := range table.Predicates { - routing, err = UpdateRoutingLogic(ctx, pred, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, pred, routing) } return &Route{ Source: src, Routing: routing, - }, nil + } } -func mergeRoutes(ctx *plancontext.PlanningContext, qg *QueryGraph, physicalOps []ops.Operator, planCache opCacheMap, crossJoinsOK bool) (ops.Operator, error) { +func mergeRoutes(ctx *plancontext.PlanningContext, qg *QueryGraph, physicalOps []Operator, planCache opCacheMap, crossJoinsOK bool) Operator { if len(physicalOps) == 0 { - return nil, nil + return nil } for len(physicalOps) > 1 { - bestTree, lIdx, rIdx, err := findBestJoin(ctx, qg, physicalOps, planCache, crossJoinsOK) - if err != nil { - return nil, err - } + bestTree, lIdx, rIdx := findBestJoin(ctx, qg, physicalOps, planCache, crossJoinsOK) // if we found a plan, we'll replace the two plans that were joined with the join plan created if bestTree != nil { // we remove one plan, and replace the other @@ -279,7 +248,7 @@ func mergeRoutes(ctx *plancontext.PlanningContext, qg *QueryGraph, physicalOps [ physicalOps = append(physicalOps, bestTree) } else { if crossJoinsOK { - return nil, vterrors.VT13001("should not happen: we should be able to merge cross joins") + panic(vterrors.VT13001("should not happen: we should be able to merge cross joins")) } // we will only fail to find a join plan when there are only cross joins left // when that happens, we switch over to allow cross joins as well. @@ -287,20 +256,20 @@ func mergeRoutes(ctx *plancontext.PlanningContext, qg *QueryGraph, physicalOps [ crossJoinsOK = true } } - return physicalOps[0], nil + return physicalOps[0] } -func removeAt(plans []ops.Operator, idx int) []ops.Operator { +func removeAt(plans []Operator, idx int) []Operator { return append(plans[:idx], plans[idx+1:]...) } func findBestJoin( ctx *plancontext.PlanningContext, qg *QueryGraph, - plans []ops.Operator, + plans []Operator, planCache opCacheMap, crossJoinsOK bool, -) (bestPlan ops.Operator, lIdx int, rIdx int, err error) { +) (bestPlan Operator, lIdx int, rIdx int) { for i, lhs := range plans { for j, rhs := range plans { if i == j { @@ -313,10 +282,7 @@ func findBestJoin( // cartesian product, which is almost always a bad idea continue } - plan, err := getJoinFor(ctx, planCache, lhs, rhs, joinPredicates) - if err != nil { - return nil, 0, 0, err - } + plan := getJoinFor(ctx, planCache, lhs, rhs, joinPredicates) if bestPlan == nil || CostOf(plan) < CostOf(bestPlan) { bestPlan = plan // remember which plans we based on, so we can remove them later @@ -325,30 +291,25 @@ func findBestJoin( } } } - return bestPlan, lIdx, rIdx, nil + return bestPlan, lIdx, rIdx } -func getJoinFor(ctx *plancontext.PlanningContext, cm opCacheMap, lhs, rhs ops.Operator, joinPredicates []sqlparser.Expr) (ops.Operator, error) { +func getJoinFor(ctx *plancontext.PlanningContext, cm opCacheMap, lhs, rhs Operator, joinPredicates []sqlparser.Expr) Operator { solves := tableSetPair{left: TableID(lhs), right: TableID(rhs)} cachedPlan := cm[solves] if cachedPlan != nil { - return cachedPlan, nil + return cachedPlan } - join, _, err := mergeOrJoin(ctx, lhs, rhs, joinPredicates, true) - if err != nil { - return nil, err - } + join, _ := mergeOrJoin(ctx, lhs, rhs, joinPredicates, true) cm[solves] = join - return join, nil + return join } // requiresSwitchingSides will return true if any of the operators with the root from the given operator tree // is of the type that should not be on the RHS of a join -func requiresSwitchingSides(ctx *plancontext.PlanningContext, op ops.Operator) bool { - required := false - - _ = rewrite.Visit(op, func(current ops.Operator) error { +func requiresSwitchingSides(ctx *plancontext.PlanningContext, op Operator) (required bool) { + _ = Visit(op, func(current Operator) error { horizon, isHorizon := current.(*Horizon) if isHorizon && !horizon.IsMergeable(ctx) { @@ -358,14 +319,13 @@ func requiresSwitchingSides(ctx *plancontext.PlanningContext, op ops.Operator) b return nil }) - - return required + return } -func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPredicates []sqlparser.Expr, inner bool) (ops.Operator, *rewrite.ApplyResult, error) { +func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredicates []sqlparser.Expr, inner bool) (Operator, *ApplyResult) { newPlan := mergeJoinInputs(ctx, lhs, rhs, joinPredicates, newJoinMerge(joinPredicates, inner)) if newPlan != nil { - return newPlan, rewrite.NewTree("merge routes into single operator"), nil + return newPlan, Rewrote("merge routes into single operator") } if len(joinPredicates) > 0 && requiresSwitchingSides(ctx, rhs) { @@ -376,26 +336,20 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs ops.Operator, joinPr join.AddJoinPredicate(ctx, pred) } ctx.SemTable.QuerySignature.HashJoin = true - return join, rewrite.NewTree("use a hash join because we have LIMIT on the LHS"), nil + return join, Rewrote("use a hash join because we have LIMIT on the LHS") } join := NewApplyJoin(Clone(rhs), Clone(lhs), nil, !inner) - newOp, err := pushJoinPredicates(ctx, joinPredicates, join) - if err != nil { - return nil, nil, err - } - return newOp, rewrite.NewTree("logical join to applyJoin, switching side because LIMIT"), nil + newOp := pushJoinPredicates(ctx, joinPredicates, join) + return newOp, Rewrote("logical join to applyJoin, switching side because LIMIT") } join := NewApplyJoin(Clone(lhs), Clone(rhs), nil, !inner) - newOp, err := pushJoinPredicates(ctx, joinPredicates, join) - if err != nil { - return nil, nil, err - } - return newOp, rewrite.NewTree("logical join to applyJoin "), nil + newOp := pushJoinPredicates(ctx, joinPredicates, join) + return newOp, Rewrote("logical join to applyJoin ") } -func operatorsToRoutes(a, b ops.Operator) (*Route, *Route) { +func operatorsToRoutes(a, b Operator) (*Route, *Route) { aRoute, ok := a.(*Route) if !ok { return nil, nil @@ -433,7 +387,7 @@ func canMergeOnFilter(ctx *plancontext.PlanningContext, a, b *Route, predicate s return rVindex == lVindex } -func findColumnVindex(ctx *plancontext.PlanningContext, a ops.Operator, exp sqlparser.Expr) vindexes.SingleColumn { +func findColumnVindex(ctx *plancontext.PlanningContext, a Operator, exp sqlparser.Expr) vindexes.SingleColumn { _, isCol := exp.(*sqlparser.ColName) if !isCol { return nil @@ -458,7 +412,7 @@ func findColumnVindex(ctx *plancontext.PlanningContext, a ops.Operator, exp sqlp deps := ctx.SemTable.RecursiveDeps(expr) - _ = rewrite.Visit(a, func(rel ops.Operator) error { + _ = Visit(a, func(rel Operator) error { to, isTableOp := rel.(tableIDIntroducer) if !isTableOp { return nil @@ -612,14 +566,14 @@ func hexEqual(a, b *sqlparser.Literal) bool { return false } -func pushJoinPredicates(ctx *plancontext.PlanningContext, exprs []sqlparser.Expr, op *ApplyJoin) (ops.Operator, error) { +func pushJoinPredicates(ctx *plancontext.PlanningContext, exprs []sqlparser.Expr, op *ApplyJoin) Operator { if len(exprs) == 0 { - return op, nil + return op } for _, expr := range exprs { AddPredicate(ctx, op, expr, true, newFilter) } - return op, nil + return op } diff --git a/go/vt/vtgate/planbuilder/operators/sequential.go b/go/vt/vtgate/planbuilder/operators/sequential.go index 2b333c6270a..2db376a97bb 100644 --- a/go/vt/vtgate/planbuilder/operators/sequential.go +++ b/go/vt/vtgate/planbuilder/operators/sequential.go @@ -17,35 +17,34 @@ limitations under the License. package operators import ( - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type Sequential struct { - Sources []ops.Operator + Sources []Operator noPredicates noColumns } // Clone implements the Operator interface -func (s *Sequential) Clone(inputs []ops.Operator) ops.Operator { +func (s *Sequential) Clone(inputs []Operator) Operator { newOp := *s newOp.Sources = inputs return &newOp } -func (s *Sequential) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (s *Sequential) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } // Inputs implements the Operator interface -func (s *Sequential) Inputs() []ops.Operator { +func (s *Sequential) Inputs() []Operator { return s.Sources } // SetInputs implements the Operator interface -func (s *Sequential) SetInputs(ops []ops.Operator) { +func (s *Sequential) SetInputs(ops []Operator) { s.Sources = ops } diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index d54db071d46..239ae9ce419 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -97,28 +97,23 @@ func (tr *ShardedRouting) isScatter() bool { // This can sometimes push a predicate to the top, so it's not hiding inside an OR // 2. If that is not enough, an additional rewrite pass is performed where we try to // turn ORs into IN, which is easier for the planner to plan -func (tr *ShardedRouting) tryImprove(ctx *plancontext.PlanningContext, queryTable *QueryTable) (Routing, error) { +func (tr *ShardedRouting) tryImprove(ctx *plancontext.PlanningContext, queryTable *QueryTable) Routing { oldPredicates := queryTable.Predicates queryTable.Predicates = nil tr.SeenPredicates = nil var routing Routing = tr - var err error for _, pred := range oldPredicates { rewritten := sqlparser.RewritePredicate(pred) predicates := sqlparser.SplitAndExpression(nil, rewritten.(sqlparser.Expr)) for _, predicate := range predicates { queryTable.Predicates = append(queryTable.Predicates, predicate) - - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, predicate, routing) } } // If we have something other than a sharded routing with scatter, we are done if sr, ok := routing.(*ShardedRouting); !ok || !sr.isScatter() { - return routing, nil + return routing } // if we _still_ haven't found a better route, we can run this additional rewrite on any ORs we have @@ -128,23 +123,19 @@ func (tr *ShardedRouting) tryImprove(ctx *plancontext.PlanningContext, queryTabl continue } for _, predicate := range sqlparser.ExtractINFromOR(or) { - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, predicate, routing) } } - return routing, nil + return routing } -func (tr *ShardedRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) error { +func (tr *ShardedRouting) UpdateRoutingParams(_ *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.Keyspace = tr.keyspace if tr.Selected != nil { rp.Vindex = tr.Selected.FoundVindex rp.Values = tr.Selected.Values } - return nil } func (tr *ShardedRouting) Clone() Routing { @@ -166,17 +157,13 @@ func (tr *ShardedRouting) Clone() Routing { } } -func (tr *ShardedRouting) updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) (Routing, error) { +func (tr *ShardedRouting) updateRoutingLogic(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Routing { tr.SeenPredicates = append(tr.SeenPredicates, expr) - newRouting, newVindexFound, err := tr.searchForNewVindexes(ctx, expr) - if err != nil { - return nil, err - } - + newRouting, newVindexFound := tr.searchForNewVindexes(ctx, expr) if newRouting != nil { // we found something that we can route with something other than ShardedRouting - return newRouting, nil + return newRouting } // if we didn't open up any new vindex Options, no need to enter here @@ -184,10 +171,10 @@ func (tr *ShardedRouting) updateRoutingLogic(ctx *plancontext.PlanningContext, e tr.PickBestAvailableVindex() } - return tr, nil + return tr } -func (tr *ShardedRouting) resetRoutingLogic(ctx *plancontext.PlanningContext) (Routing, error) { +func (tr *ShardedRouting) resetRoutingLogic(ctx *plancontext.PlanningContext) Routing { tr.RouteOpCode = engine.Scatter tr.Selected = nil for i, vp := range tr.VindexPreds { @@ -196,16 +183,12 @@ func (tr *ShardedRouting) resetRoutingLogic(ctx *plancontext.PlanningContext) (R var routing Routing = tr for _, predicate := range tr.SeenPredicates { - var err error - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, predicate, routing) } - return routing, nil + return routing } -func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, predicate sqlparser.Expr) (Routing, bool, error) { +func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, predicate sqlparser.Expr) (Routing, bool) { newVindexFound := false switch node := predicate.(type) { case *sqlparser.ComparisonExpr: @@ -216,23 +199,23 @@ func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, newVindexFound = newVindexFound || found } - return nil, newVindexFound, nil + return nil, newVindexFound } -func (tr *ShardedRouting) planComparison(ctx *plancontext.PlanningContext, cmp *sqlparser.ComparisonExpr) (routing Routing, foundNew bool, err error) { +func (tr *ShardedRouting) planComparison(ctx *plancontext.PlanningContext, cmp *sqlparser.ComparisonExpr) (routing Routing, foundNew bool) { switch cmp.Operator { case sqlparser.EqualOp: found := tr.planEqualOp(ctx, cmp) - return nil, found, nil + return nil, found case sqlparser.InOp: found := tr.planInOp(ctx, cmp) - return nil, found, nil + return nil, found case sqlparser.LikeOp: found := tr.planLikeOp(ctx, cmp) - return nil, found, nil + return nil, found } - return nil, false, nil + return nil, false } func (tr *ShardedRouting) planIsExpr(ctx *plancontext.PlanningContext, node *sqlparser.IsExpr) bool { diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index a401b29074d..279669ade38 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -34,8 +33,8 @@ import ( // outer query through a join. type SubQuery struct { // Fields filled in at the time of construction: - Outer ops.Operator // Outer query operator. - Subquery ops.Operator // Subquery operator. + Outer Operator // Outer query operator. + Subquery Operator // Subquery operator. FilterType opcode.PulloutOpcode // Type of subquery filter. Original sqlparser.Expr // This is the expression we should use if we can merge the inner to the outer originalSubquery *sqlparser.Subquery // Subquery representation, e.g., (SELECT foo from user LIMIT 1). @@ -54,7 +53,7 @@ type SubQuery struct { IsProjection bool } -func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { +func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) Operator { sq.Vars = make(map[string]int) columns, err := sq.GetJoinColumns(ctx, sq.Outer) if err != nil { @@ -69,24 +68,24 @@ func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) ops.Operator { return nil } -func (sq *SubQuery) OuterExpressionsNeeded(ctx *plancontext.PlanningContext, outer ops.Operator) (result []*sqlparser.ColName, err error) { +func (sq *SubQuery) OuterExpressionsNeeded(ctx *plancontext.PlanningContext, outer Operator) (result []*sqlparser.ColName) { joinColumns, err := sq.GetJoinColumns(ctx, outer) if err != nil { - return nil, err + return nil } for _, jc := range joinColumns { for _, lhsExpr := range jc.LHSExprs { col, ok := lhsExpr.Expr.(*sqlparser.ColName) if !ok { - return nil, vterrors.VT13001("joins can only compare columns: %s", sqlparser.String(lhsExpr.Expr)) + panic(vterrors.VT13001("joins can only compare columns: %s", sqlparser.String(lhsExpr.Expr))) } result = append(result, col) } } - return result, nil + return result } -func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer ops.Operator) ([]JoinColumn, error) { +func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer Operator) ([]JoinColumn, error) { if outer == nil { return nil, vterrors.VT13001("outer operator cannot be nil") } @@ -98,7 +97,7 @@ func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer ops.O } sq.outerID = outerID mapper := func(in sqlparser.Expr) (JoinColumn, error) { - return breakExpressionInLHSandRHSForApplyJoin(ctx, in, outerID) + return breakExpressionInLHSandRHSForApplyJoin(ctx, in, outerID), nil } joinPredicates, err := slice.MapWithError(sq.Predicates, mapper) if err != nil { @@ -109,7 +108,7 @@ func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer ops.O } // Clone implements the Operator interface -func (sq *SubQuery) Clone(inputs []ops.Operator) ops.Operator { +func (sq *SubQuery) Clone(inputs []Operator) Operator { klone := *sq switch len(inputs) { case 1: @@ -126,21 +125,21 @@ func (sq *SubQuery) Clone(inputs []ops.Operator) ops.Operator { return &klone } -func (sq *SubQuery) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (sq *SubQuery) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return sq.Outer.GetOrdering(ctx) } // Inputs implements the Operator interface -func (sq *SubQuery) Inputs() []ops.Operator { +func (sq *SubQuery) Inputs() []Operator { if sq.Outer == nil { - return []ops.Operator{sq.Subquery} + return []Operator{sq.Subquery} } - return []ops.Operator{sq.Outer, sq.Subquery} + return []Operator{sq.Outer, sq.Subquery} } // SetInputs implements the Operator interface -func (sq *SubQuery) SetInputs(inputs []ops.Operator) { +func (sq *SubQuery) SetInputs(inputs []Operator) { switch len(inputs) { case 1: sq.Subquery = inputs[0] @@ -168,7 +167,7 @@ func (sq *SubQuery) ShortDescription() string { return fmt.Sprintf("%s %v%s", typ, sq.FilterType.String(), pred) } -func (sq *SubQuery) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (sq *SubQuery) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { sq.Outer = sq.Outer.AddPredicate(ctx, expr) return sq } @@ -197,7 +196,7 @@ func (sq *SubQuery) GetMergePredicates() []sqlparser.Expr { return sq.Predicates } -func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer ops.Operator) (ops.Operator, error) { +func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer Operator) (Operator, error) { if !sq.TopLevel { return nil, subqueryNotAtTopErr } @@ -215,7 +214,7 @@ func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer ops.Operator) var correlatedSubqueryErr = vterrors.VT12001("correlated subquery is only supported for EXISTS") var subqueryNotAtTopErr = vterrors.VT12001("unmergable subquery can not be inside complex expression") -func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer ops.Operator) (ops.Operator, error) { +func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer Operator) (Operator, error) { if len(sq.Predicates) > 0 { if sq.FilterType != opcode.PulloutExists { return nil, correlatedSubqueryErr @@ -282,22 +281,8 @@ func (sq *SubQuery) isMerged(ctx *plancontext.PlanningContext) bool { } // mapExpr rewrites all expressions according to the provided function -func (sq *SubQuery) mapExpr(f func(expr sqlparser.Expr) (sqlparser.Expr, error)) error { - newPredicates, err := slice.MapWithError(sq.Predicates, f) - if err != nil { - return err - } - sq.Predicates = newPredicates - - sq.Original, err = f(sq.Original) - if err != nil { - return err - } - - originalSubquery, err := f(sq.originalSubquery) - if err != nil { - return err - } - sq.originalSubquery = originalSubquery.(*sqlparser.Subquery) - return nil +func (sq *SubQuery) mapExpr(f func(expr sqlparser.Expr) sqlparser.Expr) { + sq.Predicates = slice.Map(sq.Predicates, f) + sq.Original = f(sq.Original) + sq.originalSubquery = f(sq.originalSubquery).(*sqlparser.Subquery) } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index 1d1d12bbfe3..b2de19408b4 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -19,7 +19,6 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -32,7 +31,7 @@ type SubQueryBuilder struct { outerID semantics.TableSet } -func (sqb *SubQueryBuilder) getRootOperator(op ops.Operator, decorator func(operator ops.Operator) ops.Operator) ops.Operator { +func (sqb *SubQueryBuilder) getRootOperator(op Operator, decorator func(operator Operator) Operator) Operator { if len(sqb.Inner) == 0 { return op } @@ -53,19 +52,16 @@ func (sqb *SubQueryBuilder) handleSubquery( ctx *plancontext.PlanningContext, expr sqlparser.Expr, outerID semantics.TableSet, -) (*SubQuery, error) { +) *SubQuery { subq, parentExpr := getSubQuery(expr) if subq == nil { - return nil, nil + return nil } argName := ctx.GetReservedArgumentFor(subq) - sqInner, err := createSubqueryOp(ctx, parentExpr, expr, subq, outerID, argName) - if err != nil { - return nil, err - } + sqInner := createSubqueryOp(ctx, parentExpr, expr, subq, outerID, argName) sqb.Inner = append(sqb.Inner, sqInner) - return sqInner, nil + return sqInner } func getSubQuery(expr sqlparser.Expr) (subqueryExprExists *sqlparser.Subquery, parentExpr sqlparser.Expr) { @@ -99,7 +95,7 @@ func createSubqueryOp( subq *sqlparser.Subquery, outerID semantics.TableSet, name string, -) (*SubQuery, error) { +) *SubQuery { switch parent := parent.(type) { case *sqlparser.NotExpr: switch parent.Expr.(type) { @@ -120,20 +116,14 @@ func createSubqueryOp( // and extracts subqueries into operators func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, -) (sqlparser.Exprs, []JoinColumn, error) { +) (sqlparser.Exprs, []JoinColumn) { switch stmt := stmt.(type) { case *sqlparser.Select: return sqb.inspectSelect(ctx, stmt) case *sqlparser.Union: - exprs1, cols1, err := sqb.inspectStatement(ctx, stmt.Left) - if err != nil { - return nil, nil, err - } - exprs2, cols2, err := sqb.inspectStatement(ctx, stmt.Right) - if err != nil { - return nil, nil, err - } - return append(exprs1, exprs2...), append(cols1, cols2...), nil + exprs1, cols1 := sqb.inspectStatement(ctx, stmt.Left) + exprs2, cols2 := sqb.inspectStatement(ctx, stmt.Right) + return append(exprs1, exprs2...), append(cols1, cols2...) } panic("unknown type") } @@ -144,22 +134,12 @@ func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext, func (sqb *SubQueryBuilder) inspectSelect( ctx *plancontext.PlanningContext, sel *sqlparser.Select, -) (sqlparser.Exprs, []JoinColumn, error) { +) (sqlparser.Exprs, []JoinColumn) { // first we need to go through all the places where one can find predicates // and search for subqueries - newWhere, wherePreds, whereJoinCols, err := sqb.inspectWhere(ctx, sel.Where) - if err != nil { - return nil, nil, err - } - newHaving, havingPreds, havingJoinCols, err := sqb.inspectWhere(ctx, sel.Having) - if err != nil { - return nil, nil, err - } - - newFrom, onPreds, onJoinCols, err := sqb.inspectOnExpr(ctx, sel.From) - if err != nil { - return nil, nil, err - } + newWhere, wherePreds, whereJoinCols := sqb.inspectWhere(ctx, sel.Where) + newHaving, havingPreds, havingJoinCols := sqb.inspectWhere(ctx, sel.Having) + newFrom, onPreds, onJoinCols := sqb.inspectOnExpr(ctx, sel.From) // then we use the updated AST structs to build the operator // these AST elements have any subqueries replace by arguments @@ -168,8 +148,7 @@ func (sqb *SubQueryBuilder) inspectSelect( sel.From = newFrom return append(append(wherePreds, havingPreds...), onPreds...), - append(append(whereJoinCols, havingJoinCols...), onJoinCols...), - nil + append(append(whereJoinCols, havingJoinCols...), onJoinCols...) } func createSubquery( @@ -181,7 +160,7 @@ func createSubquery( argName string, filterType opcode.PulloutOpcode, isProjection bool, -) (*SubQuery, error) { +) *SubQuery { topLevel := ctx.SemTable.EqualsExpr(original, parent) original = cloneASTAndSemState(ctx, original) originalSq := cloneASTAndSemState(ctx, subq) @@ -189,20 +168,13 @@ func createSubquery( totalID := subqID.Merge(outerID) sqc := &SubQueryBuilder{totalID: totalID, subqID: subqID, outerID: outerID} - predicates, joinCols, err := sqc.inspectStatement(ctx, subq.Select) - if err != nil { - return nil, err - } - + predicates, joinCols := sqc.inspectStatement(ctx, subq.Select) stmt := rewriteRemainingColumns(ctx, subq.Select, subqID) // TODO: this should not be needed. We are using CopyOnRewrite above, but somehow this is not getting copied ctx.SemTable.CopySemanticInfo(subq.Select, stmt) - opInner, err := translateQueryToOp(ctx, stmt) - if err != nil { - return nil, err - } + opInner := translateQueryToOp(ctx, stmt) opInner = sqc.getRootOperator(opInner, nil) return &SubQuery{ @@ -215,15 +187,15 @@ func createSubquery( IsProjection: isProjection, TopLevel: topLevel, JoinColumns: joinCols, - }, nil + } } func (sqb *SubQueryBuilder) inspectWhere( ctx *plancontext.PlanningContext, in *sqlparser.Where, -) (*sqlparser.Where, sqlparser.Exprs, []JoinColumn, error) { +) (*sqlparser.Where, sqlparser.Exprs, []JoinColumn) { if in == nil { - return nil, nil, nil, nil + return nil, nil, nil } jpc := &joinPredicateCollector{ totalID: sqb.totalID, @@ -232,16 +204,11 @@ func (sqb *SubQueryBuilder) inspectWhere( } for _, predicate := range sqlparser.SplitAndExpression(nil, in.Expr) { sqlparser.RemoveKeyspaceFromColName(predicate) - subq, err := sqb.handleSubquery(ctx, predicate, sqb.totalID) - if err != nil { - return nil, nil, nil, err - } + subq := sqb.handleSubquery(ctx, predicate, sqb.totalID) if subq != nil { continue } - if err = jpc.inspectPredicate(ctx, predicate); err != nil { - return nil, nil, nil, err - } + jpc.inspectPredicate(ctx, predicate) } if len(jpc.remainingPredicates) == 0 { @@ -250,13 +217,13 @@ func (sqb *SubQueryBuilder) inspectWhere( in.Expr = sqlparser.AndExpressions(jpc.remainingPredicates...) } - return in, jpc.predicates, jpc.joinColumns, nil + return in, jpc.predicates, jpc.joinColumns } func (sqb *SubQueryBuilder) inspectOnExpr( ctx *plancontext.PlanningContext, from []sqlparser.TableExpr, -) (newFrom []sqlparser.TableExpr, onPreds sqlparser.Exprs, onJoinCols []JoinColumn, err error) { +) (newFrom []sqlparser.TableExpr, onPreds sqlparser.Exprs, onJoinCols []JoinColumn) { for _, tbl := range from { tbl := sqlparser.CopyOnRewrite(tbl, dontEnterSubqueries, func(cursor *sqlparser.CopyOnWriteCursor) { cond, ok := cursor.Node().(*sqlparser.JoinCondition) @@ -271,20 +238,11 @@ func (sqb *SubQueryBuilder) inspectOnExpr( } for _, pred := range sqlparser.SplitAndExpression(nil, cond.On) { - subq, innerErr := sqb.handleSubquery(ctx, pred, sqb.totalID) - if err != nil { - err = innerErr - cursor.StopTreeWalk() - return - } + subq := sqb.handleSubquery(ctx, pred, sqb.totalID) if subq != nil { continue } - if err = jpc.inspectPredicate(ctx, pred); err != nil { - err = innerErr - cursor.StopTreeWalk() - return - } + jpc.inspectPredicate(ctx, pred) } if len(jpc.remainingPredicates) == 0 { cond.On = nil @@ -294,9 +252,6 @@ func (sqb *SubQueryBuilder) inspectOnExpr( onPreds = append(onPreds, jpc.predicates...) onJoinCols = append(onJoinCols, jpc.joinColumns...) }, ctx.SemTable.CopySemanticInfo) - if err != nil { - return - } newFrom = append(newFrom, tbl.(sqlparser.TableExpr)) } return @@ -309,7 +264,7 @@ func createComparisonSubQuery( subFromOutside *sqlparser.Subquery, outerID semantics.TableSet, name string, -) (*SubQuery, error) { +) *SubQuery { subq, outside := semantics.GetSubqueryAndOtherSide(parent) if outside == nil || subq != subFromOutside { panic("uh oh") @@ -323,10 +278,7 @@ func createComparisonSubQuery( filterType = opcode.PulloutNotIn } - subquery, err := createSubquery(ctx, original, subq, outerID, parent, name, filterType, false) - if err != nil { - return nil, err - } + subquery := createSubquery(ctx, original, subq, outerID, parent, name, filterType, false) // if we are comparing with a column from the inner subquery, // we add this extra predicate to check if the two sides are mergable or not @@ -338,7 +290,7 @@ func createComparisonSubQuery( } } - return subquery, err + return subquery } func (sqb *SubQueryBuilder) pullOutValueSubqueries( @@ -346,25 +298,22 @@ func (sqb *SubQueryBuilder) pullOutValueSubqueries( expr sqlparser.Expr, outerID semantics.TableSet, isDML bool, -) (sqlparser.Expr, []*SubQuery, error) { +) (sqlparser.Expr, []*SubQuery) { original := sqlparser.CloneExpr(expr) sqe := extractSubQueries(ctx, expr, isDML) if sqe == nil { - return nil, nil, nil + return nil, nil } var newSubqs []*SubQuery for idx, subq := range sqe.subq { - sqInner, err := createSubquery(ctx, original, subq, outerID, original, sqe.cols[idx], sqe.pullOutCode[idx], true) - if err != nil { - return nil, nil, err - } + sqInner := createSubquery(ctx, original, subq, outerID, original, sqe.cols[idx], sqe.pullOutCode[idx], true) newSubqs = append(newSubqs, sqInner) } sqb.Inner = append(sqb.Inner, newSubqs...) - return sqe.new, newSubqs, nil + return sqe.new, newSubqs } type subqueryExtraction struct { diff --git a/go/vt/vtgate/planbuilder/operators/subquery_container.go b/go/vt/vtgate/planbuilder/operators/subquery_container.go index ab8d1104623..e4feeab49d8 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_container.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_container.go @@ -18,7 +18,6 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -27,15 +26,15 @@ type ( // The inner subqueries can be executed in any order, so we store them like this so we can see more opportunities // for merging SubQueryContainer struct { - Outer ops.Operator + Outer Operator Inner []*SubQuery } ) -var _ ops.Operator = (*SubQueryContainer)(nil) +var _ Operator = (*SubQueryContainer)(nil) // Clone implements the Operator interface -func (sqc *SubQueryContainer) Clone(inputs []ops.Operator) ops.Operator { +func (sqc *SubQueryContainer) Clone(inputs []Operator) Operator { result := &SubQueryContainer{ Outer: inputs[0], } @@ -49,13 +48,13 @@ func (sqc *SubQueryContainer) Clone(inputs []ops.Operator) ops.Operator { return result } -func (sqc *SubQueryContainer) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (sqc *SubQueryContainer) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return sqc.Outer.GetOrdering(ctx) } // Inputs implements the Operator interface -func (sqc *SubQueryContainer) Inputs() []ops.Operator { - operators := []ops.Operator{sqc.Outer} +func (sqc *SubQueryContainer) Inputs() []Operator { + operators := []Operator{sqc.Outer} for _, inner := range sqc.Inner { operators = append(operators, inner) } @@ -63,7 +62,7 @@ func (sqc *SubQueryContainer) Inputs() []ops.Operator { } // SetInputs implements the Operator interface -func (sqc *SubQueryContainer) SetInputs(ops []ops.Operator) { +func (sqc *SubQueryContainer) SetInputs(ops []Operator) { sqc.Outer = ops[0] } @@ -71,7 +70,7 @@ func (sqc *SubQueryContainer) ShortDescription() string { return "" } -func (sqc *SubQueryContainer) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (sqc *SubQueryContainer) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { sqc.Outer = sqc.Outer.AddPredicate(ctx, expr) return sqc } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_planning.go b/go/vt/vtgate/planbuilder/operators/subquery_planning.go index 74761aef5c5..ed0c6bde941 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_planning.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_planning.go @@ -26,13 +26,11 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) -func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.SelectStatement, op ops.Operator) bool { +func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.SelectStatement, op Operator) bool { validVindex := func(expr sqlparser.Expr) bool { sc := findColumnVindex(ctx, op, expr) return sc != nil && sc.IsUnique() @@ -74,24 +72,24 @@ func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.SelectStateme } } -func settleSubqueries(ctx *plancontext.PlanningContext, op ops.Operator) ops.Operator { - visit := func(op ops.Operator, lhsTables semantics.TableSet, isRoot bool) (ops.Operator, *rewrite.ApplyResult, error) { +func settleSubqueries(ctx *plancontext.PlanningContext, op Operator) Operator { + visit := func(op Operator, lhsTables semantics.TableSet, isRoot bool) (Operator, *ApplyResult) { switch op := op.(type) { case *SubQueryContainer: outer := op.Outer for _, subq := range op.Inner { newOuter, err := subq.settle(ctx, outer) if err != nil { - return nil, nil, err + panic(err) } subq.Outer = newOuter outer = subq } - return outer, rewrite.NewTree("extracted subqueries from subquery container"), nil + return outer, Rewrote("extracted subqueries from subquery container") case *Projection: ap, err := op.GetAliasedProjections() if err != nil { - return nil, nil, err + panic(err) } for _, pe := range ap { @@ -102,13 +100,10 @@ func settleSubqueries(ctx *plancontext.PlanningContext, op ops.Operator) ops.Ope mergeSubqueryExpr(ctx, setExpr.Expr) } } - return op, rewrite.SameTree, nil + return op, NoRewrite } - op, err := rewrite.BottomUp(op, TableID, visit, nil) - if err != nil { - panic(err) - } - return op + + return BottomUp(op, TableID, visit, nil) } func mergeSubqueryExpr(ctx *plancontext.PlanningContext, pe *ProjExpr) { @@ -194,7 +189,7 @@ func tryPushSubQueryInJoin( ctx *plancontext.PlanningContext, inner *SubQuery, outer *ApplyJoin, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { lhs := TableID(outer.LHS) rhs := TableID(outer.RHS) joinID := TableID(outer) @@ -213,12 +208,9 @@ func tryPushSubQueryInJoin( // in general, we don't want to push down uncorrelated subqueries into the RHS of a join, // since this side is executed once per row from the LHS, so we would unnecessarily execute // the subquery multiple times. The exception is if we can merge the subquery with the RHS of the join. - merged, result, err := tryMergeWithRHS(ctx, inner, outer) - if err != nil { - return nil, nil, err - } + merged, result := tryMergeWithRHS(ctx, inner, outer) if merged != nil { - return merged, result, nil + return merged, result } _, ok := inner.Subquery.(*Projection) @@ -227,41 +219,37 @@ func tryPushSubQueryInJoin( // Projections are easy to push down, so if this is still at the top, // it means we have not tried pushing it yet. // Let's give it a chance to push down before we push it on the left - return nil, rewrite.SameTree, nil + return nil, NoRewrite } if deps.IsSolvedBy(lhs) { // we can safely push down the subquery on the LHS outer.LHS = addSubQuery(outer.LHS, inner) - return outer, rewrite.NewTree("push subquery into LHS of join"), nil + return outer, Rewrote("push subquery into LHS of join") } if outer.LeftJoin || len(inner.Predicates) == 0 { // we can't push any filters on the RHS of an outer join, and // we don't want to push uncorrelated subqueries to the RHS of a join - return nil, rewrite.SameTree, nil + return nil, NoRewrite } if deps.IsSolvedBy(rhs) { // we can push down the subquery filter on RHS of the join outer.RHS = addSubQuery(outer.RHS, inner) - return outer, rewrite.NewTree("push subquery into RHS of join"), nil + return outer, Rewrote("push subquery into RHS of join") } if deps.IsSolvedBy(joinID) { // we can rewrite the predicate to not use the values from the lhs, // and instead use arguments for these dependencies. // this way we can push the subquery into the RHS of this join - err := inner.mapExpr(extractLHSExpr(ctx, outer, lhs)) - if err != nil { - return nil, nil, err - } - + inner.mapExpr(extractLHSExpr(ctx, outer, lhs)) outer.RHS = addSubQuery(outer.RHS, inner) - return outer, rewrite.NewTree("push subquery into RHS of join rewriting predicates"), nil + return outer, Rewrote("push subquery into RHS of join rewriting predicates") } - return nil, rewrite.SameTree, nil + return nil, NoRewrite } // extractLHSExpr will return a function that extracts any ColName coming from the LHS table, @@ -270,37 +258,34 @@ func extractLHSExpr( ctx *plancontext.PlanningContext, outer *ApplyJoin, lhs semantics.TableSet, -) func(expr sqlparser.Expr) (sqlparser.Expr, error) { - return func(expr sqlparser.Expr) (sqlparser.Expr, error) { - col, err := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, lhs) - if err != nil { - return nil, err - } +) func(expr sqlparser.Expr) sqlparser.Expr { + return func(expr sqlparser.Expr) sqlparser.Expr { + col := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, lhs) if col.IsPureLeft() { - return nil, vterrors.VT13001("did not expect to find any predicates that do not need data from the inner here") + panic(vterrors.VT13001("did not expect to find any predicates that do not need data from the inner here")) } for _, bve := range col.LHSExprs { if !outer.isColNameMovedFromL2R(bve.Name) { outer.ExtraLHSVars = append(outer.ExtraLHSVars, bve) } } - return col.RHSExpr, nil + return col.RHSExpr } } // tryMergeWithRHS attempts to merge a subquery with the RHS of a join -func tryMergeWithRHS(ctx *plancontext.PlanningContext, inner *SubQuery, outer *ApplyJoin) (ops.Operator, *rewrite.ApplyResult, error) { +func tryMergeWithRHS(ctx *plancontext.PlanningContext, inner *SubQuery, outer *ApplyJoin) (Operator, *ApplyResult) { if outer.LeftJoin { - return nil, nil, nil + return nil, nil } // both sides need to be routes outerRoute, ok := outer.RHS.(*Route) if !ok { - return nil, nil, nil + return nil, nil } innerRoute, ok := inner.Subquery.(*Route) if !ok { - return nil, nil, nil + return nil, nil } newExpr := rewriteOriginalPushedToRHS(ctx, inner.Original, outer) @@ -311,18 +296,18 @@ func tryMergeWithRHS(ctx *plancontext.PlanningContext, inner *SubQuery, outer *A } newOp := mergeSubqueryInputs(ctx, innerRoute, outerRoute, inner.GetMergePredicates(), sqm) if newOp == nil { - return nil, nil, nil + return nil, nil } outer.RHS = newOp ctx.MergedSubqueries = append(ctx.MergedSubqueries, inner.originalSubquery) - return outer, rewrite.NewTree("merged subquery with rhs of join"), nil + return outer, Rewrote("merged subquery with rhs of join") } // addSubQuery adds a SubQuery to the given operator. If the operator is a SubQueryContainer, // it will add the SubQuery to the SubQueryContainer. If the operator is something else, it will // create a new SubQueryContainer with the given operator as the outer and the SubQuery as the inner. -func addSubQuery(in ops.Operator, inner *SubQuery) ops.Operator { +func addSubQuery(in Operator, inner *SubQuery) Operator { sql, ok := in.(*SubQueryContainer) if !ok { return &SubQueryContainer{ @@ -364,10 +349,10 @@ func rewriteOriginalPushedToRHS(ctx *plancontext.PlanningContext, expression sql return result.(sqlparser.Expr) } -func pushProjectionToOuterContainer(ctx *plancontext.PlanningContext, p *Projection, src *SubQueryContainer) (ops.Operator, *rewrite.ApplyResult, error) { +func pushProjectionToOuterContainer(ctx *plancontext.PlanningContext, p *Projection, src *SubQueryContainer) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { - return p, rewrite.SameTree, nil + return p, NoRewrite } outer := TableID(src.Outer) @@ -378,7 +363,7 @@ func pushProjectionToOuterContainer(ctx *plancontext.PlanningContext, p *Project } if !ctx.SemTable.RecursiveDeps(pe.EvalExpr).IsSolvedBy(outer) { - return p, rewrite.SameTree, nil + return p, NoRewrite } if se, ok := pe.Info.(SubQueryExpression); ok { @@ -387,7 +372,7 @@ func pushProjectionToOuterContainer(ctx *plancontext.PlanningContext, p *Project } // all projections can be pushed to the outer src.Outer, p.Source = p, src.Outer - return src, rewrite.NewTree("push projection into outer side of subquery container"), nil + return src, Rewrote("push projection into outer side of subquery container") } func rewriteColNameToArgument(ctx *plancontext.PlanningContext, in sqlparser.Expr, se SubQueryExpression, subqueries ...*SubQuery) sqlparser.Expr { @@ -433,19 +418,16 @@ func rewriteColNameToArgument(ctx *plancontext.PlanningContext, in sqlparser.Exp return result.(sqlparser.Expr) } -func pushOrMergeSubQueryContainer(ctx *plancontext.PlanningContext, in *SubQueryContainer) (ops.Operator, *rewrite.ApplyResult, error) { +func pushOrMergeSubQueryContainer(ctx *plancontext.PlanningContext, in *SubQueryContainer) (Operator, *ApplyResult) { if !reachedPhase(ctx, initialPlanning) { - return in, rewrite.SameTree, nil + return in, NoRewrite } var remaining []*SubQuery - var result *rewrite.ApplyResult + var result *ApplyResult for _, inner := range in.Inner { - newOuter, _result, err := pushOrMerge(ctx, in.Outer, inner) - if err != nil { - return nil, nil, err - } - if _result == rewrite.SameTree { + newOuter, _result := pushOrMerge(ctx, in.Outer, inner) + if _result == NoRewrite { remaining = append(remaining, inner) continue } @@ -455,26 +437,26 @@ func pushOrMergeSubQueryContainer(ctx *plancontext.PlanningContext, in *SubQuery } if len(remaining) == 0 { - return in.Outer, result, nil + return in.Outer, result } in.Inner = remaining - return in, result, nil + return in, result } func tryMergeSubQuery( ctx *plancontext.PlanningContext, subQuery *SubQuery, outer *Route, -) (newOuter ops.Operator, result *rewrite.ApplyResult, err error) { +) (newOuter Operator, result *ApplyResult) { switch inner := subQuery.Subquery.(type) { case *Route: return tryMergeSubqueryWithOuter(ctx, subQuery, outer, inner) case *SubQueryContainer: return tryMergeSubqueriesRecursively(ctx, subQuery, outer, inner) } - return outer, rewrite.SameTree, nil + return outer, NoRewrite } // tryMergeSubqueriesRecursively attempts to merge a SubQueryContainer with the outer Route. @@ -483,7 +465,7 @@ func tryMergeSubqueriesRecursively( subQuery *SubQuery, outer *Route, inner *SubQueryContainer, -) (ops.Operator, *rewrite.ApplyResult, error) { +) (Operator, *ApplyResult) { exprs := subQuery.GetMergePredicates() merger := &subqueryRouteMerger{ outer: outer, @@ -492,32 +474,29 @@ func tryMergeSubqueriesRecursively( } op := mergeSubqueryInputs(ctx, inner.Outer, outer, exprs, merger) if op == nil { - return outer, rewrite.SameTree, nil + return outer, NoRewrite } op = Clone(op).(*Route) op.Source = outer.Source - var finalResult *rewrite.ApplyResult + var finalResult *ApplyResult for _, subq := range inner.Inner { - newOuter, res, err := tryMergeSubQuery(ctx, subq, op) - if err != nil { - return nil, nil, err - } - if res == rewrite.SameTree { + newOuter, res := tryMergeSubQuery(ctx, subq, op) + if res == NoRewrite { // we failed to merge one of the inners - we need to abort - return nil, rewrite.SameTree, nil + return nil, NoRewrite } op = newOuter.(*Route) finalResult = finalResult.Merge(res) } op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}} - return op, finalResult.Merge(rewrite.NewTree("merge outer of two subqueries")), nil + return op, finalResult.Merge(Rewrote("merge outer of two subqueries")) } -func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQuery, outer *Route, inner ops.Operator) (ops.Operator, *rewrite.ApplyResult, error) { +func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQuery, outer *Route, inner Operator) (Operator, *ApplyResult) { if updOp, ok := outer.Source.(*Update); ok && mergingIsBlocked(subQuery, updOp) { - return outer, rewrite.SameTree, nil + return outer, NoRewrite } exprs := subQuery.GetMergePredicates() merger := &subqueryRouteMerger{ @@ -527,13 +506,13 @@ func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQu } op := mergeSubqueryInputs(ctx, inner, outer, exprs, merger) if op == nil { - return outer, rewrite.SameTree, nil + return outer, NoRewrite } if !subQuery.IsProjection { op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}} } ctx.MergedSubqueries = append(ctx.MergedSubqueries, subQuery.originalSubquery) - return op, rewrite.NewTree("merged subquery with outer"), nil + return op, Rewrote("merged subquery with outer") } // This checked if subquery is part of the changed vindex values. Subquery cannot be merged with the outer route. @@ -546,21 +525,18 @@ func mergingIsBlocked(subQuery *SubQuery, updOp *Update) bool { return false } -func pushOrMerge(ctx *plancontext.PlanningContext, outer ops.Operator, inner *SubQuery) (ops.Operator, *rewrite.ApplyResult, error) { +func pushOrMerge(ctx *plancontext.PlanningContext, outer Operator, inner *SubQuery) (Operator, *ApplyResult) { switch o := outer.(type) { case *Route: return tryMergeSubQuery(ctx, inner, o) case *ApplyJoin: - join, applyResult, err := tryPushSubQueryInJoin(ctx, inner, o) - if err != nil { - return nil, nil, err - } + join, applyResult := tryPushSubQueryInJoin(ctx, inner, o) if join == nil { - return outer, rewrite.SameTree, nil + return outer, NoRewrite } - return join, applyResult, nil + return join, applyResult default: - return outer, rewrite.SameTree, nil + return outer, NoRewrite } } @@ -618,10 +594,7 @@ func (s *subqueryRouteMerger) mergeShardedRouting(ctx *plancontext.PlanningConte }) } - routing, err := tr.resetRoutingLogic(ctx) - if err != nil { - panic(err) - } + routing := tr.resetRoutingLogic(ctx) return s.merge(ctx, old1, old2, routing) } @@ -637,7 +610,7 @@ func (s *subqueryRouteMerger) merge(ctx *plancontext.PlanningContext, inner, out } } _, isSharded := r.(*ShardedRouting) - var src ops.Operator + var src Operator if isSharded { src = s.outer.Source if !s.subq.IsProjection { @@ -665,7 +638,7 @@ func (s *subqueryRouteMerger) merge(ctx *plancontext.PlanningContext, inner, out // we should be able to use this method for all plan types, // but using this method for sharded queries introduces bugs // We really need to figure out why this is not working as expected -func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningContext, inner *Route) ops.Operator { +func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningContext, inner *Route) Operator { src := s.outer.Source stmt, _, err := ToSQL(ctx, inner.Source) if err != nil { @@ -726,7 +699,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont // If they can be merged, a new operator with the merged routing is returned // If they cannot be merged, nil is returned. // These rules are similar but different from join merging -func mergeSubqueryInputs(ctx *plancontext.PlanningContext, in, out ops.Operator, joinPredicates []sqlparser.Expr, m *subqueryRouteMerger) *Route { +func mergeSubqueryInputs(ctx *plancontext.PlanningContext, in, out Operator, joinPredicates []sqlparser.Expr, m *subqueryRouteMerger) *Route { inRoute, outRoute := operatorsToRoutes(in, out) if inRoute == nil || outRoute == nil { return nil diff --git a/go/vt/vtgate/planbuilder/operators/table.go b/go/vt/vtgate/planbuilder/operators/table.go index e731ec54201..93b406232b2 100644 --- a/go/vt/vtgate/planbuilder/operators/table.go +++ b/go/vt/vtgate/planbuilder/operators/table.go @@ -22,7 +22,6 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -43,7 +42,7 @@ type ( ) // Clone implements the Operator interface -func (to *Table) Clone([]ops.Operator) ops.Operator { +func (to *Table) Clone([]Operator) Operator { var columns []*sqlparser.ColName for _, name := range to.Columns { columns = append(columns, sqlparser.CloneRefOfColName(name)) @@ -61,7 +60,7 @@ func (to *Table) introducesTableID() semantics.TableSet { } // AddPredicate implements the PhysicalOperator interface -func (to *Table) AddPredicate(_ *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (to *Table) AddPredicate(_ *plancontext.PlanningContext, expr sqlparser.Expr) Operator { return newFilter(to, expr) } @@ -92,7 +91,7 @@ func (to *Table) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Sele return transformColumnsToSelectExprs(ctx, to) } -func (to *Table) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (to *Table) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } diff --git a/go/vt/vtgate/planbuilder/operators/ops/to_json.go b/go/vt/vtgate/planbuilder/operators/to_json.go similarity index 98% rename from go/vt/vtgate/planbuilder/operators/ops/to_json.go rename to go/vt/vtgate/planbuilder/operators/to_json.go index 2b8b747f433..48b7fa9a247 100644 --- a/go/vt/vtgate/planbuilder/operators/ops/to_json.go +++ b/go/vt/vtgate/planbuilder/operators/to_json.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package ops +package operators import ( "fmt" diff --git a/go/vt/vtgate/planbuilder/operators/union.go b/go/vt/vtgate/planbuilder/operators/union.go index b3d866a00a3..454a6370c2f 100644 --- a/go/vt/vtgate/planbuilder/operators/union.go +++ b/go/vt/vtgate/planbuilder/operators/union.go @@ -23,12 +23,11 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) type Union struct { - Sources []ops.Operator + Sources []Operator // These are the select expressions coming from each source Selects []sqlparser.SelectExprs @@ -38,7 +37,7 @@ type Union struct { unionColumnsAsAlisedExprs []*sqlparser.AliasedExpr } -func newUnion(srcs []ops.Operator, sourceSelects []sqlparser.SelectExprs, columns sqlparser.SelectExprs, distinct bool) *Union { +func newUnion(srcs []Operator, sourceSelects []sqlparser.SelectExprs, columns sqlparser.SelectExprs, distinct bool) *Union { if columns == nil { panic("rt") } @@ -51,24 +50,24 @@ func newUnion(srcs []ops.Operator, sourceSelects []sqlparser.SelectExprs, column } // Clone implements the Operator interface -func (u *Union) Clone(inputs []ops.Operator) ops.Operator { +func (u *Union) Clone(inputs []Operator) Operator { newOp := *u newOp.Sources = inputs newOp.Selects = slices.Clone(u.Selects) return &newOp } -func (u *Union) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (u *Union) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } // Inputs implements the Operator interface -func (u *Union) Inputs() []ops.Operator { +func (u *Union) Inputs() []Operator { return u.Sources } // SetInputs implements the Operator interface -func (u *Union) SetInputs(ops []ops.Operator) { +func (u *Union) SetInputs(ops []Operator) { u.Sources = ops } @@ -93,7 +92,7 @@ Notice how `X.col = 42` has been translated to `foo = 42` and `id = 42` on respe The first SELECT of the union dictates the column names, and the second is whatever expression can be found on the same offset. The names of the RHS are discarded. */ -func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { offsets := make(map[string]int) sel, err := u.GetSelectFor(0) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go index 03b7a212893..953d779c6a1 100644 --- a/go/vt/vtgate/planbuilder/operators/union_merging.go +++ b/go/vt/vtgate/planbuilder/operators/union_merging.go @@ -19,14 +19,12 @@ package operators import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) // mergeUnionInputInAnyOrder merges sources the sources of the union in any order // can be used for UNION DISTINCT -func mergeUnionInputInAnyOrder(ctx *plancontext.PlanningContext, op *Union) ([]ops.Operator, []sqlparser.SelectExprs, error) { +func mergeUnionInputInAnyOrder(ctx *plancontext.PlanningContext, op *Union) ([]Operator, []sqlparser.SelectExprs) { sources := op.Sources selects := op.Selects @@ -43,10 +41,7 @@ func mergeUnionInputInAnyOrder(ctx *plancontext.PlanningContext, op *Union) ([]o } selA := selects[idx] selB := selects[j] - newPlan, sel, err := mergeUnionInputs(ctx, srcA, srcB, selA, selB, op.distinct) - if err != nil { - return nil, nil, err - } + newPlan, sel := mergeUnionInputs(ctx, srcA, srcB, selA, selB, op.distinct) if newPlan != nil { sources[idx] = newPlan selects[idx] = sel @@ -57,10 +52,10 @@ func mergeUnionInputInAnyOrder(ctx *plancontext.PlanningContext, op *Union) ([]o } } if !merged { - return sources, selects, nil + return sources, selects } - var newSources []ops.Operator + var newSources []Operator var newSelects []sqlparser.SelectExprs for i, source := range sources { if keep[i] || i <= idx { @@ -73,10 +68,10 @@ func mergeUnionInputInAnyOrder(ctx *plancontext.PlanningContext, op *Union) ([]o selects = newSelects } - return sources, selects, nil + return sources, selects } -func mergeUnionInputsInOrder(ctx *plancontext.PlanningContext, op *Union) ([]ops.Operator, []sqlparser.SelectExprs, error) { +func mergeUnionInputsInOrder(ctx *plancontext.PlanningContext, op *Union) ([]Operator, []sqlparser.SelectExprs) { sources := op.Sources selects := op.Selects for { @@ -85,10 +80,7 @@ func mergeUnionInputsInOrder(ctx *plancontext.PlanningContext, op *Union) ([]ops j := i + 1 srcA, selA := sources[i], selects[i] srcB, selB := sources[j], selects[j] - newPlan, sel, err := mergeUnionInputs(ctx, srcA, srcB, selA, selB, op.distinct) - if err != nil { - return nil, nil, err - } + newPlan, sel := mergeUnionInputs(ctx, srcA, srcB, selA, selB, op.distinct) if newPlan != nil { sources[i] = newPlan selects[i] = sel @@ -102,7 +94,7 @@ func mergeUnionInputsInOrder(ctx *plancontext.PlanningContext, op *Union) ([]ops } } - return sources, selects, nil + return sources, selects } // mergeUnionInputs checks whether two operators can be merged into a single one. @@ -111,13 +103,13 @@ func mergeUnionInputsInOrder(ctx *plancontext.PlanningContext, op *Union) ([]ops // this function is very similar to mergeJoinInputs func mergeUnionInputs( ctx *plancontext.PlanningContext, - lhs, rhs ops.Operator, + lhs, rhs Operator, lhsExprs, rhsExprs sqlparser.SelectExprs, distinct bool, -) (ops.Operator, sqlparser.SelectExprs, error) { +) (Operator, sqlparser.SelectExprs) { lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(lhs, rhs) if lhsRoute == nil { - return nil, nil, nil + return nil, nil } switch { @@ -134,12 +126,12 @@ func mergeUnionInputs( return createMergedUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routingA) case a == sharded && b == sharded && sameKeyspace: - res, exprs, err := tryMergeUnionShardedRouting(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct) - if err != nil || res != nil { - return res, exprs, err + res, exprs := tryMergeUnionShardedRouting(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct) + if res != nil { + return res, exprs } } - return nil, nil, nil + return nil, nil } func tryMergeUnionShardedRouting( @@ -147,7 +139,7 @@ func tryMergeUnionShardedRouting( routeA, routeB *Route, exprsA, exprsB sqlparser.SelectExprs, distinct bool, -) (ops.Operator, sqlparser.SelectExprs, error) { +) (Operator, sqlparser.SelectExprs) { tblA := routeA.Routing.(*ShardedRouting) tblB := routeB.Routing.(*ShardedRouting) @@ -173,7 +165,7 @@ func tryMergeUnionShardedRouting( } } - return nil, nil, nil + return nil, nil } func createMergedUnion( @@ -181,7 +173,7 @@ func createMergedUnion( lhsRoute, rhsRoute *Route, lhsExprs, rhsExprs sqlparser.SelectExprs, distinct bool, - routing Routing) (ops.Operator, sqlparser.SelectExprs, error) { + routing Routing) (Operator, sqlparser.SelectExprs) { // if there are `*` on either side, or a different number of SelectExpr items, // we give up aligning the expressions and trust that we can push everything down @@ -210,16 +202,16 @@ func createMergedUnion( ctx.SemTable.Recursive[col] = deps } - union := newUnion([]ops.Operator{lhsRoute.Source, rhsRoute.Source}, []sqlparser.SelectExprs{lhsExprs, rhsExprs}, cols, distinct) + union := newUnion([]Operator{lhsRoute.Source, rhsRoute.Source}, []sqlparser.SelectExprs{lhsExprs, rhsExprs}, cols, distinct) selectExprs := unionSelects(lhsExprs) return &Route{ Source: union, MergedWith: []*Route{rhsRoute}, Routing: routing, - }, selectExprs, nil + }, selectExprs } -func compactUnion(u *Union) *rewrite.ApplyResult { +func compactUnion(u *Union) *ApplyResult { if u.distinct { // first we remove unnecessary DISTINCTs for idx, source := range u.Sources { @@ -231,7 +223,7 @@ func compactUnion(u *Union) *rewrite.ApplyResult { } } - var newSources []ops.Operator + var newSources []Operator var newSelects []sqlparser.SelectExprs merged := false @@ -250,10 +242,10 @@ func compactUnion(u *Union) *rewrite.ApplyResult { } if !merged { - return rewrite.SameTree + return NoRewrite } u.Sources = newSources u.Selects = newSelects - return rewrite.NewTree("merged UNIONs") + return Rewrote("merged UNIONs") } diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 8868e83c247..ccfdddc3ea9 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -28,7 +28,6 @@ import ( "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -71,14 +70,14 @@ func (u *Update) introducesTableID() semantics.TableSet { } // Clone implements the Operator interface -func (u *Update) Clone([]ops.Operator) ops.Operator { +func (u *Update) Clone([]Operator) Operator { upd := *u upd.Assignments = slices.Clone(u.Assignments) upd.ChangedVindexValues = maps.Clone(u.ChangedVindexValues) return &upd } -func (u *Update) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (u *Update) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } @@ -100,51 +99,39 @@ func (u *Update) ShortDescription() string { return strings.Join(s, " ") } -func createOperatorFromUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update) (ops.Operator, error) { - tableInfo, qt, err := createQueryTableForDML(ctx, updStmt.TableExprs[0], updStmt.Where) - if err != nil { - return nil, err - } +func createOperatorFromUpdate(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update) Operator { + tableInfo, qt := createQueryTableForDML(ctx, updStmt.TableExprs[0], updStmt.Where) - vindexTable, routing, err := buildVindexTableForDML(ctx, tableInfo, qt, "update") - if err != nil { - return nil, err - } + vindexTable, routing := buildVindexTableForDML(ctx, tableInfo, qt, "update") updClone := sqlparser.CloneRefOfUpdate(updStmt) - updOp, err := createUpdateOperator(ctx, updStmt, vindexTable, qt, routing) - if err != nil { - return nil, err - } + updOp := createUpdateOperator(ctx, updStmt, vindexTable, qt, routing) parentFks := ctx.SemTable.GetParentForeignKeysList() childFks := ctx.SemTable.GetChildForeignKeysList() if len(childFks) == 0 && len(parentFks) == 0 { - return updOp, nil + return updOp } // If the delete statement has a limit, we don't support it yet. if updStmt.Limit != nil { - return nil, vterrors.VT12001("update with limit with foreign key constraints") + panic(vterrors.VT12001("update with limit with foreign key constraints")) } // Now we check if any of the foreign key columns that are being udpated have dependencies on other updated columns. // This is unsafe, and we currently don't support this in Vitess. - if err = ctx.SemTable.ErrIfFkDependentColumnUpdated(updStmt.Exprs); err != nil { - return nil, err + if err := ctx.SemTable.ErrIfFkDependentColumnUpdated(updStmt.Exprs); err != nil { + panic(err) } return buildFkOperator(ctx, updOp, updClone, parentFks, childFks, vindexTable) } -func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, vindexTable *vindexes.Table, qt *QueryTable, routing Routing) (ops.Operator, error) { +func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.Update, vindexTable *vindexes.Table, qt *QueryTable, routing Routing) Operator { sqc := &SubQueryBuilder{} assignments := make([]SetExpr, len(updStmt.Exprs)) for idx, updExpr := range updStmt.Exprs { - expr, subqs, err := sqc.pullOutValueSubqueries(ctx, updExpr.Expr, qt.ID, true) - if err != nil { - return nil, err - } + expr, subqs := sqc.pullOutValueSubqueries(ctx, updExpr.Expr, qt.ID, true) if len(subqs) == 0 { expr = updExpr.Expr } @@ -158,10 +145,7 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U } } - vp, cvv, ovq, subQueriesArgOnChangedVindex, err := getUpdateVindexInformation(ctx, updStmt, vindexTable, qt.ID, assignments) - if err != nil { - return nil, err - } + vp, cvv, ovq, subQueriesArgOnChangedVindex := getUpdateVindexInformation(ctx, updStmt, vindexTable, qt.ID, assignments) tr, ok := routing.(*ShardedRouting) if ok { @@ -169,20 +153,15 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U } for _, predicate := range qt.Predicates { - if subq, err := sqc.handleSubquery(ctx, predicate, qt.ID); err != nil { - return nil, err - } else if subq != nil { + if subq := sqc.handleSubquery(ctx, predicate, qt.ID); subq != nil { continue } - routing, err = UpdateRoutingLogic(ctx, predicate, routing) - if err != nil { - return nil, err - } + routing = UpdateRoutingLogic(ctx, predicate, routing) } if routing.OpCode() == engine.Scatter && updStmt.Limit != nil { // TODO systay: we should probably check for other op code types - IN could also hit multiple shards (2022-04-07) - return nil, vterrors.VT12001("multi shard UPDATE with LIMIT") + panic(vterrors.VT12001("multi shard UPDATE with LIMIT")) } route := &Route{ @@ -201,23 +180,20 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U Comments: updStmt.Comments, } - decorator := func(op ops.Operator) ops.Operator { + decorator := func(op Operator) Operator { return &LockAndComment{ Source: op, Lock: sqlparser.ShareModeLock, } } - return sqc.getRootOperator(route, decorator), nil + return sqc.getRootOperator(route, decorator) } -func buildFkOperator(ctx *plancontext.PlanningContext, updOp ops.Operator, updClone *sqlparser.Update, parentFks []vindexes.ParentFKInfo, childFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table) (ops.Operator, error) { +func buildFkOperator(ctx *plancontext.PlanningContext, updOp Operator, updClone *sqlparser.Update, parentFks []vindexes.ParentFKInfo, childFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table) Operator { restrictChildFks, cascadeChildFks := splitChildFks(childFks) - op, err := createFKCascadeOp(ctx, updOp, updClone, cascadeChildFks, updatedTable) - if err != nil { - return nil, err - } + op := createFKCascadeOp(ctx, updOp, updClone, cascadeChildFks, updatedTable) return createFKVerifyOp(ctx, op, updClone, parentFks, restrictChildFks, updatedTable) } @@ -241,9 +217,9 @@ func splitChildFks(fks []vindexes.ChildFKInfo) (restrictChildFks, cascadeChildFk return } -func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, updStmt *sqlparser.Update, childFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table) (ops.Operator, error) { +func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp Operator, updStmt *sqlparser.Update, childFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table) Operator { if len(childFks) == 0 { - return parentOp, nil + return parentOp } var fkChildren []*FkChild @@ -252,7 +228,7 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, for _, fk := range childFks { // We should have already filtered out update restrict foreign keys. if fk.OnUpdate.IsRestrict() { - return nil, vterrors.VT13001("ON UPDATE RESTRICT foreign keys should already be filtered") + panic(vterrors.VT13001("ON UPDATE RESTRICT foreign keys should already be filtered")) } // We need to select all the parent columns for the foreign key constraint, to use in the update of the child table. @@ -275,23 +251,17 @@ func createFKCascadeOp(ctx *plancontext.PlanningContext, parentOp ops.Operator, } } - fkChild, err := createFkChildForUpdate(ctx, fk, selectOffsets, nonLiteralUpdateInfo, updatedTable) - if err != nil { - return nil, err - } + fkChild := createFkChildForUpdate(ctx, fk, selectOffsets, nonLiteralUpdateInfo, updatedTable) fkChildren = append(fkChildren, fkChild) } - selectionOp, err := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, updStmt.OrderBy, nil, sqlparser.ForUpdateLockNoWait) - if err != nil { - return nil, err - } + selectionOp := createSelectionOp(ctx, selectExprs, updStmt.TableExprs, updStmt.Where, updStmt.OrderBy, nil, sqlparser.ForUpdateLockNoWait) return &FkCascade{ Selection: selectionOp, Children: fkChildren, Parent: parentOp, - }, nil + } } // hasNonLiteralUpdate checks if any of the update expressions have a non-literal update. @@ -404,7 +374,7 @@ func getCastTypeForColumn(updatedTable *vindexes.Table, updExpr *sqlparser.Updat } // createFkChildForUpdate creates the update query operator for the child table based on the foreign key constraints. -func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, selectOffsets []int, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) (*FkChild, error) { +func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, selectOffsets []int, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) *FkChild { // Create a ValTuple of child column names var valTuple sqlparser.ValTuple for _, column := range fk.ChildColumns { @@ -426,18 +396,14 @@ func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildF } } - var childOp ops.Operator - var err error + var childOp Operator switch fk.OnUpdate { case sqlparser.Cascade: - childOp, err = buildChildUpdOpForCascade(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) + childOp = buildChildUpdOpForCascade(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) case sqlparser.SetNull: - childOp, err = buildChildUpdOpForSetNull(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) + childOp = buildChildUpdOpForSetNull(ctx, fk, childWhereExpr, nonLiteralUpdateInfo, updatedTable) case sqlparser.SetDefault: - return nil, vterrors.VT09016() - } - if err != nil { - return nil, err + panic(vterrors.VT09016()) } return &FkChild{ @@ -445,14 +411,14 @@ func createFkChildForUpdate(ctx *plancontext.PlanningContext, fk vindexes.ChildF Cols: selectOffsets, Op: childOp, NonLiteralInfo: nonLiteralUpdateInfo, - }, nil + } } // buildChildUpdOpForCascade builds the child update statement operator for the CASCADE type foreign key constraint. // The query looks like this - // // `UPDATE SET WHERE IN ()` -func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, childWhereExpr sqlparser.Expr, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) (ops.Operator, error) { +func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.ChildFKInfo, childWhereExpr sqlparser.Expr, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table) Operator { // The update expressions are the same as the update expressions in the parent update query // with the column names replaced with the child column names. var childUpdateExprs sqlparser.UpdateExprs @@ -501,7 +467,7 @@ func buildChildUpdOpForSetNull( childWhereExpr sqlparser.Expr, nonLiteralUpdateInfo []engine.NonLiteralUpdateInfo, updatedTable *vindexes.Table, -) (ops.Operator, error) { +) Operator { // For the SET NULL type constraint, we need to set all the child columns to NULL. var childUpdateExprs sqlparser.UpdateExprs for _, column := range fk.ChildColumns { @@ -557,23 +523,20 @@ func getParsedCommentsForFkChecks(ctx *plancontext.PlanningContext) (parsedComme // createFKVerifyOp creates the verify operator for the parent foreign key constraints. func createFKVerifyOp( ctx *plancontext.PlanningContext, - childOp ops.Operator, + childOp Operator, updStmt *sqlparser.Update, parentFks []vindexes.ParentFKInfo, restrictChildFks []vindexes.ChildFKInfo, updatedTable *vindexes.Table, -) (ops.Operator, error) { +) Operator { if len(parentFks) == 0 && len(restrictChildFks) == 0 { - return childOp, nil + return childOp } var Verify []*VerifyOp // This validates that new values exists on the parent table. for _, fk := range parentFks { - op, err := createFkVerifyOpForParentFKForUpdate(ctx, updatedTable, updStmt, fk) - if err != nil { - return nil, err - } + op := createFkVerifyOpForParentFKForUpdate(ctx, updatedTable, updStmt, fk) Verify = append(Verify, &VerifyOp{ Op: op, Typ: engine.ParentVerify, @@ -581,10 +544,8 @@ func createFKVerifyOp( } // This validates that the old values don't exist on the child table. for _, fk := range restrictChildFks { - op, err := createFkVerifyOpForChildFKForUpdate(ctx, updatedTable, updStmt, fk) - if err != nil { - return nil, err - } + op := createFkVerifyOpForChildFKForUpdate(ctx, updatedTable, updStmt, fk) + Verify = append(Verify, &VerifyOp{ Op: op, Typ: engine.ChildVerify, @@ -594,7 +555,7 @@ func createFKVerifyOp( return &FkVerify{ Verify: Verify, Input: childOp, - }, nil + } } // Each parent foreign key constraint is verified by an anti join query of the form: @@ -608,11 +569,11 @@ func createFKVerifyOp( // where Parent.p1 is null and Parent.p2 is null and Child.id = 1 and Child.c2 + 1 is not null // and Child.c2 is not null and not ((Child.c1) <=> (Child.c2 + 1)) // limit 1 -func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) (ops.Operator, error) { +func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, pFK vindexes.ParentFKInfo) Operator { childTblExpr := updStmt.TableExprs[0].(*sqlparser.AliasedTableExpr) childTbl, err := childTblExpr.TableName() if err != nil { - return nil, err + panic(err) } parentTbl := pFK.Table.GetTableName() var whereCond sqlparser.Expr @@ -708,16 +669,16 @@ func createFkVerifyOpForParentFKForUpdate(ctx *plancontext.PlanningContext, upda // verify query: // select 1 from Child join Parent on Parent.p1 = Child.c1 and Parent.p2 = Child.c2 // where Parent.id = 1 and ((Parent.col + 1) IS NULL OR (child.c1) NOT IN ((Parent.col + 1))) limit 1 -func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, cFk vindexes.ChildFKInfo) (ops.Operator, error) { +func createFkVerifyOpForChildFKForUpdate(ctx *plancontext.PlanningContext, updatedTable *vindexes.Table, updStmt *sqlparser.Update, cFk vindexes.ChildFKInfo) Operator { // ON UPDATE RESTRICT foreign keys that require validation, should only be allowed in the case where we // are verifying all the FKs on vtgate level. if !ctx.VerifyAllFKs { - return nil, vterrors.VT12002() + panic(vterrors.VT12002()) } parentTblExpr := updStmt.TableExprs[0].(*sqlparser.AliasedTableExpr) parentTbl, err := parentTblExpr.TableName() if err != nil { - return nil, err + panic(err) } childTbl := cFk.Table.GetTableName() var joinCond sqlparser.Expr diff --git a/go/vt/vtgate/planbuilder/operators/utils_test.go b/go/vt/vtgate/planbuilder/operators/utils_test.go index a7e25c1337c..596489150da 100644 --- a/go/vt/vtgate/planbuilder/operators/utils_test.go +++ b/go/vt/vtgate/planbuilder/operators/utils_test.go @@ -20,33 +20,32 @@ import ( "slices" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) type fakeOp struct { id semantics.TableSet - inputs []ops.Operator + inputs []Operator cols []*sqlparser.AliasedExpr } -var _ ops.Operator = (*fakeOp)(nil) +var _ Operator = (*fakeOp)(nil) -func (f *fakeOp) Clone(inputs []ops.Operator) ops.Operator { +func (f *fakeOp) Clone(inputs []Operator) Operator { return f } -func (f *fakeOp) Inputs() []ops.Operator { +func (f *fakeOp) Inputs() []Operator { return f.inputs } -func (f *fakeOp) SetInputs(operators []ops.Operator) { +func (f *fakeOp) SetInputs(operators []Operator) { // TODO implement me panic("implement me") } -func (f *fakeOp) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (f *fakeOp) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { // TODO implement me panic("implement me") } @@ -80,7 +79,7 @@ func (f *fakeOp) ShortDescription() string { panic("implement me") } -func (f *fakeOp) GetOrdering(ctx *plancontext.PlanningContext) []ops.OrderBy { +func (f *fakeOp) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { // TODO implement me panic("implement me") } diff --git a/go/vt/vtgate/planbuilder/operators/vindex.go b/go/vt/vtgate/planbuilder/operators/vindex.go index 2fe2bf4d3e5..f8667b45aba 100644 --- a/go/vt/vtgate/planbuilder/operators/vindex.go +++ b/go/vt/vtgate/planbuilder/operators/vindex.go @@ -21,7 +21,6 @@ import ( "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/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -57,7 +56,7 @@ func (v *Vindex) introducesTableID() semantics.TableSet { } // Clone implements the Operator interface -func (v *Vindex) Clone([]ops.Operator) ops.Operator { +func (v *Vindex) Clone([]Operator) Operator { clone := *v return &clone } @@ -101,7 +100,7 @@ func (v *Vindex) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.Sele return transformColumnsToSelectExprs(ctx, v) } -func (v *Vindex) GetOrdering(*plancontext.PlanningContext) []ops.OrderBy { +func (v *Vindex) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } @@ -121,7 +120,7 @@ func (v *Vindex) CheckValid() error { return nil } -func (v *Vindex) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) ops.Operator { +func (v *Vindex) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { for _, e := range sqlparser.SplitAndExpression(nil, expr) { deps := ctx.SemTable.RecursiveDeps(e) if deps.NumberOfTables() > 1 { diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index a488dd1e470..b5c814b2ea6 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -41,7 +41,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/vtgate/engine" - oprewriters "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -261,7 +261,7 @@ func TestViews(t *testing.T) { } func TestOne(t *testing.T) { - reset := oprewriters.EnableDebugPrinting() + reset := operators.EnableDebugPrinting() defer reset() lv := loadSchema(t, "vschemas/schema.json", true) @@ -319,7 +319,7 @@ func TestOneWithUserAsDefault(t *testing.T) { } func TestOneWithTPCHVSchema(t *testing.T) { - reset := oprewriters.EnableDebugPrinting() + reset := operators.EnableDebugPrinting() defer reset() vschema := &vschemawrapper.VSchemaWrapper{ V: loadSchema(t, "vschemas/tpch_schema.json", true), diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 44976815bd2..77c883325c5 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -26,7 +26,6 @@ import ( "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -225,7 +224,7 @@ func newBuildSelectPlan( return plan, operators.TablesUsed(op), nil } -func createSelectOperator(ctx *plancontext.PlanningContext, selStmt sqlparser.SelectStatement, reservedVars *sqlparser.ReservedVars) (ops.Operator, error) { +func createSelectOperator(ctx *plancontext.PlanningContext, selStmt sqlparser.SelectStatement, reservedVars *sqlparser.ReservedVars) (operators.Operator, error) { err := queryRewrite(ctx.SemTable, reservedVars, selStmt) if err != nil { return nil, err From 15607eb2cda4fc1e2205f27ccf04056568539c4c Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Mon, 4 Dec 2023 12:53:15 +0100 Subject: [PATCH 071/119] vtbackup: Fix copy pasta typo in option description (#14664) Signed-off-by: Dirkjan Bussink --- go/cmd/vtbackup/cli/vtbackup.go | 2 +- go/flags/endtoend/vtbackup.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/cmd/vtbackup/cli/vtbackup.go b/go/cmd/vtbackup/cli/vtbackup.go index 560e9d21b2a..d55cf643de4 100644 --- a/go/cmd/vtbackup/cli/vtbackup.go +++ b/go/cmd/vtbackup/cli/vtbackup.go @@ -208,7 +208,7 @@ func init() { Main.Flags().IntVar(&mysqlPort, "mysql_port", mysqlPort, "mysql port") Main.Flags().StringVar(&mysqlSocket, "mysql_socket", mysqlSocket, "path to the mysql socket") Main.Flags().DurationVar(&mysqlTimeout, "mysql_timeout", mysqlTimeout, "how long to wait for mysqld startup") - Main.Flags().DurationVar(&mysqlShutdownTimeout, "mysql-shutdown-timeout", mysqlShutdownTimeout, "how long to wait for mysqld startup") + Main.Flags().DurationVar(&mysqlShutdownTimeout, "mysql-shutdown-timeout", mysqlShutdownTimeout, "how long to wait for mysqld shutdown") Main.Flags().StringVar(&initDBSQLFile, "init_db_sql_file", initDBSQLFile, "path to .sql file to run after mysql_install_db") Main.Flags().BoolVar(&detachedMode, "detach", detachedMode, "detached mode - run backups detached from the terminal") Main.Flags().DurationVar(&keepAliveTimeout, "keep-alive-timeout", keepAliveTimeout, "Wait until timeout elapses after a successful backup before shutting down.") diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index 3971472b74b..5fedbde91c6 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -174,7 +174,7 @@ Flags: --mycnf_slow_log_path string mysql slow query log path --mycnf_socket_file string mysql socket file --mycnf_tmp_dir string mysql tmp directory - --mysql-shutdown-timeout duration how long to wait for mysqld startup (default 5m0s) + --mysql-shutdown-timeout duration how long to wait for mysqld shutdown (default 5m0s) --mysql_port int mysql port (default 3306) --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") --mysql_socket string path to the mysql socket From 4fb3c3f6767da18c18c209e74b764b7ba742c20e Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Mon, 4 Dec 2023 06:56:53 -0500 Subject: [PATCH 072/119] VReplication: Properly Handle FK Constraints When Deferring Secondary Keys (#14543) Signed-off-by: Matt Lord --- .../tabletmanager/vreplication/vreplicator.go | 21 ++++++- .../vreplication/vreplicator_test.go | 59 ++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index c4df7e618d5..2a362645708 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -739,8 +739,27 @@ func (vr *vreplicator) getTableSecondaryKeys(ctx context.Context, tableName stri return nil, fmt.Errorf("could not determine CREATE TABLE statement from table schema %q", tableSchema) } - for _, index := range createTable.GetTableSpec().Indexes { + tableSpec := createTable.GetTableSpec() + fkIndexCols := make(map[string]bool) + for _, constraint := range tableSpec.Constraints { + if fkDef, ok := constraint.Details.(*sqlparser.ForeignKeyDefinition); ok { + fkCols := make([]string, len(fkDef.Source)) + for i, fkCol := range fkDef.Source { + fkCols[i] = fkCol.Lowered() + } + fkIndexCols[strings.Join(fkCols, ",")] = true + } + } + for _, index := range tableSpec.Indexes { if index.Info.Type != sqlparser.IndexTypePrimary { + cols := make([]string, len(index.Columns)) + for i, col := range index.Columns { + cols[i] = col.Column.Lowered() + } + if fkIndexCols[strings.Join(cols, ",")] { + // This index is needed for a FK constraint so we cannot drop it. + continue + } secondaryKeys = append(secondaryKeys, index) } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go index aaa4a974191..dd4b9dc70f8 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go @@ -34,9 +34,10 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/schemadiff" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" - "vitess.io/vitess/go/vt/schemadiff" ) func TestRecalculatePKColsInfoByColumnNames(t *testing.T) { @@ -256,6 +257,7 @@ func TestDeferSecondaryKeys(t *testing.T) { wantStashErr string wantExecErr string expectFinalSchemaDiff bool + preStashHook func() error postStashHook func() error }{ { @@ -297,6 +299,54 @@ func TestDeferSecondaryKeys(t *testing.T) { actionDDL: "alter table %s.t1 add key c1 (c1), add key c2 (c2)", WorkflowType: int32(binlogdatapb.VReplicationWorkflowType_MoveTables), }, + { + name: "2SK:1FK", + tableName: "t1", + initialDDL: "create table t1 (id int not null, c1 int default null, c2 int default null, t2_id int not null, primary key (id), key c1 (c1), key c2 (c2), foreign key (t2_id) references t2 (id))", + // Secondary key t2_id is needed to enforce the FK constraint so we do not drop it. + strippedDDL: "create table t1 (id int not null, c1 int default null, c2 int default null, t2_id int not null, primary key (id), key t2_id (t2_id), constraint t1_ibfk_1 foreign key (t2_id) references t2 (id))", + actionDDL: "alter table %s.t1 add key c1 (c1), add key c2 (c2)", + WorkflowType: int32(binlogdatapb.VReplicationWorkflowType_MoveTables), + preStashHook: func() error { + if _, err := dbClient.ExecuteFetch("drop table if exists t2", 1); err != nil { + return err + } + _, err = dbClient.ExecuteFetch("create table t2 (id int not null, c1 int not null, primary key (id))", 1) + return err + }, + }, + { + name: "3SK:2FK", + tableName: "t1", + initialDDL: "create table t1 (id int not null, id2 int default null, c1 int default null, c2 int default null, c3 int default null, t2_id int not null, t2_id2 int not null, primary key (id), key c1 (c1), key c2 (c2), foreign key (t2_id) references t2 (id), key c3 (c3), foreign key (t2_id2) references t2 (id2))", + // Secondary keys t2_id and t2_id2 are needed to enforce the FK constraint so we do not drop them. + strippedDDL: "create table t1 (id int not null, id2 int default null, c1 int default null, c2 int default null, c3 int default null, t2_id int not null, t2_id2 int not null, primary key (id), key t2_id (t2_id), key t2_id2 (t2_id2), constraint t1_ibfk_1 foreign key (t2_id) references t2 (id), constraint t1_ibfk_2 foreign key (t2_id2) references t2 (id2))", + actionDDL: "alter table %s.t1 add key c1 (c1), add key c2 (c2), add key c3 (c3)", + WorkflowType: int32(binlogdatapb.VReplicationWorkflowType_MoveTables), + preStashHook: func() error { + if _, err := dbClient.ExecuteFetch("drop table if exists t2", 1); err != nil { + return err + } + _, err = dbClient.ExecuteFetch("create table t2 (id int not null, id2 int default null, c1 int not null, primary key (id), key (id2))", 1) + return err + }, + }, + { + name: "5SK:2FK_multi-column", + tableName: "t1", + initialDDL: "create table t1 (id int not null, id2 int default null, c1 int default null, c2 int default null, c3 int default null, t2_id int not null, t2_id2 int not null, primary key (id), key c1 (c1), key c2 (c2), key t2_cs (c1,c2), key t2_ids (t2_id,t2_id2), foreign key (t2_id,t2_id2) references t2 (id, id2), key c3 (c3), foreign key (c1, c2) references t2 (c1, c2))", + // Secondary keys t2_ids and t2_cs are needed to enforce the FK constraint so we do not drop them. + strippedDDL: "create table t1 (id int not null, id2 int default null, c1 int default null, c2 int default null, c3 int default null, t2_id int not null, t2_id2 int not null, primary key (id), key t2_cs (c1,c2), key t2_ids (t2_id,t2_id2), constraint t1_ibfk_1 foreign key (t2_id, t2_id2) references t2 (id, id2), constraint t1_ibfk_2 foreign key (c1, c2) references t2 (c1, c2))", + actionDDL: "alter table %s.t1 add key c1 (c1), add key c2 (c2), add key c3 (c3)", + WorkflowType: int32(binlogdatapb.VReplicationWorkflowType_MoveTables), + preStashHook: func() error { + if _, err := dbClient.ExecuteFetch("drop table if exists t2", 1); err != nil { + return err + } + _, err = dbClient.ExecuteFetch("create table t2 (id int not null, id2 int not null, c1 int not null, c2 int not null, primary key (id,id2), key (c1,c2))", 1) + return err + }, + }, { name: "2tSK", tableName: "t1", @@ -425,6 +475,11 @@ func TestDeferSecondaryKeys(t *testing.T) { // MoveTables and Reshard workflows. vr.WorkflowType = tcase.WorkflowType + if tcase.preStashHook != nil { + err = tcase.preStashHook() + require.NoError(t, err, "error executing pre stash hook: %v", err) + } + // Create the table. _, err := dbClient.ExecuteFetch(tcase.initialDDL, 1) require.NoError(t, err) @@ -456,7 +511,7 @@ func TestDeferSecondaryKeys(t *testing.T) { if tcase.postStashHook != nil { err = tcase.postStashHook() - require.NoError(t, err) + require.NoError(t, err, "error executing post stash hook: %v", err) // We should still NOT have any secondary keys because there's still // a running controller/vreplicator in the copy phase. From eae8894aed3fd3fcb77ff69d37e5d98775d39b10 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:04:49 +0200 Subject: [PATCH 073/119] TableGC: speed up GC process via `RequestChecks()`. Utilized by Online DDL for artifact cleanup (#14431) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletmanager/tablegc/tablegc_test.go | 168 +++++++++++------- go/timer/suspendable_ticker.go | 20 ++- go/timer/suspendable_ticker_test.go | 144 +++++++++++++++ go/vt/vttablet/onlineddl/executor.go | 5 + go/vt/vttablet/tabletserver/gc/tablegc.go | 145 +++++++++------ .../vttablet/tabletserver/gc/tablegc_test.go | 8 +- go/vt/vttablet/tabletserver/tabletserver.go | 2 +- 7 files changed, 359 insertions(+), 133 deletions(-) create mode 100644 go/timer/suspendable_ticker_test.go diff --git a/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go b/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go index c6f7253c791..c21a4fe2d99 100644 --- a/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go +++ b/go/test/endtoend/tabletmanager/tablegc/tablegc_test.go @@ -26,6 +26,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vttablet/tabletserver/gc" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/onlineddl" @@ -128,13 +129,18 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -func checkTableRows(t *testing.T, tableName string, expect int64) { +func getTableRows(t *testing.T, tableName string) int64 { require.NotEmpty(t, tableName) query := `select count(*) as c from %a` parsed := sqlparser.BuildParsedQuery(query, tableName) rs, err := primaryTablet.VttabletProcess.QueryTablet(parsed.Query, keyspaceName, true) require.NoError(t, err) count := rs.Named().Row().AsInt64("c", 0) + return count +} + +func checkTableRows(t *testing.T, tableName string, expect int64) { + count := getTableRows(t, tableName) assert.Equal(t, expect, count) } @@ -176,19 +182,18 @@ func validateTableDoesNotExist(t *testing.T, tableExpr string) { defer cancel() ticker := time.NewTicker(time.Second) - var foundTableName string - var exists bool - var err error + defer ticker.Stop() + for { + exists, foundTableName, err := tableExists(tableExpr) + require.NoError(t, err) + if !exists { + return + } select { case <-ticker.C: - exists, foundTableName, err = tableExists(tableExpr) - require.NoError(t, err) - if !exists { - return - } case <-ctx.Done(): - assert.NoError(t, ctx.Err(), "validateTableDoesNotExist timed out, table %v still exists (%v)", tableExpr, foundTableName) + assert.Failf(t, "validateTableDoesNotExist timed out, table %v still exists (%v)", tableExpr, foundTableName) return } } @@ -199,59 +204,78 @@ func validateTableExists(t *testing.T, tableExpr string) { defer cancel() ticker := time.NewTicker(time.Second) - var exists bool - var err error + defer ticker.Stop() + for { + exists, _, err := tableExists(tableExpr) + require.NoError(t, err) + if exists { + return + } select { case <-ticker.C: - exists, _, err = tableExists(tableExpr) - require.NoError(t, err) - if exists { - return - } case <-ctx.Done(): - assert.NoError(t, ctx.Err(), "validateTableExists timed out, table %v still does not exist", tableExpr) + assert.Failf(t, "validateTableExists timed out, table %v still does not exist", tableExpr) return } } } func validateAnyState(t *testing.T, expectNumRows int64, states ...schema.TableGCState) { - for _, state := range states { - expectTableToExist := true - searchExpr := "" - switch state { - case schema.HoldTableGCState: - searchExpr = `\_vt\_HOLD\_%` - case schema.PurgeTableGCState: - searchExpr = `\_vt\_PURGE\_%` - case schema.EvacTableGCState: - searchExpr = `\_vt\_EVAC\_%` - case schema.DropTableGCState: - searchExpr = `\_vt\_DROP\_%` - case schema.TableDroppedGCState: - searchExpr = `\_vt\_%` - expectTableToExist = false - default: - t.Log("Unknown state") - t.Fail() - } - exists, tableName, err := tableExists(searchExpr) - require.NoError(t, err) - - if exists { - if expectNumRows >= 0 { - checkTableRows(t, tableName, expectNumRows) + t.Run(fmt.Sprintf("validateAnyState: expectNumRows=%v, states=%v", expectNumRows, states), func(t *testing.T) { + timeout := gc.NextChecksIntervals[len(gc.NextChecksIntervals)-1] + 5*time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + // Attempt validation: + for _, state := range states { + expectTableToExist := true + searchExpr := "" + switch state { + case schema.HoldTableGCState: + searchExpr = `\_vt\_HOLD\_%` + case schema.PurgeTableGCState: + searchExpr = `\_vt\_PURGE\_%` + case schema.EvacTableGCState: + searchExpr = `\_vt\_EVAC\_%` + case schema.DropTableGCState: + searchExpr = `\_vt\_DROP\_%` + case schema.TableDroppedGCState: + searchExpr = `\_vt\_%` + expectTableToExist = false + default: + require.Failf(t, "unknown state", "%v", state) + } + exists, tableName, err := tableExists(searchExpr) + require.NoError(t, err) + + var foundRows int64 + if exists { + foundRows = getTableRows(t, tableName) + // Now that the table is validated, we can drop it (test cleanup) + dropTable(t, tableName) + } + t.Logf("=== exists: %v, tableName: %v, rows: %v", exists, tableName, foundRows) + if exists == expectTableToExist { + // expectNumRows < 0 means "don't care" + if expectNumRows < 0 || (expectNumRows == foundRows) { + // All conditions are met + return + } + } + } + select { + case <-ticker.C: + case <-ctx.Done(): + assert.Failf(t, "timeout in validateAnyState", " waiting for any of these states: %v, expecting rows: %v", states, expectNumRows) + return } - // Now that the table is validated, we can drop it - dropTable(t, tableName) - } - if exists == expectTableToExist { - // condition met - return } - } - assert.Failf(t, "could not match any of the states", "states=%v", states) + }) } // dropTable drops a table @@ -309,17 +333,22 @@ func TestHold(t *testing.T) { } func TestEvac(t *testing.T) { - populateTable(t) - query, tableName, err := schema.GenerateRenameStatement("t1", schema.EvacTableGCState, time.Now().UTC().Add(tableTransitionExpiration)) - assert.NoError(t, err) - - _, err = primaryTablet.VttabletProcess.QueryTablet(query, keyspaceName, true) - assert.NoError(t, err) - - validateTableDoesNotExist(t, "t1") - - time.Sleep(tableTransitionExpiration / 2) - { + var tableName string + t.Run("setting up EVAC table", func(t *testing.T) { + populateTable(t) + var query string + var err error + query, tableName, err = schema.GenerateRenameStatement("t1", schema.EvacTableGCState, time.Now().UTC().Add(tableTransitionExpiration)) + assert.NoError(t, err) + + _, err = primaryTablet.VttabletProcess.QueryTablet(query, keyspaceName, true) + assert.NoError(t, err) + + validateTableDoesNotExist(t, "t1") + }) + + t.Run("validating before expiration", func(t *testing.T) { + time.Sleep(tableTransitionExpiration / 2) // Table was created with +10s timestamp, so it should still exist if fastDropTable { // EVAC state is skipped in mysql 8.0.23 and beyond @@ -328,13 +357,14 @@ func TestEvac(t *testing.T) { validateTableExists(t, tableName) checkTableRows(t, tableName, 1024) } - } - - time.Sleep(tableTransitionExpiration) - // We're now both beyond table's timestamp as well as a tableGC interval - validateTableDoesNotExist(t, tableName) - // Table should be renamed as _vt_DROP_... and then dropped! - validateAnyState(t, 0, schema.DropTableGCState, schema.TableDroppedGCState) + }) + + t.Run("validating rows evacuated", func(t *testing.T) { + // We're now both beyond table's timestamp as well as a tableGC interval + validateTableDoesNotExist(t, tableName) + // Table should be renamed as _vt_DROP_... and then dropped! + validateAnyState(t, 0, schema.DropTableGCState, schema.TableDroppedGCState) + }) } func TestDrop(t *testing.T) { diff --git a/go/timer/suspendable_ticker.go b/go/timer/suspendable_ticker.go index 5257626b85f..f2694a5cab3 100644 --- a/go/timer/suspendable_ticker.go +++ b/go/timer/suspendable_ticker.go @@ -28,7 +28,7 @@ type SuspendableTicker struct { // C is user facing C chan time.Time - suspended int64 + suspended atomic.Bool } // NewSuspendableTicker creates a new suspendable ticker, indicating whether the ticker should start @@ -39,7 +39,7 @@ func NewSuspendableTicker(d time.Duration, initiallySuspended bool) *Suspendable C: make(chan time.Time), } if initiallySuspended { - s.suspended = 1 + s.suspended.Store(true) } go s.loop() return s @@ -48,12 +48,12 @@ func NewSuspendableTicker(d time.Duration, initiallySuspended bool) *Suspendable // Suspend stops sending time events on the channel C // time events sent during suspended time are lost func (s *SuspendableTicker) Suspend() { - atomic.StoreInt64(&s.suspended, 1) + s.suspended.Store(true) } // Resume re-enables time events on channel C func (s *SuspendableTicker) Resume() { - atomic.StoreInt64(&s.suspended, 0) + s.suspended.Store(false) } // Stop completely stops the timer, like time.Timer @@ -64,15 +64,23 @@ func (s *SuspendableTicker) Stop() { // TickNow generates a tick at this point in time. It may block // if nothing consumes the tick. func (s *SuspendableTicker) TickNow() { - if atomic.LoadInt64(&s.suspended) == 0 { + if !s.suspended.Load() { // not suspended s.C <- time.Now() } } +// TickAfter generates a tick after given duration has passed. +// It runs asynchronously and returns immediately. +func (s *SuspendableTicker) TickAfter(d time.Duration) { + time.AfterFunc(d, func() { + s.TickNow() + }) +} + func (s *SuspendableTicker) loop() { for t := range s.ticker.C { - if atomic.LoadInt64(&s.suspended) == 0 { + if !s.suspended.Load() { // not suspended s.C <- t } diff --git a/go/timer/suspendable_ticker_test.go b/go/timer/suspendable_ticker_test.go new file mode 100644 index 00000000000..64c468a0edc --- /dev/null +++ b/go/timer/suspendable_ticker_test.go @@ -0,0 +1,144 @@ +/* +Copyright 2023 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 timer + +import ( + "context" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +const ( + fastTickerInterval = 10 * time.Millisecond +) + +func TestInitiallySuspended(t *testing.T) { + ctx := context.Background() + t.Run("true", func(t *testing.T) { + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + ticker := NewSuspendableTicker(fastTickerInterval, true) + defer ticker.Stop() + select { + case <-ticker.C: + assert.Fail(t, "unexpected tick. Was supposed to be suspended") + case <-ctx.Done(): + return + } + }) + t.Run("false", func(t *testing.T) { + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + ticker := NewSuspendableTicker(fastTickerInterval, false) + defer ticker.Stop() + select { + case <-ticker.C: + return + case <-ctx.Done(): + assert.Fail(t, "unexpected timeout. Expected tick") + } + }) +} + +func TestSuspendableTicker(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ticker := NewSuspendableTicker(fastTickerInterval, false) + defer ticker.Stop() + + var ticks atomic.Int64 + go func() { + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ticks.Add(1) + } + } + }() + t.Run("ticks running", func(t *testing.T) { + time.Sleep(time.Second) + after := ticks.Load() + assert.Greater(t, after, int64(10)) // should be about 100 + }) + t.Run("ticks suspended", func(t *testing.T) { + ticker.Suspend() + before := ticks.Load() + time.Sleep(time.Second) + after := ticks.Load() + assert.Less(t, after-before, int64(10)) + }) + t.Run("ticks resumed", func(t *testing.T) { + ticker.Resume() + before := ticks.Load() + time.Sleep(time.Second) + after := ticks.Load() + assert.Greater(t, after-before, int64(10)) + }) + t.Run("ticker stopped", func(t *testing.T) { + ticker.Stop() + before := ticks.Load() + time.Sleep(time.Second) + after := ticks.Load() + assert.Less(t, after-before, int64(10)) + }) +} + +func TestSuspendableTickerTick(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ticker := NewSuspendableTicker(time.Hour, false) + defer ticker.Stop() + + var ticks atomic.Int64 + go func() { + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + ticks.Add(1) + } + } + }() + t.Run("nothing going on", func(t *testing.T) { + time.Sleep(time.Second) + after := ticks.Load() + assert.Zero(t, after) + }) + t.Run("tick now", func(t *testing.T) { + before := ticks.Load() + ticker.TickNow() + time.Sleep(time.Second) + after := ticks.Load() + assert.Equal(t, int64(1), after-before) + }) + t.Run("tick after", func(t *testing.T) { + before := ticks.Load() + ticker.TickAfter(1 * time.Second) + time.Sleep(time.Second) + after := ticks.Load() + assert.Zero(t, after-before) + time.Sleep(3 * time.Second) + after = ticks.Load() + assert.Equal(t, int64(1), after-before) + }) +} diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index dca3186f7b3..2c78069e962 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -176,6 +176,7 @@ type Executor struct { ts *topo.Server lagThrottler *throttle.Throttler toggleBufferTableFunc func(cancelCtx context.Context, tableName string, timeout time.Duration, bufferQueries bool) + requestGCChecksFunc func() tabletAlias *topodatapb.TabletAlias keyspace string @@ -251,6 +252,7 @@ func NewExecutor(env tabletenv.Env, tabletAlias *topodatapb.TabletAlias, ts *top lagThrottler *throttle.Throttler, tabletTypeFunc func() topodatapb.TabletType, toggleBufferTableFunc func(cancelCtx context.Context, tableName string, timeout time.Duration, bufferQueries bool), + requestGCChecksFunc func(), ) *Executor { // sanitize flags if maxConcurrentOnlineDDLs < 1 { @@ -268,6 +270,7 @@ func NewExecutor(env tabletenv.Env, tabletAlias *topodatapb.TabletAlias, ts *top ts: ts, lagThrottler: lagThrottler, toggleBufferTableFunc: toggleBufferTableFunc, + requestGCChecksFunc: requestGCChecksFunc, ticks: timer.NewTimer(migrationCheckInterval), // Gracefully return an error if any caller tries to execute // a query before the executor has been fully opened. @@ -3932,6 +3935,7 @@ func (e *Executor) gcArtifacts(ctx context.Context) error { if err == nil { // artifact was renamed away and is gone. There' no need to list it in `artifacts` column. e.clearSingleArtifact(ctx, uuid, artifactTable) + e.requestGCChecksFunc() } else { return vterrors.Wrapf(err, "in gcArtifacts() for %s", artifactTable) } @@ -4502,6 +4506,7 @@ func (e *Executor) CleanupMigration(ctx context.Context, uuid string) (result *s return nil, err } log.Infof("CleanupMigration: migration %s marked as ready to clean up", uuid) + defer e.triggerNextCheckInterval() return rs, nil } diff --git a/go/vt/vttablet/tabletserver/gc/tablegc.go b/go/vt/vttablet/tabletserver/gc/tablegc.go index 8658d7c3a3b..d8d12611e43 100644 --- a/go/vt/vttablet/tabletserver/gc/tablegc.go +++ b/go/vt/vttablet/tabletserver/gc/tablegc.go @@ -49,9 +49,12 @@ const ( ) var ( - checkInterval = 1 * time.Hour - purgeReentranceInterval = 1 * time.Minute - gcLifecycle = "hold,purge,evac,drop" + checkInterval = 1 * time.Hour + purgeReentranceInterval = 1 * time.Minute + nextPurgeReentry = 1 * time.Second + checkTablesReentryMinInterval = 10 * time.Second + NextChecksIntervals = []time.Duration{time.Second, checkTablesReentryMinInterval + 5*time.Second} + gcLifecycle = "hold,purge,evac,drop" ) func init() { @@ -69,11 +72,10 @@ func registerGCFlags(fs *pflag.FlagSet) { } var ( - sqlPurgeTable = `delete from %a limit 50` - sqlShowVtTables = `show full tables like '\_vt\_%'` - sqlDropTable = "drop table if exists `%a`" - sqlDropView = "drop view if exists `%a`" - purgeReentranceFlag int64 + sqlPurgeTable = `delete from %a limit 50` + sqlShowVtTables = `show full tables like '\_vt\_%'` + sqlDropTable = "drop table if exists `%a`" + sqlDropView = "drop view if exists `%a`" ) type gcTable struct { @@ -105,6 +107,10 @@ type TableGC struct { isOpen int64 cancelOperation context.CancelFunc + purgeReentranceFlag atomic.Int64 + readReentranceFlag atomic.Int64 + checkRequestChan chan bool + throttlerClient *throttle.Client env tabletenv.Env @@ -143,7 +149,8 @@ func NewTableGC(env tabletenv.Env, ts *topo.Server, lagThrottler *throttle.Throt IdleTimeoutSeconds: env.Config().OltpReadPool.IdleTimeoutSeconds, }), - purgingTables: map[string]bool{}, + purgingTables: map[string]bool{}, + checkRequestChan: make(chan bool), } return collector @@ -226,6 +233,16 @@ func (collector *TableGC) Close() { log.Infof("TableGC - finished execution of Close") } +// RequestChecks requests that the GC will do a table check right away, as well as in a few seconds. +// Calling this function is useful to modules that are performing operations that affect GC tables. Those modules +// _know_ that changes have been made, and now have a way to tell TableGC: "please take a look asap rather +// than in the next hour". +func (collector *TableGC) RequestChecks() { + for _, d := range NextChecksIntervals { + time.AfterFunc(d, func() { collector.checkRequestChan <- true }) + } +} + // operate is the main entry point for the table garbage collector operation and logic. func (collector *TableGC) operate(ctx context.Context) { @@ -254,55 +271,47 @@ func (collector *TableGC) operate(ctx context.Context) { case <-ctx.Done(): log.Info("TableGC: done operating") return + case <-collector.checkRequestChan: + // Got a request to check tables. Probably some event took place and we will + // find something new to do. + go tableCheckTicker.TickNow() case <-tableCheckTicker.C: - { - log.Info("TableGC: tableCheckTicker") - if gcTables, err := collector.readTables(ctx); err != nil { - log.Errorf("TableGC: error while reading tables: %+v", err) - } else { - _ = collector.checkTables(ctx, gcTables, dropTablesChan, transitionRequestsChan) - } + log.Info("TableGC: tableCheckTicker") + if err := collector.readAndCheckTables(ctx, dropTablesChan, transitionRequestsChan); err != nil { + log.Error(err) } case <-purgeReentranceTicker.C: - { - // relay the request - go func() { purgeRequestsChan <- true }() - } + // relay the request + go func() { purgeRequestsChan <- true }() case <-purgeRequestsChan: - { - go func() { - tableName, err := collector.purge(ctx) - if err != nil { - log.Errorf("TableGC: error purging table %s: %+v", tableName, err) - return - } - if tableName == "" { - // No table purged (or at least not to completion) - // Either because there _is_ nothing to purge, or because PURGE isn't a handled state - return - } - // The table has been purged! Let's move the table into the next phase: - _, _, uuid, _, _ := schema.AnalyzeGCTableName(tableName) - collector.submitTransitionRequest(ctx, transitionRequestsChan, schema.PurgeTableGCState, tableName, true, uuid) - collector.removePurgingTable(tableName) - // Chances are, there's more tables waiting to be purged. Let's speed things by - // requesting another purge, instead of waiting a full purgeReentranceInterval cycle - time.AfterFunc(time.Second, func() { purgeRequestsChan <- true }) - }() - } - case dropTable := <-dropTablesChan: - { - log.Infof("TableGC: found %v in dropTablesChan", dropTable.tableName) - if err := collector.dropTable(ctx, dropTable.tableName, dropTable.isBaseTable); err != nil { - log.Errorf("TableGC: error dropping table %s: %+v", dropTable.tableName, err) + go func() { + tableName, err := collector.purge(ctx) + if err != nil { + log.Errorf("TableGC: error purging table %s: %+v", tableName, err) + return + } + if tableName == "" { + // No table purged (or at least not to completion) + // Either because there _is_ nothing to purge, or because PURGE isn't a handled state + return } + // The table has been purged! Let's move the table into the next phase: + _, _, uuid, _, _ := schema.AnalyzeGCTableName(tableName) + collector.submitTransitionRequest(ctx, transitionRequestsChan, schema.PurgeTableGCState, tableName, true, uuid) + collector.removePurgingTable(tableName) + // Chances are, there's more tables waiting to be purged. Let's speed things by + // requesting another purge, instead of waiting a full purgeReentranceInterval cycle + purgeReentranceTicker.TickAfter(nextPurgeReentry) + }() + case dropTable := <-dropTablesChan: + log.Infof("TableGC: found %v in dropTablesChan", dropTable.tableName) + if err := collector.dropTable(ctx, dropTable.tableName, dropTable.isBaseTable); err != nil { + log.Errorf("TableGC: error dropping table %s: %+v", dropTable.tableName, err) } case transition := <-transitionRequestsChan: - { - log.Info("TableGC: transitionRequestsChan, transition=%v", transition) - if err := collector.transitionTable(ctx, transition); err != nil { - log.Errorf("TableGC: error transitioning table %s to %+v: %+v", transition.fromTableName, transition.toGCState, err) - } + log.Info("TableGC: transitionRequestsChan, transition=%v", transition) + if err := collector.transitionTable(ctx, transition); err != nil { + log.Errorf("TableGC: error transitioning table %s to %+v: %+v", transition.fromTableName, transition.toGCState, err) } } } @@ -378,6 +387,32 @@ func (collector *TableGC) shouldTransitionTable(tableName string) (shouldTransit return true, state, uuid, nil } +// readAndCheckTables is the routine check for which GC tables exist, and which of those need to transition +// into the next state. The function is non-reentrant, and poses a minimal duration between any two executions. +func (collector *TableGC) readAndCheckTables( + ctx context.Context, + dropTablesChan chan<- *gcTable, + transitionRequestsChan chan<- *transitionRequest, +) (err error) { + if !collector.readReentranceFlag.CompareAndSwap(0, 1) { + // An instance of this function is already running + return nil + } + defer time.AfterFunc(checkTablesReentryMinInterval, func() { + collector.readReentranceFlag.Store(0) + }) + + log.Info("TableGC: readAndCheckTables") + gcTables, err := collector.readTables(ctx) + if err != nil { + return fmt.Errorf("TableGC: error while reading tables: %+v", err) + } + if err := collector.checkTables(ctx, gcTables, dropTablesChan, transitionRequestsChan); err != nil { + return err + } + return nil +} + // readTables reads the list of _vt_% tables from the database func (collector *TableGC) readTables(ctx context.Context) (gcTables []*gcTable, err error) { log.Infof("TableGC: read tables") @@ -457,12 +492,11 @@ func (collector *TableGC) checkTables(ctx context.Context, gcTables []*gcTable, // This function is non-reentrant: there's only one instance of this function running at any given time. // A timer keeps calling this function, so if it bails out (e.g. on error) it will later resume work func (collector *TableGC) purge(ctx context.Context) (tableName string, err error) { - if atomic.CompareAndSwapInt64(&purgeReentranceFlag, 0, 1) { - defer atomic.StoreInt64(&purgeReentranceFlag, 0) - } else { + if !collector.purgeReentranceFlag.CompareAndSwap(0, 1) { // An instance of this function is already running return "", nil } + defer collector.purgeReentranceFlag.Store(0) tableName, found := collector.nextTableToPurge() if !found { @@ -598,6 +632,9 @@ func (collector *TableGC) transitionTable(ctx context.Context, transition *trans return err } log.Infof("TableGC: renamed table: %s", transition.fromTableName) + // Since the table has transitioned, there is a potential for more work on this table or on other tables, + // let's kick a check request. + collector.RequestChecks() return nil } diff --git a/go/vt/vttablet/tabletserver/gc/tablegc_test.go b/go/vt/vttablet/tabletserver/gc/tablegc_test.go index 446f6e6ff85..12ee5e2a28b 100644 --- a/go/vt/vttablet/tabletserver/gc/tablegc_test.go +++ b/go/vt/vttablet/tabletserver/gc/tablegc_test.go @@ -60,7 +60,8 @@ func TestNextTableToPurge(t *testing.T) { } for _, ts := range tt { collector := &TableGC{ - purgingTables: make(map[string]bool), + purgingTables: make(map[string]bool), + checkRequestChan: make(chan bool), } for _, table := range ts.tables { collector.purgingTables[table] = true @@ -256,8 +257,9 @@ func TestShouldTransitionTable(t *testing.T) { func TestCheckTables(t *testing.T) { collector := &TableGC{ - isOpen: 0, - purgingTables: map[string]bool{}, + isOpen: 0, + purgingTables: map[string]bool{}, + checkRequestChan: make(chan bool), } var err error collector.lifecycleStates, err = schema.ParseGCLifecycle("hold,purge,evac,drop") diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 2e1831e0acd..3b0ac598ad0 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -187,8 +187,8 @@ func NewTabletServer(ctx context.Context, name string, config *tabletenv.TabletC tsv.te = NewTxEngine(tsv) tsv.messager = messager.NewEngine(tsv, tsv.se, tsv.vstreamer) - tsv.onlineDDLExecutor = onlineddl.NewExecutor(tsv, alias, topoServer, tsv.lagThrottler, tabletTypeFunc, tsv.onlineDDLExecutorToggleTableBuffer) tsv.tableGC = gc.NewTableGC(tsv, topoServer, tsv.lagThrottler) + tsv.onlineDDLExecutor = onlineddl.NewExecutor(tsv, alias, topoServer, tsv.lagThrottler, tabletTypeFunc, tsv.onlineDDLExecutorToggleTableBuffer, tsv.tableGC.RequestChecks) tsv.sm = &stateManager{ statelessql: tsv.statelessql, From 2da95cfb3d9dde2ec00f9affa8e3a44558b7df1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:27:36 -0600 Subject: [PATCH 074/119] Bump @adobe/css-tools from 4.3.1 to 4.3.2 in /web/vtadmin (#14654) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/vtadmin/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index 94044b24a27..ad72ae9dc2f 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -72,9 +72,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -17600,9 +17600,9 @@ }, "dependencies": { "@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", "dev": true }, "@ampproject/remapping": { From 7506019c3606648c7245a7e2f67a6973d0bde90f Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Mon, 4 Dec 2023 23:11:44 +0530 Subject: [PATCH 075/119] Add summary changes to indicate MySQL 5.7 is EOL and Vitess is dropping support for it in v19 (#14663) --- changelog/19.0/19.0.0/summary.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index 5580bc6e6f5..446b4b32bc2 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -3,6 +3,7 @@ ### Table of Contents - **[Major Changes](#major-changes)** + - **[Dropping Support for MySQL 5.7](#drop-support-mysql57)** - **[Deprecations and Deletions](#deprecations-and-deletions)** - [VTTablet Flags](#vttablet-flags) - **[Docker](#docker)** @@ -14,6 +15,13 @@ ## Major Changes +### Dropping Support for MySQL 5.7 + +Oracle has marked MySQL 5.7 end of life as of October 2023. Vitess is also dropping support for MySQL 5.7 from v19 onwards. Users are advised to upgrade to MySQL 8.0 while on v18 version of Vitess before +upgrading to v19. + +Vitess will however, continue to support importing from MySQL 5.7 into Vitess even in v19. + ### Deprecations and Deletions - The `MYSQL_FLAVOR` environment variable is now removed from all Docker Images. From 5af5ad6d9112f181dfa3b4c4d837d232a194e8cd Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:55:18 +0530 Subject: [PATCH 076/119] Fix Panic in PRS due to a missing nil check (#14656) Signed-off-by: Manan Gupta --- go/vt/vtctl/grpcvtctldserver/server.go | 2 +- go/vt/vtctl/grpcvtctldserver/server_test.go | 75 +++++++++++++++++++-- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index caa99d5e8c8..e54ee0fa96c 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -2752,7 +2752,7 @@ func (s *VtctldServer) PlannedReparentShard(ctx context.Context, req *vtctldatap resp.Keyspace = ev.ShardInfo.Keyspace() resp.Shard = ev.ShardInfo.ShardName() - if !topoproto.TabletAliasIsZero(ev.NewPrimary.Alias) { + if ev.NewPrimary != nil && !topoproto.TabletAliasIsZero(ev.NewPrimary.Alias) { resp.PromotedPrimary = ev.NewPrimary.Alias } } diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index d597ec49502..c04114d46cd 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -7439,7 +7439,7 @@ func TestPlannedReparentShard(t *testing.T) { req *vtctldatapb.PlannedReparentShardRequest expected *vtctldatapb.PlannedReparentShardResponse expectEventsToOccur bool - shouldErr bool + expectedErr string }{ { name: "successful reparent", @@ -7554,7 +7554,6 @@ func TestPlannedReparentShard(t *testing.T) { }, }, expectEventsToOccur: true, - shouldErr: false, }, { // Note: this is testing the error-handling done in @@ -7570,7 +7569,7 @@ func TestPlannedReparentShard(t *testing.T) { Shard: "-", }, expectEventsToOccur: false, - shouldErr: true, + expectedErr: "node doesn't exist: keyspaces/testkeyspace/shards/-", }, { name: "invalid WaitReplicasTimeout", @@ -7580,7 +7579,71 @@ func TestPlannedReparentShard(t *testing.T) { Nanos: 1, }, }, - shouldErr: true, + expectedErr: "duration: seconds:-1 nanos:1 is out of range for time.Duration", + }, + { + name: "tablet unreachable", + ts: memorytopo.NewServer(ctx, "zone1"), + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + PrimaryTermStartTime: &vttime.Time{ + Seconds: 100, + }, + Keyspace: "testkeyspace", + Shard: "-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_RDONLY, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + tmc: &testutil.TabletManagerClient{ + // This is only needed to verify reachability, so empty results are fine. + PrimaryStatusResults: map[string]struct { + Status *replicationdatapb.PrimaryStatus + Error error + }{ + "zone1-0000000200": { + Error: fmt.Errorf("primary status failed"), + }, + "zone1-0000000101": { + Status: &replicationdatapb.PrimaryStatus{}, + }, + "zone1-0000000100": { + Status: &replicationdatapb.PrimaryStatus{}, + }, + }, + }, + req: &vtctldatapb.PlannedReparentShardRequest{ + Keyspace: "testkeyspace", + Shard: "-", + NewPrimary: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + WaitReplicasTimeout: protoutil.DurationToProto(time.Millisecond * 10), + }, + expectEventsToOccur: true, + expectedErr: "primary status failed", }, } @@ -7610,8 +7673,8 @@ func TestPlannedReparentShard(t *testing.T) { testutil.AssertLogutilEventsOccurred(t, resp, "expected events to occur during ERS") }() - if tt.shouldErr { - assert.Error(t, err) + if tt.expectedErr != "" { + assert.EqualError(t, err, tt.expectedErr) return } From a81885479b3f268b84dc8dba01dde790f15db9b3 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:15:39 +0530 Subject: [PATCH 077/119] Take replication lag into account while selecting primary candidate (#14634) Signed-off-by: Manan Gupta --- changelog/19.0/19.0.0/summary.md | 12 + go/cmd/vtctldclient/command/reparents.go | 19 +- go/flags/endtoend/vtorc.txt | 1 + go/vt/proto/vtctldata/vtctldata.pb.go | 1875 +++++++++-------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 61 +- go/vt/vtctl/grpcvtctldserver/server.go | 5 + go/vt/vtctl/reparent.go | 3 +- .../vtctl/reparentutil/planned_reparenter.go | 3 +- go/vt/vtctl/reparentutil/util.go | 17 +- go/vt/vtctl/reparentutil/util_test.go | 144 +- go/vt/vtorc/config/config.go | 4 + go/vt/vtorc/logic/topology_recovery.go | 1 + go/vt/wrangler/reparent.go | 8 +- proto/vtctldata.proto | 4 + web/vtadmin/src/proto/vtadmin.d.ts | 6 + web/vtadmin/src/proto/vtadmin.js | 28 + 16 files changed, 1231 insertions(+), 960 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index 446b4b32bc2..af9c83399a3 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -12,6 +12,8 @@ - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) - **[Query Compatibility](#query-compatibility)** - [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces) + - **[Planned Reparent Shard](#planned-reparent-shard)** + - [`--tolerable-replication-lag` Sub-flag](#tolerable-repl-lag) ## Major Changes @@ -66,3 +68,13 @@ mysql> show vschema keyspaces; +----------+---------+-------------+---------+ 2 rows in set (0.01 sec) ``` + +### Planned Reparent Shard + +#### `--tolerable-replication-lag` Sub-flag + +A new sub-flag `--tolerable-replication-lag` has been added to the command `PlannedReparentShard` that allows users to specify the amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary. +This feature is opt-in and not specifying this sub-flag makes Vitess ignore the replication lag entirely. + +A new flag in VTOrc with the same name has been added to control the behaviour of the PlannedReparentShard calls that VTOrc issues. + diff --git a/go/cmd/vtctldclient/command/reparents.go b/go/cmd/vtctldclient/command/reparents.go index 5c83016701a..17b87eaba4f 100644 --- a/go/cmd/vtctldclient/command/reparents.go +++ b/go/cmd/vtctldclient/command/reparents.go @@ -183,9 +183,10 @@ func commandInitShardPrimary(cmd *cobra.Command, args []string) error { } var plannedReparentShardOptions = struct { - NewPrimaryAliasStr string - AvoidPrimaryAliasStr string - WaitReplicasTimeout time.Duration + NewPrimaryAliasStr string + AvoidPrimaryAliasStr string + WaitReplicasTimeout time.Duration + TolerableReplicationLag time.Duration }{} func commandPlannedReparentShard(cmd *cobra.Command, args []string) error { @@ -216,11 +217,12 @@ func commandPlannedReparentShard(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) resp, err := client.PlannedReparentShard(commandCtx, &vtctldatapb.PlannedReparentShardRequest{ - Keyspace: keyspace, - Shard: shard, - NewPrimary: newPrimaryAlias, - AvoidPrimary: avoidPrimaryAlias, - WaitReplicasTimeout: protoutil.DurationToProto(plannedReparentShardOptions.WaitReplicasTimeout), + Keyspace: keyspace, + Shard: shard, + NewPrimary: newPrimaryAlias, + AvoidPrimary: avoidPrimaryAlias, + WaitReplicasTimeout: protoutil.DurationToProto(plannedReparentShardOptions.WaitReplicasTimeout), + TolerableReplicationLag: protoutil.DurationToProto(plannedReparentShardOptions.TolerableReplicationLag), }) if err != nil { return err @@ -292,6 +294,7 @@ func init() { Root.AddCommand(InitShardPrimary) PlannedReparentShard.Flags().DurationVar(&plannedReparentShardOptions.WaitReplicasTimeout, "wait-replicas-timeout", topo.RemoteOperationTimeout, "Time to wait for replicas to catch up on replication both before and after reparenting.") + PlannedReparentShard.Flags().DurationVar(&plannedReparentShardOptions.TolerableReplicationLag, "tolerable-replication-lag", 0, "Amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary.") PlannedReparentShard.Flags().StringVar(&plannedReparentShardOptions.NewPrimaryAliasStr, "new-primary", "", "Alias of a tablet that should be the new primary.") PlannedReparentShard.Flags().StringVar(&plannedReparentShardOptions.AvoidPrimaryAliasStr, "avoid-primary", "", "Alias of a tablet that should not be the primary; i.e. \"reparent to any other tablet if this one is the primary\".") Root.AddCommand(PlannedReparentShard) diff --git a/go/flags/endtoend/vtorc.txt b/go/flags/endtoend/vtorc.txt index 0bbe8ef7469..8ea30e2ff10 100644 --- a/go/flags/endtoend/vtorc.txt +++ b/go/flags/endtoend/vtorc.txt @@ -86,6 +86,7 @@ Flags: --tablet_manager_grpc_key string the key to use to connect --tablet_manager_grpc_server_name string the server name to use to validate server certificate --tablet_manager_protocol string Protocol to use to make tabletmanager RPCs to vttablets. (default "grpc") + --tolerable-replication-lag duration Amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary in PRS --topo-information-refresh-duration duration Timer duration on which VTOrc refreshes the keyspace and vttablet records from the topology server (default 15s) --topo_consul_lock_delay duration LockDelay for consul session. (default 15s) --topo_consul_lock_session_checks string List of checks for consul session. (default "serfHealth") diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index fafa6d703cc..f7252e2d8ec 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -8704,6 +8704,10 @@ type PlannedReparentShardRequest struct { // WaitReplicasTimeout time to catch up before the reparent, and an additional // WaitReplicasTimeout time to catch up after the reparent. WaitReplicasTimeout *vttime.Duration `protobuf:"bytes,5,opt,name=wait_replicas_timeout,json=waitReplicasTimeout,proto3" json:"wait_replicas_timeout,omitempty"` + // TolerableReplicationLag is the amount of replication lag that is considered + // acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary. + // A value of 0 indicates that Vitess shouldn't consider the replication lag at all. + TolerableReplicationLag *vttime.Duration `protobuf:"bytes,6,opt,name=tolerable_replication_lag,json=tolerableReplicationLag,proto3" json:"tolerable_replication_lag,omitempty"` } func (x *PlannedReparentShardRequest) Reset() { @@ -8773,6 +8777,13 @@ func (x *PlannedReparentShardRequest) GetWaitReplicasTimeout() *vttime.Duration return nil } +func (x *PlannedReparentShardRequest) GetTolerableReplicationLag() *vttime.Duration { + if x != nil { + return x.TolerableReplicationLag + } + return nil +} + type PlannedReparentShardResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -16795,7 +16806,7 @@ var file_vtctldata_proto_rawDesc = []byte{ 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, 0x14, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x89, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd7, 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, @@ -16812,591 +16823,531 @@ var file_vtctldata_proto_rawDesc = []byte{ 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, + 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x4c, 0x0a, 0x19, 0x74, 0x6f, + 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x17, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 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, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 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, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x52, + 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x01, + 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, 0x12, 0x36, 0x0a, 0x17, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 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, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x0a, + 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, + 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, + 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 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, + 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, + 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, + 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 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, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 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, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, - 0x1c, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, - 0x83, 0x01, 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, 0x12, 0x36, 0x0a, - 0x17, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 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, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, - 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, - 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, - 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, - 0x79, 0x22, 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, - 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 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, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 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, 0x8f, 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, - 0x63, 0x6f, 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, - 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, - 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, - 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, - 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x82, 0x02, 0x0a, 0x18, 0x52, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, - 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, - 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, - 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, - 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, - 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, - 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, - 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, - 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, - 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, - 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, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, 0x2b, 0x0a, - 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x22, 0xc8, 0x01, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 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, 0x35, - 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 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, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 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, 0x72, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4f, 0x0a, 0x1d, - 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, - 0x1e, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 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, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, - 0x1f, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x22, 0x72, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 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, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x6e, 0x67, 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x01, 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, - 0x8e, 0x02, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 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, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, - 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x22, 0x46, 0x0a, 0x1d, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, - 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 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, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x64, 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, 0x38, 0x0a, 0x0c, - 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, + 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, - 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, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, + 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, 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, 0x8b, 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 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, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, 0x70, 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, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x15, 0x0a, 0x13, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 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, 0x8f, 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, + 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x6f, + 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, + 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, + 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, + 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, + 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x82, 0x02, 0x0a, 0x18, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, + 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, + 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xad, 0x01, + 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4d, 0x0a, + 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, 0x01, 0x0a, + 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, + 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, + 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, 0x0a, 0x15, + 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 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, + 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, 0x2b, 0x0a, 0x11, 0x64, + 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, + 0xc8, 0x01, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 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, 0x35, 0x0a, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 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, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 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, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4f, 0x0a, 0x1d, 0x53, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, + 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, + 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 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, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, + 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, + 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, + 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, - 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, 0x07, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x01, 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, - 0x53, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 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, 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x52, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 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, + 0x61, 0x72, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, + 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x6e, 0x67, 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x01, 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, 0x8e, 0x02, + 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 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, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, + 0x0a, 0x1d, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, + 0x74, 0x61, 0x62, 0x6c, 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, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, + 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, 0x38, 0x0a, 0x0c, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, - 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, - 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, - 0x69, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 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, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, - 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, - 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, - 0x02, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, - 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 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, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 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, 0x8b, 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 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, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, + 0x0a, 0x1e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x7c, 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, 0x70, 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, + 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, + 0x0a, 0x13, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 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, 0x07, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x01, 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, 0x53, 0x0a, + 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 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, 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, + 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 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, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, + 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x8a, 0x02, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, - 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, + 0x16, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 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, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, - 0x98, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 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, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 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, 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x12, 0x60, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, + 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 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, + 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, + 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, @@ -17405,272 +17356,337 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, - 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, - 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, - 0x6c, 0x79, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, - 0x6e, 0x6c, 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, - 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, - 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, - 0x69, 0x74, 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, - 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, - 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, - 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, - 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x52, 0x6f, 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, - 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, - 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, - 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, - 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, - 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, - 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, - 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, - 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, - 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, - 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x9a, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, - 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, - 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, - 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, - 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, - 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, + 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, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x8a, 0x02, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, + 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, + 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x22, 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, + 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 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, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 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, 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, + 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, + 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, + 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, + 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, + 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, + 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, + 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, + 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, + 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, + 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, + 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, + 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, + 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, + 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, + 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, + 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x22, 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, + 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, + 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, + 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, + 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, + 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, + 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, + 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, + 0x66, 0x69, 0x63, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, - 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, - 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, - 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, - 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, - 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, - 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, - 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, - 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, - 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, - 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, - 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, - 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, - 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, - 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, - 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, - 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, - 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, - 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, - 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, - 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, - 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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, + 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, + 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, + 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, + 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, + 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, + 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, + 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, + 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, + 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, + 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, + 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, + 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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 ( @@ -18107,106 +18123,107 @@ var file_vtctldata_proto_depIdxs = []int32{ 275, // 109: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias 275, // 110: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias 276, // 111: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 275, // 112: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 271, // 113: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 275, // 114: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 115: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 271, // 116: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 271, // 117: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 275, // 118: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 275, // 119: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 283, // 120: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 121: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 275, // 122: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 274, // 123: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 274, // 124: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 275, // 125: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 271, // 126: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 255, // 127: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 275, // 128: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 129: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 283, // 130: vtctldata.SetKeyspaceServedFromRequest.tablet_type:type_name -> topodata.TabletType - 273, // 131: vtctldata.SetKeyspaceServedFromResponse.keyspace:type_name -> topodata.Keyspace - 273, // 132: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 277, // 133: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 283, // 134: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 277, // 135: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 275, // 136: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 137: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 296, // 138: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 256, // 139: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 257, // 140: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 275, // 141: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 142: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 276, // 143: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 297, // 144: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 277, // 145: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 277, // 146: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 275, // 147: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 148: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 149: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 275, // 150: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 275, // 151: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 278, // 152: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 278, // 153: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 298, // 154: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 298, // 155: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 258, // 156: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 259, // 157: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 260, // 158: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 261, // 159: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 262, // 160: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 283, // 161: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 162: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 276, // 163: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 276, // 164: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 263, // 165: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 264, // 166: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 268, // 167: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 269, // 168: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 283, // 169: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 276, // 170: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 276, // 171: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 299, // 172: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 270, // 173: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 238, // 174: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 239, // 175: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 300, // 176: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 275, // 177: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 301, // 178: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 274, // 179: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 274, // 180: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 240, // 181: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 241, // 182: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 242, // 183: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 274, // 184: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 274, // 185: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 274, // 186: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 10, // 187: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 298, // 188: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 250, // 189: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 302, // 190: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 295, // 191: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 275, // 192: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 303, // 193: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 284, // 194: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 207, // 195: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 211, // 196: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 197: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 198: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 199: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 304, // 200: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 275, // 201: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 275, // 202: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 266, // 203: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 265, // 204: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 267, // 205: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 275, // 206: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 207, // [207:207] is the sub-list for method output_type - 207, // [207:207] is the sub-list for method input_type - 207, // [207:207] is the sub-list for extension type_name - 207, // [207:207] is the sub-list for extension extendee - 0, // [0:207] is the sub-list for field type_name + 276, // 112: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 275, // 113: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 271, // 114: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 275, // 115: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 116: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 271, // 117: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 271, // 118: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 275, // 119: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 275, // 120: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 283, // 121: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 272, // 122: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 275, // 123: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 274, // 124: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 274, // 125: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 275, // 126: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 271, // 127: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 255, // 128: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 275, // 129: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 130: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 283, // 131: vtctldata.SetKeyspaceServedFromRequest.tablet_type:type_name -> topodata.TabletType + 273, // 132: vtctldata.SetKeyspaceServedFromResponse.keyspace:type_name -> topodata.Keyspace + 273, // 133: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 277, // 134: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 283, // 135: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 277, // 136: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 275, // 137: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 138: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 296, // 139: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 256, // 140: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 257, // 141: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 275, // 142: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 143: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 144: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 297, // 145: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 277, // 146: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 277, // 147: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 275, // 148: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 149: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 150: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 275, // 151: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 275, // 152: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 278, // 153: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 278, // 154: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 298, // 155: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 298, // 156: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 258, // 157: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 259, // 158: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 260, // 159: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 261, // 160: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 262, // 161: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 283, // 162: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 272, // 163: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 276, // 164: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 276, // 165: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 263, // 166: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 264, // 167: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 268, // 168: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 269, // 169: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 283, // 170: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 276, // 171: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 276, // 172: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 299, // 173: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 270, // 174: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 238, // 175: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 239, // 176: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 300, // 177: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 275, // 178: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 301, // 179: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 274, // 180: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 274, // 181: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 240, // 182: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 241, // 183: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 242, // 184: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 274, // 185: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 274, // 186: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 274, // 187: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 10, // 188: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 298, // 189: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 250, // 190: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 302, // 191: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 295, // 192: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 275, // 193: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 303, // 194: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 284, // 195: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 207, // 196: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 211, // 197: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 198: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 199: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 200: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 304, // 201: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 275, // 202: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 275, // 203: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 266, // 204: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 265, // 205: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 267, // 206: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 275, // 207: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 208, // [208:208] is the sub-list for method output_type + 208, // [208:208] is the sub-list for method input_type + 208, // [208:208] is the sub-list for extension type_name + 208, // [208:208] is the sub-list for extension extendee + 0, // [0:208] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index 2e589fe06e1..5c8ff40f8f2 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -3110,11 +3110,12 @@ func (m *PlannedReparentShardRequest) CloneVT() *PlannedReparentShardRequest { return (*PlannedReparentShardRequest)(nil) } r := &PlannedReparentShardRequest{ - Keyspace: m.Keyspace, - Shard: m.Shard, - NewPrimary: m.NewPrimary.CloneVT(), - AvoidPrimary: m.AvoidPrimary.CloneVT(), - WaitReplicasTimeout: m.WaitReplicasTimeout.CloneVT(), + Keyspace: m.Keyspace, + Shard: m.Shard, + NewPrimary: m.NewPrimary.CloneVT(), + AvoidPrimary: m.AvoidPrimary.CloneVT(), + WaitReplicasTimeout: m.WaitReplicasTimeout.CloneVT(), + TolerableReplicationLag: m.TolerableReplicationLag.CloneVT(), } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) @@ -13680,6 +13681,16 @@ func (m *PlannedReparentShardRequest) MarshalToSizedBufferVT(dAtA []byte) (int, i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.TolerableReplicationLag != nil { + size, err := m.TolerableReplicationLag.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } if m.WaitReplicasTimeout != nil { size, err := m.WaitReplicasTimeout.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -22488,6 +22499,10 @@ func (m *PlannedReparentShardRequest) SizeVT() (n int) { l = m.WaitReplicasTimeout.SizeVT() n += 1 + l + sov(uint64(l)) } + if m.TolerableReplicationLag != nil { + l = m.TolerableReplicationLag.SizeVT() + n += 1 + l + sov(uint64(l)) + } n += len(m.unknownFields) return n } @@ -45093,6 +45108,42 @@ func (m *PlannedReparentShardRequest) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TolerableReplicationLag", 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.TolerableReplicationLag == nil { + m.TolerableReplicationLag = &vttime.Duration{} + } + if err := m.TolerableReplicationLag.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index e54ee0fa96c..ef0e9db341b 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -2711,6 +2711,10 @@ func (s *VtctldServer) PlannedReparentShard(ctx context.Context, req *vtctldatap } else if !ok { waitReplicasTimeout = time.Second * 30 } + tolerableReplLag, _, err := protoutil.DurationFromProto(req.TolerableReplicationLag) + if err != nil { + return nil, err + } span.Annotate("keyspace", req.Keyspace) span.Annotate("shard", req.Shard) @@ -2740,6 +2744,7 @@ func (s *VtctldServer) PlannedReparentShard(ctx context.Context, req *vtctldatap AvoidPrimaryAlias: req.AvoidPrimary, NewPrimaryAlias: req.NewPrimary, WaitReplicasTimeout: waitReplicasTimeout, + TolerableReplLag: tolerableReplLag, }, ) diff --git a/go/vt/vtctl/reparent.go b/go/vt/vtctl/reparent.go index 7ed0f6582b9..cd6cfe3fb6d 100644 --- a/go/vt/vtctl/reparent.go +++ b/go/vt/vtctl/reparent.go @@ -114,6 +114,7 @@ func commandPlannedReparentShard(ctx context.Context, wr *wrangler.Wrangler, sub } waitReplicasTimeout := subFlags.Duration("wait_replicas_timeout", topo.RemoteOperationTimeout, "time to wait for replicas to catch up on replication before and after reparenting") + tolerableReplicationLag := subFlags.Duration("tolerable-replication-lag", 0, "amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary") keyspaceShard := subFlags.String("keyspace_shard", "", "keyspace/shard of the shard that needs to be reparented") newPrimary := subFlags.String("new_primary", "", "alias of a tablet that should be the new primary") avoidTablet := subFlags.String("avoid_tablet", "", "alias of a tablet that should not be the primary, i.e. reparent to any other tablet if this one is the primary") @@ -149,7 +150,7 @@ func commandPlannedReparentShard(ctx context.Context, wr *wrangler.Wrangler, sub return err } } - return wr.PlannedReparentShard(ctx, keyspace, shard, newPrimaryAlias, avoidTabletAlias, *waitReplicasTimeout) + return wr.PlannedReparentShard(ctx, keyspace, shard, newPrimaryAlias, avoidTabletAlias, *waitReplicasTimeout, *tolerableReplicationLag) } func commandEmergencyReparentShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *pflag.FlagSet, args []string) error { diff --git a/go/vt/vtctl/reparentutil/planned_reparenter.go b/go/vt/vtctl/reparentutil/planned_reparenter.go index 9fc933a8e35..4109386e8d1 100644 --- a/go/vt/vtctl/reparentutil/planned_reparenter.go +++ b/go/vt/vtctl/reparentutil/planned_reparenter.go @@ -60,6 +60,7 @@ type PlannedReparentOptions struct { NewPrimaryAlias *topodatapb.TabletAlias AvoidPrimaryAlias *topodatapb.TabletAlias WaitReplicasTimeout time.Duration + TolerableReplLag time.Duration // Private options managed internally. We use value-passing semantics to // set these options inside a PlannedReparent without leaking these details @@ -179,7 +180,7 @@ func (pr *PlannedReparenter) preflightChecks( event.DispatchUpdate(ev, "searching for primary candidate") - opts.NewPrimaryAlias, err = ChooseNewPrimary(ctx, pr.tmc, &ev.ShardInfo, tabletMap, opts.AvoidPrimaryAlias, opts.WaitReplicasTimeout, opts.durability, pr.logger) + opts.NewPrimaryAlias, err = ChooseNewPrimary(ctx, pr.tmc, &ev.ShardInfo, tabletMap, opts.AvoidPrimaryAlias, opts.WaitReplicasTimeout, opts.TolerableReplLag, opts.durability, pr.logger) if err != nil { return true, err } diff --git a/go/vt/vtctl/reparentutil/util.go b/go/vt/vtctl/reparentutil/util.go index ac57e1230d1..db260cc36b6 100644 --- a/go/vt/vtctl/reparentutil/util.go +++ b/go/vt/vtctl/reparentutil/util.go @@ -65,6 +65,7 @@ func ChooseNewPrimary( tabletMap map[string]*topo.TabletInfo, avoidPrimaryAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration, + tolerableReplLag time.Duration, durability Durabler, // (TODO:@ajm188) it's a little gross we need to pass this, maybe embed in the context? logger logutil.Logger, @@ -97,10 +98,10 @@ func ChooseNewPrimary( tb := tablet.Tablet errorGroup.Go(func() error { // find and store the positions for the tablet - pos, err := findPositionForTablet(groupCtx, tb, logger, tmc, waitReplicasTimeout) + pos, replLag, err := findPositionAndLagForTablet(groupCtx, tb, logger, tmc, waitReplicasTimeout) mu.Lock() defer mu.Unlock() - if err == nil { + if err == nil && (tolerableReplLag == 0 || tolerableReplLag >= replLag) { validTablets = append(validTablets, tb) tabletPositions = append(tabletPositions, pos) } @@ -127,9 +128,9 @@ func ChooseNewPrimary( return validTablets[0].Alias, nil } -// findPositionForTablet processes the replication position for a single tablet and +// findPositionAndLagForTablet processes the replication position and lag for a single tablet and // returns it. It is safe to call from multiple goroutines. -func findPositionForTablet(ctx context.Context, tablet *topodatapb.Tablet, logger logutil.Logger, tmc tmclient.TabletManagerClient, waitTimeout time.Duration) (replication.Position, error) { +func findPositionAndLagForTablet(ctx context.Context, tablet *topodatapb.Tablet, logger logutil.Logger, tmc tmclient.TabletManagerClient, waitTimeout time.Duration) (replication.Position, time.Duration, error) { logger.Infof("getting replication position from %v", topoproto.TabletAliasString(tablet.Alias)) ctx, cancel := context.WithTimeout(ctx, waitTimeout) @@ -140,10 +141,10 @@ func findPositionForTablet(ctx context.Context, tablet *topodatapb.Tablet, logge sqlErr, isSQLErr := sqlerror.NewSQLErrorFromError(err).(*sqlerror.SQLError) if isSQLErr && sqlErr != nil && sqlErr.Number() == sqlerror.ERNotReplica { logger.Warningf("no replication statue from %v, using empty gtid set", topoproto.TabletAliasString(tablet.Alias)) - return replication.Position{}, nil + return replication.Position{}, 0, nil } logger.Warningf("failed to get replication status from %v, ignoring tablet: %v", topoproto.TabletAliasString(tablet.Alias), err) - return replication.Position{}, err + return replication.Position{}, 0, err } // Use the relay log position if available, otherwise use the executed GTID set (binary log position). @@ -154,10 +155,10 @@ func findPositionForTablet(ctx context.Context, tablet *topodatapb.Tablet, logge pos, err := replication.DecodePosition(positionString) if err != nil { logger.Warningf("cannot decode replica position %v for tablet %v, ignoring tablet: %v", positionString, topoproto.TabletAliasString(tablet.Alias), err) - return replication.Position{}, err + return replication.Position{}, 0, err } - return pos, nil + return pos, time.Second * time.Duration(status.ReplicationLagSeconds), nil } // FindCurrentPrimary returns the current primary tablet of a shard, if any. The diff --git a/go/vt/vtctl/reparentutil/util_test.go b/go/vt/vtctl/reparentutil/util_test.go index 7b0d624590f..8e48bbb3303 100644 --- a/go/vt/vtctl/reparentutil/util_test.go +++ b/go/vt/vtctl/reparentutil/util_test.go @@ -72,22 +72,85 @@ func TestChooseNewPrimary(t *testing.T) { shardInfo *topo.ShardInfo tabletMap map[string]*topo.TabletInfo avoidPrimaryAlias *topodatapb.TabletAlias + tolerableReplLag time.Duration expected *topodatapb.TabletAlias shouldErr bool }{ { name: "found a replica", tmc: &chooseNewPrimaryTestTMClient{ - // zone1-101 is behind zone1-102 + // zone1-101 is behind zone1-102 and zone1-102 has a tolerable replication lag replicationStatuses: map[string]*replicationdatapb.Status{ "zone1-0000000101": { Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1", }, "zone1-0000000102": { - Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5", + Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5", + ReplicationLagSeconds: 20, + }, + }, + }, + tolerableReplLag: 50 * time.Second, + shardInfo: topo.NewShardInfo("testkeyspace", "-", &topodatapb.Shard{ + PrimaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, nil), + tabletMap: map[string]*topo.TabletInfo{ + "primary": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + }, + "replica1": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + "replica2": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 102, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + }, + avoidPrimaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 0, + }, + expected: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 102, + }, + shouldErr: false, + }, + { + name: "found a replica ignoring replica lag", + tmc: &chooseNewPrimaryTestTMClient{ + // zone1-101 is behind zone1-102 and we don't care about the replication lag + replicationStatuses: map[string]*replicationdatapb.Status{ + "zone1-0000000101": { + Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1", + }, + "zone1-0000000102": { + Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5", + ReplicationLagSeconds: 230, }, }, }, + tolerableReplLag: 0, shardInfo: topo.NewShardInfo("testkeyspace", "-", &topodatapb.Shard{ PrimaryAlias: &topodatapb.TabletAlias{ Cell: "zone1", @@ -133,6 +196,66 @@ func TestChooseNewPrimary(t *testing.T) { }, shouldErr: false, }, + { + name: "found a replica - ignore one with replication lag", + tmc: &chooseNewPrimaryTestTMClient{ + // zone1-101 is behind zone1-102 + replicationStatuses: map[string]*replicationdatapb.Status{ + "zone1-0000000101": { + Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1", + }, + "zone1-0000000102": { + Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5", + ReplicationLagSeconds: 232, + }, + }, + }, + tolerableReplLag: 50 * time.Second, + shardInfo: topo.NewShardInfo("testkeyspace", "-", &topodatapb.Shard{ + PrimaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, nil), + tabletMap: map[string]*topo.TabletInfo{ + "primary": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + }, + "replica1": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + "replica2": { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 102, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + }, + avoidPrimaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 0, + }, + expected: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + shouldErr: false, + }, { name: "found a replica - more advanced relay log position", tmc: &chooseNewPrimaryTestTMClient{ @@ -443,7 +566,7 @@ func TestChooseNewPrimary(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - actual, err := ChooseNewPrimary(ctx, tt.tmc, tt.shardInfo, tt.tabletMap, tt.avoidPrimaryAlias, time.Millisecond*50, durability, logger) + actual, err := ChooseNewPrimary(ctx, tt.tmc, tt.shardInfo, tt.tabletMap, tt.avoidPrimaryAlias, time.Millisecond*50, tt.tolerableReplLag, durability, logger) if tt.shouldErr { assert.Error(t, err) return @@ -465,6 +588,7 @@ func TestFindPositionForTablet(t *testing.T) { tmc *testutil.TabletManagerClient tablet *topodatapb.Tablet expectedPosition string + expectedLag time.Duration expectedErr string }{ { @@ -476,7 +600,8 @@ func TestFindPositionForTablet(t *testing.T) { }{ "zone1-0000000100": { Position: &replicationdatapb.Status{ - Position: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", + Position: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", + ReplicationLagSeconds: 201, }, }, }, @@ -487,6 +612,7 @@ func TestFindPositionForTablet(t *testing.T) { Uid: 100, }, }, + expectedLag: 201 * time.Second, expectedPosition: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", }, { name: "no replication status", @@ -506,6 +632,7 @@ func TestFindPositionForTablet(t *testing.T) { Uid: 100, }, }, + expectedLag: 0, expectedPosition: "", }, { name: "relay log", @@ -516,8 +643,9 @@ func TestFindPositionForTablet(t *testing.T) { }{ "zone1-0000000100": { Position: &replicationdatapb.Status{ - Position: "unused", - RelayLogPosition: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", + Position: "unused", + RelayLogPosition: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", + ReplicationLagSeconds: 291, }, }, }, @@ -528,6 +656,7 @@ func TestFindPositionForTablet(t *testing.T) { Uid: 100, }, }, + expectedLag: 291 * time.Second, expectedPosition: "MySQL56/3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5", }, { name: "error in parsing position", @@ -555,7 +684,7 @@ func TestFindPositionForTablet(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pos, err := findPositionForTablet(ctx, test.tablet, logger, test.tmc, 10*time.Second) + pos, lag, err := findPositionAndLagForTablet(ctx, test.tablet, logger, test.tmc, 10*time.Second) if test.expectedErr != "" { require.EqualError(t, err, test.expectedErr) return @@ -563,6 +692,7 @@ func TestFindPositionForTablet(t *testing.T) { require.NoError(t, err) posString := replication.EncodePosition(pos) require.Equal(t, test.expectedPosition, posString) + require.Equal(t, test.expectedLag, lag) }) } } diff --git a/go/vt/vtorc/config/config.go b/go/vt/vtorc/config/config.go index 03067d289ac..ba3c41ddc61 100644 --- a/go/vt/vtorc/config/config.go +++ b/go/vt/vtorc/config/config.go @@ -59,6 +59,7 @@ var ( recoveryPeriodBlockDuration = 30 * time.Second preventCrossCellFailover = false waitReplicasTimeout = 30 * time.Second + tolerableReplicationLag = 0 * time.Second topoInformationRefreshDuration = 15 * time.Second recoveryPollDuration = 1 * time.Second ersEnabled = true @@ -78,6 +79,7 @@ func RegisterFlags(fs *pflag.FlagSet) { fs.DurationVar(&recoveryPeriodBlockDuration, "recovery-period-block-duration", recoveryPeriodBlockDuration, "Duration for which a new recovery is blocked on an instance after running a recovery") fs.BoolVar(&preventCrossCellFailover, "prevent-cross-cell-failover", preventCrossCellFailover, "Prevent VTOrc from promoting a primary in a different cell than the current primary in case of a failover") fs.DurationVar(&waitReplicasTimeout, "wait-replicas-timeout", waitReplicasTimeout, "Duration for which to wait for replica's to respond when issuing RPCs") + fs.DurationVar(&tolerableReplicationLag, "tolerable-replication-lag", tolerableReplicationLag, "Amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary in PRS") fs.DurationVar(&topoInformationRefreshDuration, "topo-information-refresh-duration", topoInformationRefreshDuration, "Timer duration on which VTOrc refreshes the keyspace and vttablet records from the topology server") fs.DurationVar(&recoveryPollDuration, "recovery-poll-duration", recoveryPollDuration, "Timer duration on which VTOrc polls its database to run a recovery") fs.BoolVar(&ersEnabled, "allow-emergency-reparent", ersEnabled, "Whether VTOrc should be allowed to run emergency reparent operation when it detects a dead primary") @@ -100,6 +102,7 @@ type Configuration struct { RecoveryPeriodBlockSeconds int // (overrides `RecoveryPeriodBlockMinutes`) The time for which an instance's recovery is kept "active", so as to avoid concurrent recoveries on smae instance as well as flapping PreventCrossDataCenterPrimaryFailover bool // When true (default: false), cross-DC primary failover are not allowed, vtorc will do all it can to only fail over within same DC, or else not fail over at all. WaitReplicasTimeoutSeconds int // Timeout on amount of time to wait for the replicas in case of ERS. Should be a small value because we should fail-fast. Should not be larger than LockTimeout since that is the total time we use for an ERS. + TolerableReplicationLagSeconds int // Amount of replication lag that is considered acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary in PRS. TopoInformationRefreshSeconds int // Timer duration on which VTOrc refreshes the keyspace and vttablet records from the topo-server. RecoveryPollSeconds int // Timer duration on which VTOrc recovery analysis runs } @@ -129,6 +132,7 @@ func UpdateConfigValuesFromFlags() { Config.RecoveryPeriodBlockSeconds = int(recoveryPeriodBlockDuration / time.Second) Config.PreventCrossDataCenterPrimaryFailover = preventCrossCellFailover Config.WaitReplicasTimeoutSeconds = int(waitReplicasTimeout / time.Second) + Config.TolerableReplicationLagSeconds = int(tolerableReplicationLag / time.Second) Config.TopoInformationRefreshSeconds = int(topoInformationRefreshDuration / time.Second) Config.RecoveryPollSeconds = int(recoveryPollDuration / time.Second) } diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index cf99e34e426..e5168fea541 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -852,6 +852,7 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi analyzedTablet.Shard, reparentutil.PlannedReparentOptions{ WaitReplicasTimeout: time.Duration(config.Config.WaitReplicasTimeoutSeconds) * time.Second, + TolerableReplLag: time.Duration(config.Config.TolerableReplicationLagSeconds) * time.Second, }, ) diff --git a/go/vt/wrangler/reparent.go b/go/vt/wrangler/reparent.go index fbeec55cbbc..dbad6b2ee29 100644 --- a/go/vt/wrangler/reparent.go +++ b/go/vt/wrangler/reparent.go @@ -76,7 +76,12 @@ func (wr *Wrangler) InitShardPrimary(ctx context.Context, keyspace, shard string // PlannedReparentShard will make the provided tablet the primary for the shard, // when both the current and new primary are reachable and in good shape. -func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, primaryElectTabletAlias, avoidTabletAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration) (err error) { +func (wr *Wrangler) PlannedReparentShard( + ctx context.Context, + keyspace, shard string, + primaryElectTabletAlias, avoidTabletAlias *topodatapb.TabletAlias, + waitReplicasTimeout, tolerableReplicationLag time.Duration, +) (err error) { _, err = reparentutil.NewPlannedReparenter(wr.ts, wr.tmc, wr.logger).ReparentShard( ctx, keyspace, @@ -85,6 +90,7 @@ func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard st AvoidPrimaryAlias: avoidTabletAlias, NewPrimaryAlias: primaryElectTabletAlias, WaitReplicasTimeout: waitReplicasTimeout, + TolerableReplLag: tolerableReplicationLag, }, ) diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index b84f87c9037..c16f9b5d0ea 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -1211,6 +1211,10 @@ message PlannedReparentShardRequest { // WaitReplicasTimeout time to catch up before the reparent, and an additional // WaitReplicasTimeout time to catch up after the reparent. vttime.Duration wait_replicas_timeout = 5; + // TolerableReplicationLag is the amount of replication lag that is considered + // acceptable for a tablet to be eligible for promotion when Vitess makes the choice of a new primary. + // A value of 0 indicates that Vitess shouldn't consider the replication lag at all. + vttime.Duration tolerable_replication_lag = 6; } message PlannedReparentShardResponse { diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 11489a0acc2..d19221fe676 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -57419,6 +57419,9 @@ export namespace vtctldata { /** PlannedReparentShardRequest wait_replicas_timeout */ wait_replicas_timeout?: (vttime.IDuration|null); + + /** PlannedReparentShardRequest tolerable_replication_lag */ + tolerable_replication_lag?: (vttime.IDuration|null); } /** Represents a PlannedReparentShardRequest. */ @@ -57445,6 +57448,9 @@ export namespace vtctldata { /** PlannedReparentShardRequest wait_replicas_timeout. */ public wait_replicas_timeout?: (vttime.IDuration|null); + /** PlannedReparentShardRequest tolerable_replication_lag. */ + public tolerable_replication_lag?: (vttime.IDuration|null); + /** * Creates a new PlannedReparentShardRequest instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 71d67a61ed1..7de0fde463a 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -140320,6 +140320,7 @@ export const vtctldata = $root.vtctldata = (() => { * @property {topodata.ITabletAlias|null} [new_primary] PlannedReparentShardRequest new_primary * @property {topodata.ITabletAlias|null} [avoid_primary] PlannedReparentShardRequest avoid_primary * @property {vttime.IDuration|null} [wait_replicas_timeout] PlannedReparentShardRequest wait_replicas_timeout + * @property {vttime.IDuration|null} [tolerable_replication_lag] PlannedReparentShardRequest tolerable_replication_lag */ /** @@ -140377,6 +140378,14 @@ export const vtctldata = $root.vtctldata = (() => { */ PlannedReparentShardRequest.prototype.wait_replicas_timeout = null; + /** + * PlannedReparentShardRequest tolerable_replication_lag. + * @member {vttime.IDuration|null|undefined} tolerable_replication_lag + * @memberof vtctldata.PlannedReparentShardRequest + * @instance + */ + PlannedReparentShardRequest.prototype.tolerable_replication_lag = null; + /** * Creates a new PlannedReparentShardRequest instance using the specified properties. * @function create @@ -140411,6 +140420,8 @@ export const vtctldata = $root.vtctldata = (() => { $root.topodata.TabletAlias.encode(message.avoid_primary, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); if (message.wait_replicas_timeout != null && Object.hasOwnProperty.call(message, "wait_replicas_timeout")) $root.vttime.Duration.encode(message.wait_replicas_timeout, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.tolerable_replication_lag != null && Object.hasOwnProperty.call(message, "tolerable_replication_lag")) + $root.vttime.Duration.encode(message.tolerable_replication_lag, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); return writer; }; @@ -140465,6 +140476,10 @@ export const vtctldata = $root.vtctldata = (() => { message.wait_replicas_timeout = $root.vttime.Duration.decode(reader, reader.uint32()); break; } + case 6: { + message.tolerable_replication_lag = $root.vttime.Duration.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -140521,6 +140536,11 @@ export const vtctldata = $root.vtctldata = (() => { if (error) return "wait_replicas_timeout." + error; } + if (message.tolerable_replication_lag != null && message.hasOwnProperty("tolerable_replication_lag")) { + let error = $root.vttime.Duration.verify(message.tolerable_replication_lag); + if (error) + return "tolerable_replication_lag." + error; + } return null; }; @@ -140555,6 +140575,11 @@ export const vtctldata = $root.vtctldata = (() => { throw TypeError(".vtctldata.PlannedReparentShardRequest.wait_replicas_timeout: object expected"); message.wait_replicas_timeout = $root.vttime.Duration.fromObject(object.wait_replicas_timeout); } + if (object.tolerable_replication_lag != null) { + if (typeof object.tolerable_replication_lag !== "object") + throw TypeError(".vtctldata.PlannedReparentShardRequest.tolerable_replication_lag: object expected"); + message.tolerable_replication_lag = $root.vttime.Duration.fromObject(object.tolerable_replication_lag); + } return message; }; @@ -140577,6 +140602,7 @@ export const vtctldata = $root.vtctldata = (() => { object.new_primary = null; object.avoid_primary = null; object.wait_replicas_timeout = null; + object.tolerable_replication_lag = null; } if (message.keyspace != null && message.hasOwnProperty("keyspace")) object.keyspace = message.keyspace; @@ -140588,6 +140614,8 @@ export const vtctldata = $root.vtctldata = (() => { object.avoid_primary = $root.topodata.TabletAlias.toObject(message.avoid_primary, options); if (message.wait_replicas_timeout != null && message.hasOwnProperty("wait_replicas_timeout")) object.wait_replicas_timeout = $root.vttime.Duration.toObject(message.wait_replicas_timeout, options); + if (message.tolerable_replication_lag != null && message.hasOwnProperty("tolerable_replication_lag")) + object.tolerable_replication_lag = $root.vttime.Duration.toObject(message.tolerable_replication_lag, options); return object; }; From 5929d429813c31005f44c7083dd72ef3d7b9518a Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 5 Dec 2023 04:35:39 -0500 Subject: [PATCH 078/119] tabletserver: do not consolidate streams on primary tablet when consolidator mode is `notOnPrimary` (#14332) --- changelog/19.0/19.0.0/summary.md | 8 + go/vt/vttablet/endtoend/config_test.go | 138 ++++++++++-------- go/vt/vttablet/tabletserver/query_executor.go | 2 +- .../tabletserver/stream_consolidator.go | 6 +- .../stream_consolidator_flaky_test.go | 5 +- go/vt/vttablet/tabletserver/tabletserver.go | 1 + 6 files changed, 100 insertions(+), 60 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index af9c83399a3..2b5fdfe3d65 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -8,6 +8,8 @@ - [VTTablet Flags](#vttablet-flags) - **[Docker](#docker)** - [New MySQL Image](#mysql-image) + - **[New Stats](#new-stats)** + - [Stream Consolidations](#stream-consolidations) - **[VTGate](#vtgate)** - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) - **[Query Compatibility](#query-compatibility)** @@ -43,6 +45,12 @@ This lightweight image is a replacement of `vitess/lite` to only run `mysqld`. Several tags are available to let you choose what version of MySQL you want to use: `vitess/mysql:8.0.30`, `vitess/mysql:8.0.34`. +### new stats + +#### Stream Consolidations + +Prior to 19.0 VTTablet reported how much time non-streaming executions spend waiting for consolidations to occur. In 19.0, VTTablet reports a similar stat for streaming executions in `/debug/vars` stat `Waits.Histograms.StreamConsolidations`. + ### VTGate #### `FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable diff --git a/go/vt/vttablet/endtoend/config_test.go b/go/vt/vttablet/endtoend/config_test.go index 60303cf4bf5..9eef54bd0bb 100644 --- a/go/vt/vttablet/endtoend/config_test.go +++ b/go/vt/vttablet/endtoend/config_test.go @@ -108,64 +108,88 @@ func TestDisableConsolidator(t *testing.T) { } func TestConsolidatorReplicasOnly(t *testing.T) { - totalConsolidationsTag := "Waits/Histograms/Consolidations/Count" - initial := framework.FetchInt(framework.DebugVars(), totalConsolidationsTag) - var wg sync.WaitGroup - wg.Add(2) - go func() { - framework.NewClient().Execute("select sleep(0.5) from dual", nil) - wg.Done() - }() - go func() { - framework.NewClient().Execute("select sleep(0.5) from dual", nil) - wg.Done() - }() - wg.Wait() - afterOne := framework.FetchInt(framework.DebugVars(), totalConsolidationsTag) - assert.Equal(t, initial+1, afterOne, "expected one consolidation") - - revert := changeVar(t, "Consolidator", tabletenv.NotOnPrimary) - defer revert() - - // primary should not do query consolidation - var wg2 sync.WaitGroup - wg2.Add(2) - go func() { - framework.NewClient().Execute("select sleep(0.5) from dual", nil) - wg2.Done() - }() - go func() { - framework.NewClient().Execute("select sleep(0.5) from dual", nil) - wg2.Done() - }() - wg2.Wait() - noNewConsolidations := framework.FetchInt(framework.DebugVars(), totalConsolidationsTag) - assert.Equal(t, afterOne, noNewConsolidations, "expected no new consolidations") - - // become a replica, where query consolidation should happen - client := framework.NewClientWithTabletType(topodatapb.TabletType_REPLICA) - - err := client.SetServingType(topodatapb.TabletType_REPLICA) - require.NoError(t, err) - defer func() { - err = client.SetServingType(topodatapb.TabletType_PRIMARY) - require.NoError(t, err) - }() + type executeFn func( + query string, bindvars map[string]*querypb.BindVariable, + ) (*sqltypes.Result, error) + + testCases := []struct { + name string + getExecuteFn func(qc *framework.QueryClient) executeFn + totalConsolidationsTag string + }{ + { + name: "Execute", + getExecuteFn: func(qc *framework.QueryClient) executeFn { return qc.Execute }, + totalConsolidationsTag: "Waits/Histograms/Consolidations/Count", + }, + { + name: "StreamExecute", + getExecuteFn: func(qc *framework.QueryClient) executeFn { return qc.StreamExecute }, + totalConsolidationsTag: "Waits/Histograms/StreamConsolidations/Count", + }, + } - initial = framework.FetchInt(framework.DebugVars(), totalConsolidationsTag) - var wg3 sync.WaitGroup - wg3.Add(2) - go func() { - client.Execute("select sleep(0.5) from dual", nil) - wg3.Done() - }() - go func() { - client.Execute("select sleep(0.5) from dual", nil) - wg3.Done() - }() - wg3.Wait() - afterOne = framework.FetchInt(framework.DebugVars(), totalConsolidationsTag) - assert.Equal(t, initial+1, afterOne, "expected another consolidation") + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + initial := framework.FetchInt(framework.DebugVars(), testCase.totalConsolidationsTag) + var wg sync.WaitGroup + wg.Add(2) + go func() { + testCase.getExecuteFn(framework.NewClient())("select sleep(0.5) from dual", nil) + wg.Done() + }() + go func() { + testCase.getExecuteFn(framework.NewClient())("select sleep(0.5) from dual", nil) + wg.Done() + }() + wg.Wait() + afterOne := framework.FetchInt(framework.DebugVars(), testCase.totalConsolidationsTag) + assert.Equal(t, initial+1, afterOne, "expected one consolidation") + + revert := changeVar(t, "Consolidator", tabletenv.NotOnPrimary) + defer revert() + + // primary should not do query consolidation + var wg2 sync.WaitGroup + wg2.Add(2) + go func() { + testCase.getExecuteFn(framework.NewClient())("select sleep(0.5) from dual", nil) + wg2.Done() + }() + go func() { + testCase.getExecuteFn(framework.NewClient())("select sleep(0.5) from dual", nil) + wg2.Done() + }() + wg2.Wait() + noNewConsolidations := framework.FetchInt(framework.DebugVars(), testCase.totalConsolidationsTag) + assert.Equal(t, afterOne, noNewConsolidations, "expected no new consolidations") + + // become a replica, where query consolidation should happen + client := framework.NewClientWithTabletType(topodatapb.TabletType_REPLICA) + + err := client.SetServingType(topodatapb.TabletType_REPLICA) + require.NoError(t, err) + defer func() { + err = client.SetServingType(topodatapb.TabletType_PRIMARY) + require.NoError(t, err) + }() + + initial = framework.FetchInt(framework.DebugVars(), testCase.totalConsolidationsTag) + var wg3 sync.WaitGroup + wg3.Add(2) + go func() { + testCase.getExecuteFn(client)("select sleep(0.5) from dual", nil) + wg3.Done() + }() + go func() { + testCase.getExecuteFn(client)("select sleep(0.5) from dual", nil) + wg3.Done() + }() + wg3.Wait() + afterOne = framework.FetchInt(framework.DebugVars(), testCase.totalConsolidationsTag) + assert.Equal(t, initial+1, afterOne, "expected another consolidation") + }) + } } func TestQueryPlanCache(t *testing.T) { diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 63dcd42d0a8..735562c536f 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -340,7 +340,7 @@ func (qre *QueryExecutor) Stream(callback StreamCallback) error { if consolidator := qre.tsv.qe.streamConsolidator; consolidator != nil { if qre.connID == 0 && qre.plan.PlanID == p.PlanSelectStream && qre.shouldConsolidate() { - return consolidator.Consolidate(qre.logStats, sqlWithoutComments, callback, + return consolidator.Consolidate(qre.tsv.stats.WaitTimings, qre.logStats, sqlWithoutComments, callback, func(callback StreamCallback) error { dbConn, err := qre.getStreamConn() if err != nil { diff --git a/go/vt/vttablet/tabletserver/stream_consolidator.go b/go/vt/vttablet/tabletserver/stream_consolidator.go index 9f720059dce..cbf99eaffd4 100644 --- a/go/vt/vttablet/tabletserver/stream_consolidator.go +++ b/go/vt/vttablet/tabletserver/stream_consolidator.go @@ -19,9 +19,11 @@ package tabletserver import ( "sync" "sync/atomic" + "time" "vitess.io/vitess/go/sqltypes" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" ) @@ -70,7 +72,7 @@ func (sc *StreamConsolidator) SetBlocking(block bool) { // `callback`. A `leaderCallback` must also be supplied: this function must perform the actual // query in the upstream MySQL server, yielding results into the modified callback that it receives // as an argument. -func (sc *StreamConsolidator) Consolidate(logStats *tabletenv.LogStats, sql string, callback StreamCallback, leaderCallback func(StreamCallback) error) error { +func (sc *StreamConsolidator) Consolidate(waitTimings *servenv.TimingsWrapper, logStats *tabletenv.LogStats, sql string, callback StreamCallback, leaderCallback func(StreamCallback) error) error { var ( inflight *streamInFlight catchup []*sqltypes.Result @@ -100,9 +102,11 @@ func (sc *StreamConsolidator) Consolidate(logStats *tabletenv.LogStats, sql stri // if we have a followChan, we're following up on a query that is already being served if followChan != nil { + startTime := time.Now() defer func() { memchange := inflight.unfollow(followChan, sc.cleanup) atomic.AddInt64(&sc.memory, memchange) + waitTimings.Record("StreamConsolidations", startTime) }() logStats.QuerySources |= tabletenv.QuerySourceConsolidator diff --git a/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go b/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go index 0c903933412..caa519cc477 100644 --- a/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go +++ b/go/vt/vttablet/tabletserver/stream_consolidator_flaky_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/sqltypes" @@ -123,10 +124,12 @@ func (ct *consolidationTest) run(workers int, generateCallback func(int) (string go func(worker int) { defer wg.Done() + exporter := servenv.NewExporter("ConsolidatorTest", "") + timings := exporter.NewTimings("ConsolidatorWaits", "", "StreamConsolidations") logStats := tabletenv.NewLogStats(context.Background(), "StreamConsolidation") query, callback := generateCallback(worker) start := time.Now() - err := ct.cc.Consolidate(logStats, query, func(result *sqltypes.Result) error { + err := ct.cc.Consolidate(timings, logStats, query, func(result *sqltypes.Result) error { cr := ct.results[worker] cr.items = append(cr.items, result) atomic.AddInt64(&cr.count, 1) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 3b0ac598ad0..12c6a40868f 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -948,6 +948,7 @@ func (tsv *TabletServer) streamExecute(ctx context.Context, target *querypb.Targ ctx: ctx, logStats: logStats, tsv: tsv, + tabletType: target.GetTabletType(), setting: connSetting, } return qre.Stream(callback) From 85e804eabafbc2e657cf3c659ac9880d11911f55 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:01:47 +0530 Subject: [PATCH 079/119] Postpone waiting for dba grants after restore has succeeded (#14680) Signed-off-by: Manan Gupta --- go/cmd/vttablet/cli/cli.go | 10 +----- go/vt/vtcombo/tablet_map.go | 2 +- go/vt/vttablet/tabletmanager/tm_init.go | 36 ++++++++++++++----- go/vt/vttablet/tabletmanager/tm_init_test.go | 22 ++++++------ go/vt/vttablet/tabletserver/tabletserver.go | 2 +- .../tabletserver/tabletserver_test.go | 7 ++++ go/vt/wrangler/fake_tablet_test.go | 2 +- go/vt/wrangler/testlib/fake_tablet.go | 2 +- 8 files changed, 50 insertions(+), 33 deletions(-) diff --git a/go/cmd/vttablet/cli/cli.go b/go/cmd/vttablet/cli/cli.go index bed53d284e8..d68856be9b6 100644 --- a/go/cmd/vttablet/cli/cli.go +++ b/go/cmd/vttablet/cli/cli.go @@ -102,10 +102,6 @@ vttablet \ } ) -const ( - dbaGrantWaitTime = 10 * time.Second -) - func run(cmd *cobra.Command, args []string) error { servenv.Init() @@ -155,7 +151,7 @@ func run(cmd *cobra.Command, args []string) error { VREngine: vreplication.NewEngine(config, ts, tabletAlias.Cell, mysqld, qsc.LagThrottler()), VDiffEngine: vdiff.NewEngine(config, ts, tablet), } - if err := tm.Start(tablet, config.Healthcheck.IntervalSeconds.Get()); err != nil { + if err := tm.Start(tablet, config); err != nil { ts.Close() return fmt.Errorf("failed to parse --tablet-path or initialize DB credentials: %w", err) } @@ -249,10 +245,6 @@ func createTabletServer(ctx context.Context, config *tabletenv.TabletConfig, ts return nil, fmt.Errorf("table acl config has to be specified with table-acl-config flag because enforce-tableacl-config is set.") } - err := tabletserver.WaitForDBAGrants(config, dbaGrantWaitTime) - if err != nil { - return nil, err - } // creates and registers the query service qsc := tabletserver.NewTabletServer(ctx, "", config, ts, tabletAlias) servenv.OnRun(func() { diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index 77b7f267a30..b9fc4af294b 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -117,7 +117,7 @@ func CreateTablet( Type: initTabletType, DbNameOverride: dbname, } - if err := tm.Start(tablet, 0); err != nil { + if err := tm.Start(tablet, nil); err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index c1b6c837d50..d65115990f1 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -71,10 +71,14 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" "vitess.io/vitess/go/vt/vttablet/tabletserver" + "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" ) -// Query rules from denylist -const denyListQueryList string = "DenyListQueryRules" +const ( + // Query rules from denylist + denyListQueryList string = "DenyListQueryRules" + dbaGrantWaitTime = 10 * time.Second +) var ( // The following flags initialize the tablet record. @@ -335,7 +339,7 @@ func mergeTags(a, b map[string]string) map[string]string { } // Start starts the TabletManager. -func (tm *TabletManager) Start(tablet *topodatapb.Tablet, healthCheckInterval time.Duration) error { +func (tm *TabletManager) Start(tablet *topodatapb.Tablet, config *tabletenv.TabletConfig) error { defer func() { log.Infof("TabletManager Start took ~%d ms", time.Since(servenv.GetInitStartTime()).Milliseconds()) }() @@ -395,7 +399,7 @@ func (tm *TabletManager) Start(tablet *topodatapb.Tablet, healthCheckInterval ti tm.exportStats() servenv.OnRun(tm.registerTabletManager) - restoring, err := tm.handleRestore(tm.BatchCtx) + restoring, err := tm.handleRestore(tm.BatchCtx, config) if err != nil { return err } @@ -408,8 +412,17 @@ func (tm *TabletManager) Start(tablet *topodatapb.Tablet, healthCheckInterval ti // We shouldn't use the base tablet type directly, since the type could have changed to PRIMARY // earlier in tm.checkPrimaryShip code. _, err = tm.initializeReplication(ctx, tm.Tablet().Type) + if err != nil { + return err + } + + // Make sure we have the correct privileges for the DBA user before we start the state manager. + err = tabletserver.WaitForDBAGrants(config, dbaGrantWaitTime) + if err != nil { + return err + } tm.tmState.Open() - return err + return nil } // Close prepares a tablet for shutdown. First we check our tablet ownership and @@ -764,7 +777,7 @@ func (tm *TabletManager) initTablet(ctx context.Context) error { return nil } -func (tm *TabletManager) handleRestore(ctx context.Context) (bool, error) { +func (tm *TabletManager) handleRestore(ctx context.Context, config *tabletenv.TabletConfig) (bool, error) { // Sanity check for inconsistent flags if tm.Cnf == nil && restoreFromBackup { return false, fmt.Errorf("you cannot enable --restore_from_backup without a my.cnf file") @@ -776,9 +789,6 @@ func (tm *TabletManager) handleRestore(ctx context.Context) (bool, error) { // Restore in the background if restoreFromBackup { go func() { - // Open the state manager after restore is done. - defer tm.tmState.Open() - // Zero date will cause us to use the latest, which is the default backupTime := time.Time{} // Or if a backup timestamp was specified then we use the last backup taken at or before that time @@ -803,6 +813,14 @@ func (tm *TabletManager) handleRestore(ctx context.Context) (bool, error) { if err := tm.RestoreData(ctx, logutil.NewConsoleLogger(), waitForBackupInterval, false /* deleteBeforeRestore */, backupTime, restoreToTimestamp, restoreToPos, mysqlShutdownTimeout); err != nil { log.Exitf("RestoreFromBackup failed: %v", err) } + + // Make sure we have the correct privileges for the DBA user before we start the state manager. + err := tabletserver.WaitForDBAGrants(config, dbaGrantWaitTime) + if err != nil { + log.Exitf("Failed waiting for DBA grants: %v", err) + } + // Open the state manager after restore is done. + tm.tmState.Open() }() return true, nil } diff --git a/go/vt/vttablet/tabletmanager/tm_init_test.go b/go/vt/vttablet/tabletmanager/tm_init_test.go index 148042bd6b1..16dddba7dfd 100644 --- a/go/vt/vttablet/tabletmanager/tm_init_test.go +++ b/go/vt/vttablet/tabletmanager/tm_init_test.go @@ -282,7 +282,7 @@ func TestCheckPrimaryShip(t *testing.T) { return nil }) require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -297,7 +297,7 @@ func TestCheckPrimaryShip(t *testing.T) { // correct and start as PRIMARY. err = ts.DeleteTablet(ctx, alias) require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -311,7 +311,7 @@ func TestCheckPrimaryShip(t *testing.T) { ti.Type = topodatapb.TabletType_PRIMARY err = ts.UpdateTablet(ctx, ti) require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -321,7 +321,7 @@ func TestCheckPrimaryShip(t *testing.T) { tm.Stop() // 5. Subsequent inits will still start the vttablet as PRIMARY. - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -353,7 +353,7 @@ func TestCheckPrimaryShip(t *testing.T) { return nil }) require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -380,7 +380,7 @@ func TestCheckPrimaryShip(t *testing.T) { "FAKE SET MASTER", "START SLAVE", } - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) ti, err = ts.GetTablet(ctx, alias) require.NoError(t, err) @@ -407,7 +407,7 @@ func TestStartCheckMysql(t *testing.T) { DBConfigs: dbconfigs.NewTestDBConfigs(cp, cp, ""), QueryServiceControl: tabletservermock.NewController(), } - err := tm.Start(tablet, 0) + err := tm.Start(tablet, nil) require.NoError(t, err) defer tm.Stop() @@ -435,7 +435,7 @@ func TestStartFindMysqlPort(t *testing.T) { DBConfigs: &dbconfigs.DBConfigs{}, QueryServiceControl: tabletservermock.NewController(), } - err := tm.Start(tablet, 0) + err := tm.Start(tablet, nil) require.NoError(t, err) defer tm.Stop() @@ -511,7 +511,7 @@ func TestStartDoesNotUpdateReplicationDataForTabletInWrongShard(t *testing.T) { tablet := newTestTablet(t, 1, "ks", "-d0") require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) assert.Contains(t, err.Error(), "existing tablet keyspace and shard ks/0 differ") tablets, err := ts.FindAllTabletAliasesInShard(ctx, "ks", "-d0") @@ -548,7 +548,7 @@ func TestCheckTabletTypeResets(t *testing.T) { return nil }) require.NoError(t, err) - err = tm.Start(tablet, 0) + err = tm.Start(tablet, nil) require.NoError(t, err) assert.Equal(t, tm.tmState.tablet.Type, tm.tmState.displayState.tablet.Type) ti, err = ts.GetTablet(ctx, alias) @@ -671,7 +671,7 @@ func newTestTM(t *testing.T, ts *topo.Server, uid int, keyspace, shard string) * DBConfigs: &dbconfigs.DBConfigs{}, QueryServiceControl: tabletservermock.NewController(), } - err := tm.Start(tablet, 0) + err := tm.Start(tablet, nil) require.NoError(t, err) // Wait for SrvKeyspace to be rebuilt. We know that it has been built diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 12c6a40868f..5f9310add84 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -236,7 +236,7 @@ func NewTabletServer(ctx context.Context, name string, config *tabletenv.TabletC func WaitForDBAGrants(config *tabletenv.TabletConfig, waitTime time.Duration) error { // We don't wait for grants if the tablet is externally managed. Permissions // are then the responsibility of the DBA. - if config.DB.HasGlobalSettings() || waitTime == 0 { + if config == nil || config.DB.HasGlobalSettings() || waitTime == 0 { return nil } timer := time.NewTimer(waitTime) diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index 0f85e1018f5..a72a1aa76db 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -2739,6 +2739,13 @@ func TestWaitForDBAGrants(t *testing.T) { } return tc, func() {} }, + }, { + name: "Empty config", + waitTime: 300 * time.Millisecond, + errWanted: "", + setupFunc: func(t *testing.T) (*tabletenv.TabletConfig, func()) { + return nil, func() {} + }, }, } for _, tt := range tests { diff --git a/go/vt/wrangler/fake_tablet_test.go b/go/vt/wrangler/fake_tablet_test.go index 66d5cf474d6..cae4e8ffc41 100644 --- a/go/vt/wrangler/fake_tablet_test.go +++ b/go/vt/wrangler/fake_tablet_test.go @@ -201,7 +201,7 @@ func (ft *fakeTablet) StartActionLoop(t *testing.T, wr *Wrangler) { QueryServiceControl: tabletservermock.NewController(), VDiffEngine: vdiff2.NewEngine(config, wr.TopoServer(), ft.Tablet), } - if err := ft.TM.Start(ft.Tablet, 0); err != nil { + if err := ft.TM.Start(ft.Tablet, nil); err != nil { t.Fatal(err) } ft.Tablet = ft.TM.Tablet() diff --git a/go/vt/wrangler/testlib/fake_tablet.go b/go/vt/wrangler/testlib/fake_tablet.go index a1b30813f53..9c511185769 100644 --- a/go/vt/wrangler/testlib/fake_tablet.go +++ b/go/vt/wrangler/testlib/fake_tablet.go @@ -210,7 +210,7 @@ func (ft *FakeTablet) StartActionLoop(t *testing.T, wr *wrangler.Wrangler) { QueryServiceControl: tabletservermock.NewController(), VREngine: vreplication.NewTestEngine(wr.TopoServer(), ft.Tablet.Alias.Cell, ft.FakeMysqlDaemon, binlogplayer.NewFakeDBClient, binlogplayer.NewFakeDBClient, topoproto.TabletDbName(ft.Tablet), nil), } - if err := ft.TM.Start(ft.Tablet, 0); err != nil { + if err := ft.TM.Start(ft.Tablet, nil); err != nil { t.Fatalf("Error in tablet - %v, err - %v", topoproto.TabletAliasString(ft.Tablet.Alias), err.Error()) } ft.Tablet = ft.TM.Tablet() From f0c0a9232b74a05f098a6a5bdd078b76dad8c3c4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:05:46 +0200 Subject: [PATCH 080/119] schemadiff: granular foreign key reference errors (#14682) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/errors.go | 20 ++++++++++++++++++++ go/vt/schemadiff/schema.go | 8 ++++++++ go/vt/schemadiff/schema_test.go | 12 ++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/go/vt/schemadiff/errors.go b/go/vt/schemadiff/errors.go index 8317fbe9cea..723240f0d02 100644 --- a/go/vt/schemadiff/errors.go +++ b/go/vt/schemadiff/errors.go @@ -286,6 +286,26 @@ func (e *ForeignKeyDependencyUnresolvedError) Error() string { sqlescape.EscapeID(e.Table)) } +type ForeignKeyNonexistentReferencedTableError struct { + Table string + ReferencedTable string +} + +func (e *ForeignKeyNonexistentReferencedTableError) Error() string { + return fmt.Sprintf("table %s foreign key references nonexistent table %s", + sqlescape.EscapeID(e.Table), sqlescape.EscapeID(e.ReferencedTable)) +} + +type ForeignKeyReferencesViewError struct { + Table string + ReferencedView string +} + +func (e *ForeignKeyReferencesViewError) Error() string { + return fmt.Sprintf("table %s foreign key references view %s", + sqlescape.EscapeID(e.Table), sqlescape.EscapeID(e.ReferencedView)) +} + type InvalidColumnInForeignKeyConstraintError struct { Table string Constraint string diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index c34f05b7a9f..405ad6c7f45 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -239,6 +239,14 @@ func (s *Schema) normalize() error { if referencedTableName != name { nonSelfReferenceNames = append(nonSelfReferenceNames, referencedTableName) } + referencedEntity, ok := s.named[referencedTableName] + if !ok { + return &ForeignKeyNonexistentReferencedTableError{Table: name, ReferencedTable: referencedTableName} + } + if _, ok := referencedEntity.(*CreateViewEntity); ok { + return &ForeignKeyReferencesViewError{Table: name, ReferencedView: referencedTableName} + } + fkParents[referencedTableName] = true } if allNamesFoundInLowerLevel(nonSelfReferenceNames, iterationLevel) { diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 3a609bdf769..67de705d05c 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -331,7 +331,15 @@ func TestInvalidSchema(t *testing.T) { expectErr: &ForeignKeyColumnCountMismatchError{Table: "t11", Constraint: "f11", ColumnCount: 2, ReferencedTable: "t11", ReferencedColumnCount: 1}, }, { - schema: "create table t11 (id int primary key, i int, constraint f12 foreign key (i) references t12(id) on delete restrict)", + schema: "create table t11 (id int primary key, i int, constraint f12 foreign key (i) references t12 (id) on delete restrict)", + expectErr: &ForeignKeyNonexistentReferencedTableError{Table: "t11", ReferencedTable: "t12"}, + }, + { + schema: "create view v as select 1 as id from dual; create table t11 (id int primary key, i int, constraint fv foreign key (i) references v (id) on delete restrict)", + expectErr: &ForeignKeyReferencesViewError{Table: "t11", ReferencedView: "v"}, + }, + { + schema: "create table t11 (id int primary key, i int, constraint f11 foreign key (i) references t12 (id) on delete restrict); create table t12 (id int primary key, i int, constraint f12 foreign key (i) references t11 (id) on delete restrict)", expectErr: &ForeignKeyDependencyUnresolvedError{Table: "t11"}, }, { @@ -393,7 +401,7 @@ func TestInvalidTableForeignKeyReference(t *testing.T) { } _, err := NewSchemaFromQueries(fkQueries) assert.Error(t, err) - assert.EqualError(t, err, (&ForeignKeyDependencyUnresolvedError{Table: "t11"}).Error()) + assert.EqualError(t, err, (&ForeignKeyNonexistentReferencedTableError{Table: "t11", ReferencedTable: "t12"}).Error()) } { fkQueries := []string{ From 324364d14510c7c1e47d2403d5002c4e39ac0184 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:22:10 +0530 Subject: [PATCH 081/119] Make vttestserver docker image work with vtctldclient (#14665) Signed-off-by: Manan Gupta --- changelog/19.0/19.0.0/summary.md | 8 ++++ docker/vttestserver/run.sh | 1 + go/cmd/vttestserver/cli/main.go | 3 ++ go/flags/endtoend/vttestserver.txt | 1 + go/test/endtoend/docker/vttestserver.go | 13 ++++--- go/test/endtoend/docker/vttestserver_test.go | 40 ++++++++++++++++---- go/vt/vttest/local_cluster.go | 7 +++- go/vt/vttest/vtprocess.go | 10 ++++- 8 files changed, 67 insertions(+), 16 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index 2b5fdfe3d65..a303dff02cc 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -12,6 +12,8 @@ - [Stream Consolidations](#stream-consolidations) - **[VTGate](#vtgate)** - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) + - **[Vttestserver](#vttestserver)** + - [`--vtcombo-bind-host` flag](#vtcombo-bind-host) - **[Query Compatibility](#query-compatibility)** - [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces) - **[Planned Reparent Shard](#planned-reparent-shard)** @@ -57,6 +59,12 @@ Prior to 19.0 VTTablet reported how much time non-streaming executions spend wai When VTGate receives a query to change the `FOREIGN_KEY_CHECKS` value for a session, instead of sending the value down to MySQL, VTGate now keeps track of the value and changes the queries by adding `SET_VAR(FOREIGN_KEY_CHECKS=On/Off)` style query optimizer hints wherever required. +### Vttestserver + +#### `--vtcombo-bind-host` flag + +A new flag `--vtcombo-bind-host` has been added to vttestserver that allows the users to configure the bind host that vtcombo uses. This is especially useful when running vttestserver as a docker image and you want to run vtctld commands and look at the vtcombo `/debug/status` dashboard. + ### Query Compatibility #### `SHOW VSCHEMA KEYSPACES` Query diff --git a/docker/vttestserver/run.sh b/docker/vttestserver/run.sh index 1ff79153af5..e3a99ab38f4 100755 --- a/docker/vttestserver/run.sh +++ b/docker/vttestserver/run.sh @@ -35,6 +35,7 @@ rm -vf "$VTDATAROOT"/"$tablet_dir"/{mysql.sock,mysql.sock.lock} --keyspaces "$KEYSPACES" \ --num_shards "$NUM_SHARDS" \ --mysql_bind_host "${MYSQL_BIND_HOST:-127.0.0.1}" \ + --vtcombo-bind-host "${VTCOMBO_BIND_HOST:-127.0.0.1}" \ --mysql_server_version "${MYSQL_SERVER_VERSION:-$1}" \ --charset "${CHARSET:-utf8mb4}" \ --foreign_key_mode "${FOREIGN_KEY_MODE:-allow}" \ diff --git a/go/cmd/vttestserver/cli/main.go b/go/cmd/vttestserver/cli/main.go index ea92ae7dda0..644796c5bca 100644 --- a/go/cmd/vttestserver/cli/main.go +++ b/go/cmd/vttestserver/cli/main.go @@ -177,6 +177,9 @@ func New() (cmd *cobra.Command) { cmd.Flags().StringVar(&config.MySQLBindHost, "mysql_bind_host", "localhost", "which host to bind vtgate mysql listener to") + cmd.Flags().StringVar(&config.VtComboBindAddress, "vtcombo-bind-host", "localhost", + "which host to bind vtcombo servenv listener to") + cmd.Flags().StringVar(&mycnf, "extra_my_cnf", "", "extra files to add to the config, separated by ':'") diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index f6b9332a95e..aac0d1e5286 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -140,6 +140,7 @@ Flags: -v, --version print binary version --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema_ddl_authorized_users string Comma separated list of users authorized to execute vschema ddl operations via vtgate + --vtcombo-bind-host string which host to bind vtcombo servenv listener to (default "localhost") --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") --vtctld_grpc_ca string the server ca to use to validate servers when connecting --vtctld_grpc_cert string the cert to use to connect diff --git a/go/test/endtoend/docker/vttestserver.go b/go/test/endtoend/docker/vttestserver.go index 7f24134a28f..4f86c7616a1 100644 --- a/go/test/endtoend/docker/vttestserver.go +++ b/go/test/endtoend/docker/vttestserver.go @@ -39,7 +39,7 @@ type vttestserver struct { keyspaces []string numShards []int mysqlMaxConnecetions int - port int + basePort int } func newVttestserver(dockerImage string, keyspaces []string, numShards []int, mysqlMaxConnections, port int) *vttestserver { @@ -48,7 +48,7 @@ func newVttestserver(dockerImage string, keyspaces []string, numShards []int, my keyspaces: keyspaces, numShards: numShards, mysqlMaxConnecetions: mysqlMaxConnections, - port: port, + basePort: port, } } @@ -64,13 +64,16 @@ func (v *vttestserver) teardown() { 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, "-p", fmt.Sprintf("%d:%d", v.basePort, v.basePort)) + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+1, v.basePort+1)) + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+3, v.basePort+3)) + cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("PORT=%d", v.basePort)) 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", "VTCOMBO_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", fmt.Sprintf("mysqladmin ping -h127.0.0.1 -P%d", v.basePort+3)) cmd.Args = append(cmd.Args, "--health-interval=5s") cmd.Args = append(cmd.Args, "--health-timeout=2s") cmd.Args = append(cmd.Args, "--health-retries=5") diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index c89f6299f30..e34be52accf 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -22,6 +22,7 @@ import ( "os" "testing" + "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" "vitess.io/vitess/go/mysql" @@ -44,7 +45,7 @@ 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) + vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -56,7 +57,7 @@ func TestUnsharded(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -73,7 +74,7 @@ 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) + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -85,7 +86,7 @@ func TestSharded(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -103,7 +104,7 @@ 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) + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -115,7 +116,7 @@ func TestMysqlMaxCons(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -125,6 +126,29 @@ func TestMysqlMaxCons(t *testing.T) { } } +// TestVtctldCommands tests that vtctld commands can be run with the docker image. +func TestVtctldCommands(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + vtest := newVttestserver(image, []string{"long_ks_name"}, []int{2}, 100, 33574) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() + + // wait for the docker to be setup + err = vtest.waitUntilDockerHealthy(10) + require.NoError(t, err) + + vtctldClient := cluster.VtctldClientProcessInstance("localhost", vtest.basePort+1, os.TempDir()) + res, err := vtctldClient.ExecuteCommandWithOutput("GetKeyspaces") + require.NoError(t, err) + // We verify that the command succeeds, and the keyspace name is present in the output. + require.Contains(t, res, "long_ks_name") + }) + } +} + func TestLargeNumberOfKeyspaces(t *testing.T) { dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} for _, image := range dockerImages { @@ -136,7 +160,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) { numShards = append(numShards, 1) } - vtest := newVttestserver(image, keyspaces, numShards, 100000, 33577) + vtest := newVttestserver(image, keyspaces, numShards, 100000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -148,7 +172,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 6138508aea6..fcf164df187 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -109,6 +109,10 @@ type Config struct { // cluster startup if the data directory does not already exist. PersistentMode bool + // VtCombo bind address. + // vtcombo will bind to this address when running the servenv. + VtComboBindAddress string + // MySQL protocol bind address. // vtcombo will bind to this address when exposing the mysql protocol socket MySQLBindHost string @@ -641,6 +645,7 @@ func (db *LocalCluster) JSONConfig() any { } config := map[string]any{ + "bind_address": db.vt.BindAddress, "port": db.vt.Port, "socket": db.mysql.UnixSocket(), "vtcombo_mysql_port": db.Env.PortForProtocol("vtcombo_mysql_port", ""), @@ -783,7 +788,7 @@ func (db *LocalCluster) VTProcess() *VtProcess { // a pointer to the interface. To read this vschema, the caller must convert it to a map func (vt *VtProcess) ReadVSchema() (*interface{}, error) { httpClient := &http.Client{Timeout: 5 * time.Second} - resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", "127.0.0.1", vt.Port)) + resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", vt.BindAddress, vt.Port)) if err != nil { return nil, err } diff --git a/go/vt/vttest/vtprocess.go b/go/vt/vttest/vtprocess.go index 2053973b766..c17d66dedec 100644 --- a/go/vt/vttest/vtprocess.go +++ b/go/vt/vttest/vtprocess.go @@ -50,6 +50,7 @@ type VtProcess struct { Binary string ExtraArgs []string Env []string + BindAddress string Port int PortGrpc int HealthCheck HealthChecker @@ -91,7 +92,7 @@ func (vtp *VtProcess) IsHealthy() bool { // Address returns the main address for this Vitess process. // This is usually the main HTTP endpoint for the service. func (vtp *VtProcess) Address() string { - return fmt.Sprintf("localhost:%d", vtp.Port) + return fmt.Sprintf("%s:%d", vtp.BindAddress, vtp.Port) } // WaitTerminate attempts to gracefully shutdown the Vitess process by sending @@ -128,7 +129,7 @@ func (vtp *VtProcess) WaitStart() (err error) { vtp.proc = exec.Command( vtp.Binary, "--port", fmt.Sprintf("%d", vtp.Port), - "--bind-address", "127.0.0.1", + "--bind-address", vtp.BindAddress, "--log_dir", vtp.LogDirectory, "--alsologtostderr", ) @@ -196,11 +197,16 @@ var QueryServerArgs = []string{ // configured with the given Config. // The process must be manually started by calling WaitStart() func VtcomboProcess(environment Environment, args *Config, mysql MySQLManager) (*VtProcess, error) { + vtcomboBindAddress := "127.0.0.1" + if args.VtComboBindAddress != "" { + vtcomboBindAddress = args.VtComboBindAddress + } vt := &VtProcess{ Name: "vtcombo", Directory: environment.Directory(), LogDirectory: environment.LogDirectory(), Binary: environment.BinaryPath("vtcombo"), + BindAddress: vtcomboBindAddress, Port: environment.PortForProtocol("vtcombo", ""), PortGrpc: environment.PortForProtocol("vtcombo", "grpc"), HealthCheck: environment.ProcessHealthCheck("vtcombo"), From 302b4886fa47f0ef584e8e05288bd71c36d5d8a6 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Tue, 5 Dec 2023 11:11:20 -0500 Subject: [PATCH 082/119] go/vt/topo: enable concurrency for FindAllShardsInKeyspace (#14670) Signed-off-by: Matt Layher --- go/vt/topo/keyspace.go | 78 +++++++++++++--- go/vt/topo/keyspace_external_test.go | 89 +++++++++++++++++++ go/vt/topo/shard.go | 9 +- go/vt/topotools/rebuild_keyspace.go | 7 +- go/vt/topotools/split.go | 5 +- go/vt/vtctl/grpcvtctldserver/server.go | 2 +- go/vt/vtctl/workflow/utils.go | 2 +- go/vt/vtorc/logic/keyspace_shard_discovery.go | 7 +- go/vt/wrangler/keyspace.go | 2 +- 9 files changed, 180 insertions(+), 21 deletions(-) create mode 100644 go/vt/topo/keyspace_external_test.go diff --git a/go/vt/topo/keyspace.go b/go/vt/topo/keyspace.go index feb80c374e5..2bdd616a261 100755 --- a/go/vt/topo/keyspace.go +++ b/go/vt/topo/keyspace.go @@ -19,6 +19,9 @@ package topo import ( "context" "path" + "sync" + + "golang.org/x/sync/errgroup" "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/vt/vterrors" @@ -270,26 +273,77 @@ func (ts *Server) UpdateKeyspace(ctx context.Context, ki *KeyspaceInfo) error { return nil } -// FindAllShardsInKeyspace reads and returns all the existing shards in -// a keyspace. It doesn't take any lock. -func (ts *Server) FindAllShardsInKeyspace(ctx context.Context, keyspace string) (map[string]*ShardInfo, error) { +// FindAllShardsInKeyspaceOptions controls the behavior of +// Server.FindAllShardsInKeyspace. +type FindAllShardsInKeyspaceOptions struct { + // Concurrency controls the maximum number of concurrent calls to GetShard. + // If <= 0, Concurrency is set to 1. + Concurrency int +} + +// FindAllShardsInKeyspace reads and returns all the existing shards in a +// keyspace. It doesn't take any lock. +// +// If opt is non-nil, it is used to configure the method's behavior. Otherwise, +// the default options are used. +func (ts *Server) FindAllShardsInKeyspace(ctx context.Context, keyspace string, opt *FindAllShardsInKeyspaceOptions) (map[string]*ShardInfo, error) { + // Apply any necessary defaults. + if opt == nil { + opt = &FindAllShardsInKeyspaceOptions{} + } + if opt.Concurrency <= 0 { + opt.Concurrency = 1 + } + shards, err := ts.GetShardNames(ctx, keyspace) if err != nil { return nil, vterrors.Wrapf(err, "failed to get list of shards for keyspace '%v'", keyspace) } - result := make(map[string]*ShardInfo, len(shards)) + // Keyspaces with a large number of shards and geographically distributed + // topo instances may experience significant latency fetching shard records. + // + // A prior version of this logic used unbounded concurrency to fetch shard + // records which resulted in overwhelming topo server instances: + // https://github.com/vitessio/vitess/pull/5436. + // + // However, removing the concurrency altogether can cause large operations + // to fail due to timeout. The caller chooses the appropriate concurrency + // level so that certain paths can be optimized (such as vtctld + // RebuildKeyspace calls, which do not run on every vttablet). + var ( + mu sync.Mutex + result = make(map[string]*ShardInfo, len(shards)) + ) + + eg, ctx := errgroup.WithContext(ctx) + eg.SetLimit(opt.Concurrency) + for _, shard := range shards { - si, err := ts.GetShard(ctx, keyspace, shard) - if err != nil { - if IsErrType(err, NoNode) { + shard := shard + + eg.Go(func() error { + si, err := ts.GetShard(ctx, keyspace, shard) + switch { + case IsErrType(err, NoNode): log.Warningf("GetShard(%v, %v) returned ErrNoNode, consider checking the topology.", keyspace, shard) - } else { - return nil, vterrors.Wrapf(err, "GetShard(%v, %v) failed", keyspace, shard) + return nil + case err == nil: + mu.Lock() + result[shard] = si + mu.Unlock() + + return nil + default: + return vterrors.Wrapf(err, "GetShard(%v, %v) failed", keyspace, shard) } - } - result[shard] = si + }) } + + if err := eg.Wait(); err != nil { + return nil, err + } + return result, nil } @@ -319,7 +373,7 @@ func (ts *Server) GetServingShards(ctx context.Context, keyspace string) ([]*Sha // GetOnlyShard returns the single ShardInfo of an unsharded keyspace. func (ts *Server) GetOnlyShard(ctx context.Context, keyspace string) (*ShardInfo, error) { - allShards, err := ts.FindAllShardsInKeyspace(ctx, keyspace) + allShards, err := ts.FindAllShardsInKeyspace(ctx, keyspace, nil) if err != nil { return nil, err } diff --git a/go/vt/topo/keyspace_external_test.go b/go/vt/topo/keyspace_external_test.go new file mode 100644 index 00000000000..064c4cba93b --- /dev/null +++ b/go/vt/topo/keyspace_external_test.go @@ -0,0 +1,89 @@ +/* +Copyright 2023 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 topo_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/key" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +func TestServerFindAllShardsInKeyspace(t *testing.T) { + tests := []struct { + name string + shards int + opt *topo.FindAllShardsInKeyspaceOptions + }{ + { + name: "negative concurrency", + shards: 1, + // Ensure this doesn't panic. + opt: &topo.FindAllShardsInKeyspaceOptions{Concurrency: -1}, + }, + { + name: "unsharded", + shards: 1, + // Make sure the defaults apply as expected. + opt: nil, + }, + { + name: "sharded", + shards: 32, + opt: &topo.FindAllShardsInKeyspaceOptions{Concurrency: 8}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ts := memorytopo.NewServer(ctx) + defer ts.Close() + + // Create an ephemeral keyspace and generate shard records within + // the keyspace to fetch later. + const keyspace = "keyspace" + require.NoError(t, ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{})) + + shards, err := key.GenerateShardRanges(tt.shards) + require.NoError(t, err) + + for _, s := range shards { + require.NoError(t, ts.CreateShard(ctx, keyspace, s)) + } + + // Verify that we return a complete list of shards and that each + // key range is present in the output. + out, err := ts.FindAllShardsInKeyspace(ctx, keyspace, tt.opt) + require.NoError(t, err) + require.Len(t, out, tt.shards) + + for _, s := range shards { + if _, ok := out[s]; !ok { + t.Errorf("shard %q was not found", s) + } + } + }) + } +} diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index 183ed409bbb..752001438f4 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -314,7 +314,14 @@ func (ts *Server) CreateShard(ctx context.Context, keyspace, shard string) (err // Set primary as serving only if its keyrange doesn't overlap // with other shards. This applies to unsharded keyspaces also value.IsPrimaryServing = true - sis, err := ts.FindAllShardsInKeyspace(ctx, keyspace) + sis, err := ts.FindAllShardsInKeyspace(ctx, keyspace, &FindAllShardsInKeyspaceOptions{ + // Assume that CreateShard may be called by many vttablets concurrently + // in a large, sharded keyspace. Do not apply concurrency to avoid + // overwhelming the toposerver. + // + // See: https://github.com/vitessio/vitess/pull/5436. + Concurrency: 1, + }) if err != nil && !IsErrType(err, NoNode) { return err } diff --git a/go/vt/topotools/rebuild_keyspace.go b/go/vt/topotools/rebuild_keyspace.go index d58ce0b7160..09df8b8fadc 100644 --- a/go/vt/topotools/rebuild_keyspace.go +++ b/go/vt/topotools/rebuild_keyspace.go @@ -64,7 +64,12 @@ func RebuildKeyspaceLocked(ctx context.Context, log logutil.Logger, ts *topo.Ser } } - shards, err := ts.FindAllShardsInKeyspace(ctx, keyspace) + shards, err := ts.FindAllShardsInKeyspace(ctx, keyspace, &topo.FindAllShardsInKeyspaceOptions{ + // Fetch shard records concurrently to speed up the rebuild process. + // This call is invoked by the first tablet in a given keyspace or + // manually via vtctld, so there is little risk of a thundering herd. + Concurrency: 8, + }) if err != nil { return err } diff --git a/go/vt/topotools/split.go b/go/vt/topotools/split.go index ace3dda94a7..0671c2c5cb8 100644 --- a/go/vt/topotools/split.go +++ b/go/vt/topotools/split.go @@ -17,12 +17,11 @@ limitations under the License. package topotools import ( + "context" "errors" "fmt" "sort" - "context" - "vitess.io/vitess/go/vt/key" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" @@ -119,7 +118,7 @@ func OverlappingShardsForShard(os []*OverlappingShards, shardName string) *Overl // will return an error). // If shards don't perfectly overlap, they are not returned. func FindOverlappingShards(ctx context.Context, ts *topo.Server, keyspace string) ([]*OverlappingShards, error) { - shardMap, err := ts.FindAllShardsInKeyspace(ctx, keyspace) + shardMap, err := ts.FindAllShardsInKeyspace(ctx, keyspace, nil) if err != nil { return nil, err } diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index ef0e9db341b..2ece69876e8 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -1243,7 +1243,7 @@ func (s *VtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctlda span.Annotate("keyspace", req.Keyspace) - result, err := s.ts.FindAllShardsInKeyspace(ctx, req.Keyspace) + result, err := s.ts.FindAllShardsInKeyspace(ctx, req.Keyspace, nil) if err != nil { return nil, err } diff --git a/go/vt/vtctl/workflow/utils.go b/go/vt/vtctl/workflow/utils.go index 1a723c6192c..4d1a3c5df4d 100644 --- a/go/vt/vtctl/workflow/utils.go +++ b/go/vt/vtctl/workflow/utils.go @@ -86,7 +86,7 @@ func getTablesInKeyspace(ctx context.Context, ts *topo.Server, tmc tmclient.Tabl // validateNewWorkflow ensures that the specified workflow doesn't already exist // in the keyspace. func validateNewWorkflow(ctx context.Context, ts *topo.Server, tmc tmclient.TabletManagerClient, keyspace, workflow string) error { - allshards, err := ts.FindAllShardsInKeyspace(ctx, keyspace) + allshards, err := ts.FindAllShardsInKeyspace(ctx, keyspace, nil) if err != nil { return err } diff --git a/go/vt/vtorc/logic/keyspace_shard_discovery.go b/go/vt/vtorc/logic/keyspace_shard_discovery.go index c79ace5bdc3..b1e93fe2a01 100644 --- a/go/vt/vtorc/logic/keyspace_shard_discovery.go +++ b/go/vt/vtorc/logic/keyspace_shard_discovery.go @@ -124,7 +124,12 @@ func refreshKeyspaceHelper(ctx context.Context, keyspaceName string) error { // refreshAllShards refreshes all the shard records in the given keyspace. func refreshAllShards(ctx context.Context, keyspaceName string) error { - shardInfos, err := ts.FindAllShardsInKeyspace(ctx, keyspaceName) + shardInfos, err := ts.FindAllShardsInKeyspace(ctx, keyspaceName, &topo.FindAllShardsInKeyspaceOptions{ + // Fetch shard records concurrently to speed up discovery. A typical + // Vitess cluster will have 1-3 vtorc instances deployed, so there is + // little risk of a thundering herd. + Concurrency: 8, + }) if err != nil { log.Error(err) return err diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index 7f3f00da4f8..a5f7d6ae0bf 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -44,7 +44,7 @@ const ( // validateNewWorkflow ensures that the specified workflow doesn't already exist // in the keyspace. func (wr *Wrangler) validateNewWorkflow(ctx context.Context, keyspace, workflow string) error { - allshards, err := wr.ts.FindAllShardsInKeyspace(ctx, keyspace) + allshards, err := wr.ts.FindAllShardsInKeyspace(ctx, keyspace, nil) if err != nil { return err } From 4e8be87978b0afd74ea13a4548787ad2486c7b5b Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Tue, 5 Dec 2023 20:44:12 -0500 Subject: [PATCH 083/119] go/vt/vttablet: fix nilness issues (#14686) --- go/vt/vttablet/grpctabletconn/conn.go | 14 +++++++------- go/vt/vttablet/onlineddl/executor.go | 4 ++-- go/vt/vttablet/onlineddl/vrepl.go | 6 +++--- go/vt/vttablet/tabletmanager/vdiff/action.go | 3 --- .../queryhistory/sequenced_expectation_set.go | 4 ++-- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/go/vt/vttablet/grpctabletconn/conn.go b/go/vt/vttablet/grpctabletconn/conn.go index 2399420a8d0..775118aee73 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -188,7 +188,7 @@ func (conn *gRPCQueryClient) StreamExecute(ctx context.Context, target *querypb. fields = ser.Result.Fields } if err := callback(sqltypes.CustomProto3ToResult(fields, ser.Result)); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return nil } return err @@ -537,7 +537,7 @@ func (conn *gRPCQueryClient) BeginStreamExecute(ctx context.Context, target *que fields = ser.Result.Fields } if err := callback(sqltypes.CustomProto3ToResult(fields, ser.Result)); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return state, nil } return state, err @@ -583,7 +583,7 @@ func (conn *gRPCQueryClient) MessageStream(ctx context.Context, target *querypb. fields = msr.Result.Fields } if err := callback(sqltypes.CustomProto3ToResult(fields, msr.Result)); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return nil } return err @@ -640,7 +640,7 @@ func (conn *gRPCQueryClient) StreamHealth(ctx context.Context, callback func(*qu return tabletconn.ErrorFromGRPC(err) } if err := callback(shr); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return nil } return err @@ -924,7 +924,7 @@ func (conn *gRPCQueryClient) ReserveBeginStreamExecute(ctx context.Context, targ fields = ser.Result.Fields } if err := callback(sqltypes.CustomProto3ToResult(fields, ser.Result)); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return state, nil } return state, err @@ -1029,7 +1029,7 @@ func (conn *gRPCQueryClient) ReserveStreamExecute(ctx context.Context, target *q fields = ser.Result.Fields } if err := callback(sqltypes.CustomProto3ToResult(fields, ser.Result)); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return state, nil } return state, err @@ -1092,7 +1092,7 @@ func (conn *gRPCQueryClient) GetSchema(ctx context.Context, target *querypb.Targ return tabletconn.ErrorFromGRPC(err) } if err := callback(shr); err != nil { - if err == nil || err == io.EOF { + if err == io.EOF { return nil } return err diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 2c78069e962..3b2dd30c9f6 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -778,7 +778,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) er defer tmClient.Close() // sanity checks: - vreplTable, err := getVreplTable(ctx, s) + vreplTable, err := getVreplTable(s) if err != nil { return err } @@ -1422,7 +1422,7 @@ func (e *Executor) initVreplicationRevertMigration(ctx context.Context, onlineDD return nil, err } - vreplTableName, err := getVreplTable(ctx, revertStream) + vreplTableName, err := getVreplTable(revertStream) if err != nil { return nil, err } diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 7934aed6af1..5cdb24ae5e4 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -659,16 +659,16 @@ func (v *VRepl) generateStartStatement(ctx context.Context) (string, error) { ) } -func getVreplTable(ctx context.Context, s *VReplStream) (string, error) { +func getVreplTable(s *VReplStream) (string, error) { // sanity checks: if s == nil { - return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "No vreplication stream migration %s", s.workflow) + return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "No vreplication stream migration") } if s.bls.Filter == nil { return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "No binlog source filter for migration %s", s.workflow) } if len(s.bls.Filter.Rules) != 1 { - return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "Cannot detect filter rules for migration/vreplication %+v", s.workflow) + return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "Cannot detect filter rules for migration/vreplication %s", s.workflow) } vreplTable := s.bls.Filter.Rules[0].Match return vreplTable, nil diff --git a/go/vt/vttablet/tabletmanager/vdiff/action.go b/go/vt/vttablet/tabletmanager/vdiff/action.go index 59ee79077f7..ded232bf3c7 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/action.go +++ b/go/vt/vttablet/tabletmanager/vdiff/action.go @@ -232,9 +232,6 @@ func (vde *Engine) handleCreateResumeAction(ctx context.Context, dbClient binlog if qr.RowsAffected == 0 { msg := fmt.Sprintf("no completed or stopped vdiff found for UUID %s on tablet %v", req.VdiffUuid, vde.thisTablet.Alias) - if err != nil { - msg = fmt.Sprintf("%s (%v)", msg, err) - } return fmt.Errorf(msg) } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/queryhistory/sequenced_expectation_set.go b/go/vt/vttablet/tabletmanager/vreplication/queryhistory/sequenced_expectation_set.go index 9ab0bf99043..95b2c3e4f67 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/queryhistory/sequenced_expectation_set.go +++ b/go/vt/vttablet/tabletmanager/vreplication/queryhistory/sequenced_expectation_set.go @@ -12,7 +12,7 @@ type sequencedExpectationSet map[SequencedExpectation]any func (ses *sequencedExpectationSet) Add(expectation SequencedExpectation) { if ses == nil { - *ses = make(sequencedExpectationSet) + ses = new(sequencedExpectationSet) } (*ses)[expectation] = true } @@ -27,7 +27,7 @@ func (ses *sequencedExpectationSet) Contains(expectation SequencedExpectation) b func (ses *sequencedExpectationSet) Slice() []SequencedExpectation { s := make([]SequencedExpectation, 0) - if len(*ses) == 0 { + if ses == nil || len(*ses) == 0 { return s } for se := range *ses { From c40e91192841a461ee4b6df5ba98cc5200e15dc4 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Tue, 5 Dec 2023 20:51:19 -0500 Subject: [PATCH 084/119] go/vt/vtgate: fix nilness issues (#14685) --- go/vt/vtgate/engine/vindex_lookup.go | 4 ---- go/vt/vtgate/evalengine/api_coerce.go | 2 +- go/vt/vtgate/planbuilder/operator_transformers.go | 6 ------ .../vtgate/planbuilder/operators/query_planning.go | 13 ++++--------- go/vt/vtgate/planbuilder/operators/vindex.go | 5 +---- 5 files changed, 6 insertions(+), 24 deletions(-) diff --git a/go/vt/vtgate/engine/vindex_lookup.go b/go/vt/vtgate/engine/vindex_lookup.go index aaf49feea95..8bf8755c40e 100644 --- a/go/vt/vtgate/engine/vindex_lookup.go +++ b/go/vt/vtgate/engine/vindex_lookup.go @@ -227,10 +227,6 @@ func (vr *VindexLookup) executeBatch(ctx context.Context, vcursor VCursor, ids [ } else { result, err = vcursor.ExecutePrimitive(ctx, vr.Lookup, bindVars, false) } - if err != nil { - return nil, err - } - if err != nil { return nil, vterrors.Wrapf(err, "failed while running the lookup query") } diff --git a/go/vt/vtgate/evalengine/api_coerce.go b/go/vt/vtgate/evalengine/api_coerce.go index 89b36458198..cbd1b145ca6 100644 --- a/go/vt/vtgate/evalengine/api_coerce.go +++ b/go/vt/vtgate/evalengine/api_coerce.go @@ -48,7 +48,7 @@ func CoerceTypes(v1, v2 Type) (out Type, err error) { switch { case sqltypes.IsTextOrBinary(v1.Type()) && sqltypes.IsTextOrBinary(v2.Type()): mergedCollation, _, _, ferr := mergeCollations(typedCoercionCollation(v1.Type(), v1.Collation()), typedCoercionCollation(v2.Type(), v2.Collation()), v1.Type(), v2.Type()) - if err != nil { + if ferr != nil { return Type{}, ferr } out.collation = mergedCollation.Collation diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 3974a307e71..7d3eb05549a 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -251,9 +251,6 @@ func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggrega }) } - if err != nil { - return nil, err - } oa.truncateColumnCount = op.ResultColumns return oa, nil } @@ -431,9 +428,6 @@ func routeToEngineRoute(ctx *plancontext.PlanningContext, op *operators.Route, h rp := newRoutingParams(ctx, op.Routing.OpCode()) op.Routing.UpdateRoutingParams(ctx, rp) - if err != nil { - return nil, err - } e := &engine.Route{ TableName: strings.Join(tableNames, ", "), diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 0994ee4402a..38e4e4cd8c0 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -55,8 +55,8 @@ func planQuery(ctx *plancontext.PlanningContext, root Operator) (output Operator // If we can push it under a route - done. // If we can't, we will instead expand the Horizon into // smaller operators and try to push these down as far as possible -func runPhases(ctx *plancontext.PlanningContext, root Operator) (op Operator, err error) { - op = root +func runPhases(ctx *plancontext.PlanningContext, root Operator) (Operator, error) { + op := root p := phaser{} for phase := p.next(ctx); phase != DONE; phase = p.next(ctx) { @@ -66,19 +66,14 @@ func runPhases(ctx *plancontext.PlanningContext, root Operator) (op Operator, er } op = phase.act(ctx, op) - if err != nil { - return nil, err - } + var err error op, err = runRewriters(ctx, op) if err != nil { return nil, err } op = compact(ctx, op) - if err != nil { - return nil, err - } } return addGroupByOnRHSOfJoin(op), nil @@ -222,7 +217,7 @@ func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq * return p, NoRewrite } - if !reachedPhase(ctx, subquerySettling) || err != nil { + if !reachedPhase(ctx, subquerySettling) { return p, NoRewrite } diff --git a/go/vt/vtgate/planbuilder/operators/vindex.go b/go/vt/vtgate/planbuilder/operators/vindex.go index f8667b45aba..0b49083785a 100644 --- a/go/vt/vtgate/planbuilder/operators/vindex.go +++ b/go/vt/vtgate/planbuilder/operators/vindex.go @@ -148,15 +148,12 @@ func (v *Vindex) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.E } // check RHS - var err error if sqlparser.IsValue(comparison.Right) || sqlparser.IsSimpleTuple(comparison.Right) { v.Value = comparison.Right } else { panic(vterrors.VT09018(wrongWhereCond + " (rhs is not a value)")) } - if err != nil { - panic(vterrors.VT09018(wrongWhereCond+": %v", err)) - } + v.OpCode = engine.VindexMap v.Table.Predicates = append(v.Table.Predicates, e) } From 6e59cfc07b3c8c1d4d963cfa281a58615aec0ef4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 10:41:16 +0530 Subject: [PATCH 085/119] [main] Upgrade the Golang version to `go1.21.5` (#14689) Signed-off-by: GitHub Signed-off-by: Florent Poinsard Co-authored-by: frouioui Co-authored-by: Florent Poinsard --- .github/workflows/assign_milestone.yml | 2 +- .github/workflows/check_make_vtadmin_authz_testgen.yml | 2 +- .github/workflows/check_make_vtadmin_web_proto.yml | 2 +- .github/workflows/cluster_endtoend_12.yml | 2 +- .github/workflows/cluster_endtoend_13.yml | 2 +- .github/workflows/cluster_endtoend_15.yml | 2 +- .github/workflows/cluster_endtoend_18.yml | 2 +- .github/workflows/cluster_endtoend_21.yml | 2 +- .github/workflows/cluster_endtoend_22.yml | 2 +- .github/workflows/cluster_endtoend_backup_pitr.yml | 2 +- .github/workflows/cluster_endtoend_backup_pitr_mysql57.yml | 2 +- .../workflows/cluster_endtoend_backup_pitr_xtrabackup.yml | 2 +- .../cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml | 2 +- .../cluster_endtoend_ers_prs_newfeatures_heavy.yml | 2 +- .github/workflows/cluster_endtoend_mysql80.yml | 2 +- .github/workflows/cluster_endtoend_mysql_server_vault.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_ghost.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_revert.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_revert_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_scheduler.yml | 2 +- .../cluster_endtoend_onlineddl_scheduler_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_vrepl.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_stress.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_stress_suite.yml | 2 +- ...luster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_suite.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_schemadiff_vrepl.yml | 2 +- .../workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_tabletmanager_consul.yml | 2 +- .../workflows/cluster_endtoend_tabletmanager_tablegc.yml | 2 +- .../cluster_endtoend_tabletmanager_tablegc_mysql57.yml | 2 +- .../cluster_endtoend_tabletmanager_throttler_topo.yml | 2 +- .../workflows/cluster_endtoend_topo_connection_cache.yml | 2 +- .../cluster_endtoend_vreplication_across_db_versions.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_basic.yml | 2 +- .../workflows/cluster_endtoend_vreplication_cellalias.yml | 2 +- .../cluster_endtoend_vreplication_foreign_key_stress.yml | 2 +- ...ster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml | 2 +- .../workflows/cluster_endtoend_vreplication_multicell.yml | 2 +- ...uster_endtoend_vreplication_partial_movetables_basic.yml | 2 +- ...r_endtoend_vreplication_partial_movetables_sequences.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_v2.yml | 2 +- .github/workflows/cluster_endtoend_vstream_failover.yml | 2 +- .../cluster_endtoend_vstream_stoponreshard_false.yml | 2 +- .../cluster_endtoend_vstream_stoponreshard_true.yml | 2 +- .../cluster_endtoend_vstream_with_keyspaces_to_watch.yml | 2 +- .github/workflows/cluster_endtoend_vtbackup.yml | 2 +- ...uster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_concurrentdml.yml | 2 +- .../workflows/cluster_endtoend_vtgate_foreignkey_stress.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_gen4.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_general_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_godriver.yml | 2 +- .../workflows/cluster_endtoend_vtgate_partial_keyspace.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_queries.yml | 2 +- .../workflows/cluster_endtoend_vtgate_readafterwrite.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_reservedconn.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_schema.yml | 2 +- .../workflows/cluster_endtoend_vtgate_schema_tracker.yml | 2 +- .../cluster_endtoend_vtgate_tablet_healthcheck_cache.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_consul.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_etcd.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_transaction.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_unsharded.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vschema.yml | 2 +- .github/workflows/cluster_endtoend_vtorc.yml | 2 +- .github/workflows/cluster_endtoend_vtorc_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_vttablet_prscomplex.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup_mysql57.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery_mysql57.yml | 2 +- .github/workflows/codeql_analysis.yml | 2 +- .github/workflows/create_release.yml | 2 +- .github/workflows/docker_test_cluster_10.yml | 2 +- .github/workflows/docker_test_cluster_25.yml | 2 +- .github/workflows/e2e_race.yml | 2 +- .github/workflows/endtoend.yml | 2 +- .github/workflows/local_example.yml | 2 +- .github/workflows/region_example.yml | 2 +- .github/workflows/static_checks_etc.yml | 2 +- .github/workflows/unit_race.yml | 2 +- .github/workflows/unit_test_mysql57.yml | 2 +- .github/workflows/unit_test_mysql80.yml | 2 +- .github/workflows/update_golang_version.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_e2e_next_release.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_backups_manual_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_queries.yml | 2 +- ...de_downgrade_test_query_serving_queries_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_schema.yml | 2 +- ...ade_downgrade_test_query_serving_schema_next_release.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_new_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_new_vttablet.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_old_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_old_vttablet.yml | 2 +- Makefile | 2 +- build.env | 2 +- docker/base/Dockerfile | 2 +- docker/base/Dockerfile.mysql57 | 2 +- docker/base/Dockerfile.percona57 | 2 +- docker/base/Dockerfile.percona80 | 2 +- docker/bootstrap/CHANGELOG.md | 6 +++++- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile.mysql57 | 2 +- docker/lite/Dockerfile.mysql80 | 2 +- docker/lite/Dockerfile.percona57 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/lite/Dockerfile.testing | 2 +- docker/lite/Dockerfile.ubi7.mysql57 | 2 +- docker/lite/Dockerfile.ubi7.mysql80 | 2 +- docker/lite/Dockerfile.ubi7.percona57 | 2 +- docker/lite/Dockerfile.ubi7.percona80 | 2 +- docker/lite/Dockerfile.ubi8.arm64.mysql80 | 2 +- docker/lite/Dockerfile.ubi8.mysql80 | 2 +- docker/local/Dockerfile | 2 +- docker/vttestserver/Dockerfile.mysql57 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- test.go | 2 +- test/templates/cluster_endtoend_test.tpl | 2 +- test/templates/cluster_endtoend_test_docker.tpl | 2 +- test/templates/cluster_endtoend_test_mysql57.tpl | 2 +- test/templates/dockerfile.tpl | 2 +- test/templates/unit_test.tpl | 2 +- 131 files changed, 135 insertions(+), 131 deletions(-) diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml index 686655b9284..7d98dc36296 100644 --- a/.github/workflows/assign_milestone.yml +++ b/.github/workflows/assign_milestone.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Checkout code uses: actions/checkout@v3 diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml index 064a700d833..2f693af6d5b 100644 --- a/.github/workflows/check_make_vtadmin_authz_testgen.yml +++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml @@ -50,7 +50,7 @@ jobs: uses: actions/setup-go@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml index 7db6bceeeeb..3ded0eea834 100644 --- a/.github/workflows/check_make_vtadmin_web_proto.yml +++ b/.github/workflows/check_make_vtadmin_web_proto.yml @@ -52,7 +52,7 @@ jobs: uses: actions/setup-go@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Setup Node if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index 7496577ef0d..4c94a333396 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index c93f7e5526d..e79ebf36534 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index 469cfaf3080..760e914bce9 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index d76a5ada83d..ace3e0c7b74 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index 23d570a2b98..07f2a5d180b 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_22.yml b/.github/workflows/cluster_endtoend_22.yml index 9cba996f309..a9785f8e88a 100644 --- a/.github/workflows/cluster_endtoend_22.yml +++ b/.github/workflows/cluster_endtoend_22.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index 75e0c552d84..869673823ec 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml b/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml index d5a0f529d80..4eb16725804 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index e1f66a29eb9..2fb689bb7be 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml index e9ae31c02c9..5f07c5c9367 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index 5c0e1e3a012..5d76588cf9d 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index ea82738337d..65dc504f5b6 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index 5d14faee1af..a26fe5277f1 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml index f51032f2a34..3cf03c4dce5 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml index d69865221e0..56c2b8e7a37 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_ghost_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index 42fcb0ac100..5b4be8640d5 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml index e3b4e0960dc..bf9efcdce3b 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index 087d33bf9b6..ed7bb179b8e 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml index 5e21df5ac38..f613eb4e2c6 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index fb1b980793e..26b57d9e334 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml index 1fc42939924..ae93acc4020 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index 38f09912b51..332b50bd46c 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml index dbd670e82b5..7b6f61c1272 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index 86f22cf8610..08cb88af31b 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml index f0c8d0b7bda..1c417ad97cb 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index b20cc1f901d..9897682174d 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml index 8568b13288b..1ac230968e0 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index b937e72ef82..f837238380c 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml index 2dae908d301..515446d9835 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl_mysql57.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 341eae60951..b49af219a22 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index 13c3ae789ed..c113f79da00 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml index 3d6b40bd8a7..28ea4d092d5 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index cc6b02e2324..d9ffcdfd01a 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index 142d2358b47..02f68755630 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index 965c29d6bad..884d814ca8c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index 7f77747477f..c5356020662 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index 7dddf5f34d1..46c14c2cc5c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml index 50b65ecc27d..cadd0868fcb 100644 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.3 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml index 412113b055f..916c80b8738 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_multicell.yml b/.github/workflows/cluster_endtoend_vreplication_multicell.yml index 01b1c242b91..327ba0cc0c9 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multicell.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multicell.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml index c9d8f74c5ce..6004d091196 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_basic.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml index 501cd17ca62..5293bb6f798 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_sequences.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 61fb9971f0b..81205a94a3e 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_failover.yml b/.github/workflows/cluster_endtoend_vstream_failover.yml index 23c384fb5dc..95059b4938a 100644 --- a/.github/workflows/cluster_endtoend_vstream_failover.yml +++ b/.github/workflows/cluster_endtoend_vstream_failover.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml b/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml index 36e4cec2f6b..0856cb43ced 100644 --- a/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml +++ b/.github/workflows/cluster_endtoend_vstream_stoponreshard_false.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml b/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml index fc9bea5efe8..5a89f9e2828 100644 --- a/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml +++ b/.github/workflows/cluster_endtoend_vstream_stoponreshard_true.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml b/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml index 5135354ee13..a0df5795d83 100644 --- a/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml +++ b/.github/workflows/cluster_endtoend_vstream_with_keyspaces_to_watch.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 4b954911a5f..06626666db9 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index c1137849dd2..3326ac47a5a 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index 070936647e2..8740ab38e19 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index ff6688e1878..2b07c0c28d7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 8a12094028b..913007d8444 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index a076b7b0a1a..ec500363be5 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index 8b652338b51..0cf853a4c58 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index e8cbcf61a83..cb017bf7d55 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index d908a13fe23..5de998239ab 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index 6a027d039cf..4bd39055b99 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index b0278160979..5279471a146 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index 3d99a03cace..81e3b5aed69 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index edbd27f3bf6..413645efb03 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index 2ab51d691c2..4a90794de53 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index ce316847045..e6fc09c1fc7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index eac4ada3249..ee858058ebb 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index 7b108e5cbad..f29d12b8a5f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index bbef397dea9..348b5492c54 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index 23151270d1e..657f05af472 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index ead14d0fd63..60f29b6cb22 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index 9c6abdc0ad2..bddaaa72d53 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index 631bac6fda1..352a0021f17 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml index 04248744a26..9eb8df0635e 100644 --- a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml +++ b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index 48b336a6c11..f45aaefeed2 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index 8a3158fadd9..b3cea7c007c 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml b/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml index e34ce3e1e8a..04663cbdcec 100644 --- a/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml +++ b/.github/workflows/cluster_endtoend_xb_backup_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index 6f62db39ce8..f8ee6179227 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml b/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml index 2a9fe0eba92..fafddf82224 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery_mysql57.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index 2ec63e4fe5c..f47ef881dcd 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -44,7 +44,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Get base dependencies run: | diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 86bd5b686a0..a315b608a09 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Setup node uses: actions/setup-node@v3 diff --git a/.github/workflows/docker_test_cluster_10.yml b/.github/workflows/docker_test_cluster_10.yml index 8b9d2e278ae..f4afa9125a5 100644 --- a/.github/workflows/docker_test_cluster_10.yml +++ b/.github/workflows/docker_test_cluster_10.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/docker_test_cluster_25.yml b/.github/workflows/docker_test_cluster_25.yml index 007035b6e71..e7315d4c83e 100644 --- a/.github/workflows/docker_test_cluster_25.yml +++ b/.github/workflows/docker_test_cluster_25.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index 55b84fb378a..d09e0bf2b6c 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 57802c676a9..243213d2836 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 30ab7e3e335..faf7b43ceba 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - uses: actions/setup-node@v3 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index 6a87d0de54f..8c4a5415e8e 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - uses: actions/setup-node@v3 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 1854e8f052a..a2cd18996a7 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -102,7 +102,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true') uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index fe7fa7e684e..8b297b76318 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index a1bb1653775..6c5748f2052 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 6c9416be543..5e631f7b60e 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index 4eddbf9841b..2a789ee9449 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index 4ebca519d18..b1e0697237d 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -85,7 +85,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index 09b5a80ce16..3929e22c536 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -88,7 +88,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index cd806eb3c4f..039e416cb1c 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 5806fb83891..e4a9bd11fb3 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index 9ddc8c44da3..95133c0baf5 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index 4d9db1b6776..6552f145ac3 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 2b666e4cdb5..728aa60d224 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index d4e05e32967..881fae62202 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index 09468aaf325..2bf1735e1f7 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index 9e65388c10c..0c2f6cf3dd5 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -90,7 +90,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index a2cf8dbce38..d9d4759b187 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index 1a1173ff5eb..b417f11e1fc 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/Makefile b/Makefile index 2b662f7aa34..47132e64b38 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql57 mysql80 percona57 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=25 +BOOTSTRAP_VERSION=26 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index bcc6180814c..7e75fa4b84e 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.21.4 || echo "Go version reported: `go version`. Version 1.21.4+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.21.5 || echo "Go version reported: `go version`. Version 1.21.5+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index f53b73ec372..43aadb77169 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" diff --git a/docker/base/Dockerfile.mysql57 b/docker/base/Dockerfile.mysql57 index b416553f5c0..d62f4372e89 100644 --- a/docker/base/Dockerfile.mysql57 +++ b/docker/base/Dockerfile.mysql57 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" diff --git a/docker/base/Dockerfile.percona57 b/docker/base/Dockerfile.percona57 index 971d021efaa..8b905d1c092 100644 --- a/docker/base/Dockerfile.percona57 +++ b/docker/base/Dockerfile.percona57 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" diff --git a/docker/base/Dockerfile.percona80 b/docker/base/Dockerfile.percona80 index 2f600ad5f79..a6073fa09f6 100644 --- a/docker/base/Dockerfile.percona80 +++ b/docker/base/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index 6fed662b8be..4dfad307e24 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -96,4 +96,8 @@ List of changes between bootstrap image versions. ## [25] - 2023-11-08 ### Changes -- Update build to golang 1.21.4 \ No newline at end of file +- Update build to golang 1.21.4 + +## [26] - 2023-12-06 +### Changes +- Update build to golang 1.21.5 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 69186240fbc..a1a2dafd2fd 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.21.4-bullseye +FROM --platform=linux/amd64 golang:1.21.5-bullseye # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile.mysql57 b/docker/lite/Dockerfile.mysql57 index a10cdefd1a2..fedb1d3659f 100644 --- a/docker/lite/Dockerfile.mysql57 +++ b/docker/lite/Dockerfile.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.mysql80 b/docker/lite/Dockerfile.mysql80 index 98254bf3cdd..0884b161490 100644 --- a/docker/lite/Dockerfile.mysql80 +++ b/docker/lite/Dockerfile.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.percona57 b/docker/lite/Dockerfile.percona57 index e4c3db5fff1..eb490d49d02 100644 --- a/docker/lite/Dockerfile.percona57 +++ b/docker/lite/Dockerfile.percona57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index cb9e34d834d..48807ff8f33 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.testing b/docker/lite/Dockerfile.testing index 3aa24a1334b..1b44e0aa59b 100644 --- a/docker/lite/Dockerfile.testing +++ b/docker/lite/Dockerfile.testing @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.mysql57 b/docker/lite/Dockerfile.ubi7.mysql57 index c1a20afe589..8c82b394650 100644 --- a/docker/lite/Dockerfile.ubi7.mysql57 +++ b/docker/lite/Dockerfile.ubi7.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.mysql80 b/docker/lite/Dockerfile.ubi7.mysql80 index 2e1dd80cdc1..c53b1b35b01 100644 --- a/docker/lite/Dockerfile.ubi7.mysql80 +++ b/docker/lite/Dockerfile.ubi7.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.percona57 b/docker/lite/Dockerfile.ubi7.percona57 index 1e3af0a686d..f4c791d0d3e 100644 --- a/docker/lite/Dockerfile.ubi7.percona57 +++ b/docker/lite/Dockerfile.ubi7.percona57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona57" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi7.percona80 b/docker/lite/Dockerfile.ubi7.percona80 index 32f3cf8b0f4..fc8cb24988c 100644 --- a/docker/lite/Dockerfile.ubi7.percona80 +++ b/docker/lite/Dockerfile.ubi7.percona80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi8.arm64.mysql80 b/docker/lite/Dockerfile.ubi8.arm64.mysql80 index c4124a7f468..48d86cbef47 100644 --- a/docker/lite/Dockerfile.ubi8.arm64.mysql80 +++ b/docker/lite/Dockerfile.ubi8.arm64.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.ubi8.mysql80 b/docker/lite/Dockerfile.ubi8.mysql80 index 38c85b8778d..acf780a51eb 100644 --- a/docker/lite/Dockerfile.ubi8.mysql80 +++ b/docker/lite/Dockerfile.ubi8.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/local/Dockerfile b/docker/local/Dockerfile index 24e79eb90bd..ce277e0856a 100644 --- a/docker/local/Dockerfile +++ b/docker/local/Dockerfile @@ -1,4 +1,4 @@ -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-common" FROM "${image}" diff --git a/docker/vttestserver/Dockerfile.mysql57 b/docker/vttestserver/Dockerfile.mysql57 index 2eca5377d76..cfdcd9579ae 100644 --- a/docker/vttestserver/Dockerfile.mysql57 +++ b/docker/vttestserver/Dockerfile.mysql57 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql57" FROM "${image}" AS builder diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 5bbd7584eba..3777d9cdd70 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/test.go b/test.go index a9528c1ddd9..77d3f28ac29 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql57", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "25", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "26", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index f1c825a0c12..553cba53f9f 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index e42116fed69..dafcbf87ec4 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index 69a6028b316..95573da6066 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -77,7 +77,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 060dde341cd..8978aa60ae0 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=25 +ARG bootstrap_version=26 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 73ce4737fcd..5e3aa1f0737 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -69,7 +69,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v4 with: - go-version: 1.21.4 + go-version: 1.21.5 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' From 98e412b791307d44150cbda027a7c85520915e3d Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Wed, 6 Dec 2023 04:09:22 -0500 Subject: [PATCH 086/119] go/vt/vtadmin: fix nilness issues (#14687) Signed-off-by: Matt Layher --- go/vt/vtadmin/api_authz_test.go | 388 +++++------------- go/vt/vtadmin/rbac/authentication.go | 6 + .../vtadmin/testutil/authztestgen/template.go | 5 +- 3 files changed, 105 insertions(+), 294 deletions(-) diff --git a/go/vt/vtadmin/api_authz_test.go b/go/vt/vtadmin/api_authz_test.go index eb67757a1c1..dc524a64ad4 100644 --- a/go/vt/vtadmin/api_authz_test.go +++ b/go/vt/vtadmin/api_authz_test.go @@ -78,9 +78,7 @@ func TestCreateKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.CreateKeyspace(ctx, &vtadminpb.CreateKeyspaceRequest{ ClusterId: "test", @@ -97,9 +95,7 @@ func TestCreateKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.CreateKeyspace(ctx, &vtadminpb.CreateKeyspaceRequest{ ClusterId: "test", @@ -147,9 +143,7 @@ func TestCreateShard(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.CreateShard(ctx, &vtadminpb.CreateShardRequest{ ClusterId: "test", @@ -167,9 +161,7 @@ func TestCreateShard(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.CreateShard(ctx, &vtadminpb.CreateShardRequest{ ClusterId: "test", @@ -218,9 +210,7 @@ func TestDeleteKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteKeyspace(ctx, &vtadminpb.DeleteKeyspaceRequest{ ClusterId: "test", @@ -237,9 +227,7 @@ func TestDeleteKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteKeyspace(ctx, &vtadminpb.DeleteKeyspaceRequest{ ClusterId: "test", @@ -287,9 +275,7 @@ func TestDeleteShards(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteShards(ctx, &vtadminpb.DeleteShardsRequest{ ClusterId: "test", @@ -311,9 +297,7 @@ func TestDeleteShards(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteShards(ctx, &vtadminpb.DeleteShardsRequest{ ClusterId: "test", @@ -366,9 +350,7 @@ func TestDeleteTablet(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteTablet(ctx, &vtadminpb.DeleteTabletRequest{ ClusterIds: []string{"test"}, @@ -386,9 +368,7 @@ func TestDeleteTablet(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.DeleteTablet(ctx, &vtadminpb.DeleteTabletRequest{ ClusterIds: []string{"test"}, @@ -437,9 +417,7 @@ func TestEmergencyFailoverShard(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.EmergencyFailoverShard(ctx, &vtadminpb.EmergencyFailoverShardRequest{ ClusterId: "test", @@ -457,9 +435,7 @@ func TestEmergencyFailoverShard(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.EmergencyFailoverShard(ctx, &vtadminpb.EmergencyFailoverShardRequest{ ClusterId: "test", @@ -514,9 +490,7 @@ func TestFindSchema(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.FindSchema(ctx, &vtadminpb.FindSchemaRequest{ Table: "t1", @@ -537,9 +511,7 @@ func TestFindSchema(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.FindSchema(ctx, &vtadminpb.FindSchemaRequest{ Table: "t1", @@ -559,9 +531,7 @@ func TestFindSchema(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.FindSchema(ctx, &vtadminpb.FindSchemaRequest{ Table: "t1", @@ -613,9 +583,7 @@ func TestGetBackups(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetBackups(ctx, &vtadminpb.GetBackupsRequest{}) assert.NoError(t, err) @@ -627,9 +595,7 @@ func TestGetBackups(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetBackups(ctx, &vtadminpb.GetBackupsRequest{}) assert.NotEmpty(t, resp.Backups, "actor %+v should be permitted to GetBackups", actor) @@ -641,9 +607,7 @@ func TestGetBackups(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetBackups(ctx, &vtadminpb.GetBackupsRequest{}) assert.NotEmpty(t, resp.Backups, "actor %+v should be permitted to GetBackups", actor) @@ -692,9 +656,7 @@ func TestGetCellInfos(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetCellInfos(ctx, &vtadminpb.GetCellInfosRequest{ NamesOnly: true, @@ -708,9 +670,7 @@ func TestGetCellInfos(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetCellInfos(ctx, &vtadminpb.GetCellInfosRequest{ NamesOnly: true, @@ -724,9 +684,7 @@ func TestGetCellInfos(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetCellInfos(ctx, &vtadminpb.GetCellInfosRequest{ NamesOnly: true, @@ -777,9 +735,7 @@ func TestGetCellsAliases(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetCellsAliases(ctx, &vtadminpb.GetCellsAliasesRequest{}) assert.NoError(t, err) @@ -791,9 +747,7 @@ func TestGetCellsAliases(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetCellsAliases(ctx, &vtadminpb.GetCellsAliasesRequest{}) assert.NotEmpty(t, resp.Aliases, "actor %+v should be permitted to GetCellsAliases", actor) @@ -805,9 +759,7 @@ func TestGetCellsAliases(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetCellsAliases(ctx, &vtadminpb.GetCellsAliasesRequest{}) assert.NotEmpty(t, resp.Aliases, "actor %+v should be permitted to GetCellsAliases", actor) @@ -850,9 +802,7 @@ func TestGetClusters(t *testing.T) { var actor *rbac.Actor ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetClusters(ctx, &vtadminpb.GetClustersRequest{}) assert.Empty(t, resp.Clusters, "actor %+v should not be permitted to GetClusters", actor) @@ -863,9 +813,7 @@ func TestGetClusters(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetClusters(ctx, &vtadminpb.GetClustersRequest{}) assert.Empty(t, resp.Clusters, "actor %+v should not be permitted to GetClusters", actor) @@ -876,9 +824,7 @@ func TestGetClusters(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetClusters(ctx, &vtadminpb.GetClustersRequest{}) require.NoError(t, err) @@ -927,9 +873,7 @@ func TestGetGates(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetGates(ctx, &vtadminpb.GetGatesRequest{}) assert.NoError(t, err) @@ -948,9 +892,7 @@ func TestGetGates(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetGates(ctx, &vtadminpb.GetGatesRequest{}) assert.NotEmpty(t, resp.Gates, "actor %+v should be permitted to GetGates", actor) @@ -970,9 +912,7 @@ func TestGetGates(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetGates(ctx, &vtadminpb.GetGatesRequest{}) assert.NotEmpty(t, resp.Gates, "actor %+v should be permitted to GetGates", actor) @@ -1016,9 +956,7 @@ func TestGetKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetKeyspace(ctx, &vtadminpb.GetKeyspaceRequest{ ClusterId: "test", @@ -1033,9 +971,7 @@ func TestGetKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetKeyspace(ctx, &vtadminpb.GetKeyspaceRequest{ ClusterId: "test", @@ -1087,9 +1023,7 @@ func TestGetKeyspaces(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetKeyspaces(ctx, &vtadminpb.GetKeyspacesRequest{}) assert.NoError(t, err) @@ -1101,9 +1035,7 @@ func TestGetKeyspaces(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetKeyspaces(ctx, &vtadminpb.GetKeyspacesRequest{}) assert.NotEmpty(t, resp.Keyspaces, "actor %+v should be permitted to GetKeyspaces", actor) @@ -1122,9 +1054,7 @@ func TestGetKeyspaces(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetKeyspaces(ctx, &vtadminpb.GetKeyspacesRequest{}) assert.NotEmpty(t, resp.Keyspaces, "actor %+v should be permitted to GetKeyspaces", actor) @@ -1174,9 +1104,7 @@ func TestGetSchema(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSchema(ctx, &vtadminpb.GetSchemaRequest{ ClusterId: "test", @@ -1199,9 +1127,7 @@ func TestGetSchema(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSchema(ctx, &vtadminpb.GetSchemaRequest{ ClusterId: "test", @@ -1254,9 +1180,7 @@ func TestGetSchemas(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSchemas(ctx, &vtadminpb.GetSchemasRequest{}) assert.NoError(t, err) @@ -1275,9 +1199,7 @@ func TestGetSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetSchemas(ctx, &vtadminpb.GetSchemasRequest{}) assert.NotEmpty(t, resp.Schemas, "actor %+v should be permitted to GetSchemas", actor) @@ -1303,9 +1225,7 @@ func TestGetSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetSchemas(ctx, &vtadminpb.GetSchemasRequest{}) assert.NotEmpty(t, resp.Schemas, "actor %+v should be permitted to GetSchemas", actor) @@ -1361,9 +1281,7 @@ func TestGetShardReplicationPositions(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetShardReplicationPositions(ctx, &vtadminpb.GetShardReplicationPositionsRequest{}) assert.NoError(t, err) @@ -1375,9 +1293,7 @@ func TestGetShardReplicationPositions(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetShardReplicationPositions(ctx, &vtadminpb.GetShardReplicationPositionsRequest{}) assert.NotEmpty(t, resp.ReplicationPositions, "actor %+v should be permitted to GetShardReplicationPositions", actor) @@ -1396,9 +1312,7 @@ func TestGetShardReplicationPositions(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetShardReplicationPositions(ctx, &vtadminpb.GetShardReplicationPositionsRequest{}) assert.NotEmpty(t, resp.ReplicationPositions, "actor %+v should be permitted to GetShardReplicationPositions", actor) @@ -1448,9 +1362,7 @@ func TestGetSrvVSchema(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSrvVSchema(ctx, &vtadminpb.GetSrvVSchemaRequest{ ClusterId: "test", @@ -1465,9 +1377,7 @@ func TestGetSrvVSchema(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSrvVSchema(ctx, &vtadminpb.GetSrvVSchemaRequest{ ClusterId: "test", @@ -1519,9 +1429,7 @@ func TestGetSrvVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetSrvVSchemas(ctx, &vtadminpb.GetSrvVSchemasRequest{}) require.NoError(t, err) @@ -1533,9 +1441,7 @@ func TestGetSrvVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetSrvVSchemas(ctx, &vtadminpb.GetSrvVSchemasRequest{}) assert.NotEmpty(t, resp.SrvVSchemas, "actor %+v should be permitted to GetSrvVSchemas", actor) @@ -1554,9 +1460,7 @@ func TestGetSrvVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetSrvVSchemas(ctx, &vtadminpb.GetSrvVSchemasRequest{}) assert.NotEmpty(t, resp.SrvVSchemas, "actor %+v should be permitted to GetSrvVSchemas", actor) @@ -1606,9 +1510,7 @@ func TestGetTablet(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetTablet(ctx, &vtadminpb.GetTabletRequest{ Alias: &topodatapb.TabletAlias{ @@ -1625,9 +1527,7 @@ func TestGetTablet(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetTablet(ctx, &vtadminpb.GetTabletRequest{ Alias: &topodatapb.TabletAlias{ @@ -1681,9 +1581,7 @@ func TestGetTablets(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetTablets(ctx, &vtadminpb.GetTabletsRequest{}) require.NoError(t, err) @@ -1695,9 +1593,7 @@ func TestGetTablets(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetTablets(ctx, &vtadminpb.GetTabletsRequest{}) assert.NotEmpty(t, resp.Tablets, "actor %+v should be permitted to GetTablets", actor) @@ -1716,9 +1612,7 @@ func TestGetTablets(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetTablets(ctx, &vtadminpb.GetTabletsRequest{}) assert.NotEmpty(t, resp.Tablets, "actor %+v should be permitted to GetTablets", actor) @@ -1768,9 +1662,7 @@ func TestGetVSchema(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetVSchema(ctx, &vtadminpb.GetVSchemaRequest{ ClusterId: "test", @@ -1785,9 +1677,7 @@ func TestGetVSchema(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetVSchema(ctx, &vtadminpb.GetVSchemaRequest{ ClusterId: "test", @@ -1839,9 +1729,7 @@ func TestGetVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetVSchemas(ctx, &vtadminpb.GetVSchemasRequest{}) require.NoError(t, err) @@ -1853,9 +1741,7 @@ func TestGetVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetVSchemas(ctx, &vtadminpb.GetVSchemasRequest{}) assert.NotEmpty(t, resp.VSchemas, "actor %+v should be permitted to GetVSchemas", actor) @@ -1874,9 +1760,7 @@ func TestGetVSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetVSchemas(ctx, &vtadminpb.GetVSchemasRequest{}) assert.NotEmpty(t, resp.VSchemas, "actor %+v should be permitted to GetVSchemas", actor) @@ -1932,9 +1816,7 @@ func TestGetVtctlds(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetVtctlds(ctx, &vtadminpb.GetVtctldsRequest{}) assert.NoError(t, err) @@ -1953,9 +1835,7 @@ func TestGetVtctlds(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetVtctlds(ctx, &vtadminpb.GetVtctldsRequest{}) assert.NotEmpty(t, resp.Vtctlds, "actor %+v should be permitted to GetVtctlds", actor) @@ -1975,9 +1855,7 @@ func TestGetVtctlds(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetVtctlds(ctx, &vtadminpb.GetVtctldsRequest{}) assert.NotEmpty(t, resp.Vtctlds, "actor %+v should be permitted to GetVtctlds", actor) @@ -2021,9 +1899,7 @@ func TestGetWorkflow(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetWorkflow(ctx, &vtadminpb.GetWorkflowRequest{ ClusterId: "test", @@ -2039,9 +1915,7 @@ func TestGetWorkflow(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetWorkflow(ctx, &vtadminpb.GetWorkflowRequest{ ClusterId: "test", @@ -2094,9 +1968,7 @@ func TestGetWorkflows(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.GetWorkflows(ctx, &vtadminpb.GetWorkflowsRequest{}) require.NoError(t, err) @@ -2108,9 +1980,7 @@ func TestGetWorkflows(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetWorkflows(ctx, &vtadminpb.GetWorkflowsRequest{}) assert.NotEmpty(t, resp.WorkflowsByCluster, "actor %+v should be permitted to GetWorkflows", actor) @@ -2122,9 +1992,7 @@ func TestGetWorkflows(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.GetWorkflows(ctx, &vtadminpb.GetWorkflowsRequest{}) assert.NotEmpty(t, resp.WorkflowsByCluster, "actor %+v should be permitted to GetWorkflows", actor) @@ -2167,9 +2035,7 @@ func TestPingTablet(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.PingTablet(ctx, &vtadminpb.PingTabletRequest{ Alias: &topodatapb.TabletAlias{ @@ -2186,9 +2052,7 @@ func TestPingTablet(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.PingTablet(ctx, &vtadminpb.PingTabletRequest{ Alias: &topodatapb.TabletAlias{ @@ -2236,9 +2100,7 @@ func TestPlannedFailoverShard(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.PlannedFailoverShard(ctx, &vtadminpb.PlannedFailoverShardRequest{ ClusterId: "test", @@ -2256,9 +2118,7 @@ func TestPlannedFailoverShard(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.PlannedFailoverShard(ctx, &vtadminpb.PlannedFailoverShardRequest{ ClusterId: "test", @@ -2307,9 +2167,7 @@ func TestRefreshState(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RefreshState(ctx, &vtadminpb.RefreshStateRequest{ Alias: &topodatapb.TabletAlias{ @@ -2326,9 +2184,7 @@ func TestRefreshState(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RefreshState(ctx, &vtadminpb.RefreshStateRequest{ Alias: &topodatapb.TabletAlias{ @@ -2376,9 +2232,7 @@ func TestRefreshTabletReplicationSource(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RefreshTabletReplicationSource(ctx, &vtadminpb.RefreshTabletReplicationSourceRequest{ Alias: &topodatapb.TabletAlias{ @@ -2395,9 +2249,7 @@ func TestRefreshTabletReplicationSource(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RefreshTabletReplicationSource(ctx, &vtadminpb.RefreshTabletReplicationSourceRequest{ Alias: &topodatapb.TabletAlias{ @@ -2451,9 +2303,7 @@ func TestReloadSchemas(t *testing.T) { actor := &rbac.Actor{Name: "unauthorized"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ReloadSchemas(ctx, &vtadminpb.ReloadSchemasRequest{ Keyspaces: []string{ @@ -2470,9 +2320,7 @@ func TestReloadSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.ReloadSchemas(ctx, &vtadminpb.ReloadSchemasRequest{ Keyspaces: []string{ @@ -2488,9 +2336,7 @@ func TestReloadSchemas(t *testing.T) { actor := &rbac.Actor{Name: "allowed-all"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, _ := api.ReloadSchemas(ctx, &vtadminpb.ReloadSchemasRequest{ Keyspaces: []string{ @@ -2537,9 +2383,7 @@ func TestRunHealthCheck(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RunHealthCheck(ctx, &vtadminpb.RunHealthCheckRequest{ Alias: &topodatapb.TabletAlias{ @@ -2556,9 +2400,7 @@ func TestRunHealthCheck(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.RunHealthCheck(ctx, &vtadminpb.RunHealthCheckRequest{ Alias: &topodatapb.TabletAlias{ @@ -2606,9 +2448,7 @@ func TestSetReadOnly(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.SetReadOnly(ctx, &vtadminpb.SetReadOnlyRequest{ Alias: &topodatapb.TabletAlias{ @@ -2625,9 +2465,7 @@ func TestSetReadOnly(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.SetReadOnly(ctx, &vtadminpb.SetReadOnlyRequest{ Alias: &topodatapb.TabletAlias{ @@ -2675,9 +2513,7 @@ func TestSetReadWrite(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.SetReadWrite(ctx, &vtadminpb.SetReadWriteRequest{ Alias: &topodatapb.TabletAlias{ @@ -2694,9 +2530,7 @@ func TestSetReadWrite(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.SetReadWrite(ctx, &vtadminpb.SetReadWriteRequest{ Alias: &topodatapb.TabletAlias{ @@ -2744,9 +2578,7 @@ func TestStartReplication(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.StartReplication(ctx, &vtadminpb.StartReplicationRequest{ Alias: &topodatapb.TabletAlias{ @@ -2763,9 +2595,7 @@ func TestStartReplication(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.StartReplication(ctx, &vtadminpb.StartReplicationRequest{ Alias: &topodatapb.TabletAlias{ @@ -2813,9 +2643,7 @@ func TestStopReplication(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.StopReplication(ctx, &vtadminpb.StopReplicationRequest{ Alias: &topodatapb.TabletAlias{ @@ -2832,9 +2660,7 @@ func TestStopReplication(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.StopReplication(ctx, &vtadminpb.StopReplicationRequest{ Alias: &topodatapb.TabletAlias{ @@ -2882,9 +2708,7 @@ func TestTabletExternallyPromoted(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.TabletExternallyPromoted(ctx, &vtadminpb.TabletExternallyPromotedRequest{ Alias: &topodatapb.TabletAlias{ @@ -2901,9 +2725,7 @@ func TestTabletExternallyPromoted(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.TabletExternallyPromoted(ctx, &vtadminpb.TabletExternallyPromotedRequest{ Alias: &topodatapb.TabletAlias{ @@ -2951,9 +2773,7 @@ func TestVTExplain(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.VTExplain(ctx, &vtadminpb.VTExplainRequest{ Cluster: "test", @@ -2975,9 +2795,7 @@ func TestVTExplain(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.VTExplain(ctx, &vtadminpb.VTExplainRequest{ Cluster: "test", @@ -3023,9 +2841,7 @@ func TestValidateKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateKeyspace(ctx, &vtadminpb.ValidateKeyspaceRequest{ ClusterId: "test", @@ -3040,9 +2856,7 @@ func TestValidateKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateKeyspace(ctx, &vtadminpb.ValidateKeyspaceRequest{ ClusterId: "test", @@ -3088,9 +2902,7 @@ func TestValidateSchemaKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateSchemaKeyspace(ctx, &vtadminpb.ValidateSchemaKeyspaceRequest{ ClusterId: "test", @@ -3105,9 +2917,7 @@ func TestValidateSchemaKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateSchemaKeyspace(ctx, &vtadminpb.ValidateSchemaKeyspaceRequest{ ClusterId: "test", @@ -3153,9 +2963,7 @@ func TestValidateVersionKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "other"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateVersionKeyspace(ctx, &vtadminpb.ValidateVersionKeyspaceRequest{ ClusterId: "test", @@ -3170,9 +2978,7 @@ func TestValidateVersionKeyspace(t *testing.T) { actor := &rbac.Actor{Name: "allowed"} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) resp, err := api.ValidateVersionKeyspace(ctx, &vtadminpb.ValidateVersionKeyspaceRequest{ ClusterId: "test", diff --git a/go/vt/vtadmin/rbac/authentication.go b/go/vt/vtadmin/rbac/authentication.go index 374f95b636d..9e5e3aebb96 100644 --- a/go/vt/vtadmin/rbac/authentication.go +++ b/go/vt/vtadmin/rbac/authentication.go @@ -99,7 +99,13 @@ type actorkey struct{} // NewContext returns a context with the given actor stored in it. This is used // to pass actor information from the authentication middleware and interceptors // to the actual vtadmin api methods. +// +// If actor is nil, the context is returned with no actor attached. func NewContext(ctx context.Context, actor *Actor) context.Context { + if actor == nil { + return ctx + } + return context.WithValue(ctx, actorkey{}, actor) } diff --git a/go/vt/vtadmin/testutil/authztestgen/template.go b/go/vt/vtadmin/testutil/authztestgen/template.go index 518d710fb3f..f1ee272c373 100644 --- a/go/vt/vtadmin/testutil/authztestgen/template.go +++ b/go/vt/vtadmin/testutil/authztestgen/template.go @@ -111,9 +111,8 @@ func Test{{ .Method }}(t *testing.T) { {{ getActor .Actor }} ctx := context.Background() - if actor != nil { - ctx = rbac.NewContext(ctx, actor) - } + ctx = rbac.NewContext(ctx, actor) + {{ if .IncludeErrorVar }} resp, err := api.{{ $test.Method }}(ctx, {{ $test.Request }}) {{ else }} From 4bec17e6244fb6b93d801605d93de18acec95029 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Wed, 6 Dec 2023 04:39:04 -0500 Subject: [PATCH 087/119] go/cache: fix nilness issues and unused code (#14688) Signed-off-by: Matt Layher --- go/cache/theine/store.go | 42 ++++++++++++++--------------------- go/cache/theine/store_test.go | 4 ++-- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/go/cache/theine/store.go b/go/cache/theine/store.go index 3d86e549867..21ce084e8a5 100644 --- a/go/cache/theine/store.go +++ b/go/cache/theine/store.go @@ -44,17 +44,17 @@ const ( ) type Shard[K cachekey, V any] struct { - hashmap map[K]*Entry[K, V] - dookeeper *bf.Bloomfilter - deque *deque.Deque[*Entry[K, V]] - group *Group[K, V] - qsize uint - qlen int - counter uint - mu sync.RWMutex + hashmap map[K]*Entry[K, V] + doorkeeper *bf.Bloomfilter + deque *deque.Deque[*Entry[K, V]] + group *Group[K, V] + qsize uint + qlen int + counter uint + mu sync.RWMutex } -func NewShard[K cachekey, V any](size uint, qsize uint, doorkeeper bool) *Shard[K, V] { +func NewShard[K cachekey, V any](qsize uint, doorkeeper bool) *Shard[K, V] { s := &Shard[K, V]{ hashmap: make(map[K]*Entry[K, V]), qsize: qsize, @@ -62,17 +62,17 @@ func NewShard[K cachekey, V any](size uint, qsize uint, doorkeeper bool) *Shard[ group: NewGroup[K, V](), } if doorkeeper { - s.dookeeper = bf.New(0.01) + s.doorkeeper = bf.New(0.01) } return s } func (s *Shard[K, V]) set(key K, entry *Entry[K, V]) { s.hashmap[key] = entry - if s.dookeeper != nil { + if s.doorkeeper != nil { ds := 20 * len(s.hashmap) - if ds > s.dookeeper.Capacity { - s.dookeeper.EnsureCapacity(ds) + if ds > s.doorkeeper.Capacity { + s.doorkeeper.EnsureCapacity(ds) } } } @@ -195,10 +195,6 @@ func NewStore[K cachekey, V cacheval](maxsize int64, doorkeeper bool) *Store[K, shardCount = 128 } dequeSize := int(maxsize) / 100 / shardCount - shardSize := int(maxsize) / shardCount - if shardSize < 50 { - shardSize = 50 - } policySize := int(maxsize) - (dequeSize * shardCount) s := &Store[K, V]{ @@ -213,7 +209,7 @@ func NewStore[K cachekey, V cacheval](maxsize int64, doorkeeper bool) *Store[K, } s.shards = make([]*Shard[K, V], 0, s.shardCount) for i := 0; i < int(s.shardCount); i++ { - s.shards = append(s.shards, NewShard[K, V](uint(shardSize), uint(dequeSize), doorkeeper)) + s.shards = append(s.shards, NewShard[K, V](uint(dequeSize), doorkeeper)) } go s.maintenance() @@ -329,11 +325,11 @@ func (s *Store[K, V]) setInternal(key K, value V, cost int64, epoch uint32) (*Sh return shard, exist, true } if s.doorkeeper { - if shard.counter > uint(shard.dookeeper.Capacity) { - shard.dookeeper.Reset() + if shard.counter > uint(shard.doorkeeper.Capacity) { + shard.doorkeeper.Reset() shard.counter = 0 } - hit := shard.dookeeper.Insert(h) + hit := shard.doorkeeper.Insert(h) if !hit { shard.counter += 1 shard.mu.Unlock() @@ -373,7 +369,6 @@ func (s *Store[K, V]) processDeque(shard *Shard[K, V], epoch uint32) { return } var evictedkv []dequeKV[K, V] - var expiredkv []dequeKV[K, V] // send to slru send := make([]*Entry[K, V], 0, 2) @@ -422,9 +417,6 @@ func (s *Store[K, V]) processDeque(shard *Shard[K, V], epoch uint32) { for _, kv := range evictedkv { s.OnRemoval(kv.k, kv.v, EVICTED) } - for _, kv := range expiredkv { - s.OnRemoval(kv.k, kv.v, EXPIRED) - } } } diff --git a/go/cache/theine/store_test.go b/go/cache/theine/store_test.go index 880acf30193..9f337b818ad 100644 --- a/go/cache/theine/store_test.go +++ b/go/cache/theine/store_test.go @@ -74,9 +74,9 @@ func TestProcessDeque(t *testing.T) { func TestDoorKeeperDynamicSize(t *testing.T) { store := NewStore[keyint, cachedint](200000, true) shard := store.shards[0] - require.True(t, shard.dookeeper.Capacity == 512) + require.True(t, shard.doorkeeper.Capacity == 512) for i := keyint(0); i < 5000; i++ { shard.set(i, &Entry[keyint, cachedint]{}) } - require.True(t, shard.dookeeper.Capacity > 100000) + require.True(t, shard.doorkeeper.Capacity > 100000) } From 21bba512193d077c9ccf0a7a76306e87bd502de0 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:12:13 +0200 Subject: [PATCH 088/119] schemadiff: pursue foreign key errors and proceed to build schema (#14705) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/schema.go | 28 ++++++++++++++++++++++++---- go/vt/schemadiff/schema_test.go | 29 ++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 405ad6c7f45..311ccd94896 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -214,6 +214,18 @@ func (s *Schema) normalize() error { return true } + // Utility map and function to only record one foreign-key error per table. We make this limitation + // because the search algorithm below could review the same table twice, thus potentially unnecessarily duplicating + // found errors. + entityFkErrors := map[string]error{} + addEntityFkError := func(e Entity, err error) error { + if _, ok := entityFkErrors[e.Name()]; ok { + // error already recorded for this entity + return nil + } + entityFkErrors[e.Name()] = err + return err + } // We now iterate all tables. We iterate "dependency levels": // - first we want all tables that don't have foreign keys or which only reference themselves // - then we only want tables that reference 1st level tables. these are 2nd level tables @@ -241,10 +253,12 @@ func (s *Schema) normalize() error { } referencedEntity, ok := s.named[referencedTableName] if !ok { - return &ForeignKeyNonexistentReferencedTableError{Table: name, ReferencedTable: referencedTableName} + errs = errors.Join(errs, addEntityFkError(t, &ForeignKeyNonexistentReferencedTableError{Table: name, ReferencedTable: referencedTableName})) + continue } if _, ok := referencedEntity.(*CreateViewEntity); ok { - return &ForeignKeyReferencesViewError{Table: name, ReferencedView: referencedTableName} + errs = errors.Join(errs, addEntityFkError(t, &ForeignKeyReferencesViewError{Table: name, ReferencedView: referencedTableName})) + continue } fkParents[referencedTableName] = true @@ -310,7 +324,8 @@ func (s *Schema) normalize() error { if _, ok := dependencyLevels[t.Name()]; !ok { // We _know_ that in this iteration, at least one foreign key is not found. // We return the first one. - return &ForeignKeyDependencyUnresolvedError{Table: t.Name()} + errs = errors.Join(errs, addEntityFkError(t, &ForeignKeyDependencyUnresolvedError{Table: t.Name()})) + s.sorted = append(s.sorted, t) } } for _, v := range s.views { @@ -364,7 +379,12 @@ func (s *Schema) normalize() error { continue } referencedTableName := check.ReferenceDefinition.ReferencedTable.Name.String() - referencedTable := s.Table(referencedTableName) // we know this exists because we validated foreign key dependencies earlier on + referencedTable := s.Table(referencedTableName) + if referencedTable == nil { + // This can happen because earlier, when we validated existence of reference table, we took note + // of nonexisting tables, but kept on going. + continue + } referencedColumns := map[string]*sqlparser.ColumnDefinition{} for _, col := range referencedTable.CreateTable.TableSpec.Columns { diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 67de705d05c..8c410f54381 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -17,6 +17,7 @@ limitations under the License. package schemadiff import ( + "errors" "fmt" "math/rand" "sort" @@ -27,7 +28,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "vitess.io/vitess/go/errors" + vterrors "vitess.io/vitess/go/errors" "vitess.io/vitess/go/vt/sqlparser" ) @@ -161,7 +162,7 @@ func TestNewSchemaFromQueriesLoop(t *testing.T) { ) _, err := NewSchemaFromQueries(queries) require.Error(t, err) - err = errors.UnwrapFirst(err) + err = vterrors.UnwrapFirst(err) assert.EqualError(t, err, (&ViewDependencyUnresolvedError{View: "v7"}).Error()) } @@ -339,8 +340,11 @@ func TestInvalidSchema(t *testing.T) { expectErr: &ForeignKeyReferencesViewError{Table: "t11", ReferencedView: "v"}, }, { - schema: "create table t11 (id int primary key, i int, constraint f11 foreign key (i) references t12 (id) on delete restrict); create table t12 (id int primary key, i int, constraint f12 foreign key (i) references t11 (id) on delete restrict)", - expectErr: &ForeignKeyDependencyUnresolvedError{Table: "t11"}, + schema: "create table t11 (id int primary key, i int, constraint f11 foreign key (i) references t12 (id) on delete restrict); create table t12 (id int primary key, i int, constraint f12 foreign key (i) references t11 (id) on delete restrict)", + expectErr: errors.Join( + &ForeignKeyDependencyUnresolvedError{Table: "t11"}, + &ForeignKeyDependencyUnresolvedError{Table: "t12"}, + ), }, { schema: "create table t11 (id int primary key, i int, key ix(i), constraint f11 foreign key (i) references t11(id2) on delete restrict)", @@ -396,11 +400,20 @@ func TestInvalidSchema(t *testing.T) { func TestInvalidTableForeignKeyReference(t *testing.T) { { fkQueries := []string{ + "create table t10 (id int primary key)", "create table t11 (id int primary key, i int, constraint f12 foreign key (i) references t12(id) on delete restrict)", "create table t15(id int, primary key(id))", } - _, err := NewSchemaFromQueries(fkQueries) + s, err := NewSchemaFromQueries(fkQueries) assert.Error(t, err) + // Even though there's errors, we still expect the schema to have been created. + assert.NotNil(t, s) + // Even though t11 caused an error, we still expect the schema to have parsed all tables. + assert.Equal(t, 3, len(s.Entities())) + t11 := s.Table("t11") + assert.NotNil(t, t11) + // validate t11 table definition is complete, even though it was invalid. + assert.Equal(t, "create table t11 (\n\tid int,\n\ti int,\n\tprimary key (id),\n\tkey f12 (i),\n\tconstraint f12 foreign key (i) references t12 (id) on delete restrict\n)", t11.Create().StatementString()) assert.EqualError(t, err, (&ForeignKeyNonexistentReferencedTableError{Table: "t11", ReferencedTable: "t12"}).Error()) } { @@ -411,7 +424,9 @@ func TestInvalidTableForeignKeyReference(t *testing.T) { } _, err := NewSchemaFromQueries(fkQueries) assert.Error(t, err) - assert.EqualError(t, err, (&ForeignKeyDependencyUnresolvedError{Table: "t11"}).Error()) + assert.ErrorContains(t, err, (&ForeignKeyDependencyUnresolvedError{Table: "t11"}).Error()) + assert.ErrorContains(t, err, (&ForeignKeyDependencyUnresolvedError{Table: "t12"}).Error()) + assert.ErrorContains(t, err, (&ForeignKeyDependencyUnresolvedError{Table: "t13"}).Error()) } } @@ -716,7 +731,7 @@ func TestViewReferences(t *testing.T) { require.NotNil(t, schema) } else { require.Error(t, err) - err = errors.UnwrapFirst(err) + err = vterrors.UnwrapFirst(err) require.Equal(t, ts.expectErr, err, "received error: %v", err) } }) From 4a85ef7efc1b1e3bd13a06715e358ca70df8a7ef Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 6 Dec 2023 21:15:35 +0530 Subject: [PATCH 089/119] add foreign key as part of set statement when reserved connection is needed (#14696) Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/foreignkey/fk_test.go | 28 +++++++++++++++++++ go/vt/sqlparser/ast_rewriting.go | 2 +- go/vt/sqlparser/ast_rewriting_test.go | 2 +- go/vt/sqlparser/comments.go | 2 +- go/vt/sqlparser/comments_test.go | 16 +++++------ go/vt/sysvars/sysvars.go | 5 ++-- go/vt/vtgate/engine/fake_vcursor_test.go | 8 ------ go/vt/vtgate/engine/primitive.go | 1 - go/vt/vtgate/engine/set.go | 2 -- go/vt/vtgate/executor_set_test.go | 9 ++++-- go/vt/vtgate/planbuilder/operators/insert.go | 1 + go/vt/vtgate/planbuilder/operators/update.go | 4 +-- .../testdata/foreignkey_checks_on_cases.json | 2 +- go/vt/vtgate/planbuilder/update.go | 2 +- go/vt/vtgate/safe_session.go | 20 +++++++++++++ go/vt/vtgate/vcursor_impl.go | 23 +-------------- 16 files changed, 74 insertions(+), 53 deletions(-) diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index 101cd313e21..c3f1d9dc29c 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -1207,3 +1207,31 @@ func TestReplaceWithFK(t *testing.T) { utils.AssertMatches(t, conn, `select * from u_t1`, `[[INT64(1) INT64(1)] [INT64(2) INT64(2)]]`) utils.AssertMatches(t, conn, `select * from u_t2`, `[[INT64(1) NULL] [INT64(2) NULL]]`) } + +// TestDDLFk tests that table is created with fk constraint when foreign_key_checks is off. +func TestDDLFk(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + utils.Exec(t, mcmp.VtConn, `use uks`) + + createTableDDLTemp1 := ` +create table temp1(id bigint auto_increment primary key, col varchar(20) not null, +foreign key (col) references temp2(col)) +` + mcmp.Exec(`set foreign_key_checks = off`) + // should be able to create `temp1` table without a `temp2` + mcmp.Exec(createTableDDLTemp1) + + createTableDDLTemp2 := ` +create table temp2(id bigint auto_increment primary key, col varchar(20) not null, key (col)) +` + // now create `temp2` + mcmp.Exec(createTableDDLTemp2) + + // inserting some data with fk constraints on. + mcmp.Exec(`set foreign_key_checks = on`) + mcmp.Exec(`insert into temp2(col) values('a'), ('b'), ('c') `) + mcmp.Exec(`insert into temp1(col) values('a') `) + mcmp.ExecAllowAndCompareError(`insert into temp1(col) values('d') `) +} diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index e20a5b80f70..659383ec6d6 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -191,7 +191,7 @@ func (er *astRewriter) rewriteUp(cursor *Cursor) bool { supportOptimizerHint.SetComments(newComments) } if er.fkChecksState != nil { - newComments := supportOptimizerHint.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, FkChecksStateString(er.fkChecksState)) + newComments := supportOptimizerHint.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks, FkChecksStateString(er.fkChecksState)) supportOptimizerHint.SetComments(newComments) } } diff --git a/go/vt/sqlparser/ast_rewriting_test.go b/go/vt/sqlparser/ast_rewriting_test.go index c8bc0fdbef9..86bab314dd8 100644 --- a/go/vt/sqlparser/ast_rewriting_test.go +++ b/go/vt/sqlparser/ast_rewriting_test.go @@ -365,7 +365,7 @@ func TestRewrites(in *testing.T) { assert.Equal(tc.rowCount, result.NeedsFuncResult(RowCountName), "should need row count") assert.Equal(tc.udv, len(result.NeedUserDefinedVariables), "count of user defined variables") assert.Equal(tc.autocommit, result.NeedsSysVar(sysvars.Autocommit.Name), "should need :__vtautocommit") - assert.Equal(tc.foreignKeyChecks, result.NeedsSysVar(sysvars.ForeignKeyChecks.Name), "should need :__vtforeignKeyChecks") + assert.Equal(tc.foreignKeyChecks, result.NeedsSysVar(sysvars.ForeignKeyChecks), "should need :__vtforeignKeyChecks") assert.Equal(tc.clientFoundRows, result.NeedsSysVar(sysvars.ClientFoundRows.Name), "should need :__vtclientFoundRows") assert.Equal(tc.skipQueryPlanCache, result.NeedsSysVar(sysvars.SkipQueryPlanCache.Name), "should need :__vtskipQueryPlanCache") assert.Equal(tc.sqlSelectLimit, result.NeedsSysVar(sysvars.SQLSelectLimit.Name), "should need :__vtsqlSelectLimit") diff --git a/go/vt/sqlparser/comments.go b/go/vt/sqlparser/comments.go index fbc1e17ba2f..780f1e67594 100644 --- a/go/vt/sqlparser/comments.go +++ b/go/vt/sqlparser/comments.go @@ -558,7 +558,7 @@ func AllowScatterDirective(stmt Statement) bool { func ForeignKeyChecksState(stmt Statement) *bool { cmt, ok := stmt.(Commented) if ok { - fkChecksVal := cmt.GetParsedComments().GetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name) + fkChecksVal := cmt.GetParsedComments().GetMySQLSetVarValue(sysvars.ForeignKeyChecks) // If the value of the `foreign_key_checks` optimizer hint is something that doesn't make sense, // then MySQL just ignores it and treats it like the case, where it is unspecified. We are choosing // to have the same behaviour here. If the value doesn't match any of the acceptable values, we return nil, diff --git a/go/vt/sqlparser/comments_test.go b/go/vt/sqlparser/comments_test.go index 6312acb5994..734cd28e088 100644 --- a/go/vt/sqlparser/comments_test.go +++ b/go/vt/sqlparser/comments_test.go @@ -564,7 +564,7 @@ func TestGetMySQLSetVarValue(t *testing.T) { { name: "SET_VAR clause in the middle", comments: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=OFF) NO_ICP(t1, t2) */"}, - valToFind: sysvars.ForeignKeyChecks.Name, + valToFind: sysvars.ForeignKeyChecks, want: "OFF", }, { @@ -582,19 +582,19 @@ func TestGetMySQLSetVarValue(t *testing.T) { { name: "Multiple SET_VAR clauses", comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, - valToFind: sysvars.ForeignKeyChecks.Name, + valToFind: sysvars.ForeignKeyChecks, want: "", }, { name: "Verify casing", comments: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR( foReiGn_key_checks = On) */"}, - valToFind: sysvars.ForeignKeyChecks.Name, + valToFind: sysvars.ForeignKeyChecks, want: "On", }, { name: "Leading comment is a normal comment", comments: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR( foreign_key_checks = 1) */"}, - valToFind: sysvars.ForeignKeyChecks.Name, + valToFind: sysvars.ForeignKeyChecks, want: "1", }, } @@ -619,7 +619,7 @@ func TestSetMySQLSetVarValue(t *testing.T) { { name: "SET_VAR clause in the middle", comments: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=OFF) NO_ICP(t1, t2) */"}, - key: sysvars.ForeignKeyChecks.Name, + key: sysvars.ForeignKeyChecks, value: "On", commentsWanted: []string{"/*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) SET_VAR(foreign_key_checks=On) NO_ICP(t1, t2) */"}, }, @@ -640,21 +640,21 @@ func TestSetMySQLSetVarValue(t *testing.T) { { name: "Multiple SET_VAR clauses", comments: []string{"/*+ SET_VAR(sort_buffer_size = 16M) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, - key: sysvars.ForeignKeyChecks.Name, + key: sysvars.ForeignKeyChecks, value: "1", commentsWanted: []string{"/*+ SET_VAR(sort_buffer_size = 16M) SET_VAR(foreign_key_checks=1) */", "/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') */", "/*+ SET_VAR( foReiGn_key_checks = On) */"}, }, { name: "Verify casing", comments: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR( foReiGn_key_checks = On) */"}, - key: sysvars.ForeignKeyChecks.Name, + key: sysvars.ForeignKeyChecks, value: "off", commentsWanted: []string{"/*+ SET_VAR(optimizer_switch = 'mrr_cost_b(ased=of\"f') SET_VAR(foReiGn_key_checks=off) */"}, }, { name: "Leading comment is a normal comment", comments: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR( foreign_key_checks = 1) */"}, - key: sysvars.ForeignKeyChecks.Name, + key: sysvars.ForeignKeyChecks, value: "Off", commentsWanted: []string{"/* This is a normal comment */", "/*+ MAX_EXECUTION_TIME(1000) SET_VAR(foreign_key_checks=Off) */"}, }, diff --git a/go/vt/sysvars/sysvars.go b/go/vt/sysvars/sysvars.go index 945a60ae965..c8037563ca1 100644 --- a/go/vt/sysvars/sysvars.go +++ b/go/vt/sysvars/sysvars.go @@ -57,6 +57,8 @@ var ( off = "0" utf8mb4 = "'utf8mb4'" + ForeignKeyChecks = "foreign_key_checks" + Autocommit = SystemVariable{Name: "autocommit", IsBoolean: true, Default: on} Charset = SystemVariable{Name: "charset", Default: utf8mb4, IdentifierAsString: true} ClientFoundRows = SystemVariable{Name: "client_found_rows", IsBoolean: true, Default: off} @@ -71,7 +73,6 @@ var ( TxReadOnly = SystemVariable{Name: "tx_read_only", IsBoolean: true, Default: off} Workload = SystemVariable{Name: "workload", IdentifierAsString: true} QueryTimeout = SystemVariable{Name: "query_timeout"} - ForeignKeyChecks = SystemVariable{Name: "foreign_key_checks", IsBoolean: true, SupportSetVar: true} // Online DDL DDLStrategy = SystemVariable{Name: "ddl_strategy", IdentifierAsString: true} @@ -105,7 +106,6 @@ var ( ReadAfterWriteTimeOut, SessionTrackGTIDs, QueryTimeout, - ForeignKeyChecks, } ReadOnly = []SystemVariable{ @@ -188,6 +188,7 @@ var ( {Name: "end_markers_in_json", IsBoolean: true, SupportSetVar: true}, {Name: "eq_range_index_dive_limit", SupportSetVar: true}, {Name: "explicit_defaults_for_timestamp"}, + {Name: ForeignKeyChecks, IsBoolean: true, SupportSetVar: true}, {Name: "group_concat_max_len", SupportSetVar: true}, {Name: "information_schema_stats_expiry"}, {Name: "max_heap_table_size", SupportSetVar: true}, diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index f9cedd74bfc..ae1c9e918a7 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -275,10 +275,6 @@ func (t *noopVCursor) SetAutocommit(context.Context, bool) error { panic("implement me") } -func (t *noopVCursor) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { - panic("implement me") -} - func (t *noopVCursor) SetClientFoundRows(context.Context, bool) error { panic("implement me") } @@ -747,10 +743,6 @@ func (f *loggingVCursor) SetAutocommit(context.Context, bool) error { panic("implement me") } -func (f *loggingVCursor) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { - panic("implement me") -} - func (f *loggingVCursor) SetClientFoundRows(context.Context, bool) error { panic("implement me") } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 833f4cc3b45..c69423ee3fb 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -154,7 +154,6 @@ type ( SetAutocommit(ctx context.Context, autocommit bool) error SetClientFoundRows(context.Context, bool) error - SetSessionForeignKeyChecks(ctx context.Context, autocommit bool) error SetSkipQueryPlanCache(context.Context, bool) error SetSQLSelectLimit(int64) error SetTransactionMode(vtgatepb.TransactionMode) diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index a0d4987d85a..9e9500d1ca8 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -445,8 +445,6 @@ func (svss *SysVarSetAware) Execute(ctx context.Context, vcursor VCursor, env *e switch svss.Name { case sysvars.Autocommit.Name: err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetAutocommit) - case sysvars.ForeignKeyChecks.Name: - err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetSessionForeignKeyChecks) case sysvars.ClientFoundRows.Name: err = svss.setBoolSysVar(ctx, env, vcursor.Session().SetClientFoundRows) case sysvars.SkipQueryPlanCache.Name: diff --git a/go/vt/vtgate/executor_set_test.go b/go/vt/vtgate/executor_set_test.go index 68898b7ea45..5377f72c66b 100644 --- a/go/vt/vtgate/executor_set_test.go +++ b/go/vt/vtgate/executor_set_test.go @@ -319,9 +319,12 @@ func TestExecutorSetOp(t *testing.T) { sysVars: map[string]string{"sql_quote_show_create": "0"}, result: returnResult("sql_quote_show_create", "int64", "0"), }, { - in: "set foreign_key_checks = 1", - sysVars: map[string]string{"foreign_key_checks": "1"}, - result: returnNoResult("foreign_key_checks", "int64"), + in: "set foreign_key_checks = 1", + result: returnNoResult("foreign_key_checks", "int64"), + }, { + in: "set foreign_key_checks = 0", + sysVars: map[string]string{"foreign_key_checks": "0"}, + result: returnResult("foreign_key_checks", "int64", "0"), }, { in: "set unique_checks = 0", sysVars: map[string]string{"unique_checks": "0"}, diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index f783ac7a5bc..5cb25feb66c 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -134,6 +134,7 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I whereExpr := getWhereCondExpr(append(uniqKeyCompExprs, pkCompExpr)) delStmt := &sqlparser.Delete{ + Comments: ins.Comments, TableExprs: sqlparser.TableExprs{sqlparser.CloneRefOfAliasedTableExpr(ins.Table)}, Where: sqlparser.NewWhere(sqlparser.WhereClause, whereExpr), } diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index ccfdddc3ea9..f780e5405db 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -442,7 +442,7 @@ func buildChildUpdOpForCascade(ctx *plancontext.PlanningContext, fk vindexes.Chi // Because we could be updating the child to a non-null value, // We have to run with foreign key checks OFF because the parent isn't guaranteed to have // the data being updated to. - parsedComments := (&sqlparser.ParsedComments{}).SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "OFF").Parsed() + parsedComments := (&sqlparser.ParsedComments{}).SetMySQLSetVarValue(sysvars.ForeignKeyChecks, "OFF").Parsed() childUpdStmt := &sqlparser.Update{ Comments: parsedComments, Exprs: childUpdateExprs, @@ -515,7 +515,7 @@ func buildChildUpdOpForSetNull( func getParsedCommentsForFkChecks(ctx *plancontext.PlanningContext) (parsedComments *sqlparser.ParsedComments) { fkState := ctx.VSchema.GetForeignKeyChecksState() if fkState != nil && *fkState { - parsedComments = parsedComments.SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "ON").Parsed() + parsedComments = parsedComments.SetMySQLSetVarValue(sysvars.ForeignKeyChecks, "ON").Parsed() } return parsedComments } diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json index b4892a99052..a61a035a8d8 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json @@ -1772,7 +1772,7 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "delete from u_tbl1 where (id) in ((1))", + "Query": "delete /*+ SET_VAR(foreign_key_checks=On) */ from u_tbl1 where (id) in ((1))", "Table": "u_tbl1" } ] diff --git a/go/vt/vtgate/planbuilder/update.go b/go/vt/vtgate/planbuilder/update.go index 9bcc8691f8e..9fbfd85afab 100644 --- a/go/vt/vtgate/planbuilder/update.go +++ b/go/vt/vtgate/planbuilder/update.go @@ -51,7 +51,7 @@ func gen4UpdateStmtPlanner( if ctx.SemTable.HasNonLiteralForeignKeyUpdate(updStmt.Exprs) { // Since we are running the query with foreign key checks off, we have to verify all the foreign keys validity on vtgate. ctx.VerifyAllFKs = true - updStmt.SetComments(updStmt.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks.Name, "OFF")) + updStmt.SetComments(updStmt.GetParsedComments().SetMySQLSetVarValue(sysvars.ForeignKeyChecks, "OFF")) } // Remove all the foreign keys that don't require any handling. diff --git a/go/vt/vtgate/safe_session.go b/go/vt/vtgate/safe_session.go index 60d99ab1952..2adb5b665a5 100644 --- a/go/vt/vtgate/safe_session.go +++ b/go/vt/vtgate/safe_session.go @@ -572,6 +572,26 @@ func (session *SafeSession) TimeZone() *time.Location { return loc } +// ForeignKeyChecks returns the foreign_key_checks stored in system_variables map in the session. +func (session *SafeSession) ForeignKeyChecks() *bool { + session.mu.Lock() + fkVal, ok := session.SystemVariables[sysvars.ForeignKeyChecks] + session.mu.Unlock() + + if !ok { + return nil + } + switch strings.ToLower(fkVal) { + case "off", "0": + fkCheckBool := false + return &fkCheckBool + case "on", "1": + fkCheckBool := true + return &fkCheckBool + } + return nil +} + // SetOptions sets the options func (session *SafeSession) SetOptions(options *querypb.ExecuteOptions) { session.mu.Lock() diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index db678d56354..616b1ce8846 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -43,7 +43,6 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" - "vitess.io/vitess/go/vt/sysvars" "vitess.io/vitess/go/vt/topo" topoprotopb "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" @@ -832,16 +831,6 @@ func (vc *vcursorImpl) SetAutocommit(ctx context.Context, autocommit bool) error return nil } -// SetSessionForeignKeyChecks implements the SessionActions interface -func (vc *vcursorImpl) SetSessionForeignKeyChecks(ctx context.Context, foreignKeyChecks bool) error { - if foreignKeyChecks { - vc.safeSession.SetSystemVariable(sysvars.ForeignKeyChecks.Name, "1") - } else { - vc.safeSession.SetSystemVariable(sysvars.ForeignKeyChecks.Name, "0") - } - return nil -} - // SetQueryTimeout implements the SessionActions interface func (vc *vcursorImpl) SetQueryTimeout(maxExecutionTime int64) { vc.safeSession.QueryTimeout = maxExecutionTime @@ -1365,17 +1354,7 @@ func (vc *vcursorImpl) UpdateForeignKeyChecksState(fkStateFromQuery *bool) { return } // If the query doesn't have anything, then we consult the session state. - fkVal, isPresent := vc.safeSession.SystemVariables[sysvars.ForeignKeyChecks.Name] - if isPresent { - switch strings.ToLower(fkVal) { - case "on", "1": - val := true - vc.fkChecksState = &val - case "off", "0": - val := false - vc.fkChecksState = &val - } - } + vc.fkChecksState = vc.safeSession.ForeignKeyChecks() } // GetForeignKeyChecksState gets the stored foreign key checks state in the vcursor. From fc4a74b1f01bae9787ca0bef71f3b7a387c12265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Wed, 6 Dec 2023 17:45:55 +0100 Subject: [PATCH 090/119] bugfix: use the original expression and not the alias (#14704) Signed-off-by: Andres Taylor --- .../operators/aggregation_pushing.go | 11 +-- .../planbuilder/testdata/aggr_cases.json | 70 +++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index e50483ce8d2..b0fdf683121 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -433,19 +433,22 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg var groupingJCs []JoinColumn for _, groupBy := range rootAggr.Grouping { - deps := ctx.SemTable.RecursiveDeps(groupBy.Inner) - expr := groupBy.Inner + expr, err := rootAggr.QP.GetSimplifiedExpr(ctx, groupBy.Inner) + if err != nil { + panic(err) + } + deps := ctx.SemTable.RecursiveDeps(expr) switch { case deps.IsSolvedBy(lhs.tableID): lhs.addGrouping(ctx, groupBy) groupingJCs = append(groupingJCs, JoinColumn{ - Original: groupBy.Inner, + Original: expr, LHSExprs: []BindVarExpr{{Expr: expr}}, }) case deps.IsSolvedBy(rhs.tableID): rhs.addGrouping(ctx, groupBy) groupingJCs = append(groupingJCs, JoinColumn{ - Original: groupBy.Inner, + Original: expr, RHSExpr: expr, }) case deps.IsSolvedBy(lhs.tableID.Merge(rhs.tableID)): diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index 2254baa36a6..d1e9c42c1dd 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6372,5 +6372,75 @@ "user.user" ] } + }, + { + "comment": "Group by aliases on both sides of a join", + "query": "select count(*), cast(user.foo as datetime) as f1, cast(music.foo as datetime) as f2 from user join music group by f1, f2", + "plan": { + "QueryType": "SELECT", + "Original": "select count(*), cast(user.foo as datetime) as f1, cast(music.foo as datetime) as f2 from user join music group by f1, f2", + "Instructions": { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "sum_count_star(0) AS count(*)", + "GroupBy": "(1|3), (2|4)", + "ResultColumns": 3, + "Inputs": [ + { + "OperatorType": "Sort", + "Variant": "Memory", + "OrderBy": "(1|3) ASC, (2|4) ASC", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "count(*) * count(*) as count(*)", + ":2 as f1", + ":3 as f2", + ":4 as weight_string(cast(`user`.foo as datetime))", + ":5 as weight_string(cast(music.foo as datetime))" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0,R:0,L:1,R:1,L:2,R:2", + "TableName": "`user`_music", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select count(*), cast(`user`.foo as datetime) as f1, weight_string(cast(`user`.foo as datetime)) from `user` where 1 != 1 group by f1, weight_string(cast(`user`.foo as datetime))", + "Query": "select count(*), cast(`user`.foo as datetime) as f1, weight_string(cast(`user`.foo as datetime)) from `user` group by f1, weight_string(cast(`user`.foo as datetime))", + "Table": "`user`" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select count(*), cast(music.foo as datetime) as f2, weight_string(cast(music.foo as datetime)) from music where 1 != 1 group by f2, weight_string(cast(music.foo as datetime))", + "Query": "select count(*), cast(music.foo as datetime) as f2, weight_string(cast(music.foo as datetime)) from music group by f2, weight_string(cast(music.foo as datetime))", + "Table": "music" + } + ] + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.music", + "user.user" + ] + } } ] From 90ea96f1025d6eaf41ff97a16341cd1152a06fdd Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Wed, 6 Dec 2023 22:16:43 +0530 Subject: [PATCH 091/119] Fail correlated subquery in planning phase instead of a runtime error (#14701) Signed-off-by: Manan Gupta --- .../vtgate/planbuilder/operators/ast_to_op.go | 19 ++++++++++--------- .../vtgate/planbuilder/operators/subquery.go | 6 ++++++ .../planbuilder/operators/subquery_builder.go | 8 +++----- .../testdata/info_schema57_cases.json | 8 ++++---- .../testdata/info_schema80_cases.json | 8 ++++---- .../testdata/unsupported_cases.json | 5 +++++ 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index f8c8891f8f9..be296d54218 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -108,23 +108,24 @@ func findTablesContained(ctx *plancontext.PlanningContext, node sqlparser.SQLNod return } -func rewriteRemainingColumns( +func checkForCorrelatedSubqueries( ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, subqID semantics.TableSet, -) sqlparser.SelectStatement { - return sqlparser.CopyOnRewrite(stmt, nil, func(cursor *sqlparser.CopyOnWriteCursor) { - colname, isColname := cursor.Node().(*sqlparser.ColName) +) (correlated bool) { + _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + colname, isColname := node.(*sqlparser.ColName) if !isColname { - return + return true, nil } deps := ctx.SemTable.RecursiveDeps(colname) if deps.IsSolvedBy(subqID) { - return + return true, nil } - rsv := ctx.GetReservedArgumentFor(colname) - cursor.Replace(sqlparser.NewArgument(rsv)) - }, nil).(sqlparser.SelectStatement) + correlated = true + return false, nil + }, stmt) + return correlated } // joinPredicateCollector is used to inspect the predicates inside the subquery, looking for any diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index 279669ade38..ab3859eb355 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -49,6 +49,9 @@ type SubQuery struct { // Fields related to correlated subqueries: Vars map[string]int // Arguments copied from outer to inner, set during offset planning. outerID semantics.TableSet + // correlated stores whether this subquery is correlated or not. + // We use this information to fail the planning if we are unable to merge the subquery with a route. + correlated bool IsProjection bool } @@ -200,6 +203,9 @@ func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer Operator) (Op if !sq.TopLevel { return nil, subqueryNotAtTopErr } + if sq.correlated { + return nil, correlatedSubqueryErr + } if sq.IsProjection { if len(sq.GetMergePredicates()) > 0 { // this means that we have a correlated subquery on our hands diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index b2de19408b4..8ca91673398 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -169,12 +169,9 @@ func createSubquery( sqc := &SubQueryBuilder{totalID: totalID, subqID: subqID, outerID: outerID} predicates, joinCols := sqc.inspectStatement(ctx, subq.Select) - stmt := rewriteRemainingColumns(ctx, subq.Select, subqID) + correlated := checkForCorrelatedSubqueries(ctx, subq.Select, subqID) - // TODO: this should not be needed. We are using CopyOnRewrite above, but somehow this is not getting copied - ctx.SemTable.CopySemanticInfo(subq.Select, stmt) - - opInner := translateQueryToOp(ctx, stmt) + opInner := translateQueryToOp(ctx, subq.Select) opInner = sqc.getRootOperator(opInner, nil) return &SubQuery{ @@ -187,6 +184,7 @@ func createSubquery( IsProjection: isProjection, TopLevel: topLevel, JoinColumns: joinCols, + correlated: correlated, } } diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json index 58cfbf1e68c..5b02add1c24 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json @@ -1037,10 +1037,10 @@ }, { "comment": "merge even one side have schema name in subquery", - "query": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `COLUMN_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", + "query": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `TABLE_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", "plan": { "QueryType": "SELECT", - "Original": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `COLUMN_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", + "Original": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `TABLE_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", "Instructions": { "OperatorType": "UncorrelatedSubquery", "Variant": "PulloutIn", @@ -1066,8 +1066,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select :COLUMN_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select distinct :COLUMN_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", + "FieldQuery": "select TABLE_NAME from information_schema.`tables` as t where 1 != 1", + "Query": "select distinct TABLE_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", "SysTableTableSchema": "['a']", "Table": "information_schema.`tables`" }, diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json index b13e2912645..df9654d5b0b 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json @@ -1102,10 +1102,10 @@ }, { "comment": "merge even one side have schema name in subquery", - "query": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `COLUMN_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", + "query": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `TABLE_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", "plan": { "QueryType": "SELECT", - "Original": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `COLUMN_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", + "Original": "select `COLLATION_NAME` from information_schema.`COLUMNS` t where `COLUMN_NAME` in (select `TABLE_NAME` from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select `COLUMN_NAME` from information_schema.columns)", "Instructions": { "OperatorType": "UncorrelatedSubquery", "Variant": "PulloutIn", @@ -1131,8 +1131,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select :COLUMN_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select distinct :COLUMN_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", + "FieldQuery": "select TABLE_NAME from information_schema.`tables` as t where 1 != 1", + "Query": "select distinct TABLE_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", "SysTableTableSchema": "['a']", "Table": "information_schema.`tables`" }, diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index fdab7835738..ba69f459e2d 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -378,5 +378,10 @@ "comment": "Alias cannot clash with base tables", "query": "WITH user AS (SELECT col FROM user) SELECT * FROM user", "plan": "VT12001: unsupported: do not support CTE that use the CTE alias inside the CTE query" + }, + { + "comment": "correlated subqueries in select expressions are unsupported", + "query": "SELECT (SELECT sum(user.name) FROM music LIMIT 1) FROM user", + "plan": "VT12001: unsupported: correlated subquery is only supported for EXISTS" } ] From 361a43bc53e29e599f5598d41413fdbf8d18a54a Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 6 Dec 2023 19:39:09 -0500 Subject: [PATCH 092/119] VReplication VPlayer: support statement and transaction batching (#14502) Signed-off-by: Matt Lord Signed-off-by: Rohit Nayak Co-authored-by: Rohit Nayak --- .../onlineddl_vrepl_mini_stress_test.go | 15 +- .../onlineddl_vrepl_stress_suite_test.go | 17 +- go/test/endtoend/vreplication/fk_test.go | 10 +- .../vreplication/vreplication_test.go | 38 ++- go/vt/binlog/binlogplayer/binlog_player.go | 22 +- go/vt/binlog/binlogplayer/dbclient.go | 40 +++ go/vt/binlog/binlogplayer/fake_dbclient.go | 4 + go/vt/binlog/binlogplayer/mock_dbclient.go | 17 ++ go/vt/vttablet/flags.go | 3 + .../tabletmanager/vdiff/framework_test.go | 16 ++ .../vreplication/framework_test.go | 31 ++- .../vreplication/replicator_plan.go | 128 ++++++++- .../tabletmanager/vreplication/stats.go | 72 +++++ .../tabletmanager/vreplication/stats_test.go | 10 + .../vreplication/table_plan_builder.go | 14 + .../tabletmanager/vreplication/vcopier.go | 10 +- .../tabletmanager/vreplication/vdbclient.go | 70 +++++ .../tabletmanager/vreplication/vplayer.go | 125 +++++++-- .../vreplication/vplayer_flaky_test.go | 253 +++++++++++++++++- .../tabletmanager/vreplication/vreplicator.go | 14 +- go/vt/wrangler/fake_dbclient_test.go | 17 ++ 21 files changed, 843 insertions(+), 83 deletions(-) diff --git a/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go b/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go index 7f560a24f9e..9f442a39c76 100644 --- a/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go +++ b/go/test/endtoend/onlineddl/vrepl_stress/onlineddl_vrepl_mini_stress_test.go @@ -29,16 +29,16 @@ import ( "testing" "time" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/schema" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/onlineddl" "vitess.io/vitess/go/test/endtoend/throttler" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/vttablet" ) type WriteMetrics struct { @@ -184,6 +184,9 @@ func TestMain(m *testing.M) { "--heartbeat_on_demand_duration", "5s", "--migration_check_interval", "5s", "--watch_replication_stream", + // Test VPlayer batching mode. + fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching), } clusterInstance.VtGateExtraArgs = []string{ "--ddl_strategy", "online", diff --git a/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go b/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go index bac59241cf2..2d9caaa6703 100644 --- a/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_stress_suite/onlineddl_vrepl_stress_suite_test.go @@ -40,18 +40,18 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/timer" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/schema" - "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/onlineddl" "vitess.io/vitess/go/test/endtoend/throttler" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/timer" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/vttablet" ) type testcase struct { @@ -436,6 +436,9 @@ func TestMain(m *testing.M) { "--migration_check_interval", "5s", "--vstream_packet_size", "4096", // Keep this value small and below 10k to ensure multilple vstream iterations "--watch_replication_stream", + // Test VPlayer batching mode. + fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching), } clusterInstance.VtGateExtraArgs = []string{ "--ddl_strategy", "online", diff --git a/go/test/endtoend/vreplication/fk_test.go b/go/test/endtoend/vreplication/fk_test.go index 4798edfb975..7d5f01c13db 100644 --- a/go/test/endtoend/vreplication/fk_test.go +++ b/go/test/endtoend/vreplication/fk_test.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vttablet" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -38,8 +39,13 @@ import ( // It inserts initial data, then simulates load. We insert both child rows with foreign keys and those without, // i.e. with foreign_key_checks=0. func TestFKWorkflow(t *testing.T) { - // ensure that there are multiple copy phase cycles per table - extraVTTabletArgs = []string{"--vstream_packet_size=256"} + extraVTTabletArgs = []string{ + // Ensure that there are multiple copy phase cycles per table. + "--vstream_packet_size=256", + // Test VPlayer batching mode. + fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching), + } defer func() { extraVTTabletArgs = nil }() cellName := "zone" diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index 62d174df067..2bc4df760ee 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -27,27 +27,27 @@ import ( "testing" "time" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" - + "github.com/buger/jsonparser" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" - "github.com/buger/jsonparser" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/log" - querypb "vitess.io/vitess/go/vt/proto/query" - throttlebase "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/vtgateconn" + "vitess.io/vitess/go/vt/vttablet" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + throttlebase "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) var ( @@ -280,6 +280,11 @@ func TestVreplicationCopyThrottling(t *testing.T) { } func TestBasicVreplicationWorkflow(t *testing.T) { + ogflags := extraVTTabletArgs + defer func() { extraVTTabletArgs = ogflags }() + // Test VPlayer batching mode. + extraVTTabletArgs = append(extraVTTabletArgs, fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching)) sourceKsOpts["DBTypeVersion"] = "mysql-8.0" targetKsOpts["DBTypeVersion"] = "mysql-8.0" testBasicVreplicationWorkflow(t, "noblob") @@ -622,8 +627,15 @@ func testVStreamCellFlag(t *testing.T) { func TestCellAliasVreplicationWorkflow(t *testing.T) { cells := []string{"zone1", "zone2"} mainClusterConfig.vreplicationCompressGTID = true + oldVTTabletExtraArgs := extraVTTabletArgs + extraVTTabletArgs = append(extraVTTabletArgs, + // Test VPlayer batching mode. + fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching), + ) defer func() { mainClusterConfig.vreplicationCompressGTID = false + extraVTTabletArgs = oldVTTabletExtraArgs }() vc = NewVitessCluster(t, "TestCellAliasVreplicationWorkflow", cells, mainClusterConfig) require.NotNil(t, vc) @@ -777,6 +789,12 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl } require.Equal(t, true, dec80Replicated) + // Insert multiple rows in the loadtest table and immediately delete them to confirm that bulk delete + // works the same way with the vplayer optimization enabled and disabled. Currently this optimization + // is disabled by default, but enabled in TestCellAliasVreplicationWorkflow. + execVtgateQuery(t, vtgateConn, sourceKs, "insert into loadtest(id, name) values(10001, 'tempCustomer'), (10002, 'tempCustomer2'), (10003, 'tempCustomer3'), (10004, 'tempCustomer4')") + execVtgateQuery(t, vtgateConn, sourceKs, "delete from loadtest where id > 10000") + // Confirm that all partial query metrics get updated when we are testing the noblob mode. t.Run("validate partial query counts", func(t *testing.T) { if !isBinlogRowImageNoBlob(t, productTab) { diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index 6d689bc5436..5b9d2e40e1e 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -60,8 +60,12 @@ var ( // BlplQuery is the key for the stats map. BlplQuery = "Query" + // BlplMultiQuery is the key for the stats map. + BlplMultiQuery = "MultiQuery" // BlplTransaction is the key for the stats map. BlplTransaction = "Transaction" + // BlplBatchTransaction is the key for the stats map. + BlplBatchTransaction = "BatchTransaction" ) // Stats is the internal stats of a player. It is a different @@ -84,13 +88,15 @@ type Stats struct { State atomic.Value - PhaseTimings *stats.Timings - QueryTimings *stats.Timings - QueryCount *stats.CountersWithSingleLabel - CopyRowCount *stats.Counter - CopyLoopCount *stats.Counter - ErrorCounts *stats.CountersWithMultiLabels - NoopQueryCount *stats.CountersWithSingleLabel + PhaseTimings *stats.Timings + QueryTimings *stats.Timings + QueryCount *stats.CountersWithSingleLabel + BulkQueryCount *stats.CountersWithSingleLabel + TrxQueryBatchCount *stats.CountersWithSingleLabel + CopyRowCount *stats.Counter + CopyLoopCount *stats.Counter + ErrorCounts *stats.CountersWithMultiLabels + NoopQueryCount *stats.CountersWithSingleLabel VReplicationLags *stats.Timings VReplicationLagRates *stats.Rates @@ -157,6 +163,8 @@ func NewStats() *Stats { bps.PhaseTimings = stats.NewTimings("", "", "Phase") bps.QueryTimings = stats.NewTimings("", "", "Phase") bps.QueryCount = stats.NewCountersWithSingleLabel("", "", "Phase", "") + bps.BulkQueryCount = stats.NewCountersWithSingleLabel("", "", "Statement", "") + bps.TrxQueryBatchCount = stats.NewCountersWithSingleLabel("", "", "Statement", "") bps.CopyRowCount = stats.NewCounter("", "") bps.CopyLoopCount = stats.NewCounter("", "") bps.ErrorCounts = stats.NewCountersWithMultiLabels("", "", []string{"type"}) diff --git a/go/vt/binlog/binlogplayer/dbclient.go b/go/vt/binlog/binlogplayer/dbclient.go index f9cd03691a5..ce2ccaccb17 100644 --- a/go/vt/binlog/binlogplayer/dbclient.go +++ b/go/vt/binlog/binlogplayer/dbclient.go @@ -19,6 +19,7 @@ package binlogplayer import ( "context" "fmt" + "strings" "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/mysql" @@ -38,6 +39,7 @@ type DBClient interface { Rollback() error Close() ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) + ExecuteFetchMulti(query string, maxrows int) (qrs []*sqltypes.Result, err error) } // dbClientImpl is a real DBClient backed by a mysql connection. @@ -140,6 +142,25 @@ func (dc *dbClientImpl) ExecuteFetch(query string, maxrows int) (*sqltypes.Resul return mqr, nil } +func (dc *dbClientImpl) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + results := make([]*sqltypes.Result, 0) + mqr, more, err := dc.dbConn.ExecuteFetchMulti(query, maxrows, true) + if err != nil { + dc.handleError(err) + return nil, err + } + results = append(results, mqr) + for more { + mqr, more, _, err = dc.dbConn.ReadQueryResult(maxrows, false) + if err != nil { + dc.handleError(err) + return nil, err + } + results = append(results, mqr) + } + return results, nil +} + func (dcr *dbClientImplWithSidecarDBReplacement) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, error) { // Replace any provided sidecar database qualifiers with the correct one. uq, err := sqlparser.ReplaceTableQualifiers(query, sidecar.DefaultName, sidecar.GetName()) @@ -148,3 +169,22 @@ func (dcr *dbClientImplWithSidecarDBReplacement) ExecuteFetch(query string, maxr } return dcr.dbClientImpl.ExecuteFetch(uq, maxrows) } + +func (dcr *dbClientImplWithSidecarDBReplacement) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + // Replace any provided sidecar database qualifiers with the correct one. + qps, err := sqlparser.SplitStatementToPieces(query) + if err != nil { + return nil, err + } + for i, qp := range qps { + uq, err := sqlparser.ReplaceTableQualifiers(qp, sidecar.DefaultName, sidecar.GetName()) + if err != nil { + return nil, err + } + qps[i] = uq + } + if err != nil { + return nil, err + } + return dcr.dbClientImpl.ExecuteFetchMulti(strings.Join(qps, ";"), maxrows) +} diff --git a/go/vt/binlog/binlogplayer/fake_dbclient.go b/go/vt/binlog/binlogplayer/fake_dbclient.go index 186722cf12f..750f35b3fe3 100644 --- a/go/vt/binlog/binlogplayer/fake_dbclient.go +++ b/go/vt/binlog/binlogplayer/fake_dbclient.go @@ -80,3 +80,7 @@ func (dc *fakeDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Re } return nil, fmt.Errorf("unexpected: %v", query) } + +func (dc *fakeDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + return make([]*sqltypes.Result, 0), nil +} diff --git a/go/vt/binlog/binlogplayer/mock_dbclient.go b/go/vt/binlog/binlogplayer/mock_dbclient.go index d64c4d40146..ce07fbe9179 100644 --- a/go/vt/binlog/binlogplayer/mock_dbclient.go +++ b/go/vt/binlog/binlogplayer/mock_dbclient.go @@ -25,6 +25,7 @@ import ( "time" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/sqlparser" ) const mockClientUNameFiltered = "Filtered" @@ -224,3 +225,19 @@ func (dc *MockDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Re } return result.result, result.err } + +func (dc *MockDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + queries, err := sqlparser.SplitStatementToPieces(query) + if err != nil { + return nil, err + } + results := make([]*sqltypes.Result, 0, len(queries)) + for _, query := range queries { + qr, err := dc.ExecuteFetch(query, maxrows) + if err != nil { + return nil, err + } + results = append(results, qr) + } + return results, nil +} diff --git a/go/vt/vttablet/flags.go b/go/vt/vttablet/flags.go index 3ce2cd3b378..994080b95a5 100644 --- a/go/vt/vttablet/flags.go +++ b/go/vt/vttablet/flags.go @@ -25,11 +25,14 @@ import ( ) const ( + // VReplicationExperimentalFlags is a bitmask of experimental features in vreplication. VReplicationExperimentalFlagOptimizeInserts = int64(1) VReplicationExperimentalFlagAllowNoBlobBinlogRowImage = int64(2) + VReplicationExperimentalFlagVPlayerBatching = int64(4) ) var ( + // Default flags. VReplicationExperimentalFlags = VReplicationExperimentalFlagOptimizeInserts | VReplicationExperimentalFlagAllowNoBlobBinlogRowImage VReplicationNetReadTimeout = 300 VReplicationNetWriteTimeout = 600 diff --git a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go index d5e8c134814..d0b81179f0f 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go @@ -396,6 +396,22 @@ func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Resu return qr, err } +func (dbc *realDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + queries, err := sqlparser.SplitStatementToPieces(query) + if err != nil { + return nil, err + } + results := make([]*sqltypes.Result, 0, len(queries)) + for _, query := range queries { + qr, err := dbc.ExecuteFetch(query, maxrows) + if err != nil { + return nil, err + } + results = append(results, qr) + } + return results, nil +} + //---------------------------------------------- // fakeTMClient diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index ee1a1dbc06c..64a924f28d3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -28,26 +28,25 @@ import ( "testing" "time" - "vitess.io/vitess/go/mysql/replication" - "vitess.io/vitess/go/vt/dbconnpool" - "vitess.io/vitess/go/vt/vttablet" - - "vitess.io/vitess/go/test/utils" - "vitess.io/vitess/go/vt/dbconfigs" - "github.com/spf13/pflag" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" _flag "vitess.io/vitess/go/internal/flag" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/sidecardb" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vttablet" "vitess.io/vitess/go/vt/vttablet/queryservice" "vitess.io/vitess/go/vt/vttablet/queryservice/fakes" "vitess.io/vitess/go/vt/vttablet/tabletconn" @@ -70,6 +69,7 @@ var ( globalFBC = &fakeBinlogClient{} vrepldb = "vrepl" globalDBQueries = make(chan string, 1000) + lastMultiExecQuery = "" testForeignKeyQueries = false testSetForeignKeyQueries = false doNotLogDBQueries = false @@ -494,6 +494,23 @@ func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Resu return qr, err } +func (dc *realDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + queries, err := sqlparser.SplitStatementToPieces(query) + if err != nil { + return nil, err + } + results := make([]*sqltypes.Result, 0, len(queries)) + for _, query := range queries { + qr, err := dc.ExecuteFetch(query, maxrows) + if err != nil { + return nil, err + } + results = append(results, qr) + } + lastMultiExecQuery = query + return results, nil +} + func expectDeleteQueries(t *testing.T) { t.Helper() if doNotLogDBQueries { diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 39ffdef04ae..9ecf8669d6d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -29,13 +29,14 @@ import ( vjson "vitess.io/vitess/go/mysql/json" "vitess.io/vitess/go/sqltypes" "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" "vitess.io/vitess/go/vt/vttablet" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // ReplicatorPlan is the execution plan for the replicator. It contains @@ -195,6 +196,7 @@ type TablePlan struct { Insert *sqlparser.ParsedQuery Update *sqlparser.ParsedQuery Delete *sqlparser.ParsedQuery + MultiDelete *sqlparser.ParsedQuery Fields []*querypb.Field EnumValuesMap map[string](map[string]string) ConvertIntToEnum map[string]bool @@ -444,6 +446,126 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun return nil, nil } +// applyBulkDeleteChanges applies a bulk DELETE statement from the row changes +// to the target table -- which resulted from a DELETE statement executed on the +// source that deleted N rows -- using an IN clause with the primary key values +// of the rows to be deleted. This currently only supports tables with single +// column primary keys. This limitation is in place for now as we know that case +// will still be efficient. When using large multi-column IN or OR group clauses +// in DELETES we could end up doing large (table) scans that actually make things +// slower. +// TODO: Add support for multi-column primary keys. +func (tp *TablePlan) applyBulkDeleteChanges(rowDeletes []*binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error), maxQuerySize int64) (*sqltypes.Result, error) { + if len(rowDeletes) == 0 { + return &sqltypes.Result{}, nil + } + if (len(tp.TablePlanBuilder.pkCols) + len(tp.TablePlanBuilder.extraSourcePkCols)) != 1 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "bulk delete is only supported for tables with a single primary key column") + } + if tp.MultiDelete == nil { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "plan has no bulk delete query") + } + + baseQuerySize := int64(len(tp.MultiDelete.Query)) + querySize := baseQuerySize + + execQuery := func(pkVals *[]sqltypes.Value) (*sqltypes.Result, error) { + pksBV, err := sqltypes.BuildBindVariable(*pkVals) + if err != nil { + return nil, err + } + query, err := tp.MultiDelete.GenerateQuery(map[string]*querypb.BindVariable{"bulk_pks": pksBV}, nil) + if err != nil { + return nil, err + } + tp.TablePlanBuilder.stats.BulkQueryCount.Add("delete", 1) + return executor(query) + } + + pkIndex := -1 + pkVals := make([]sqltypes.Value, 0, len(rowDeletes)) + for _, rowDelete := range rowDeletes { + vals := sqltypes.MakeRowTrusted(tp.Fields, rowDelete.Before) + if pkIndex == -1 { + for i := range vals { + if tp.PKIndices[i] { + pkIndex = i + break + } + } + } + addedSize := int64(len(vals[pkIndex].Raw()) + 2) // Plus 2 for the comma and space + if querySize+addedSize > maxQuerySize { + if _, err := execQuery(&pkVals); err != nil { + return nil, err + } + pkVals = nil + querySize = baseQuerySize + } + pkVals = append(pkVals, vals[pkIndex]) + querySize += addedSize + } + + return execQuery(&pkVals) +} + +// applyBulkInsertChanges generates a multi-row INSERT statement from the row +// changes generated from a multi-row INSERT statement executed on the source. +func (tp *TablePlan) applyBulkInsertChanges(rowInserts []*binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error), maxQuerySize int64) (*sqltypes.Result, error) { + if len(rowInserts) == 0 { + return &sqltypes.Result{}, nil + } + if tp.BulkInsertFront == nil { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "plan has no bulk insert query") + } + + prefix := &strings.Builder{} + prefix.WriteString(tp.BulkInsertFront.Query) + prefix.WriteString(" values ") + insertPrefix := prefix.String() + maxQuerySize -= int64(len(insertPrefix)) + values := &strings.Builder{} + + execQuery := func(vals *strings.Builder) (*sqltypes.Result, error) { + if tp.BulkInsertOnDup != nil { + vals.WriteString(tp.BulkInsertOnDup.Query) + } + tp.TablePlanBuilder.stats.BulkQueryCount.Add("insert", 1) + return executor(insertPrefix + vals.String()) + } + + newStmt := true + for _, rowInsert := range rowInserts { + rowValues := &strings.Builder{} + bindvars := make(map[string]*querypb.BindVariable, len(tp.Fields)) + vals := sqltypes.MakeRowTrusted(tp.Fields, rowInsert.After) + for n, field := range tp.Fields { + bindVar, err := tp.bindFieldVal(field, &vals[n]) + if err != nil { + return nil, err + } + bindvars["a_"+field.Name] = bindVar + } + if err := tp.BulkInsertValues.Append(rowValues, bindvars, nil); err != nil { + return nil, err + } + if int64(values.Len()+2+rowValues.Len()) > maxQuerySize { // Plus 2 for the comma and space + if _, err := execQuery(values); err != nil { + return nil, err + } + values.Reset() + newStmt = true + } + if !newStmt { + values.WriteString(", ") + } + values.WriteString(rowValues.String()) + newStmt = false + } + + return execQuery(values) +} + func getQuery(pq *sqlparser.ParsedQuery, bindvars map[string]*querypb.BindVariable) (string, error) { sql, err := pq.GenerateQuery(bindvars, nil) if err != nil { diff --git a/go/vt/vttablet/tabletmanager/vreplication/stats.go b/go/vt/vttablet/tabletmanager/vreplication/stats.go index 6379a9ba04f..892247efee0 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/stats.go +++ b/go/vt/vttablet/tabletmanager/vreplication/stats.go @@ -254,6 +254,39 @@ func (st *vrStats) register() { return result }) + stats.NewGaugesFuncWithMultiLabels( + "VReplicationBulkQueryCount", + "vreplication vplayer queries with consolidated row events counts per DML type per stream", + []string{"source_keyspace", "source_shard", "workflow", "counts", "dml_type"}, + func() map[string]int64 { + st.mu.Lock() + defer st.mu.Unlock() + result := make(map[string]int64, len(st.controllers)) + for _, ct := range st.controllers { + for label, count := range ct.blpStats.BulkQueryCount.Counts() { + if label == "" { + continue + } + result[ct.source.Keyspace+"."+ct.source.Shard+"."+ct.workflow+"."+fmt.Sprintf("%v", ct.id)+"."+label] = count + } + } + return result + }) + stats.NewCounterFunc( + "VReplicationBulkQueryCountTotal", + "vreplication vplayer queries with consolidated row events counts aggregated across all streams", + func() int64 { + st.mu.Lock() + defer st.mu.Unlock() + result := int64(0) + for _, ct := range st.controllers { + for _, count := range ct.blpStats.BulkQueryCount.Counts() { + result += count + } + } + return result + }) + stats.NewGaugesFuncWithMultiLabels( "VReplicationNoopQueryCount", "vreplication noop query counts per stream", @@ -287,6 +320,41 @@ func (st *vrStats) register() { } return result }) + + stats.NewGaugesFuncWithMultiLabels( + "VReplicationTrxQueryBatchCount", + "vreplication vplayer transaction query batch counts per type per stream", + []string{"source_keyspace", "source_shard", "workflow", "counts", "commit_or_not"}, + func() map[string]int64 { + st.mu.Lock() + defer st.mu.Unlock() + result := make(map[string]int64, len(st.controllers)) + for _, ct := range st.controllers { + for label, count := range ct.blpStats.TrxQueryBatchCount.Counts() { + if label == "" { + continue + } + result[ct.source.Keyspace+"."+ct.source.Shard+"."+ct.workflow+"."+fmt.Sprintf("%v", ct.id)+"."+label] = count + } + } + return result + }) + + stats.NewCounterFunc( + "VReplicationTrxQueryBatchCountTotal", + "vreplication vplayer transaction query batch counts aggregated across all streams", + func() int64 { + st.mu.Lock() + defer st.mu.Unlock() + result := int64(0) + for _, ct := range st.controllers { + for _, count := range ct.blpStats.TrxQueryBatchCount.Counts() { + result += count + } + } + return result + }) + stats.NewGaugesFuncWithMultiLabels( "VReplicationCopyRowCount", "vreplication rows copied in copy phase per stream", @@ -476,6 +544,8 @@ func (st *vrStats) status() *EngineStatus { SourceTablet: ct.sourceTablet.Load().(*topodatapb.TabletAlias), Messages: ct.blpStats.MessageHistory(), QueryCounts: ct.blpStats.QueryCount.Counts(), + BulkQueryCounts: ct.blpStats.BulkQueryCount.Counts(), + TrxQueryBatchCounts: ct.blpStats.TrxQueryBatchCount.Counts(), PhaseTimings: ct.blpStats.PhaseTimings.Counts(), CopyRowCount: ct.blpStats.CopyRowCount.Get(), CopyLoopCount: ct.blpStats.CopyLoopCount.Get(), @@ -514,6 +584,8 @@ type ControllerStatus struct { SourceTablet *topodatapb.TabletAlias Messages []string QueryCounts map[string]int64 + BulkQueryCounts map[string]int64 + TrxQueryBatchCounts map[string]int64 PhaseTimings map[string]int64 CopyRowCount int64 CopyLoopCount int64 diff --git a/go/vt/vttablet/tabletmanager/vreplication/stats_test.go b/go/vt/vttablet/tabletmanager/vreplication/stats_test.go index d5b5eacbdf2..79149d34d6d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/stats_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/stats_test.go @@ -169,6 +169,16 @@ func TestVReplicationStats(t *testing.T) { require.Equal(t, int64(11), testStats.status().Controllers[0].QueryCounts["replicate"]) require.Equal(t, int64(23), testStats.status().Controllers[0].QueryCounts["fastforward"]) + blpStats.BulkQueryCount.Add("insert", 101) + blpStats.BulkQueryCount.Add("delete", 203) + require.Equal(t, int64(101), testStats.status().Controllers[0].BulkQueryCounts["insert"]) + require.Equal(t, int64(203), testStats.status().Controllers[0].BulkQueryCounts["delete"]) + + blpStats.TrxQueryBatchCount.Add("without_commit", 10) + blpStats.TrxQueryBatchCount.Add("with_commit", 2193) + require.Equal(t, int64(10), testStats.status().Controllers[0].TrxQueryBatchCounts["without_commit"]) + require.Equal(t, int64(2193), testStats.status().Controllers[0].TrxQueryBatchCounts["with_commit"]) + blpStats.CopyLoopCount.Add(100) blpStats.CopyRowCount.Add(200) require.Equal(t, int64(100), testStats.status().Controllers[0].CopyLoopCount) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index d94d0640529..715d87186a6 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" @@ -361,6 +362,7 @@ func (tpb *tablePlanBuilder) generate() *TablePlan { Insert: tpb.generateInsertStatement(), Update: tpb.generateUpdateStatement(), Delete: tpb.generateDeleteStatement(), + MultiDelete: tpb.generateMultiDeleteStatement(), PKReferences: pkrefs, PKIndices: tpb.pkIndices, Stats: tpb.stats, @@ -870,6 +872,18 @@ func (tpb *tablePlanBuilder) generateDeleteStatement() *sqlparser.ParsedQuery { return buf.ParsedQuery() } +func (tpb *tablePlanBuilder) generateMultiDeleteStatement() *sqlparser.ParsedQuery { + if vttablet.VReplicationExperimentalFlags&vttablet.VReplicationExperimentalFlagVPlayerBatching == 0 || + (len(tpb.pkCols)+len(tpb.extraSourcePkCols)) != 1 { + return nil + } + return sqlparser.BuildParsedQuery("delete from %s where %s in %a", + sqlparser.String(tpb.name), + sqlparser.String(tpb.pkCols[0].colName), + "::bulk_pks", + ) +} + func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bindvarFormatter) { buf.WriteString(" where ") bvf.mode = bvBefore diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index f88c900f2db..196ee6aac86 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -27,20 +27,20 @@ import ( "google.golang.org/protobuf/encoding/prototext" - "vitess.io/vitess/go/vt/vttablet" - "vitess.io/vitess/go/bytes2" "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/pools" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/log" - 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/vttablet" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) type vcopier struct { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vdbclient.go b/go/vt/vttablet/tabletmanager/vreplication/vdbclient.go index c3941b0f1bb..39a8229efc6 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vdbclient.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vdbclient.go @@ -19,12 +19,15 @@ package vreplication import ( "context" "io" + "strings" "time" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" ) // vdbClient is a wrapper on binlogplayer.DBClient. @@ -35,6 +38,9 @@ type vdbClient struct { InTransaction bool startTime time.Time queries []string + queriesPos int64 + batchSize int64 + maxBatchSize int64 } func newVDBClient(dbclient binlogplayer.DBClient, stats *binlogplayer.Stats) *vdbClient { @@ -51,6 +57,13 @@ func (vc *vdbClient) Begin() error { if err := vc.DBClient.Begin(); err != nil { return err } + + // If we're batching, we only batch the contents of the + // transaction, which starts with the begin and ends with + // the commit. + vc.queriesPos = int64(len(vc.queries)) + vc.batchSize = 6 // begin and semicolon + vc.queries = append(vc.queries, "begin") vc.InTransaction = true vc.startTime = time.Now() @@ -63,10 +76,30 @@ func (vc *vdbClient) Commit() error { } vc.InTransaction = false vc.queries = nil + vc.batchSize = 0 vc.stats.Timings.Record(binlogplayer.BlplTransaction, vc.startTime) return nil } +// CommitTrxQueryBatch sends the current transaction's query batch -- which +// is often the full contents of the transaction, unless we've crossed +// the maxBatchSize one or more times -- down the wire to the database, +// including the final commit. +func (vc *vdbClient) CommitTrxQueryBatch() error { + vc.queries = append(vc.queries, "commit") + queries := strings.Join(vc.queries[vc.queriesPos:], ";") + for _, err := vc.DBClient.ExecuteFetchMulti(queries, -1); err != nil; { + return err + } + vc.InTransaction = false + vc.queries = nil + vc.queriesPos = 0 + vc.batchSize = 0 + vc.stats.TrxQueryBatchCount.Add("with_commit", 1) + vc.stats.Timings.Record(binlogplayer.BlplBatchTransaction, vc.startTime) + return nil +} + func (vc *vdbClient) Rollback() error { if !vc.InTransaction { return nil @@ -90,6 +123,43 @@ func (vc *vdbClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, return vc.DBClient.ExecuteFetch(query, maxrows) } +// AddQueryToTrxBatch adds the query to the current transaction's query +// batch. If this new query would cause the current batch to exceed +// the maxBatchSize, then the current unsent batch is sent down the +// wire and this query will be included in the next batch. +func (vc *vdbClient) AddQueryToTrxBatch(query string) error { + if !vc.InTransaction { + return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "cannot batch query outside of a transaction: %s", query) + } + + addedSize := int64(len(query)) + 1 // Plus 1 for the semicolon + if vc.batchSize+addedSize > vc.maxBatchSize { + if _, err := vc.ExecuteTrxQueryBatch(); err != nil { + return err + } + } + vc.queries = append(vc.queries, query) + vc.batchSize += addedSize + + return nil +} + +// ExecuteQueryBatch sends the transaction's current batch of queries +// down the wire to the database. +func (vc *vdbClient) ExecuteTrxQueryBatch() ([]*sqltypes.Result, error) { + defer vc.stats.Timings.Record(binlogplayer.BlplMultiQuery, time.Now()) + + qrs, err := vc.DBClient.ExecuteFetchMulti(strings.Join(vc.queries[vc.queriesPos:], ";"), -1) + if err != nil { + return nil, err + } + vc.stats.TrxQueryBatchCount.Add("without_commit", 1) + vc.queriesPos += int64(len(vc.queries[vc.queriesPos:])) + vc.batchSize = 0 + + return qrs, nil +} + // Execute is ExecuteFetch without the maxrows. func (vc *vdbClient) Execute(query string) (*sqltypes.Result, error) { // Number of rows should never exceed relayLogMaxItems. diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index be8876f26d2..c222bc11781 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -28,9 +28,9 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vttablet" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -47,6 +47,14 @@ type vplayer struct { replicatorPlan *ReplicatorPlan tablePlans map[string]*TablePlan + // These are set when creating the VPlayer based on whether the VPlayer + // is in batch (stmt and trx) execution mode or not. + query func(ctx context.Context, sql string) (*sqltypes.Result, error) + commit func() error + // If the VPlayer is in batch mode, we accumulate each transaction's statements + // that are then sent as a single multi-statement protocol request to the database. + batchMode bool + pos replication.Position // unsavedEvent is set any time we skip an event without // saving, which is on an empty commit. @@ -104,6 +112,47 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map settings.StopPos = pausePos saveStop = false } + + queryFunc := func(ctx context.Context, sql string) (*sqltypes.Result, error) { + return vr.dbClient.ExecuteWithRetry(ctx, sql) + } + commitFunc := func() error { + return vr.dbClient.Commit() + } + batchMode := false + if vttablet.VReplicationExperimentalFlags&vttablet.VReplicationExperimentalFlagVPlayerBatching != 0 { + batchMode = true + } + if batchMode { + // relayLogMaxSize is effectively the limit used when not batching. + maxAllowedPacket := int64(relayLogMaxSize) + // We explicitly do NOT want to batch this, we want to send it down the wire + // immediately so we use ExecuteFetch directly. + res, err := vr.dbClient.ExecuteFetch("select @@session.max_allowed_packet as max_allowed_packet", 1) + if err != nil { + log.Errorf("Error getting max_allowed_packet, will use the relay_log_max_size value of %d bytes: %v", relayLogMaxSize, err) + } else { + if maxAllowedPacket, err = res.Rows[0][0].ToInt64(); err != nil { + log.Errorf("Error getting max_allowed_packet, will use the relay_log_max_size value of %d bytes: %v", relayLogMaxSize, err) + } + } + // Leave 64 bytes of room for the commit to be sure that we have a more than + // ample buffer left. The default value of max_allowed_packet is 4MiB in 5.7 + // and 64MiB in 8.0 -- and the default for max_relay_log_size is 250000 + // bytes -- so we have plenty of room. + maxAllowedPacket -= 64 + queryFunc = func(ctx context.Context, sql string) (*sqltypes.Result, error) { + if !vr.dbClient.InTransaction { // Should be sent down the wire immediately + return vr.dbClient.Execute(sql) + } + return nil, vr.dbClient.AddQueryToTrxBatch(sql) // Should become part of the trx batch + } + commitFunc = func() error { + return vr.dbClient.CommitTrxQueryBatch() // Commit the current trx batch + } + vr.dbClient.maxBatchSize = maxAllowedPacket + } + return &vplayer{ vr: vr, startPos: settings.StartPos, @@ -115,6 +164,9 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map tablePlans: make(map[string]*TablePlan), phase: phase, throttlerAppName: throttlerapp.VCopierName.ConcatenateString(vr.throttlerAppName()), + query: queryFunc, + commit: commitFunc, + batchMode: batchMode, } } @@ -177,7 +229,7 @@ func (vp *vplayer) updateFKCheck(ctx context.Context, flags2 uint32) error { return nil } log.Infof("Setting this session's foreign_key_checks to %s", strconv.FormatBool(dbForeignKeyChecksEnabled)) - if _, err := vp.vr.dbClient.ExecuteWithRetry(ctx, "set @@session.foreign_key_checks="+strconv.FormatBool(dbForeignKeyChecksEnabled)); err != nil { + if _, err := vp.query(ctx, "set @@session.foreign_key_checks="+strconv.FormatBool(dbForeignKeyChecksEnabled)); err != nil { return fmt.Errorf("failed to set session foreign_key_checks: %w", err) } vp.foreignKeyChecksEnabled = dbForeignKeyChecksEnabled @@ -263,7 +315,7 @@ func (vp *vplayer) applyStmtEvent(ctx context.Context, event *binlogdatapb.VEven } if event.Type == binlogdatapb.VEventType_SAVEPOINT || vp.canAcceptStmtEvents { start := time.Now() - _, err := vp.vr.dbClient.ExecuteWithRetry(ctx, sql) + _, err := vp.query(ctx, sql) vp.vr.stats.QueryTimings.Record(vp.phase, start) vp.vr.stats.QueryCount.Add(vp.phase, 1) return err @@ -279,27 +331,46 @@ func (vp *vplayer) applyRowEvent(ctx context.Context, rowEvent *binlogdatapb.Row if tplan == nil { return fmt.Errorf("unexpected event on table %s", rowEvent.TableName) } + applyFunc := func(sql string) (*sqltypes.Result, error) { + stats := NewVrLogStats("ROWCHANGE") + start := time.Now() + qr, err := vp.query(ctx, sql) + vp.vr.stats.QueryCount.Add(vp.phase, 1) + vp.vr.stats.QueryTimings.Record(vp.phase, start) + stats.Send(sql) + return qr, err + } + + if vp.batchMode && len(rowEvent.RowChanges) > 1 { + // If we have multiple delete row events for a table with a single PK column + // then we can perform a simple bulk DELETE using an IN clause. + if (rowEvent.RowChanges[0].Before != nil && rowEvent.RowChanges[0].After == nil) && + tplan.MultiDelete != nil { + _, err := tplan.applyBulkDeleteChanges(rowEvent.RowChanges, applyFunc, vp.vr.dbClient.maxBatchSize) + return err + } + // If we're done with the copy phase then we will be replicating all INSERTS + // regardless of the PK value and can use a single INSERT statment with + // multiple VALUES clauses. + if len(vp.copyState) == 0 && (rowEvent.RowChanges[0].Before == nil && rowEvent.RowChanges[0].After != nil) { + _, err := tplan.applyBulkInsertChanges(rowEvent.RowChanges, applyFunc, vp.vr.dbClient.maxBatchSize) + return err + } + } + for _, change := range rowEvent.RowChanges { - _, err := tplan.applyChange(change, func(sql string) (*sqltypes.Result, error) { - stats := NewVrLogStats("ROWCHANGE") - start := time.Now() - qr, err := vp.vr.dbClient.ExecuteWithRetry(ctx, sql) - vp.vr.stats.QueryCount.Add(vp.phase, 1) - vp.vr.stats.QueryTimings.Record(vp.phase, start) - stats.Send(sql) - return qr, err - }) - if err != nil { + if _, err := tplan.applyChange(change, applyFunc); err != nil { return err } } + return nil } -func (vp *vplayer) updatePos(ts int64) (posReached bool, err error) { +func (vp *vplayer) updatePos(ctx context.Context, ts int64) (posReached bool, err error) { vp.numAccumulatedHeartbeats = 0 update := binlogplayer.GenerateUpdatePos(vp.vr.id, vp.pos, time.Now().Unix(), ts, vp.vr.stats.CopyRowCount.Get(), vreplicationStoreCompressedGTID) - if _, err := vp.vr.dbClient.Execute(update); err != nil { + if _, err := vp.query(ctx, update); err != nil { return false, fmt.Errorf("error %v updating position", err) } vp.unsavedEvent = nil @@ -393,7 +464,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { if ctx.Err() != nil { return ctx.Err() } - // check throttler. + // Check throttler. if !vp.vr.vre.throttlerClient.ThrottleCheckOKOrWaitAppName(ctx, throttlerapp.Name(vp.throttlerAppName)) { _ = vp.vr.updateTimeThrottled(throttlerapp.VPlayerName) continue @@ -417,7 +488,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { // In both cases, now > timeLastSaved. If so, the GTID of the last unsavedEvent // must be saved. if time.Since(vp.timeLastSaved) >= idleTimeout && vp.unsavedEvent != nil { - posReached, err := vp.updatePos(vp.unsavedEvent.Timestamp) + posReached, err := vp.updatePos(ctx, vp.unsavedEvent.Timestamp) if err != nil { return err } @@ -516,11 +587,11 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m vp.unsavedEvent = event return nil } - posReached, err := vp.updatePos(event.Timestamp) + posReached, err := vp.updatePos(ctx, event.Timestamp) if err != nil { return err } - if err := vp.vr.dbClient.Commit(); err != nil { + if err := vp.commit(); err != nil { return err } if posReached { @@ -573,7 +644,7 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m return fmt.Errorf("internal error: vplayer is in a transaction on event: %v", event) } // Just update the position. - posReached, err := vp.updatePos(event.Timestamp) + posReached, err := vp.updatePos(ctx, event.Timestamp) if err != nil { return err } @@ -589,7 +660,7 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m switch vp.vr.source.OnDdl { case binlogdatapb.OnDDLAction_IGNORE: // We still have to update the position. - posReached, err := vp.updatePos(event.Timestamp) + posReached, err := vp.updatePos(ctx, event.Timestamp) if err != nil { return err } @@ -600,13 +671,13 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m if err := vp.vr.dbClient.Begin(); err != nil { return err } - if _, err := vp.updatePos(event.Timestamp); err != nil { + if _, err := vp.updatePos(ctx, event.Timestamp); err != nil { return err } if err := vp.vr.setState(binlogdatapb.VReplicationWorkflowState_Stopped, fmt.Sprintf("Stopped at DDL %s", event.Statement)); err != nil { return err } - if err := vp.vr.dbClient.Commit(); err != nil { + if err := vp.commit(); err != nil { return err } return io.EOF @@ -615,11 +686,11 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m // So, we apply the DDL first, and then save the position. // Manual intervention may be needed if there is a partial // failure here. - if _, err := vp.vr.dbClient.ExecuteWithRetry(ctx, event.Statement); err != nil { + if _, err := vp.query(ctx, event.Statement); err != nil { return err } stats.Send(fmt.Sprintf("%v", event.Statement)) - posReached, err := vp.updatePos(event.Timestamp) + posReached, err := vp.updatePos(ctx, event.Timestamp) if err != nil { return err } @@ -627,11 +698,11 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m return io.EOF } case binlogdatapb.OnDDLAction_EXEC_IGNORE: - if _, err := vp.vr.dbClient.ExecuteWithRetry(ctx, event.Statement); err != nil { + if _, err := vp.query(ctx, event.Statement); err != nil { log.Infof("Ignoring error: %v for DDL: %s", err, event.Statement) } stats.Send(fmt.Sprintf("%v", event.Statement)) - posReached, err := vp.updatePos(event.Timestamp) + posReached, err := vp.updatePos(ctx, event.Timestamp) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 3b215d03791..dc11ac7bd9c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "os" + "regexp" "strconv" "strings" "sync" @@ -2335,7 +2336,7 @@ func TestPlayerCancelOnLock(t *testing.T) { } } -func TestPlayerBatching(t *testing.T) { +func TestPlayerTransactions(t *testing.T) { defer deleteTablet(addTablet(100)) execStatements(t, []string{ @@ -3107,6 +3108,256 @@ func TestPlayerNoBlob(t *testing.T) { require.Equal(t, int64(4), stats.PartialQueryCount.Counts()["update"]) } +func TestPlayerBatchMode(t *testing.T) { + // To test trx batch splitting at 1024-64 bytes. + maxAllowedPacket := 1024 + oldVreplicationExperimentalFlags := vttablet.VReplicationExperimentalFlags + vttablet.VReplicationExperimentalFlags = vttablet.VReplicationExperimentalFlagVPlayerBatching + defer func() { + vttablet.VReplicationExperimentalFlags = oldVreplicationExperimentalFlags + }() + + defer deleteTablet(addTablet(100)) + execStatements(t, []string{ + fmt.Sprintf("set @@global.max_allowed_packet=%d", maxAllowedPacket), + "create table t1(id bigint, val1 varchar(1000), primary key(id))", + fmt.Sprintf("create table %s.t1(id bigint, val1 varchar(1000), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: filter, + OnDdl: binlogdatapb.OnDDLAction_IGNORE, + } + cancel, vrID := startVReplication(t, bls, "") + defer cancel() + + maxBatchSize := maxAllowedPacket - 64 // VPlayer leaves 64 bytes of room + // When the trx will be in a single batch. + trxFullBatchExpectRE := `^begin;(set @@session\.foreign_key_checks=.*;)?%s;update _vt\.vreplication set pos=.*;commit$` + // If the trx batch is split, then we only expect the end part. + trxLastBatchExpectRE := `%s;update _vt\.vreplication set pos=.*;commit$` + // The vreplication position update statement will look like this: + // update _vt.vreplication set pos='MySQL56/b213e4de-937a-11ee-b184-668979c675f4:1-38', time_updated=1701786574, transaction_timestamp=1701786574, rows_copied=0, message='' where id=1; + // So it will use 182 bytes in the batch. + // This long value can be used to test the handling of bulk statements + // which bump up against the max batch size, as well as testing the trx + // batch splitting into multiple wire messages when hitting the max size. + longStr := strings.Repeat("a", maxBatchSize-70) + + testcases := []struct { + input string + output []string + expectedNonCommitBatches int64 + expectedInLastBatch string // Should only be set if we expect 1+ non-commit batches + expectedBulkInserts int64 + expectedBulkDeletes int64 + table string + data [][]string + }{ + { + input: "insert into t1(id, val1) values (1, 'aaa'), (2, 'bbb'), (3, 'ccc'), (4, 'ddd'), (5, 'eee')", + output: []string{"insert into t1(id,val1) values (1,'aaa'), (2,'bbb'), (3,'ccc'), (4,'ddd'), (5,'eee')"}, + expectedBulkInserts: 1, + table: "t1", + data: [][]string{ + {"1", "aaa"}, + {"2", "bbb"}, + {"3", "ccc"}, + {"4", "ddd"}, + {"5", "eee"}, + }, + }, + { + input: "delete from t1 where id = 1", + output: []string{"delete from t1 where id=1"}, + table: "t1", + data: [][]string{ + {"2", "bbb"}, + {"3", "ccc"}, + {"4", "ddd"}, + {"5", "eee"}, + }, + }, + { + input: "delete from t1 where id > 3", + output: []string{"delete from t1 where id in (4, 5)"}, + expectedBulkDeletes: 1, + table: "t1", + data: [][]string{ + {"2", "bbb"}, + {"3", "ccc"}, + }, + }, + { + input: fmt.Sprintf("insert into t1(id, val1) values (1, '%s'), (2, 'bbb'), (3, 'ccc') on duplicate key update id = id+100", longStr), + output: []string{ + fmt.Sprintf("insert into t1(id,val1) values (1,'%s')", longStr), + "delete from t1 where id=2", + "insert into t1(id,val1) values (102,'bbb')", + "delete from t1 where id=3", + // This will be in the second/last batch, along with the vrepl pos update. + "insert into t1(id,val1) values (103,'ccc')", + }, + expectedInLastBatch: "insert into t1(id,val1) values (103,'ccc')", + expectedNonCommitBatches: 1, + table: "t1", + data: [][]string{ + {"1", longStr}, + {"102", "bbb"}, + {"103", "ccc"}, + }, + }, + { + input: "insert into t1(id, val1) values (1, 'aaa'), (2, 'bbb'), (3, 'ccc') on duplicate key update id = id+500, val1 = values(val1)", + output: []string{ + "delete from t1 where id=1", + "insert into t1(id,val1) values (501,'aaa')", + "insert into t1(id,val1) values (2,'bbb'), (3,'ccc')", + }, + expectedBulkInserts: 1, + table: "t1", + data: [][]string{ + {"2", "bbb"}, + {"3", "ccc"}, + {"102", "bbb"}, + {"103", "ccc"}, + {"501", "aaa"}, + }, + }, + { + input: "delete from t1", + output: []string{"delete from t1 where id in (2, 3, 102, 103, 501)"}, + expectedBulkDeletes: 1, + table: "t1", + }, + { + input: fmt.Sprintf("insert into t1(id, val1) values (1, '%s'), (2, 'bbb'), (3, 'ccc'), (4, 'ddd'), (5, 'eee')", longStr), + output: []string{ + // This bulk insert is long enough that the BEGIN gets sent down by itself. + // The bulk query then gets split into two queries. It also causes the trx + // to get split into three batches (BEGIN, INSERT, INSERT). + fmt.Sprintf("insert into t1(id,val1) values (1,'%s'), (2,'bbb'), (3,'ccc'), (4,'ddd')", longStr), + // This will be in the second/last batch, along with the vrepl pos update. + "insert into t1(id,val1) values (5,'eee')", + }, + expectedBulkInserts: 2, + // The BEGIN, then the INSERT. + expectedNonCommitBatches: 2, // The last one includes the commit + expectedInLastBatch: "insert into t1(id,val1) values (5,'eee')", + table: "t1", + data: [][]string{ + {"1", longStr}, + {"2", "bbb"}, + {"3", "ccc"}, + {"4", "ddd"}, + {"5", "eee"}, + }, + }, + { + input: "insert into t1(id, val1) values (1000000000000, 'x'), (1000000000001, 'x'), (1000000000002, 'x'), (1000000000003, 'x'), (1000000000004, 'x'), (1000000000005, 'x'), (1000000000006, 'x'), (1000000000007, 'x'), (1000000000008, 'x'), (1000000000009, 'x'), (1000000000010, 'x'), (1000000000011, 'x'), (1000000000012, 'x'), (1000000000013, 'x'), (1000000000014, 'x'), (1000000000015, 'x'), (1000000000016, 'x'), (1000000000017, 'x'), (1000000000018, 'x'), (1000000000019, 'x'), (1000000000020, 'x'), (1000000000021, 'x'), (1000000000022, 'x'), (1000000000023, 'x'), (1000000000024, 'x'), (1000000000025, 'x'), (1000000000026, 'x'), (1000000000027, 'x'), (1000000000028, 'x'), (1000000000029, 'x'), (1000000000030, 'x'), (1000000000031, 'x'), (1000000000032, 'x'), (1000000000033, 'x'), (1000000000034, 'x'), (1000000000035, 'x'), (1000000000036, 'x'), (1000000000037, 'x'), (1000000000038, 'x'), (1000000000039, 'x'), (1000000000040, 'x'), (1000000000041, 'x'), (1000000000042, 'x'), (1000000000043, 'x'), (1000000000044, 'x'), (1000000000045, 'x'), (1000000000046, 'x'), (1000000000047, 'x'), (1000000000048, 'x'), (1000000000049, 'x'), (1000000000050, 'x'), (1000000000051, 'x'), (1000000000052, 'x'), (1000000000053, 'x'), (1000000000054, 'x'), (1000000000055, 'x'), (1000000000056, 'x'), (1000000000057, 'x'), (1000000000058, 'x'), (1000000000059, 'x'), (1000000000060, 'x'), (1000000000061, 'x'), (1000000000062, 'x'), (1000000000063, 'x'), (1000000000064, 'x'), (1000000000065, 'x'), (1000000000066, 'x'), (1000000000067, 'x'), (1000000000068, 'x'), (1000000000069, 'x'), (1000000000070, 'x'), (1000000000071, 'x'), (1000000000072, 'x'), (1000000000073, 'x'), (1000000000074, 'x'), (1000000000075, 'x'), (1000000000076, 'x'), (1000000000077, 'x'), (1000000000078, 'x'), (1000000000079, 'x'), (1000000000080, 'x'), (1000000000081, 'x'), (1000000000082, 'x'), (1000000000083, 'x'), (1000000000084, 'x'), (1000000000085, 'x'), (1000000000086, 'x'), (1000000000087, 'x'), (1000000000088, 'x'), (1000000000089, 'x'), (1000000000090, 'x'), (1000000000091, 'x'), (1000000000092, 'x'), (1000000000093, 'x'), (1000000000094, 'x'), (1000000000095, 'x'), (1000000000096, 'x'), (1000000000097, 'x'), (1000000000098, 'x'), (1000000000099, 'x'), (1000000000100, 'x'), (1000000000101, 'x'), (1000000000102, 'x'), (1000000000103, 'x'), (1000000000104, 'x'), (1000000000105, 'x'), (1000000000106, 'x'), (1000000000107, 'x'), (1000000000108, 'x'), (1000000000109, 'x'), (1000000000110, 'x'), (1000000000111, 'x'), (1000000000112, 'x'), (1000000000113, 'x'), (1000000000114, 'x'), (1000000000115, 'x'), (1000000000116, 'x'), (1000000000117, 'x'), (1000000000118, 'x'), (1000000000119, 'x'), (1000000000120, 'x'), (1000000000121, 'x'), (1000000000122, 'x'), (1000000000123, 'x'), (1000000000124, 'x'), (1000000000125, 'x'), (1000000000126, 'x'), (1000000000127, 'x'), (1000000000128, 'x'), (1000000000129, 'x'), (1000000000130, 'x'), (1000000000131, 'x'), (1000000000132, 'x'), (1000000000133, 'x'), (1000000000134, 'x'), (1000000000135, 'x'), (1000000000136, 'x'), (1000000000137, 'x'), (1000000000138, 'x'), (1000000000139, 'x'), (1000000000140, 'x'), (1000000000141, 'x'), (1000000000142, 'x'), (1000000000143, 'x'), (1000000000144, 'x'), (1000000000145, 'x'), (1000000000146, 'x'), (1000000000147, 'x'), (1000000000148, 'x'), (1000000000149, 'x'), (1000000000150, 'x')", + output: []string{ + "insert into t1(id,val1) values (1000000000000,'x'), (1000000000001,'x'), (1000000000002,'x'), (1000000000003,'x'), (1000000000004,'x'), (1000000000005,'x'), (1000000000006,'x'), (1000000000007,'x'), (1000000000008,'x'), (1000000000009,'x'), (1000000000010,'x'), (1000000000011,'x'), (1000000000012,'x'), (1000000000013,'x'), (1000000000014,'x'), (1000000000015,'x'), (1000000000016,'x'), (1000000000017,'x'), (1000000000018,'x'), (1000000000019,'x'), (1000000000020,'x'), (1000000000021,'x'), (1000000000022,'x'), (1000000000023,'x'), (1000000000024,'x'), (1000000000025,'x'), (1000000000026,'x'), (1000000000027,'x'), (1000000000028,'x'), (1000000000029,'x'), (1000000000030,'x'), (1000000000031,'x'), (1000000000032,'x'), (1000000000033,'x'), (1000000000034,'x'), (1000000000035,'x'), (1000000000036,'x'), (1000000000037,'x'), (1000000000038,'x'), (1000000000039,'x'), (1000000000040,'x'), (1000000000041,'x'), (1000000000042,'x'), (1000000000043,'x')", + "insert into t1(id,val1) values (1000000000044,'x'), (1000000000045,'x'), (1000000000046,'x'), (1000000000047,'x'), (1000000000048,'x'), (1000000000049,'x'), (1000000000050,'x'), (1000000000051,'x'), (1000000000052,'x'), (1000000000053,'x'), (1000000000054,'x'), (1000000000055,'x'), (1000000000056,'x'), (1000000000057,'x'), (1000000000058,'x'), (1000000000059,'x'), (1000000000060,'x'), (1000000000061,'x'), (1000000000062,'x'), (1000000000063,'x'), (1000000000064,'x'), (1000000000065,'x'), (1000000000066,'x'), (1000000000067,'x'), (1000000000068,'x'), (1000000000069,'x'), (1000000000070,'x'), (1000000000071,'x'), (1000000000072,'x'), (1000000000073,'x'), (1000000000074,'x'), (1000000000075,'x'), (1000000000076,'x'), (1000000000077,'x'), (1000000000078,'x'), (1000000000079,'x'), (1000000000080,'x'), (1000000000081,'x'), (1000000000082,'x'), (1000000000083,'x'), (1000000000084,'x'), (1000000000085,'x'), (1000000000086,'x'), (1000000000087,'x')", + "insert into t1(id,val1) values (1000000000088,'x'), (1000000000089,'x'), (1000000000090,'x'), (1000000000091,'x'), (1000000000092,'x'), (1000000000093,'x'), (1000000000094,'x'), (1000000000095,'x'), (1000000000096,'x'), (1000000000097,'x'), (1000000000098,'x'), (1000000000099,'x'), (1000000000100,'x'), (1000000000101,'x'), (1000000000102,'x'), (1000000000103,'x'), (1000000000104,'x'), (1000000000105,'x'), (1000000000106,'x'), (1000000000107,'x'), (1000000000108,'x'), (1000000000109,'x'), (1000000000110,'x'), (1000000000111,'x'), (1000000000112,'x'), (1000000000113,'x'), (1000000000114,'x'), (1000000000115,'x'), (1000000000116,'x'), (1000000000117,'x'), (1000000000118,'x'), (1000000000119,'x'), (1000000000120,'x'), (1000000000121,'x'), (1000000000122,'x'), (1000000000123,'x'), (1000000000124,'x'), (1000000000125,'x'), (1000000000126,'x'), (1000000000127,'x'), (1000000000128,'x'), (1000000000129,'x'), (1000000000130,'x'), (1000000000131,'x')", + // This will be in the last batch, along with the vrepl pos update. + "insert into t1(id,val1) values (1000000000132,'x'), (1000000000133,'x'), (1000000000134,'x'), (1000000000135,'x'), (1000000000136,'x'), (1000000000137,'x'), (1000000000138,'x'), (1000000000139,'x'), (1000000000140,'x'), (1000000000141,'x'), (1000000000142,'x'), (1000000000143,'x'), (1000000000144,'x'), (1000000000145,'x'), (1000000000146,'x'), (1000000000147,'x'), (1000000000148,'x'), (1000000000149,'x'), (1000000000150,'x')", + }, + expectedBulkInserts: 4, + expectedNonCommitBatches: 3, // The last one includes the commit + expectedInLastBatch: "insert into t1(id,val1) values (1000000000132,'x'), (1000000000133,'x'), (1000000000134,'x'), (1000000000135,'x'), (1000000000136,'x'), (1000000000137,'x'), (1000000000138,'x'), (1000000000139,'x'), (1000000000140,'x'), (1000000000141,'x'), (1000000000142,'x'), (1000000000143,'x'), (1000000000144,'x'), (1000000000145,'x'), (1000000000146,'x'), (1000000000147,'x'), (1000000000148,'x'), (1000000000149,'x'), (1000000000150,'x')", + table: "t1", + data: [][]string{ + {"1", longStr}, + {"2", "bbb"}, + {"3", "ccc"}, + {"4", "ddd"}, + {"5", "eee"}, + {"1000000000000", "x"}, {"1000000000001", "x"}, {"1000000000002", "x"}, {"1000000000003", "x"}, {"1000000000004", "x"}, {"1000000000005", "x"}, {"1000000000006", "x"}, {"1000000000007", "x"}, {"1000000000008", "x"}, {"1000000000009", "x"}, {"1000000000010", "x"}, {"1000000000011", "x"}, {"1000000000012", "x"}, {"1000000000013", "x"}, {"1000000000014", "x"}, {"1000000000015", "x"}, {"1000000000016", "x"}, {"1000000000017", "x"}, {"1000000000018", "x"}, {"1000000000019", "x"}, {"1000000000020", "x"}, {"1000000000021", "x"}, {"1000000000022", "x"}, {"1000000000023", "x"}, {"1000000000024", "x"}, {"1000000000025", "x"}, {"1000000000026", "x"}, {"1000000000027", "x"}, {"1000000000028", "x"}, {"1000000000029", "x"}, {"1000000000030", "x"}, {"1000000000031", "x"}, {"1000000000032", "x"}, {"1000000000033", "x"}, {"1000000000034", "x"}, {"1000000000035", "x"}, {"1000000000036", "x"}, {"1000000000037", "x"}, {"1000000000038", "x"}, {"1000000000039", "x"}, {"1000000000040", "x"}, {"1000000000041", "x"}, {"1000000000042", "x"}, {"1000000000043", "x"}, {"1000000000044", "x"}, {"1000000000045", "x"}, {"1000000000046", "x"}, {"1000000000047", "x"}, {"1000000000048", "x"}, {"1000000000049", "x"}, {"1000000000050", "x"}, {"1000000000051", "x"}, {"1000000000052", "x"}, {"1000000000053", "x"}, {"1000000000054", "x"}, {"1000000000055", "x"}, {"1000000000056", "x"}, {"1000000000057", "x"}, {"1000000000058", "x"}, {"1000000000059", "x"}, {"1000000000060", "x"}, {"1000000000061", "x"}, {"1000000000062", "x"}, {"1000000000063", "x"}, {"1000000000064", "x"}, {"1000000000065", "x"}, {"1000000000066", "x"}, {"1000000000067", "x"}, {"1000000000068", "x"}, {"1000000000069", "x"}, {"1000000000070", "x"}, {"1000000000071", "x"}, {"1000000000072", "x"}, {"1000000000073", "x"}, {"1000000000074", "x"}, {"1000000000075", "x"}, {"1000000000076", "x"}, {"1000000000077", "x"}, {"1000000000078", "x"}, {"1000000000079", "x"}, {"1000000000080", "x"}, {"1000000000081", "x"}, {"1000000000082", "x"}, {"1000000000083", "x"}, {"1000000000084", "x"}, {"1000000000085", "x"}, {"1000000000086", "x"}, {"1000000000087", "x"}, {"1000000000088", "x"}, {"1000000000089", "x"}, {"1000000000090", "x"}, {"1000000000091", "x"}, {"1000000000092", "x"}, {"1000000000093", "x"}, {"1000000000094", "x"}, {"1000000000095", "x"}, {"1000000000096", "x"}, {"1000000000097", "x"}, {"1000000000098", "x"}, {"1000000000099", "x"}, {"1000000000100", "x"}, {"1000000000101", "x"}, {"1000000000102", "x"}, {"1000000000103", "x"}, {"1000000000104", "x"}, {"1000000000105", "x"}, {"1000000000106", "x"}, {"1000000000107", "x"}, {"1000000000108", "x"}, {"1000000000109", "x"}, {"1000000000110", "x"}, {"1000000000111", "x"}, {"1000000000112", "x"}, {"1000000000113", "x"}, {"1000000000114", "x"}, {"1000000000115", "x"}, {"1000000000116", "x"}, {"1000000000117", "x"}, {"1000000000118", "x"}, {"1000000000119", "x"}, {"1000000000120", "x"}, {"1000000000121", "x"}, {"1000000000122", "x"}, {"1000000000123", "x"}, {"1000000000124", "x"}, {"1000000000125", "x"}, {"1000000000126", "x"}, {"1000000000127", "x"}, {"1000000000128", "x"}, {"1000000000129", "x"}, {"1000000000130", "x"}, {"1000000000131", "x"}, {"1000000000132", "x"}, {"1000000000133", "x"}, {"1000000000134", "x"}, {"1000000000135", "x"}, {"1000000000136", "x"}, {"1000000000137", "x"}, {"1000000000138", "x"}, {"1000000000139", "x"}, {"1000000000140", "x"}, {"1000000000141", "x"}, {"1000000000142", "x"}, {"1000000000143", "x"}, {"1000000000144", "x"}, {"1000000000145", "x"}, {"1000000000146", "x"}, {"1000000000147", "x"}, {"1000000000148", "x"}, {"1000000000149", "x"}, {"1000000000150", "x"}, + }, + }, + { // Now we have enough long IDs to cause the bulk delete to also be split along with the trx batch. + input: "delete from t1 where id > 1 and id <= 1000000000149", + output: []string{ + "delete from t1 where id in (2, 3, 4, 5, 1000000000000, 1000000000001, 1000000000002, 1000000000003, 1000000000004, 1000000000005, 1000000000006, 1000000000007, 1000000000008, 1000000000009, 1000000000010, 1000000000011, 1000000000012, 1000000000013, 1000000000014, 1000000000015, 1000000000016, 1000000000017, 1000000000018, 1000000000019, 1000000000020, 1000000000021, 1000000000022, 1000000000023, 1000000000024, 1000000000025, 1000000000026, 1000000000027, 1000000000028, 1000000000029, 1000000000030, 1000000000031, 1000000000032, 1000000000033, 1000000000034, 1000000000035, 1000000000036, 1000000000037, 1000000000038, 1000000000039, 1000000000040, 1000000000041, 1000000000042, 1000000000043, 1000000000044, 1000000000045, 1000000000046, 1000000000047, 1000000000048, 1000000000049, 1000000000050, 1000000000051, 1000000000052, 1000000000053, 1000000000054, 1000000000055, 1000000000056, 1000000000057, 1000000000058, 1000000000059)", + "delete from t1 where id in (1000000000060, 1000000000061, 1000000000062, 1000000000063, 1000000000064, 1000000000065, 1000000000066, 1000000000067, 1000000000068, 1000000000069, 1000000000070, 1000000000071, 1000000000072, 1000000000073, 1000000000074, 1000000000075, 1000000000076, 1000000000077, 1000000000078, 1000000000079, 1000000000080, 1000000000081, 1000000000082, 1000000000083, 1000000000084, 1000000000085, 1000000000086, 1000000000087, 1000000000088, 1000000000089, 1000000000090, 1000000000091, 1000000000092, 1000000000093, 1000000000094, 1000000000095, 1000000000096, 1000000000097, 1000000000098, 1000000000099, 1000000000100, 1000000000101, 1000000000102, 1000000000103, 1000000000104, 1000000000105, 1000000000106, 1000000000107, 1000000000108, 1000000000109, 1000000000110, 1000000000111, 1000000000112, 1000000000113, 1000000000114, 1000000000115, 1000000000116, 1000000000117, 1000000000118, 1000000000119, 1000000000120)", + // This will be in the last batch, along with the vrepl pos update. + "delete from t1 where id in (1000000000121, 1000000000122, 1000000000123, 1000000000124, 1000000000125, 1000000000126, 1000000000127, 1000000000128, 1000000000129, 1000000000130, 1000000000131, 1000000000132, 1000000000133, 1000000000134, 1000000000135, 1000000000136, 1000000000137, 1000000000138, 1000000000139, 1000000000140, 1000000000141, 1000000000142, 1000000000143, 1000000000144, 1000000000145, 1000000000146, 1000000000147, 1000000000148, 1000000000149)", + }, + expectedBulkDeletes: 3, + expectedNonCommitBatches: 2, // The last one includes the commit + expectedInLastBatch: "delete from t1 where id in (1000000000121, 1000000000122, 1000000000123, 1000000000124, 1000000000125, 1000000000126, 1000000000127, 1000000000128, 1000000000129, 1000000000130, 1000000000131, 1000000000132, 1000000000133, 1000000000134, 1000000000135, 1000000000136, 1000000000137, 1000000000138, 1000000000139, 1000000000140, 1000000000141, 1000000000142, 1000000000143, 1000000000144, 1000000000145, 1000000000146, 1000000000147, 1000000000148, 1000000000149)", + table: "t1", + data: [][]string{ + {"1", longStr}, + {"1000000000150", "x"}, + }, + }, + { + input: "delete from t1 where id = 1 or id > 1000000000149", + output: []string{"delete from t1 where id in (1, 1000000000150)"}, + expectedBulkDeletes: 1, + table: "t1", + }, + } + + expectedBulkInserts, expectedBulkDeletes, expectedTrxBatchExecs, expectedTrxBatchCommits := int64(0), int64(0), int64(0), int64(0) + stats := globalStats.controllers[int32(vrID)].blpStats + + for _, tcase := range testcases { + t.Run(fmt.Sprintf("%.50s", tcase.input), func(t *testing.T) { + execStatements(t, []string{tcase.input}) + var output qh.ExpectationSequencer + switch len(tcase.output) { + case 0: + require.FailNow(t, "no expected output provided for test case") + case 1: + output = qh.Expect(tcase.output[0]) + default: + output = qh.Expect(tcase.output[0], tcase.output[1:]...) + } + for _, stmt := range tcase.output { + require.LessOrEqual(t, len(stmt), maxBatchSize, "expected output statement is longer than the max batch size (%d): %s", maxBatchSize, stmt) + } + expectNontxQueries(t, output) + time.Sleep(1 * time.Second) + log.Flush() + if tcase.table != "" { + expectData(t, tcase.table, tcase.data) + } + + // Confirm that the row events generated the expected multi-row + // statements and the statements were sent in multi-statement + // protocol message(s) as expected. + expectedBulkDeletes += tcase.expectedBulkDeletes + expectedBulkInserts += tcase.expectedBulkInserts + expectedTrxBatchCommits++ // Should only ever be 1 per test case + expectedTrxBatchExecs += tcase.expectedNonCommitBatches + if tcase.expectedInLastBatch != "" { // We expect the trx to be split + require.Regexpf(t, regexp.MustCompile(fmt.Sprintf(trxLastBatchExpectRE, regexp.QuoteMeta(tcase.expectedInLastBatch))), lastMultiExecQuery, "Unexpected batch statement: %s", lastMultiExecQuery) + } else { + require.Regexpf(t, regexp.MustCompile(fmt.Sprintf(trxFullBatchExpectRE, regexp.QuoteMeta(strings.Join(tcase.output, ";")))), lastMultiExecQuery, "Unexpected batch statement: %s", lastMultiExecQuery) + } + require.Equal(t, expectedBulkInserts, stats.BulkQueryCount.Counts()["insert"], "expected %d bulk inserts but got %d", expectedBulkInserts, stats.BulkQueryCount.Counts()["insert"]) + require.Equal(t, expectedBulkDeletes, stats.BulkQueryCount.Counts()["delete"], "expected %d bulk deletes but got %d", expectedBulkDeletes, stats.BulkQueryCount.Counts()["delete"]) + require.Equal(t, expectedTrxBatchExecs, stats.TrxQueryBatchCount.Counts()["without_commit"], "expected %d trx batch execs but got %d", expectedTrxBatchExecs, stats.TrxQueryBatchCount.Counts()["without_commit"]) + require.Equal(t, expectedTrxBatchCommits, stats.TrxQueryBatchCount.Counts()["with_commit"], "expected %d trx batch commits but got %d", expectedTrxBatchCommits, stats.TrxQueryBatchCount.Counts()["with_commit"]) + }) + } +} + func expectJSON(t *testing.T, table string, values [][]string, id int, exec func(ctx context.Context, query string) (*sqltypes.Result, error)) { t.Helper() diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index 2a362645708..9c065866c15 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -28,22 +28,20 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/mysql/sqlerror" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/timer" + "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" - querypb "vitess.io/vitess/go/vt/proto/query" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/binlog/binlogplayer" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/mysqlctl" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) var ( diff --git a/go/vt/wrangler/fake_dbclient_test.go b/go/vt/wrangler/fake_dbclient_test.go index 7bcc5f5bcf2..03fad81d7b8 100644 --- a/go/vt/wrangler/fake_dbclient_test.go +++ b/go/vt/wrangler/fake_dbclient_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/assert" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/sqltypes" ) @@ -160,6 +161,22 @@ func (dc *fakeDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Resul return qr, err } +func (dc *fakeDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltypes.Result, error) { + queries, err := sqlparser.SplitStatementToPieces(query) + if err != nil { + return nil, err + } + results := make([]*sqltypes.Result, 0, len(queries)) + for _, query := range queries { + qr, err := dc.executeFetch(query, maxrows) + if err != nil { + return nil, err + } + results = append(results, qr) + } + return results, nil +} + // ExecuteFetch is part of the DBClient interface func (dc *fakeDBClient) executeFetch(query string, maxrows int) (*sqltypes.Result, error) { if dbrs := dc.queries[query]; dbrs != nil { From 529f300def87fa07e2f10a203a0048a0aafb2267 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Thu, 7 Dec 2023 01:04:24 -0500 Subject: [PATCH 093/119] go/vt/vtctl: fix nilness issues and error scopes (#14711) --- go/vt/vtctl/grpcvtctldserver/server.go | 10 +++------- go/vt/vtctl/workflow/server.go | 10 ++++------ go/vt/vtctl/workflow/traffic_switcher.go | 3 --- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 2ece69876e8..8ec786322da 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -4992,9 +4992,7 @@ func (s *VtctldServer) getTopologyCell(ctx context.Context, cellPath string) (*v return nil, err } - data, _, dataErr := conn.Get(ctx, relativePath) - - if dataErr == nil { + if data, _, err := conn.Get(ctx, relativePath); err == nil { result, err := topo.DecodeContent(relativePath, data, false) if err != nil { err := vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "error decoding file content for cell %s: %v", cellPath, err) @@ -5006,15 +5004,13 @@ func (s *VtctldServer) getTopologyCell(ctx context.Context, cellPath string) (*v return &topoCell, nil } - children, childrenErr := conn.ListDir(ctx, relativePath, false /*full*/) - - if childrenErr != nil && dataErr != nil { + children, err := conn.ListDir(ctx, relativePath, false /*full*/) + if err != nil { err := vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cell %s with path %s has no file contents and no children: %v", cell, cellPath, err) return nil, err } topoCell.Children = make([]string, len(children)) - for i, c := range children { topoCell.Children[i] = c.Name } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 95f1ecd42d4..ec39efa875b 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -1442,13 +1442,11 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl return nil, err } } - if vschema != nil { - // We added to the vschema. - if err := s.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { - return nil, err - } - } + // We added to the vschema. + if err := s.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { + return nil, err + } } if err := s.ts.RebuildSrvVSchema(ctx, nil); err != nil { return nil, err diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index 35f1d1b966b..9999d46cdcc 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -380,9 +380,6 @@ func (ts *trafficSwitcher) addParticipatingTablesToKeyspace(ctx context.Context, if err := json2.Unmarshal([]byte(wrap), ks); err != nil { return err } - if err != nil { - return err - } for table, vtab := range ks.Tables { vschema.Tables[table] = vtab } From 7fc6a9a67421c976b575f16020d3a76cbf38575a Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Thu, 7 Dec 2023 01:05:03 -0500 Subject: [PATCH 094/119] go/vt/wrangler: fix nilness issues and unused variable (#14710) --- go/vt/wrangler/materializer.go | 10 ++++------ go/vt/wrangler/traffic_switcher.go | 3 --- go/vt/wrangler/vexec.go | 7 ++----- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/go/vt/wrangler/materializer.go b/go/vt/wrangler/materializer.go index 01a3a640fb8..13f430919fd 100644 --- a/go/vt/wrangler/materializer.go +++ b/go/vt/wrangler/materializer.go @@ -318,13 +318,11 @@ func (wr *Wrangler) MoveTables(ctx context.Context, workflow, sourceKeyspace, ta return err } } - if vschema != nil { - // We added to the vschema. - if err := wr.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { - return err - } - } + // We added to the vschema. + if err := wr.ts.SaveVSchema(ctx, targetKeyspace, vschema); err != nil { + return err + } } if err := wr.ts.RebuildSrvVSchema(ctx, nil); err != nil { return err diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index e7700e08079..498e83a2a3a 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -1920,9 +1920,6 @@ func (ts *trafficSwitcher) addParticipatingTablesToKeyspace(ctx context.Context, if err := json2.Unmarshal([]byte(wrap), ks); err != nil { return err } - if err != nil { - return err - } for table, vtab := range ks.Tables { vschema.Tables[table] = vtab } diff --git a/go/vt/wrangler/vexec.go b/go/vt/wrangler/vexec.go index 7cad9a5f318..c705ad3f6f1 100644 --- a/go/vt/wrangler/vexec.go +++ b/go/vt/wrangler/vexec.go @@ -661,9 +661,6 @@ func (wr *Wrangler) getReplicationStatusFromRow(ctx context.Context, row sqltype workflowSubType, _ = row.ToInt32("workflow_sub_type") deferSecondaryKeys, _ = row.ToBool("defer_secondary_keys") rowsCopied = row.AsInt64("rows_copied", 0) - if err != nil { - return nil, "", err - } status := &ReplicationStatus{ Shard: primary.Shard, @@ -701,8 +698,8 @@ func (wr *Wrangler) getStreams(ctx context.Context, workflow, keyspace string) ( var rsr ReplicationStatusResult rsr.ShardStatuses = make(map[string]*ShardReplicationStatus) rsr.Workflow = workflow - var results map[*topo.TabletInfo]*querypb.QueryResult - query := `select + + const query = `select id, source, pos, From 6e5bd6e899dc140bec37e92aea7a5538cb6c5154 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Thu, 7 Dec 2023 10:58:34 -0500 Subject: [PATCH 095/119] go/vt/topo: fix nilness issues and unused variables (#14709) --- go/vt/topo/srv_keyspace.go | 14 ++++++-------- go/vt/topo/tablet.go | 19 +++++++++---------- go/vt/topo/test/trylock.go | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/go/vt/topo/srv_keyspace.go b/go/vt/topo/srv_keyspace.go index 8054764eeff..11e49f3c569 100644 --- a/go/vt/topo/srv_keyspace.go +++ b/go/vt/topo/srv_keyspace.go @@ -137,7 +137,7 @@ func (ts *Server) GetShardServingCells(ctx context.Context, si *ShardInfo) (serv var mu sync.Mutex for _, cell := range cells { wg.Add(1) - go func(cell, keyspace string) { + go func(cell string) { defer wg.Done() srvKeyspace, err := ts.GetSrvKeyspace(ctx, cell, si.keyspace) switch { @@ -166,7 +166,7 @@ func (ts *Server) GetShardServingCells(ctx context.Context, si *ShardInfo) (serv rec.RecordError(err) return } - }(cell, si.Keyspace()) + }(cell) } wg.Wait() if rec.HasErrors() { @@ -188,7 +188,7 @@ func (ts *Server) GetShardServingTypes(ctx context.Context, si *ShardInfo) (serv var mu sync.Mutex for _, cell := range cells { wg.Add(1) - go func(cell, keyspace string) { + go func(cell string) { defer wg.Done() srvKeyspace, err := ts.GetSrvKeyspace(ctx, cell, si.keyspace) switch { @@ -223,7 +223,7 @@ func (ts *Server) GetShardServingTypes(ctx context.Context, si *ShardInfo) (serv rec.RecordError(err) return } - }(cell, si.Keyspace()) + }(cell) } wg.Wait() if rec.HasErrors() { @@ -613,10 +613,8 @@ func (ts *Server) MigrateServedType(ctx context.Context, keyspace string, shards case IsErrType(err, NoNode): // Assuming this cell is not active, nothing to do. default: - if err != nil { - rec.RecordError(err) - return - } + rec.RecordError(err) + return } }(cell, keyspace) } diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index d17235f6948..5254252db1c 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -443,21 +443,20 @@ func (ts *Server) CreateTablet(ctx context.Context, tablet *topodatapb.Tablet) e return err } tabletPath := path.Join(TabletsPath, topoproto.TabletAliasString(tablet.Alias), TabletFile) - if _, err = conn.Create(ctx, tabletPath, data); err != nil { + if _, err := conn.Create(ctx, tabletPath, data); err != nil { return err } - if updateErr := UpdateTabletReplicationData(ctx, ts, tablet); updateErr != nil { - return updateErr + if err := UpdateTabletReplicationData(ctx, ts, tablet); err != nil { + return err } - if err == nil { - event.Dispatch(&events.TabletChange{ - Tablet: tablet, - Status: "created", - }) - } - return err + event.Dispatch(&events.TabletChange{ + Tablet: tablet, + Status: "created", + }) + + return nil } // DeleteTablet wraps the underlying conn.Delete diff --git a/go/vt/topo/test/trylock.go b/go/vt/topo/test/trylock.go index 4519d1bcaab..c553e74bb61 100644 --- a/go/vt/topo/test/trylock.go +++ b/go/vt/topo/test/trylock.go @@ -138,7 +138,7 @@ func checkTryLockTimeout(ctx context.Context, t *testing.T, conn topo.Conn) { // test we can't unlock again if err := lockDescriptor.Unlock(ctx); err == nil { - require.Fail(t, "Unlock failed", err.Error()) + require.Fail(t, "Unlock succeeded but should not have") } } From 26c557ecd0a4d7da0bdbfda0d118141545bce8b9 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:21:11 +0530 Subject: [PATCH 096/119] Fix RegisterNotifier to use a copy of the tables to prevent data races (#14716) Signed-off-by: Manan Gupta --- go/vt/vttablet/tabletserver/schema/engine.go | 14 ++++------- .../tabletserver/schema/engine_test.go | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index ae50b460a96..f328972ca2e 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -21,6 +21,7 @@ import ( "context" "encoding/json" "fmt" + "maps" "net/http" "strings" "sync" @@ -706,7 +707,8 @@ func (se *Engine) RegisterNotifier(name string, f notifier, runNotifier bool) { created = append(created, table) } if runNotifier { - f(se.tables, created, nil, nil) + s := maps.Clone(se.tables) + f(s, created, nil, nil) } } @@ -734,10 +736,7 @@ func (se *Engine) broadcast(created, altered, dropped []*Table) { se.notifierMu.Lock() defer se.notifierMu.Unlock() - s := make(map[string]*Table, len(se.tables)) - for k, v := range se.tables { - s[k] = v - } + s := maps.Clone(se.tables) for _, f := range se.notifiers { f(s, created, altered, dropped) } @@ -755,10 +754,7 @@ func (se *Engine) GetTable(tableName sqlparser.IdentifierCS) *Table { func (se *Engine) GetSchema() map[string]*Table { se.mu.Lock() defer se.mu.Unlock() - tables := make(map[string]*Table, len(se.tables)) - for k, v := range se.tables { - tables[k] = v - } + tables := maps.Clone(se.tables) return tables } diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index 9d55f654d4e..408d0a35841 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -705,6 +705,29 @@ func AddFakeInnoDBReadRowsResult(db *fakesqldb.DB, value int) *fakesqldb.Expecte )) } +// TestRegisterNotifier tests the functionality of RegisterNotifier +// It also makes sure that writing to the tables map in the schema engine doesn't change the tables received by the notifiers. +func TestRegisterNotifier(t *testing.T) { + // Create a new engine for testing + se := NewEngineForTests() + se.notifiers = map[string]notifier{} + se.tables = map[string]*Table{ + "t1": nil, + "t2": nil, + "t3": nil, + } + + var tablesReceived map[string]*Table + // Register a notifier and make it run immediately. + se.RegisterNotifier("TestRegisterNotifier", func(full map[string]*Table, created, altered, dropped []*Table) { + tablesReceived = full + }, true) + + // Change the se.tables and make sure it doesn't affect the tables received by the notifier. + se.tables["t4"] = nil + require.Len(t, tablesReceived, 3) +} + // TestEngineMysqlTime tests the functionality of Engine.mysqlTime function func TestEngineMysqlTime(t *testing.T) { tests := []struct { From c02f941e5e1bea24574430effe0d27f7e196346f Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 7 Dec 2023 13:35:42 -0500 Subject: [PATCH 097/119] Reduce flakiness in TestShardReplicationPositions (#14708) Signed-off-by: Andrew Mason --- go/vt/vtctl/grpcvtctldserver/server_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index c04114d46cd..60f29221a3c 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -10837,7 +10837,7 @@ func TestShardReplicationPositions(t *testing.T) { }, tmc: &testutil.TabletManagerClient{ PrimaryPositionDelays: map[string]time.Duration{ - "zone1-0000000100": time.Millisecond * 100, + "zone1-0000000100": time.Second * 2, }, PrimaryPositionResults: map[string]struct { Position string @@ -10848,7 +10848,7 @@ func TestShardReplicationPositions(t *testing.T) { }, }, ReplicationStatusDelays: map[string]time.Duration{ - "zone1-0000000101": time.Millisecond * 100, + "zone1-0000000101": time.Second * 2, }, ReplicationStatusResults: map[string]struct { Position *replicationdatapb.Status @@ -10861,7 +10861,7 @@ func TestShardReplicationPositions(t *testing.T) { }, }, }, - ctxTimeout: time.Millisecond * 10, + ctxTimeout: time.Second, req: &vtctldatapb.ShardReplicationPositionsRequest{ Keyspace: "testkeyspace", Shard: "-", From 093d723d1d757ff37a100d3250434b7365af272d Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 7 Dec 2023 19:42:04 +0100 Subject: [PATCH 098/119] Flaky TestFKExtWorkflow: fix Foreign Key stress test flakiness (#14714) --- go/test/endtoend/vreplication/fk_ext_test.go | 34 ++++++++++++-------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/go/test/endtoend/vreplication/fk_ext_test.go b/go/test/endtoend/vreplication/fk_ext_test.go index 665f8052486..a06fafb257e 100644 --- a/go/test/endtoend/vreplication/fk_ext_test.go +++ b/go/test/endtoend/vreplication/fk_ext_test.go @@ -194,17 +194,8 @@ func TestFKExt(t *testing.T) { } -// compareRowCounts compares the row counts for the parent and child tables in the source and target shards. In addition to vdiffs, -// it is another check to ensure that both tables have the same number of rows in the source and target shards after load generation -// has stopped. -func compareRowCounts(t *testing.T, keyspace string, sourceShards, targetShards []string) error { - log.Infof("Comparing row counts for keyspace %s, source shards: %v, target shards: %v", keyspace, sourceShards, targetShards) - lg.Stop() - defer lg.Start() - if err := waitForCondition("load generator to stop", func() bool { return lg.State() == LoadGeneratorStateStopped }, 10*time.Second); err != nil { - return err - } - +// checkRowCounts checks that the parent and child tables in the source and target shards have the same number of rows. +func checkRowCounts(t *testing.T, keyspace string, sourceShards, targetShards []string) bool { sourceTabs := make(map[string]*cluster.VttabletProcess) targetTabs := make(map[string]*cluster.VttabletProcess) for _, shard := range sourceShards { @@ -239,9 +230,26 @@ func compareRowCounts(t *testing.T, keyspace string, sourceShards, targetShards log.Infof("Source parent count: %d, child count: %d, target parent count: %d, child count: %d.", sourceParentCount, sourceChildCount, targetParentCount, targetChildCount) if sourceParentCount != targetParentCount || sourceChildCount != targetChildCount { - return fmt.Errorf(fmt.Sprintf("source and target row counts do not match; source parent count: %d, target parent count: %d, source child count: %d, target child count: %d", - sourceParentCount, targetParentCount, sourceChildCount, targetChildCount)) + log.Infof("Row counts do not match for keyspace %s, source shards: %v, target shards: %v", keyspace, sourceShards, targetShards) + return false + } + return true +} + +// compareRowCounts compares the row counts for the parent and child tables in the source and target shards. In addition to vdiffs, +// it is another check to ensure that both tables have the same number of rows in the source and target shards after load generation +// has stopped. +func compareRowCounts(t *testing.T, keyspace string, sourceShards, targetShards []string) error { + log.Infof("Comparing row counts for keyspace %s, source shards: %v, target shards: %v", keyspace, sourceShards, targetShards) + lg.Stop() + defer lg.Start() + if err := waitForCondition("load generator to stop", func() bool { return lg.State() == LoadGeneratorStateStopped }, 10*time.Second); err != nil { + return err } + if err := waitForCondition("matching row counts", func() bool { return checkRowCounts(t, keyspace, sourceShards, targetShards) }, 30*time.Second); err != nil { + return err + } + return nil } From 9172bb3da1e656b82670d3cf0a40d02a293bc029 Mon Sep 17 00:00:00 2001 From: Iheanyi Ekechukwu Date: Thu, 7 Dec 2023 14:49:24 -0600 Subject: [PATCH 099/119] Fix typo for `--cells` flag help description in `ApplyRoutingRules` (#14721) Signed-off-by: Iheanyi Ekechukwu --- go/cmd/vtctldclient/command/routing_rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/vtctldclient/command/routing_rules.go b/go/cmd/vtctldclient/command/routing_rules.go index 5f16ad7ab07..0ffee0c2c24 100644 --- a/go/cmd/vtctldclient/command/routing_rules.go +++ b/go/cmd/vtctldclient/command/routing_rules.go @@ -148,7 +148,7 @@ func commandGetRoutingRules(cmd *cobra.Command, args []string) error { func init() { ApplyRoutingRules.Flags().StringVarP(&applyRoutingRulesOptions.Rules, "rules", "r", "", "Routing rules, specified as a string.") ApplyRoutingRules.Flags().StringVarP(&applyRoutingRulesOptions.RulesFilePath, "rules-file", "f", "", "Path to a file containing routing rules specified as JSON.") - ApplyRoutingRules.Flags().StringSliceVarP(&applyRoutingRulesOptions.Cells, "cells", "c", nil, "Limit the VSchema graph rebuildingg to the specified cells. Ignored if --skip-rebuild is specified.") + ApplyRoutingRules.Flags().StringSliceVarP(&applyRoutingRulesOptions.Cells, "cells", "c", nil, "Limit the VSchema graph rebuilding to the specified cells. Ignored if --skip-rebuild is specified.") ApplyRoutingRules.Flags().BoolVar(&applyRoutingRulesOptions.SkipRebuild, "skip-rebuild", false, "Skip rebuilding the SrvVSchema objects.") ApplyRoutingRules.Flags().BoolVarP(&applyRoutingRulesOptions.DryRun, "dry-run", "d", false, "Load the specified routing rules as a validation step, but do not actually apply the rules to the topo.") Root.AddCommand(ApplyRoutingRules) From f27a5742f5846aa167fa3df70b2f6294082209b1 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Thu, 7 Dec 2023 21:16:06 -0600 Subject: [PATCH 100/119] Add step to static check to ensure consistency of GHA workflows (#14724) --- .github/workflows/static_checks_etc.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index a2cd18996a7..2285895b0db 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -97,6 +97,10 @@ jobs: - 'changelog/**' - './go/tools/releases/**' - '.github/workflows/static_checks_etc.yml' + workflows: + - '.github/**' + - 'Makefile' + - 'test/ci_workflow_gen.go' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true') @@ -214,3 +218,18 @@ jobs: echo "$output" echo "" exit 1 + + - name: Check make generate_ci_workflows + if: steps.skip-workflow.outputs.skip-workflow == 'false' + run: | + set -e + make generate_ci_workflows + output=$(git status -s) + if [ -z "${output}" ]; then + exit 0 + fi + echo 'Please run `make generate_ci_workflows`, commit and push again.' + echo 'Running `make generate_ci_workflows` on CI yields the following changes:' + echo "$output" + echo "" + exit 1 From d3750cd13750be66e6cad7ca852552303b5384c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicent=20Mart=C3=AD?= <42793+vmg@users.noreply.github.com> Date: Fri, 8 Dec 2023 13:13:52 +0100 Subject: [PATCH 101/119] connpool: fix racy test (#14731) Signed-off-by: Vicent Marti --- go/pools/smartconnpool/pool_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index c9c2235d90f..9a9fb9500b6 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -149,7 +149,7 @@ func TestOpen(t *testing.T) { } // Test that Get waits - ch := make(chan bool) + done := make(chan struct{}) go func() { for i := 0; i < 5; i++ { if i%2 == 0 { @@ -163,14 +163,16 @@ func TestOpen(t *testing.T) { for i := 0; i < 5; i++ { p.put(resources[i]) } - ch <- true + close(done) }() for i := 0; i < 5; i++ { - // Sleep to ensure the goroutine waits - time.Sleep(10 * time.Millisecond) + // block until we have a client wait for a connection, then offer it + for p.wait.waiting() == 0 { + time.Sleep(time.Millisecond) + } p.put(resources[i]) } - <-ch + <-done assert.EqualValues(t, 5, p.Metrics.WaitCount()) assert.Equal(t, 5, len(state.waits)) // verify start times are monotonic increasing From 5c2f6b3afd3a27d60b1c6dae6aa75e573410cb2d Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Fri, 8 Dec 2023 17:04:04 +0100 Subject: [PATCH 102/119] build: Allow compilation on Windows (#14718) Signed-off-by: Dirkjan Bussink --- go.mod | 10 +-- go.sum | 20 ++--- go/cmd/vtctl/vtctl.go | 7 +- go/cmd/vtctl/vtctl_unix.go | 33 +++++++ go/cmd/vtctl/vtctl_windows.go | 27 ++++++ go/cmd/vttablet/cli/plugin_sysloglogger.go | 2 + go/event/syslogger/syslogger.go | 2 + go/event/syslogger/syslogger_test.go | 2 + go/mysql/conn.go | 39 --------- go/mysql/conn_unix.go | 65 ++++++++++++++ go/mysql/conn_windows.go | 24 +++++ go/streamlog/streamlog.go | 4 +- go/streamlog/streamlog_unix.go | 29 +++++++ go/streamlog/streamlog_windows.go | 29 +++++++ go/syscallutil/kill_unix.go | 27 ++++++ go/syscallutil/kill_windows.go | 28 ++++++ go/test/endtoend/cluster/cluster_process.go | 3 +- go/test/endtoend/cluster/mysqlctl_process.go | 5 +- go/test/endtoend/cluster/vttablet_process.go | 5 -- .../endtoend/cluster/vttablet_process_unix.go | 26 ++++++ .../cluster/vttablet_process_windows.go | 28 ++++++ go/test/endtoend/filelock/filelock.go | 20 +---- go/test/endtoend/filelock/filelock_unix.go | 6 +- go/test/endtoend/filelock/filelock_windows.go | 26 ++++++ go/vt/servenv/pprof.go | 41 --------- go/vt/servenv/pprof_unix.go | 66 ++++++++++++++ go/vt/servenv/pprof_windows.go | 27 ++++++ go/vt/servenv/servenv.go | 60 ------------- go/vt/servenv/servenv_unix.go | 87 +++++++++++++++++++ go/vt/servenv/servenv_windows.go | 21 +++++ go/vt/topo/events/keyspace_change_syslog.go | 2 + .../events/keyspace_change_syslog_test.go | 2 + go/vt/topo/events/shard_change_syslog.go | 2 + go/vt/topo/events/shard_change_syslog_test.go | 2 + go/vt/topo/events/tablet_change_syslog.go | 2 + .../topo/events/tablet_change_syslog_test.go | 2 + go/vt/topotools/events/reparent_syslog.go | 2 + .../topotools/events/reparent_syslog_test.go | 2 + go/vt/vtgate/plugin_mysql_server.go | 9 +- go/vt/vtgate/plugin_mysql_server_unix.go | 40 +++++++++ go/vt/vtgate/plugin_mysql_server_windows.go | 29 +++++++ go/vt/vtorc/inst/audit_dao.go | 21 +---- go/vt/vtorc/inst/audit_dao_nosyslog.go | 32 +++++++ go/vt/vtorc/inst/audit_dao_syslog.go | 43 +++++++++ go/vt/vttablet/onlineddl/executor.go | 5 +- go/vt/vttablet/sysloglogger/sysloglogger.go | 2 + .../sysloglogger/sysloglogger_test.go | 2 + go/vt/zkctl/zkctl.go | 5 +- 48 files changed, 748 insertions(+), 225 deletions(-) create mode 100644 go/cmd/vtctl/vtctl_unix.go create mode 100644 go/cmd/vtctl/vtctl_windows.go create mode 100644 go/mysql/conn_unix.go create mode 100644 go/mysql/conn_windows.go create mode 100644 go/streamlog/streamlog_unix.go create mode 100644 go/streamlog/streamlog_windows.go create mode 100644 go/syscallutil/kill_unix.go create mode 100644 go/syscallutil/kill_windows.go create mode 100644 go/test/endtoend/cluster/vttablet_process_unix.go create mode 100644 go/test/endtoend/cluster/vttablet_process_windows.go create mode 100644 go/test/endtoend/filelock/filelock_windows.go create mode 100644 go/vt/servenv/pprof_unix.go create mode 100644 go/vt/servenv/pprof_windows.go create mode 100644 go/vt/servenv/servenv_unix.go create mode 100644 go/vt/servenv/servenv_windows.go create mode 100644 go/vt/vtgate/plugin_mysql_server_unix.go create mode 100644 go/vt/vtgate/plugin_mysql_server_windows.go create mode 100644 go/vt/vtorc/inst/audit_dao_nosyslog.go create mode 100644 go/vt/vtorc/inst/audit_dao_syslog.go diff --git a/go.mod b/go.mod index 7a396338352..af1ae0a7488 100644 --- a/go.mod +++ b/go.mod @@ -71,12 +71,12 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.8 go.etcd.io/etcd/client/v3 v3.5.8 go.uber.org/mock v0.2.0 - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.16.0 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 + golang.org/x/net v0.19.0 golang.org/x/oauth2 v0.11.0 - golang.org/x/sys v0.14.0 - golang.org/x/term v0.13.0 + golang.org/x/sys v0.15.0 + golang.org/x/term v0.15.0 golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 @@ -149,7 +149,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-ieproxy v0.0.10 // indirect + github.com/mattn/go-ieproxy v0.0.11 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect diff --git a/go.sum b/go.sum index 395f8439090..1df92514455 100644 --- a/go.sum +++ b/go.sum @@ -406,8 +406,8 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= -github.com/mattn/go-ieproxy v0.0.10 h1:P+2QihaKCLgbs/32dhFLbxXlqsy8tIG1LUXHIoPaQPo= -github.com/mattn/go-ieproxy v0.0.10/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0= +github.com/mattn/go-ieproxy v0.0.11 h1:MQ/5BuGSgDAHZOJe6YY80IF2UVCfGkwfo6AeD7HtHYo= +github.com/mattn/go-ieproxy v0.0.11/go.mod h1:/NsJd+kxZBmjMc5hrJCKMbP57B84rvq9BiDRbtO9AS0= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -663,8 +663,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -756,8 +756,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -854,14 +854,14 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/go/cmd/vtctl/vtctl.go b/go/cmd/vtctl/vtctl.go index 175e49c6831..e95f484cf4f 100644 --- a/go/cmd/vtctl/vtctl.go +++ b/go/cmd/vtctl/vtctl.go @@ -19,7 +19,6 @@ package main import ( "context" "fmt" - "log/syslog" "os" "os/signal" "strings" @@ -118,11 +117,7 @@ func main() { startMsg := fmt.Sprintf("USER=%v SUDO_USER=%v %v", os.Getenv("USER"), os.Getenv("SUDO_USER"), strings.Join(os.Args, " ")) - if syslogger, err := syslog.New(syslog.LOG_INFO, "vtctl "); err == nil { - syslogger.Info(startMsg) // nolint:errcheck - } else { - log.Warningf("cannot connect to syslog: %v", err) - } + logSyslog(startMsg) closer := trace.StartTracing("vtctl") defer trace.LogErrorsWhenClosing(closer) diff --git a/go/cmd/vtctl/vtctl_unix.go b/go/cmd/vtctl/vtctl_unix.go new file mode 100644 index 00000000000..bee0be238d7 --- /dev/null +++ b/go/cmd/vtctl/vtctl_unix.go @@ -0,0 +1,33 @@ +//go:build !windows + +/* +Copyright 2023 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 + +import ( + "log/syslog" + + "vitess.io/vitess/go/vt/log" +) + +func logSyslog(msg string) { + if syslogger, err := syslog.New(syslog.LOG_INFO, "vtctl "); err == nil { + syslogger.Info(msg) // nolint:errcheck + } else { + log.Warningf("cannot connect to syslog: %v", err) + } +} diff --git a/go/cmd/vtctl/vtctl_windows.go b/go/cmd/vtctl/vtctl_windows.go new file mode 100644 index 00000000000..63c5cceb63b --- /dev/null +++ b/go/cmd/vtctl/vtctl_windows.go @@ -0,0 +1,27 @@ +//go:build windows + +/* +Copyright 2023 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 + +import ( + "vitess.io/vitess/go/vt/log" +) + +func logSyslog(msg string) { + log.Warningf("windows does not have syslog support") +} diff --git a/go/cmd/vttablet/cli/plugin_sysloglogger.go b/go/cmd/vttablet/cli/plugin_sysloglogger.go index 303bf014d83..90860abe826 100644 --- a/go/cmd/vttablet/cli/plugin_sysloglogger.go +++ b/go/cmd/vttablet/cli/plugin_sysloglogger.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/event/syslogger/syslogger.go b/go/event/syslogger/syslogger.go index 1c8ff22136b..eef3257e518 100644 --- a/go/event/syslogger/syslogger.go +++ b/go/event/syslogger/syslogger.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/event/syslogger/syslogger_test.go b/go/event/syslogger/syslogger_test.go index fddeef12b27..8217b945baa 100644 --- a/go/event/syslogger/syslogger_test.go +++ b/go/event/syslogger/syslogger_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 9cac35ea01f..1908875db49 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -28,7 +28,6 @@ import ( "strings" "sync" "sync/atomic" - "syscall" "time" "vitess.io/vitess/go/bucketpool" @@ -1699,41 +1698,3 @@ func (c *Conn) IsMarkedForClose() bool { func (c *Conn) IsShuttingDown() bool { return c.listener.shutdown.Load() } - -// ConnCheck ensures that this connection to the MySQL server hasn't been broken. -// This is a fast, non-blocking check. For details on its implementation, please read -// "Three Bugs in the Go MySQL Driver" (Vicent Marti, GitHub, 2020) -// https://github.blog/2020-05-20-three-bugs-in-the-go-mysql-driver/ -func (c *Conn) ConnCheck() error { - conn := c.conn - if tlsconn, ok := conn.(*tls.Conn); ok { - conn = tlsconn.NetConn() - } - if conn, ok := conn.(syscall.Conn); ok { - rc, err := conn.SyscallConn() - if err != nil { - return err - } - - var n int - var buff [1]byte - rerr := rc.Read(func(fd uintptr) bool { - n, err = syscall.Read(int(fd), buff[:]) - return true - }) - - switch { - case rerr != nil: - return rerr - case n == 0 && err == nil: - return io.EOF - case n > 0: - return sqlerror.NewSQLError(sqlerror.CRUnknownError, sqlerror.SSUnknownSQLState, "unexpected read from conn") - case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: - return nil - default: - return err - } - } - return nil -} diff --git a/go/mysql/conn_unix.go b/go/mysql/conn_unix.go new file mode 100644 index 00000000000..54e883efcd9 --- /dev/null +++ b/go/mysql/conn_unix.go @@ -0,0 +1,65 @@ +//go:build !windows + +/* +Copyright 2023 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 ( + "crypto/tls" + "io" + "syscall" + + "vitess.io/vitess/go/mysql/sqlerror" +) + +// ConnCheck ensures that this connection to the MySQL server hasn't been broken. +// This is a fast, non-blocking check. For details on its implementation, please read +// "Three Bugs in the Go MySQL Driver" (Vicent Marti, GitHub, 2020) +// https://github.blog/2020-05-20-three-bugs-in-the-go-mysql-driver/ +func (c *Conn) ConnCheck() error { + conn := c.conn + if tlsconn, ok := conn.(*tls.Conn); ok { + conn = tlsconn.NetConn() + } + if conn, ok := conn.(syscall.Conn); ok { + rc, err := conn.SyscallConn() + if err != nil { + return err + } + + var n int + var buff [1]byte + rerr := rc.Read(func(fd uintptr) bool { + n, err = syscall.Read(int(fd), buff[:]) + return true + }) + + switch { + case rerr != nil: + return rerr + case n == 0 && err == nil: + return io.EOF + case n > 0: + return sqlerror.NewSQLError(sqlerror.CRUnknownError, sqlerror.SSUnknownSQLState, "unexpected read from conn") + case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: + return nil + default: + return err + } + } + return nil +} diff --git a/go/mysql/conn_windows.go b/go/mysql/conn_windows.go new file mode 100644 index 00000000000..695c5703cdb --- /dev/null +++ b/go/mysql/conn_windows.go @@ -0,0 +1,24 @@ +//go:build windows + +/* +Copyright 2023 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 + +// ConnCheck is not implemented for Windows. +func (c *Conn) ConnCheck() error { + return nil +} diff --git a/go/streamlog/streamlog.go b/go/streamlog/streamlog.go index 26248fcd1b1..25e60182c4a 100644 --- a/go/streamlog/streamlog.go +++ b/go/streamlog/streamlog.go @@ -23,10 +23,8 @@ import ( "net/http" "net/url" "os" - "os/signal" "strings" "sync" - "syscall" "github.com/spf13/pflag" @@ -215,7 +213,7 @@ func (logger *StreamLogger[T]) ServeLogs(url string, logf LogFormatter) { // it. func (logger *StreamLogger[T]) LogToFile(path string, logf LogFormatter) (chan T, error) { rotateChan := make(chan os.Signal, 1) - signal.Notify(rotateChan, syscall.SIGUSR2) + setupRotate(rotateChan) logChan := logger.Subscribe("FileLog") formatParams := map[string][]string{"full": {}} diff --git a/go/streamlog/streamlog_unix.go b/go/streamlog/streamlog_unix.go new file mode 100644 index 00000000000..0cfa4b9e6bc --- /dev/null +++ b/go/streamlog/streamlog_unix.go @@ -0,0 +1,29 @@ +//go:build !windows + +/* +Copyright 2023 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 streamlog + +import ( + "os" + "os/signal" + "syscall" +) + +func setupRotate(ch chan os.Signal) { + signal.Notify(ch, syscall.SIGUSR2) +} diff --git a/go/streamlog/streamlog_windows.go b/go/streamlog/streamlog_windows.go new file mode 100644 index 00000000000..ef69058b97c --- /dev/null +++ b/go/streamlog/streamlog_windows.go @@ -0,0 +1,29 @@ +//go:build windows + +/* +Copyright 2023 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 streamlog + +import ( + "os" + + "vitess.io/vitess/go/vt/log" +) + +func setupRotate(ch chan os.Signal) { + log.Warningf("signal based log rotation is not supported on Windows") +} diff --git a/go/syscallutil/kill_unix.go b/go/syscallutil/kill_unix.go new file mode 100644 index 00000000000..d0b1776ae3c --- /dev/null +++ b/go/syscallutil/kill_unix.go @@ -0,0 +1,27 @@ +//go:build !windows + +/* +Copyright 2023 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 syscallutil + +import ( + "syscall" +) + +func Kill(pid int, signum syscall.Signal) (err error) { + return syscall.Kill(pid, signum) +} diff --git a/go/syscallutil/kill_windows.go b/go/syscallutil/kill_windows.go new file mode 100644 index 00000000000..091fcdf759d --- /dev/null +++ b/go/syscallutil/kill_windows.go @@ -0,0 +1,28 @@ +//go:build windows + +/* +Copyright 2023 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 syscallutil + +import ( + "errors" + "syscall" +) + +func Kill(pid int, signum syscall.Signal) (err error) { + return errors.New("kill is not supported on windows") +} diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index 28a8807cf08..3a1390eec0c 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -41,6 +41,7 @@ import ( "vitess.io/vitess/go/json2" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/syscallutil" "vitess.io/vitess/go/test/endtoend/filelock" "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/log" @@ -1091,7 +1092,7 @@ func (cluster *LocalProcessCluster) waitForMySQLProcessToExit(mysqlctlProcessLis log.Errorf("Error in conversion to integer: %v", err) return } - err = syscall.Kill(pid, syscall.SIGKILL) + err = syscallutil.Kill(pid, syscall.SIGKILL) if err != nil { log.Errorf("Error in killing process: %v", err) } diff --git a/go/test/endtoend/cluster/mysqlctl_process.go b/go/test/endtoend/cluster/mysqlctl_process.go index 06808627254..79248b6d9a7 100644 --- a/go/test/endtoend/cluster/mysqlctl_process.go +++ b/go/test/endtoend/cluster/mysqlctl_process.go @@ -30,6 +30,7 @@ import ( "github.com/google/safehtml/template" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/syscallutil" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/tlstest" @@ -215,11 +216,11 @@ func (mysqlctl *MysqlctlProcess) Stop() (err error) { // If we found a valid associated mysqld_safe process then let's kill // it first. if err == nil && mysqldSafePID > 0 { - if err = syscall.Kill(mysqldSafePID, syscall.SIGKILL); err != nil { + if err = syscallutil.Kill(mysqldSafePID, syscall.SIGKILL); err != nil { return err } } - return syscall.Kill(pid, syscall.SIGKILL) + return syscallutil.Kill(pid, syscall.SIGKILL) } // StopProcess executes mysqlctl command to stop mysql instance and returns process reference diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index f51e1838a5b..96bec7c624b 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -556,11 +556,6 @@ func (vttablet *VttabletProcess) getDBSystemValues(placeholder string, value str return "", nil } -// ToggleProfiling enables or disables the configured CPU profiler on this vttablet -func (vttablet *VttabletProcess) ToggleProfiling() error { - return vttablet.proc.Process.Signal(syscall.SIGUSR1) -} - // WaitForVReplicationToCatchup waits for "workflow" to finish copying func (vttablet *VttabletProcess) WaitForVReplicationToCatchup(t testing.TB, workflow, database string, sidecarDBName string, duration time.Duration) { if sidecarDBName == "" { diff --git a/go/test/endtoend/cluster/vttablet_process_unix.go b/go/test/endtoend/cluster/vttablet_process_unix.go new file mode 100644 index 00000000000..3f5c76e9988 --- /dev/null +++ b/go/test/endtoend/cluster/vttablet_process_unix.go @@ -0,0 +1,26 @@ +//go:build !windows + +/* +Copyright 2023 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 cluster + +import "syscall" + +// ToggleProfiling enables or disables the configured CPU profiler on this vttablet +func (vttablet *VttabletProcess) ToggleProfiling() error { + return vttablet.proc.Process.Signal(syscall.SIGUSR1) +} diff --git a/go/test/endtoend/cluster/vttablet_process_windows.go b/go/test/endtoend/cluster/vttablet_process_windows.go new file mode 100644 index 00000000000..6c233746e8a --- /dev/null +++ b/go/test/endtoend/cluster/vttablet_process_windows.go @@ -0,0 +1,28 @@ +//go:build windows + +/* +Copyright 2023 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 cluster + +import ( + "errors" +) + +// ToggleProfiling enables or disables the configured CPU profiler on this vttablet. +func (vttablet *VttabletProcess) ToggleProfiling() error { + return errors.New("not implemented") +} diff --git a/go/test/endtoend/filelock/filelock.go b/go/test/endtoend/filelock/filelock.go index 05f27c321a8..d37331892d1 100644 --- a/go/test/endtoend/filelock/filelock.go +++ b/go/test/endtoend/filelock/filelock.go @@ -10,7 +10,6 @@ package filelock import ( "errors" "io/fs" - "os" ) // A File provides the minimal set of methods required to lock an open file. @@ -78,22 +77,7 @@ func (lt lockType) String() string { // IsNotSupported returns a boolean indicating whether the error is known to // report that a function is not supported (possibly for a specific input). -// It is satisfied by ErrNotSupported as well as some syscall errors. +// It is satisfied by errors.ErrUnsupported as well as some syscall errors. func IsNotSupported(err error) bool { - return isNotSupported(underlyingError(err)) -} - -var ErrNotSupported = errors.New("operation not supported") - -// underlyingError returns the underlying error for known os error types. -func underlyingError(err error) error { - switch err := err.(type) { - case *fs.PathError: - return err.Err - case *os.LinkError: - return err.Err - case *os.SyscallError: - return err.Err - } - return err + return errors.Is(err, errors.ErrUnsupported) } diff --git a/go/test/endtoend/filelock/filelock_unix.go b/go/test/endtoend/filelock/filelock_unix.go index 23064dae0be..6f73b1bfeea 100644 --- a/go/test/endtoend/filelock/filelock_unix.go +++ b/go/test/endtoend/filelock/filelock_unix.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd + package filelock import ( @@ -36,7 +38,3 @@ func lock(f File, lt lockType) (err error) { func unlock(f File) error { return lock(f, syscall.LOCK_UN) } - -func isNotSupported(err error) bool { - return err == syscall.ENOSYS || err == syscall.ENOTSUP || err == syscall.EOPNOTSUPP || err == ErrNotSupported -} diff --git a/go/test/endtoend/filelock/filelock_windows.go b/go/test/endtoend/filelock/filelock_windows.go new file mode 100644 index 00000000000..34df039b96b --- /dev/null +++ b/go/test/endtoend/filelock/filelock_windows.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package filelock + +import ( + "errors" +) + +type lockType uint32 + +const ( + readLock lockType = 0 + writeLock lockType = 1 +) + +func lock(f File, lt lockType) error { + return errors.New("filelock: not implemented on windows") +} + +func unlock(f File) error { + return errors.New("filelock: not implemented on windows") +} diff --git a/go/vt/servenv/pprof.go b/go/vt/servenv/pprof.go index d1d8e99588f..7aff18ca05a 100644 --- a/go/vt/servenv/pprof.go +++ b/go/vt/servenv/pprof.go @@ -20,7 +20,6 @@ import ( "fmt" "io" "os" - "os/signal" "path/filepath" "runtime" "runtime/pprof" @@ -28,7 +27,6 @@ import ( "strconv" "strings" "sync/atomic" - "syscall" "github.com/spf13/pflag" @@ -298,45 +296,6 @@ func (prof *profile) init() (start func(), stop func()) { } } -func pprofInit() { - prof, err := parseProfileFlag(pprofFlag) - if err != nil { - log.Fatal(err) - } - if prof != nil { - start, stop := prof.init() - startSignal := make(chan os.Signal, 1) - stopSignal := make(chan os.Signal, 1) - - if prof.waitSig { - signal.Notify(startSignal, syscall.SIGUSR1) - } else { - start() - signal.Notify(stopSignal, syscall.SIGUSR1) - } - - go func() { - for { - <-startSignal - start() - signal.Reset(syscall.SIGUSR1) - signal.Notify(stopSignal, syscall.SIGUSR1) - } - }() - - go func() { - for { - <-stopSignal - stop() - signal.Reset(syscall.SIGUSR1) - signal.Notify(startSignal, syscall.SIGUSR1) - } - }() - - OnTerm(stop) - } -} - func init() { OnParse(func(fs *pflag.FlagSet) { fs.StringSliceVar(&pprofFlag, "pprof", pprofFlag, "enable profiling") diff --git a/go/vt/servenv/pprof_unix.go b/go/vt/servenv/pprof_unix.go new file mode 100644 index 00000000000..097abc08720 --- /dev/null +++ b/go/vt/servenv/pprof_unix.go @@ -0,0 +1,66 @@ +//go:build !windows + +/* +Copyright 2023 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 servenv + +import ( + "os" + "os/signal" + "syscall" + + "vitess.io/vitess/go/vt/log" +) + +func pprofInit() { + prof, err := parseProfileFlag(pprofFlag) + if err != nil { + log.Fatal(err) + } + if prof != nil { + start, stop := prof.init() + startSignal := make(chan os.Signal, 1) + stopSignal := make(chan os.Signal, 1) + + if prof.waitSig { + signal.Notify(startSignal, syscall.SIGUSR1) + } else { + start() + signal.Notify(stopSignal, syscall.SIGUSR1) + } + + go func() { + for { + <-startSignal + start() + signal.Reset(syscall.SIGUSR1) + signal.Notify(stopSignal, syscall.SIGUSR1) + } + }() + + go func() { + for { + <-stopSignal + stop() + signal.Reset(syscall.SIGUSR1) + signal.Notify(startSignal, syscall.SIGUSR1) + } + }() + + OnTerm(stop) + } +} diff --git a/go/vt/servenv/pprof_windows.go b/go/vt/servenv/pprof_windows.go new file mode 100644 index 00000000000..7ec4be816df --- /dev/null +++ b/go/vt/servenv/pprof_windows.go @@ -0,0 +1,27 @@ +//go:build windows + +/* +Copyright 2023 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 servenv + +import ( + "vitess.io/vitess/go/vt/log" +) + +func pprofInit() { + log.Warningf("pprof is not supported on Windows") +} diff --git a/go/vt/servenv/servenv.go b/go/vt/servenv/servenv.go index e7c28855997..6a7898501f8 100644 --- a/go/vt/servenv/servenv.go +++ b/go/vt/servenv/servenv.go @@ -33,11 +33,8 @@ import ( "fmt" "net/url" "os" - "os/signal" - "runtime/debug" "strings" "sync" - "syscall" "time" "github.com/spf13/cobra" @@ -111,63 +108,6 @@ func GetInitStartTime() time.Time { return initStartTime } -// Init is the first phase of the server startup. -func Init() { - mu.Lock() - defer mu.Unlock() - initStartTime = time.Now() - - // Uptime metric - _ = stats.NewGaugeFunc("Uptime", "Uptime in nanoseconds", func() int64 { - return int64(time.Since(serverStart).Nanoseconds()) - }) - - // Ignore SIGPIPE if specified - // The Go runtime catches SIGPIPE for us on all fds except stdout/stderr - // See https://golang.org/pkg/os/signal/#hdr-SIGPIPE - if catchSigpipe { - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGPIPE) - go func() { - <-sigChan - log.Warning("Caught SIGPIPE (ignoring all future SIGPIPEs)") - signal.Ignore(syscall.SIGPIPE) - }() - } - - // Add version tag to every info log - log.Infof(AppVersion.String()) - if inited { - log.Fatal("servenv.Init called second time") - } - inited = true - - // Once you run as root, you pretty much destroy the chances of a - // non-privileged user starting the program correctly. - if uid := os.Getuid(); uid == 0 { - log.Exitf("servenv.Init: running this as root makes no sense") - } - - // We used to set this limit directly, but you pretty much have to - // use a root account to allow increasing a limit reliably. Dropping - // privileges is also tricky. The best strategy is to make a shell - // script set up the limits as root and switch users before starting - // the server. - fdLimit := &syscall.Rlimit{} - if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, fdLimit); err != nil { - log.Errorf("max-open-fds failed: %v", err) - } - fdl := stats.NewGauge("MaxFds", "File descriptor limit") - fdl.Set(int64(fdLimit.Cur)) - - // Limit the stack size. We don't need huge stacks and smaller limits mean - // any infinite recursion fires earlier and on low memory systems avoids - // out of memory issues in favor of a stack overflow error. - debug.SetMaxStack(maxStackSize) - - onInitHooks.Fire() -} - func populateListeningURL(port int32) { host, err := netutil.FullyQualifiedHostname() if err != nil { diff --git a/go/vt/servenv/servenv_unix.go b/go/vt/servenv/servenv_unix.go new file mode 100644 index 00000000000..17fa85c4167 --- /dev/null +++ b/go/vt/servenv/servenv_unix.go @@ -0,0 +1,87 @@ +//go:build !windows + +/* +Copyright 2023 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 servenv + +import ( + "os" + "os/signal" + "runtime/debug" + "syscall" + "time" + + "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/vt/log" +) + +// Init is the first phase of the server startup. +func Init() { + mu.Lock() + defer mu.Unlock() + initStartTime = time.Now() + + // Uptime metric + _ = stats.NewGaugeFunc("Uptime", "Uptime in nanoseconds", func() int64 { + return int64(time.Since(serverStart).Nanoseconds()) + }) + + // Ignore SIGPIPE if specified + // The Go runtime catches SIGPIPE for us on all fds except stdout/stderr + // See https://golang.org/pkg/os/signal/#hdr-SIGPIPE + if catchSigpipe { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGPIPE) + go func() { + <-sigChan + log.Warning("Caught SIGPIPE (ignoring all future SIGPIPEs)") + signal.Ignore(syscall.SIGPIPE) + }() + } + + // Add version tag to every info log + log.Infof(AppVersion.String()) + if inited { + log.Fatal("servenv.Init called second time") + } + inited = true + + // Once you run as root, you pretty much destroy the chances of a + // non-privileged user starting the program correctly. + if uid := os.Getuid(); uid == 0 { + log.Exitf("servenv.Init: running this as root makes no sense") + } + + // We used to set this limit directly, but you pretty much have to + // use a root account to allow increasing a limit reliably. Dropping + // privileges is also tricky. The best strategy is to make a shell + // script set up the limits as root and switch users before starting + // the server. + fdLimit := &syscall.Rlimit{} + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, fdLimit); err != nil { + log.Errorf("max-open-fds failed: %v", err) + } + fdl := stats.NewGauge("MaxFds", "File descriptor limit") + fdl.Set(int64(fdLimit.Cur)) + + // Limit the stack size. We don't need huge stacks and smaller limits mean + // any infinite recursion fires earlier and on low memory systems avoids + // out of memory issues in favor of a stack overflow error. + debug.SetMaxStack(maxStackSize) + + onInitHooks.Fire() +} diff --git a/go/vt/servenv/servenv_windows.go b/go/vt/servenv/servenv_windows.go new file mode 100644 index 00000000000..bd610b1f245 --- /dev/null +++ b/go/vt/servenv/servenv_windows.go @@ -0,0 +1,21 @@ +//go:build windows + +/* +Copyright 2023 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 servenv + +func Init() {} diff --git a/go/vt/topo/events/keyspace_change_syslog.go b/go/vt/topo/events/keyspace_change_syslog.go index d7f456ae6b8..7404c3ca882 100644 --- a/go/vt/topo/events/keyspace_change_syslog.go +++ b/go/vt/topo/events/keyspace_change_syslog.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topo/events/keyspace_change_syslog_test.go b/go/vt/topo/events/keyspace_change_syslog_test.go index 1367cf27b23..8ba7225a025 100644 --- a/go/vt/topo/events/keyspace_change_syslog_test.go +++ b/go/vt/topo/events/keyspace_change_syslog_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topo/events/shard_change_syslog.go b/go/vt/topo/events/shard_change_syslog.go index 3f6422a9175..2055e4268ec 100644 --- a/go/vt/topo/events/shard_change_syslog.go +++ b/go/vt/topo/events/shard_change_syslog.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topo/events/shard_change_syslog_test.go b/go/vt/topo/events/shard_change_syslog_test.go index fc721bae923..bdac457853e 100644 --- a/go/vt/topo/events/shard_change_syslog_test.go +++ b/go/vt/topo/events/shard_change_syslog_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topo/events/tablet_change_syslog.go b/go/vt/topo/events/tablet_change_syslog.go index e2dae020c8e..55de46674dc 100644 --- a/go/vt/topo/events/tablet_change_syslog.go +++ b/go/vt/topo/events/tablet_change_syslog.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topo/events/tablet_change_syslog_test.go b/go/vt/topo/events/tablet_change_syslog_test.go index 4a5bb4d7ea9..7ecabf3f7fb 100644 --- a/go/vt/topo/events/tablet_change_syslog_test.go +++ b/go/vt/topo/events/tablet_change_syslog_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topotools/events/reparent_syslog.go b/go/vt/topotools/events/reparent_syslog.go index dae22467d1f..dd995f34d73 100644 --- a/go/vt/topotools/events/reparent_syslog.go +++ b/go/vt/topotools/events/reparent_syslog.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/topotools/events/reparent_syslog_test.go b/go/vt/topotools/events/reparent_syslog_test.go index 93a9b860fe2..f4ba39f602b 100644 --- a/go/vt/topotools/events/reparent_syslog_test.go +++ b/go/vt/topotools/events/reparent_syslog_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 273592b5bf7..00eb5e1b605 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -550,17 +550,10 @@ func initMySQLProtocol(vtgate *VTGate) *mysqlServer { } if mysqlServerSocketPath != "" { - // Let's create this unix socket with permissions to all users. In this way, - // clients can connect to vtgate mysql server without being vtgate user - oldMask := syscall.Umask(000) - srv.unixListener, err = newMysqlUnixSocket(mysqlServerSocketPath, authServer, srv.vtgateHandle) - _ = syscall.Umask(oldMask) + err = setupUnixSocket(srv, authServer, mysqlServerSocketPath) if err != nil { log.Exitf("mysql.NewListener failed: %v", err) - return nil } - // Listen for unix socket - go srv.unixListener.Accept() } return srv } diff --git a/go/vt/vtgate/plugin_mysql_server_unix.go b/go/vt/vtgate/plugin_mysql_server_unix.go new file mode 100644 index 00000000000..95c9731fccc --- /dev/null +++ b/go/vt/vtgate/plugin_mysql_server_unix.go @@ -0,0 +1,40 @@ +//go:build !windows + +/* +Copyright 2023 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 vtgate + +import ( + "syscall" + + "vitess.io/vitess/go/mysql" +) + +func setupUnixSocket(srv *mysqlServer, authServer mysql.AuthServer, path string) error { + // Let's create this unix socket with permissions to all users. In this way, + // clients can connect to vtgate mysql server without being vtgate user + var err error + oldMask := syscall.Umask(000) + srv.unixListener, err = newMysqlUnixSocket(path, authServer, srv.vtgateHandle) + _ = syscall.Umask(oldMask) + if err != nil { + return err + } + // Listen for unix socket + go srv.unixListener.Accept() + return nil +} diff --git a/go/vt/vtgate/plugin_mysql_server_windows.go b/go/vt/vtgate/plugin_mysql_server_windows.go new file mode 100644 index 00000000000..0502cadf863 --- /dev/null +++ b/go/vt/vtgate/plugin_mysql_server_windows.go @@ -0,0 +1,29 @@ +//go:build windows + +/* +Copyright 2023 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 vtgate + +import ( + "errors" + + "vitess.io/vitess/go/mysql" +) + +func setupUnixSocket(srv *mysqlServer, authServer mysql.AuthServer, path string) error { + return errors.New("unix sockets are not supported on windows") +} diff --git a/go/vt/vtorc/inst/audit_dao.go b/go/vt/vtorc/inst/audit_dao.go index 96db7f32ccf..fc1528c9640 100644 --- a/go/vt/vtorc/inst/audit_dao.go +++ b/go/vt/vtorc/inst/audit_dao.go @@ -18,36 +18,22 @@ package inst import ( "fmt" - "log/syslog" "os" "time" - "vitess.io/vitess/go/vt/log" - "github.com/rcrowley/go-metrics" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/vtorc/config" "vitess.io/vitess/go/vt/vtorc/db" ) -// syslogWriter is optional, and defaults to nil (disabled) -var syslogWriter *syslog.Writer - var auditOperationCounter = metrics.NewCounter() func init() { _ = metrics.Register("audit.write", auditOperationCounter) } -// EnableSyslogWriter enables, if possible, writes to syslog. These will execute _in addition_ to normal logging -func EnableAuditSyslog() (err error) { - syslogWriter, err = syslog.New(syslog.LOG_ERR, "vtorc") - if err != nil { - syslogWriter = nil - } - return err -} - // AuditOperation creates and writes a new audit entry by given params func AuditOperation(auditType string, tabletAlias string, message string) error { keyspace := "" @@ -94,11 +80,8 @@ func AuditOperation(auditType string, tabletAlias string, message string) error } } logMessage := fmt.Sprintf("auditType:%s alias:%s keyspace:%s shard:%s message:%s", auditType, tabletAlias, keyspace, shard, message) - if syslogWriter != nil { + if syslogMessage(logMessage) { auditWrittenToFile = true - go func() { - _ = syslogWriter.Info(logMessage) - }() } if !auditWrittenToFile { log.Infof(logMessage) diff --git a/go/vt/vtorc/inst/audit_dao_nosyslog.go b/go/vt/vtorc/inst/audit_dao_nosyslog.go new file mode 100644 index 00000000000..a61b3eb8f42 --- /dev/null +++ b/go/vt/vtorc/inst/audit_dao_nosyslog.go @@ -0,0 +1,32 @@ +//go:build windows + +/* + Copyright 2014 Outbrain Inc. + + 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 inst + +import ( + "errors" +) + +// EnableAuditSyslog enables, if possible, writes to syslog. These will execute _in addition_ to normal logging +func EnableAuditSyslog() (err error) { + return errors.New("syslog is not supported on windows") +} + +func syslogMessage(logMessage string) bool { + return false +} diff --git a/go/vt/vtorc/inst/audit_dao_syslog.go b/go/vt/vtorc/inst/audit_dao_syslog.go new file mode 100644 index 00000000000..2567409f03e --- /dev/null +++ b/go/vt/vtorc/inst/audit_dao_syslog.go @@ -0,0 +1,43 @@ +//go:build !windows + +/* + Copyright 2014 Outbrain Inc. + + 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 inst + +import "log/syslog" + +// syslogWriter is optional, and defaults to nil (disabled) +var syslogWriter *syslog.Writer + +// EnableAuditSyslog enables, if possible, writes to syslog. These will execute _in addition_ to normal logging +func EnableAuditSyslog() (err error) { + syslogWriter, err = syslog.New(syslog.LOG_ERR, "vtorc") + if err != nil { + syslogWriter = nil + } + return err +} + +func syslogMessage(logMessage string) bool { + if syslogWriter == nil { + return false + } + go func() { + _ = syslogWriter.Info(logMessage) + }() + return true +} diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 3b2dd30c9f6..cdd890ef5d7 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -43,6 +43,7 @@ import ( "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/syscallutil" "vitess.io/vitess/go/textutil" "vitess.io/vitess/go/timer" "vitess.io/vitess/go/vt/binlog/binlogplayer" @@ -2044,10 +2045,10 @@ func (e *Executor) terminateMigration(ctx context.Context, onlineDDL *schema.Onl foundRunning = true // Because pt-osc doesn't offer much control, we take a brute force approach to killing it, // revoking its privileges, and cleaning up its triggers. - if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { + if err := syscallutil.Kill(pid, syscall.SIGTERM); err != nil { return foundRunning, nil } - if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { + if err := syscallutil.Kill(pid, syscall.SIGKILL); err != nil { return foundRunning, nil } if err := e.dropOnlineDDLUser(ctx); err != nil { diff --git a/go/vt/vttablet/sysloglogger/sysloglogger.go b/go/vt/vttablet/sysloglogger/sysloglogger.go index 87601884d5c..37672911e23 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/vttablet/sysloglogger/sysloglogger_test.go b/go/vt/vttablet/sysloglogger/sysloglogger_test.go index c62a4396ac6..7a1678638ca 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger_test.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger_test.go @@ -1,3 +1,5 @@ +//go:build !windows + /* Copyright 2019 The Vitess Authors. diff --git a/go/vt/zkctl/zkctl.go b/go/vt/zkctl/zkctl.go index acb8dba6356..60102d1bbf9 100644 --- a/go/vt/zkctl/zkctl.go +++ b/go/vt/zkctl/zkctl.go @@ -33,6 +33,7 @@ import ( zookeeper "github.com/z-division/go-zookeeper/zk" + "vitess.io/vitess/go/syscallutil" "vitess.io/vitess/go/vt/env" "vitess.io/vitess/go/vt/log" ) @@ -137,13 +138,13 @@ func (zkd *Zkd) Shutdown() error { if err != nil { return err } - err = syscall.Kill(pid, syscall.SIGKILL) + err = syscallutil.Kill(pid, syscall.SIGKILL) if err != nil && err != syscall.ESRCH { return err } timeout := time.Now().Add(shutdownWaitTime) for time.Now().Before(timeout) { - if syscall.Kill(pid, syscall.SIGKILL) == syscall.ESRCH { + if syscallutil.Kill(pid, syscall.SIGKILL) == syscall.ESRCH { return nil } time.Sleep(time.Second) From 6c6822735a642863884309aa89ca7236b27430d2 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 8 Dec 2023 22:46:14 +0530 Subject: [PATCH 103/119] fix: flush tables with read lock to run only with reserved connection (#14720) Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/misc_test.go | 50 ++++++++++++ go/vt/vtgate/engine/send.go | 64 +++++++-------- go/vt/vtgate/engine/unlock.go | 79 +++++++++++++++++++ go/vt/vtgate/planbuilder/builder.go | 30 +++---- go/vt/vtgate/planbuilder/locktables.go | 3 +- .../planbuilder/testdata/flush_cases.json | 40 +++++++++- .../flush_cases_no_default_keyspace.json | 18 +++-- .../planbuilder/testdata/lock_cases.json | 2 +- go/vt/vttablet/endtoend/reserve_test.go | 22 +++++- .../tabletserver/planbuilder/builder.go | 18 +++++ .../tabletserver/planbuilder/permission.go | 3 +- .../vttablet/tabletserver/planbuilder/plan.go | 4 +- .../planbuilder/testdata/exec_cases.txt | 19 +++++ go/vt/vttablet/tabletserver/query_engine.go | 2 +- go/vt/vttablet/tabletserver/query_executor.go | 4 +- 15 files changed, 293 insertions(+), 65 deletions(-) create mode 100644 go/vt/vtgate/engine/unlock.go diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 83c41fd7183..f0c063b1caf 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -17,9 +17,13 @@ limitations under the License. package vtgate import ( + "context" "fmt" + "sync/atomic" "testing" + "time" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/test/endtoend/utils" @@ -336,6 +340,52 @@ func TestFlush(t *testing.T) { utils.Exec(t, conn, "flush local tables t1, t2") } +// TestFlushLock tests that ftwrl and unlock tables should unblock other session connections to execute the query. +func TestFlushLock(t *testing.T) { + conn, closer := start(t) + defer closer() + + // replica: fail it + utils.Exec(t, conn, "use @replica") + _, err := utils.ExecAllowError(t, conn, "flush tables ks.t1, ks.t2 with read lock") + require.ErrorContains(t, err, "VT09012: FLUSH statement with REPLICA tablet not allowed") + + // primary: should work + utils.Exec(t, conn, "use @primary") + utils.Exec(t, conn, "flush tables ks.t1, ks.t2 with read lock") + + var cnt atomic.Int32 + go func() { + ctx := context.Background() + conn2, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn2.Close() + + cnt.Add(1) + utils.Exec(t, conn2, "select * from ks.t1 for update") + cnt.Add(1) + }() + for cnt.Load() == 0 { + } + // added sleep to let the query execute inside the go routine, which should be blocked. + time.Sleep(1 * time.Second) + require.EqualValues(t, 1, cnt.Load()) + + // unlock it + utils.Exec(t, conn, "unlock tables") + + // now wait for go routine to complete. + timeout := time.After(3 * time.Second) + for cnt.Load() != 2 { + select { + case <-timeout: + t.Fatalf("test timeout waiting for select query to complete") + default: + + } + } +} + func TestShowVariables(t *testing.T) { conn, closer := start(t) defer closer() diff --git a/go/vt/vtgate/engine/send.go b/go/vt/vtgate/engine/send.go index 1a95d8f93fa..83ba960af9e 100644 --- a/go/vt/vtgate/engine/send.go +++ b/go/vt/vtgate/engine/send.go @@ -54,6 +54,8 @@ type Send struct { // MultishardAutocommit specifies that a multishard transaction query can autocommit MultishardAutocommit bool + ReservedConnectionNeeded bool + noInputs } @@ -88,19 +90,12 @@ func (s *Send) GetTableName() string { func (s *Send) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { ctx, cancelFunc := addQueryTimeout(ctx, vcursor, 0) defer cancelFunc() - rss, _, err := vcursor.ResolveDestinations(ctx, s.Keyspace.Name, nil, []key.Destination{s.TargetDestination}) + + rss, err := s.checkAndReturnShards(ctx, vcursor) if err != nil { return nil, err } - if !s.Keyspace.Sharded && len(rss) != 1 { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Keyspace does not have exactly one shard: %v", rss) - } - - if s.SingleShardOnly && len(rss) != 1 { - return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Unexpected error, DestinationKeyspaceID mapping to multiple shards: %s, got: %v", s.Query, s.TargetDestination) - } - queries := make([]*querypb.BoundQuery, len(rss)) for i, rs := range rss { bv := bindVars @@ -123,6 +118,26 @@ func (s *Send) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[str return result, nil } +func (s *Send) checkAndReturnShards(ctx context.Context, vcursor VCursor) ([]*srvtopo.ResolvedShard, error) { + rss, _, err := vcursor.ResolveDestinations(ctx, s.Keyspace.Name, nil, []key.Destination{s.TargetDestination}) + if err != nil { + return nil, err + } + + if !s.Keyspace.Sharded && len(rss) != 1 { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Keyspace does not have exactly one shard: %v", rss) + } + + if s.SingleShardOnly && len(rss) != 1 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Unexpected error, DestinationKeyspaceID mapping to multiple shards: %s, got: %v", s.Query, s.TargetDestination) + } + + if s.ReservedConnectionNeeded { + vcursor.Session().NeedsReservedConn() + } + return rss, nil +} + func (s *Send) canAutoCommit(vcursor VCursor, rss []*srvtopo.ResolvedShard) bool { if s.IsDML { return (len(rss) == 1 || s.MultishardAutocommit) && vcursor.AutocommitApproval() @@ -140,19 +155,11 @@ func copyBindVars(in map[string]*querypb.BindVariable) map[string]*querypb.BindV // TryStreamExecute implements Primitive interface func (s *Send) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - rss, _, err := vcursor.ResolveDestinations(ctx, s.Keyspace.Name, nil, []key.Destination{s.TargetDestination}) + rss, err := s.checkAndReturnShards(ctx, vcursor) if err != nil { return err } - if !s.Keyspace.Sharded && len(rss) != 1 { - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Keyspace does not have exactly one shard: %v", rss) - } - - if s.SingleShardOnly && len(rss) != 1 { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Unexpected error, DestinationKeyspaceID mapping to multiple shards: %s, got: %v", s.Query, s.TargetDestination) - } - multiBindVars := make([]map[string]*querypb.BindVariable, len(rss)) for i, rs := range rss { bv := bindVars @@ -178,20 +185,13 @@ func (s *Send) GetFields(ctx context.Context, vcursor VCursor, bindVars map[stri func (s *Send) description() PrimitiveDescription { other := map[string]any{ - "Query": s.Query, - "Table": s.GetTableName(), - } - if s.IsDML { - other["IsDML"] = true - } - if s.SingleShardOnly { - other["SingleShardOnly"] = true - } - if s.ShardNameNeeded { - other["ShardNameNeeded"] = true - } - if s.MultishardAutocommit { - other["MultishardAutocommit"] = true + "Query": s.Query, + "Table": s.GetTableName(), + "IsDML": s.IsDML, + "SingleShardOnly": s.SingleShardOnly, + "ShardNameNeeded": s.ShardNameNeeded, + "MultishardAutocommit": s.MultishardAutocommit, + "ReservedConnectionNeeded": s.ReservedConnectionNeeded, } return PrimitiveDescription{ OperatorType: "Send", diff --git a/go/vt/vtgate/engine/unlock.go b/go/vt/vtgate/engine/unlock.go new file mode 100644 index 00000000000..5addbb957fa --- /dev/null +++ b/go/vt/vtgate/engine/unlock.go @@ -0,0 +1,79 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/vterrors" +) + +var _ Primitive = (*Unlock)(nil) + +// Unlock primitive will execute unlock tables to all connections in the session. +type Unlock struct { + noTxNeeded + noInputs +} + +const unlockTables = "unlock tables" + +func (u *Unlock) RouteType() string { + return "UNLOCK" +} + +func (u *Unlock) GetKeyspaceName() string { + return "" +} + +func (u *Unlock) GetTableName() string { + return "" +} + +func (u *Unlock) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return nil, vterrors.VT13001("GetFields should not be called for unlock tables") +} + +func (u *Unlock) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { + rss := vcursor.Session().ShardSession() + + if len(rss) == 0 { + return &sqltypes.Result{}, nil + } + bqs := make([]*querypb.BoundQuery, len(rss)) + for i := 0; i < len(rss); i++ { + bqs[i] = &querypb.BoundQuery{Sql: unlockTables} + } + qr, errs := vcursor.ExecuteMultiShard(ctx, u, rss, bqs, true, false) + return qr, vterrors.Aggregate(errs) +} + +func (u *Unlock) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + qr, err := u.TryExecute(ctx, vcursor, bindVars, wantfields) + if err != nil { + return err + } + return callback(qr) +} + +func (u *Unlock) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "UnlockTables", + } +} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index ffa316d4b71..4c1bfc0c547 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -382,18 +382,12 @@ func buildFlushOptions(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*pla dest = key.DestinationAllShards{} } - tc := &tableCollector{} - for _, tbl := range stmt.TableNames { - tc.addASTTable(keyspace.Name, tbl) - } - return newPlanResult(&engine.Send{ - Keyspace: keyspace, - TargetDestination: dest, - Query: sqlparser.String(stmt), - IsDML: false, - SingleShardOnly: false, - }, tc.getTables()...), nil + Keyspace: keyspace, + TargetDestination: dest, + Query: sqlparser.String(stmt), + ReservedConnectionNeeded: stmt.WithLock, + }), nil } func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*planResult, error) { @@ -441,9 +435,10 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan if len(tablesMap) == 1 { for sendDest, tables := range tablesMap { return newPlanResult(&engine.Send{ - Keyspace: sendDest.ks, - TargetDestination: sendDest.dest, - Query: sqlparser.String(newFlushStmt(stmt, tables)), + Keyspace: sendDest.ks, + TargetDestination: sendDest.dest, + Query: sqlparser.String(newFlushStmt(stmt, tables)), + ReservedConnectionNeeded: stmt.WithLock, }, tc.getTables()...), nil } } @@ -455,9 +450,10 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan var sources []engine.Primitive for _, sendDest := range keys { plan := &engine.Send{ - Keyspace: sendDest.ks, - TargetDestination: sendDest.dest, - Query: sqlparser.String(newFlushStmt(stmt, tablesMap[sendDest])), + Keyspace: sendDest.ks, + TargetDestination: sendDest.dest, + Query: sqlparser.String(newFlushStmt(stmt, tablesMap[sendDest])), + ReservedConnectionNeeded: stmt.WithLock, } sources = append(sources, plan) } diff --git a/go/vt/vtgate/planbuilder/locktables.go b/go/vt/vtgate/planbuilder/locktables.go index 9c3a5fa44e9..e8776d13e65 100644 --- a/go/vt/vtgate/planbuilder/locktables.go +++ b/go/vt/vtgate/planbuilder/locktables.go @@ -33,6 +33,5 @@ func buildLockPlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, _ planco // buildUnlockPlan plans lock tables statement. func buildUnlockPlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, _ plancontext.VSchema) (*planResult, error) { - log.Warningf("Unlock Tables statement is ignored: %v", stmt) - return newPlanResult(engine.NewRowsPrimitive(make([][]sqltypes.Value, 0), make([]*querypb.Field, 0))), nil + return newPlanResult(&engine.Unlock{}), nil } diff --git a/go/vt/vtgate/planbuilder/testdata/flush_cases.json b/go/vt/vtgate/planbuilder/testdata/flush_cases.json index 8298c6de649..26a1f218c8d 100644 --- a/go/vt/vtgate/planbuilder/testdata/flush_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/flush_cases.json @@ -33,7 +33,8 @@ "Sharded": false }, "TargetDestination": "AllShards()", - "Query": "flush local tables with read lock" + "Query": "flush local tables with read lock", + "ReservedConnectionNeeded": true } } }, @@ -53,5 +54,42 @@ "Query": "flush local hosts, logs" } } + }, + { + "comment": "Flush statement with multiple tables in different keyspace with read lock", + "query": "flush tables user.music, main.unsharded with read lock", + "plan": { + "QueryType": "FLUSH", + "Original": "flush tables user.music, main.unsharded with read lock", + "Instructions": { + "OperatorType": "Concatenate", + "Inputs": [ + { + "OperatorType": "Send", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetDestination": "AllShards()", + "Query": "flush tables unsharded with read lock", + "ReservedConnectionNeeded": true + }, + { + "OperatorType": "Send", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetDestination": "AllShards()", + "Query": "flush tables music with read lock", + "ReservedConnectionNeeded": true + } + ] + }, + "TablesUsed": [ + "main.unsharded", + "user.music" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/flush_cases_no_default_keyspace.json b/go/vt/vtgate/planbuilder/testdata/flush_cases_no_default_keyspace.json index a3370a74f5d..7afd090ba21 100644 --- a/go/vt/vtgate/planbuilder/testdata/flush_cases_no_default_keyspace.json +++ b/go/vt/vtgate/planbuilder/testdata/flush_cases_no_default_keyspace.json @@ -15,7 +15,8 @@ "Sharded": false }, "TargetDestination": "AllShards()", - "Query": "flush local tables unsharded_a with read lock" + "Query": "flush local tables unsharded_a with read lock", + "ReservedConnectionNeeded": true }, { "OperatorType": "Send", @@ -24,7 +25,8 @@ "Sharded": true }, "TargetDestination": "AllShards()", - "Query": "flush local tables `user`, user_extra with read lock" + "Query": "flush local tables `user`, user_extra with read lock", + "ReservedConnectionNeeded": true } ] }, @@ -105,7 +107,8 @@ "Sharded": false }, "TargetDestination": "AllShards()", - "Query": "flush tables a with read lock" + "Query": "flush tables a with read lock", + "ReservedConnectionNeeded": true }, "TablesUsed": [ "main.a" @@ -128,7 +131,8 @@ "Sharded": false }, "TargetDestination": "AllShards()", - "Query": "flush local tables unsharded_a with read lock" + "Query": "flush local tables unsharded_a with read lock", + "ReservedConnectionNeeded": true }, { "OperatorType": "Send", @@ -137,7 +141,8 @@ "Sharded": false }, "TargetDestination": "AllShards()", - "Query": "flush local tables unsharded_tab with read lock" + "Query": "flush local tables unsharded_tab with read lock", + "ReservedConnectionNeeded": true }, { "OperatorType": "Send", @@ -146,7 +151,8 @@ "Sharded": true }, "TargetDestination": "AllShards()", - "Query": "flush local tables `user`, user_extra with read lock" + "Query": "flush local tables `user`, user_extra with read lock", + "ReservedConnectionNeeded": true } ] }, diff --git a/go/vt/vtgate/planbuilder/testdata/lock_cases.json b/go/vt/vtgate/planbuilder/testdata/lock_cases.json index 568b066fa22..2490424a1ec 100644 --- a/go/vt/vtgate/planbuilder/testdata/lock_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/lock_cases.json @@ -97,7 +97,7 @@ "QueryType": "UNLOCK_TABLES", "Original": "unlock tables", "Instructions": { - "OperatorType": "Rows" + "OperatorType": "UnlockTables" } } }, diff --git a/go/vt/vttablet/endtoend/reserve_test.go b/go/vt/vttablet/endtoend/reserve_test.go index 63b87f9c00f..d3fb685dd49 100644 --- a/go/vt/vttablet/endtoend/reserve_test.go +++ b/go/vt/vttablet/endtoend/reserve_test.go @@ -28,8 +28,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/endtoend/framework" ) -//TODO: Add Counter checks in all the tests. - func TestMultipleReserveHaveDifferentConnection(t *testing.T) { framework.Server.Config().EnableSettingsPool = false defer func() { @@ -1190,3 +1188,23 @@ func TestReserveQueryTimeout(t *testing.T) { assert.NoError(t, client.Release()) } + +// TestReserveFlushTables checks that `flush table with read lock` works only with reserve api. +func TestReserveFlushTables(t *testing.T) { + client := framework.NewClient() + + _, err := client.Execute("flush tables with read lock", nil) + assert.ErrorContains(t, err, "Flush not allowed without reserved connection") + + _, err = client.Execute("unlock tables", nil) + assert.ErrorContains(t, err, "unlock tables should be executed with an existing connection") + + _, err = client.ReserveExecute("flush tables with read lock", nil, nil) + assert.NoError(t, err) + + _, err = client.Execute("unlock tables", nil) + assert.NoError(t, err) + + assert.NoError(t, + client.Release()) +} diff --git a/go/vt/vttablet/tabletserver/planbuilder/builder.go b/go/vt/vttablet/tabletserver/planbuilder/builder.go index 3cae292b593..4594f6350f6 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/builder.go +++ b/go/vt/vttablet/tabletserver/planbuilder/builder.go @@ -219,3 +219,21 @@ func analyzeDDL(stmt sqlparser.DDLStatement) (*Plan, error) { } return &Plan{PlanID: PlanDDL, FullQuery: fullQuery, FullStmt: stmt, NeedsReservedConn: stmt.IsTemporary()}, nil } + +func analyzeFlush(stmt *sqlparser.Flush, tables map[string]*schema.Table) (*Plan, error) { + plan := &Plan{PlanID: PlanFlush, FullQuery: GenerateFullQuery(stmt)} + + for _, tbl := range stmt.TableNames { + if schemaTbl, ok := tables[tbl.Name.String()]; ok { + plan.AllTables = append(plan.AllTables, schemaTbl) + } + } + if len(plan.AllTables) == 1 { + plan.Table = plan.AllTables[0] + } + + if stmt.WithLock { + plan.NeedsReservedConn = true + } + return plan, nil +} diff --git a/go/vt/vttablet/tabletserver/planbuilder/permission.go b/go/vt/vttablet/tabletserver/planbuilder/permission.go index a9d772f2931..d6069c6adf3 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/permission.go +++ b/go/vt/vttablet/tabletserver/planbuilder/permission.go @@ -65,7 +65,8 @@ func BuildPermissions(stmt sqlparser.Statement) []Permission { case *sqlparser.Analyze: permissions = buildTableNamePermissions(node.Table, tableacl.WRITER, permissions) case *sqlparser.OtherAdmin, *sqlparser.CallProc, *sqlparser.Begin, *sqlparser.Commit, *sqlparser.Rollback, - *sqlparser.Load, *sqlparser.Savepoint, *sqlparser.Release, *sqlparser.SRollback, *sqlparser.Set, *sqlparser.Show, sqlparser.Explain: + *sqlparser.Load, *sqlparser.Savepoint, *sqlparser.Release, *sqlparser.SRollback, *sqlparser.Set, *sqlparser.Show, sqlparser.Explain, + *sqlparser.UnlockTables: // no op default: panic(fmt.Errorf("BUG: unexpected statement type: %T", node)) diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan.go b/go/vt/vttablet/tabletserver/planbuilder/plan.go index c4a8f905607..6f491692241 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan.go @@ -246,7 +246,9 @@ func Build(statement sqlparser.Statement, tables map[string]*schema.Table, dbNam case *sqlparser.Load: plan, err = &Plan{PlanID: PlanLoad}, nil case *sqlparser.Flush: - plan, err = &Plan{PlanID: PlanFlush, FullQuery: GenerateFullQuery(stmt)}, nil + plan, err = analyzeFlush(stmt, tables) + case *sqlparser.UnlockTables: + plan, err = &Plan{PlanID: PlanUnlockTables}, nil case *sqlparser.CallProc: plan, err = &Plan{PlanID: PlanCallProc, FullQuery: GenerateFullQuery(stmt)}, nil default: diff --git a/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt b/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt index d5bd99ca7a0..1e9dbf6ad12 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt +++ b/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt @@ -939,6 +939,25 @@ options:PassthroughDMLs "FullQuery": "flush tables a, b" } +# flush statement with read lock +"flush tables a,b with read lock" +{ + "PlanID": "Flush", + "TableName": "", + "Permissions": [ + { + "TableName": "a", + "Role": 2 + }, + { + "TableName": "b", + "Role": 2 + } + ], + "FullQuery": "flush tables a, b with read lock", + "NeedsReservedConn": true +} + # call proc "call getAllTheThings()" { diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index c31b65be8dd..0afe76d14ce 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -109,7 +109,7 @@ func (ep *TabletPlan) IsValid(hasReservedCon, hasSysSettings bool) error { func isValid(planType planbuilder.PlanType, hasReservedCon bool, hasSysSettings bool) error { switch planType { - case planbuilder.PlanSelectLockFunc, planbuilder.PlanDDL: + case planbuilder.PlanSelectLockFunc, planbuilder.PlanDDL, planbuilder.PlanFlush: if hasReservedCon { return nil } diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 735562c536f..e53bdaec754 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -207,6 +207,8 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) { return qre.execShowThrottledApps() case p.PlanShowThrottlerStatus: return qre.execShowThrottlerStatus() + case p.PlanUnlockTables: + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "unlock tables should be executed with an existing connection") case p.PlanSet: if qre.setting == nil { return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "[BUG] %s not allowed without setting connection", qre.query) @@ -279,7 +281,7 @@ func (qre *QueryExecutor) txConnExec(conn *StatefulConnection) (*sqltypes.Result return qre.txFetch(conn, true) case p.PlanUpdateLimit, p.PlanDeleteLimit: return qre.execDMLLimit(conn) - case p.PlanOtherRead, p.PlanOtherAdmin, p.PlanFlush: + case p.PlanOtherRead, p.PlanOtherAdmin, p.PlanFlush, p.PlanUnlockTables: return qre.execStatefulConn(conn, qre.query, true) case p.PlanSavepoint, p.PlanRelease, p.PlanSRollback: return qre.execStatefulConn(conn, qre.query, true) From a2fe7ae072d3331b69f2887ed926bbde8aabd516 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Fri, 8 Dec 2023 21:50:22 +0100 Subject: [PATCH 104/119] mysql: Refactor out usage of servenv (#14732) Signed-off-by: Dirkjan Bussink --- go/cmd/vtgate/cli/plugin_auth_clientcert.go | 6 ++- go/cmd/vtgate/cli/plugin_auth_ldap.go | 13 +++++- go/cmd/vtgate/cli/plugin_auth_static.go | 16 ++++++- go/cmd/vtgate/cli/plugin_auth_vault.go | 28 ++++++++++++- go/flags/endtoend/vtcombo.txt | 1 + go/mysql/auth_server_clientcert.go | 15 ++----- go/mysql/auth_server_clientcert_test.go | 14 ++----- go/mysql/auth_server_static.go | 21 +--------- go/mysql/client.go | 2 +- go/mysql/client_test.go | 10 ++--- go/mysql/conn.go | 14 +++++-- go/mysql/conn_fake.go | 2 +- go/mysql/conn_flaky_test.go | 12 +++--- go/mysql/conn_params.go | 5 +++ go/mysql/fakesqldb/server.go | 2 +- go/mysql/handshake_test.go | 4 +- go/mysql/ldapauthserver/auth_server_ldap.go | 20 +-------- go/mysql/mysql_fuzzer.go | 8 ++-- go/mysql/server.go | 19 +++++++-- go/mysql/server_flaky_test.go | 46 ++++++++++----------- go/mysql/vault/auth_server_vault.go | 33 +-------------- go/vt/vtgate/plugin_mysql_server.go | 10 ++++- go/vt/vtgate/plugin_mysql_server_test.go | 4 +- 23 files changed, 157 insertions(+), 148 deletions(-) diff --git a/go/cmd/vtgate/cli/plugin_auth_clientcert.go b/go/cmd/vtgate/cli/plugin_auth_clientcert.go index 1a1334e71ba..d486669847f 100644 --- a/go/cmd/vtgate/cli/plugin_auth_clientcert.go +++ b/go/cmd/vtgate/cli/plugin_auth_clientcert.go @@ -23,6 +23,10 @@ import ( "vitess.io/vitess/go/vt/vtgate" ) +var clientcertAuthMethod string + func init() { - vtgate.RegisterPluginInitializer(func() { mysql.InitAuthServerClientCert() }) + Main.Flags().StringVar(&clientcertAuthMethod, "mysql_clientcert_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.") + + vtgate.RegisterPluginInitializer(func() { mysql.InitAuthServerClientCert(clientcertAuthMethod) }) } diff --git a/go/cmd/vtgate/cli/plugin_auth_ldap.go b/go/cmd/vtgate/cli/plugin_auth_ldap.go index 7aab7e9c7f4..f8312267504 100644 --- a/go/cmd/vtgate/cli/plugin_auth_ldap.go +++ b/go/cmd/vtgate/cli/plugin_auth_ldap.go @@ -19,10 +19,21 @@ package cli // This plugin imports ldapauthserver to register the LDAP implementation of AuthServer. import ( + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/ldapauthserver" "vitess.io/vitess/go/vt/vtgate" ) +var ( + ldapAuthConfigFile string + ldapAuthConfigString string + ldapAuthMethod string +) + func init() { - vtgate.RegisterPluginInitializer(func() { ldapauthserver.Init() }) + Main.Flags().StringVar(&ldapAuthConfigFile, "mysql_ldap_auth_config_file", "", "JSON File from which to read LDAP server config.") + Main.Flags().StringVar(&ldapAuthConfigString, "mysql_ldap_auth_config_string", "", "JSON representation of LDAP server config.") + Main.Flags().StringVar(&ldapAuthMethod, "mysql_ldap_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.") + + vtgate.RegisterPluginInitializer(func() { ldapauthserver.Init(ldapAuthConfigFile, ldapAuthConfigString, ldapAuthMethod) }) } diff --git a/go/cmd/vtgate/cli/plugin_auth_static.go b/go/cmd/vtgate/cli/plugin_auth_static.go index 76cdf8318ba..7ed0e7b8f61 100644 --- a/go/cmd/vtgate/cli/plugin_auth_static.go +++ b/go/cmd/vtgate/cli/plugin_auth_static.go @@ -19,10 +19,24 @@ package cli // This plugin imports staticauthserver to register the flat-file implementation of AuthServer. import ( + "time" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/vtgate" ) +var ( + mysqlAuthServerStaticFile string + mysqlAuthServerStaticString string + mysqlAuthServerStaticReloadInterval time.Duration +) + func init() { - vtgate.RegisterPluginInitializer(func() { mysql.InitAuthServerStatic() }) + Main.Flags().StringVar(&mysqlAuthServerStaticFile, "mysql_auth_server_static_file", "", "JSON File to read the users/passwords from.") + Main.Flags().StringVar(&mysqlAuthServerStaticString, "mysql_auth_server_static_string", "", "JSON representation of the users/passwords config.") + Main.Flags().DurationVar(&mysqlAuthServerStaticReloadInterval, "mysql_auth_static_reload_interval", 0, "Ticker to reload credentials") + + vtgate.RegisterPluginInitializer(func() { + mysql.InitAuthServerStatic(mysqlAuthServerStaticFile, mysqlAuthServerStaticString, mysqlAuthServerStaticReloadInterval) + }) } diff --git a/go/cmd/vtgate/cli/plugin_auth_vault.go b/go/cmd/vtgate/cli/plugin_auth_vault.go index fe5fe2207d4..a119d2d389b 100644 --- a/go/cmd/vtgate/cli/plugin_auth_vault.go +++ b/go/cmd/vtgate/cli/plugin_auth_vault.go @@ -19,10 +19,36 @@ package cli // This plugin imports InitAuthServerVault to register the HashiCorp Vault implementation of AuthServer. import ( + "time" + "vitess.io/vitess/go/mysql/vault" "vitess.io/vitess/go/vt/vtgate" ) +var ( + vaultAddr string + vaultTimeout time.Duration + vaultCACert string + vaultPath string + vaultCacheTTL time.Duration + vaultTokenFile string + vaultRoleID string + vaultRoleSecretIDFile string + vaultRoleMountPoint string +) + func init() { - vtgate.RegisterPluginInitializer(func() { vault.InitAuthServerVault() }) + Main.Flags().StringVar(&vaultAddr, "mysql_auth_vault_addr", "", "URL to Vault server") + Main.Flags().DurationVar(&vaultTimeout, "mysql_auth_vault_timeout", 10*time.Second, "Timeout for vault API operations") + Main.Flags().StringVar(&vaultCACert, "mysql_auth_vault_tls_ca", "", "Path to CA PEM for validating Vault server certificate") + Main.Flags().StringVar(&vaultPath, "mysql_auth_vault_path", "", "Vault path to vtgate credentials JSON blob, e.g.: secret/data/prod/vtgatecreds") + Main.Flags().DurationVar(&vaultCacheTTL, "mysql_auth_vault_ttl", 30*time.Minute, "How long to cache vtgate credentials from the Vault server") + Main.Flags().StringVar(&vaultTokenFile, "mysql_auth_vault_tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") + Main.Flags().StringVar(&vaultRoleID, "mysql_auth_vault_roleid", "", "Vault AppRole id; can also be passed using VAULT_ROLEID environment variable") + Main.Flags().StringVar(&vaultRoleSecretIDFile, "mysql_auth_vault_role_secretidfile", "", "Path to file containing Vault AppRole secret_id; can also be passed using VAULT_SECRETID environment variable") + Main.Flags().StringVar(&vaultRoleMountPoint, "mysql_auth_vault_role_mountpoint", "approle", "Vault AppRole mountpoint; can also be passed using VAULT_MOUNTPOINT environment variable") + + vtgate.RegisterPluginInitializer(func() { + vault.InitAuthServerVault(vaultAddr, vaultTimeout, vaultCACert, vaultPath, vaultCacheTTL, vaultTokenFile, vaultRoleID, vaultRoleSecretIDFile, vaultRoleMountPoint) + }) } diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index d32df437787..cc3b55ee9cd 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -228,6 +228,7 @@ Flags: --mysql_default_workload string Default session workload (OLTP, OLAP, DBA) (default "OLTP") --mysql_port int mysql port (default 3306) --mysql_server_bind_address string Binds on this address when listening to MySQL binary protocol. Useful to restrict listening to 'localhost' only for instance. + --mysql_server_flush_delay duration Delay after which buffered response will be flushed to the client. (default 100ms) --mysql_server_port int If set, also listen for MySQL binary protocol connections on this port. (default -1) --mysql_server_query_timeout duration mysql query timeout --mysql_server_read_timeout duration connection read timeout diff --git a/go/mysql/auth_server_clientcert.go b/go/mysql/auth_server_clientcert.go index 10a01487208..bb0a4028683 100644 --- a/go/mysql/auth_server_clientcert.go +++ b/go/mysql/auth_server_clientcert.go @@ -23,17 +23,8 @@ import ( "github.com/spf13/pflag" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/servenv" ) -var clientcertAuthMethod string - -func init() { - servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) { - fs.StringVar(&clientcertAuthMethod, "mysql_clientcert_auth_method", string(MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.") - }) -} - // AuthServerClientCert implements AuthServer which enforces client side certificates type AuthServerClientCert struct { methods []AuthMethod @@ -41,7 +32,7 @@ type AuthServerClientCert struct { } // InitAuthServerClientCert is public so it can be called from plugin_auth_clientcert.go (go/cmd/vtgate) -func InitAuthServerClientCert() { +func InitAuthServerClientCert(clientcertAuthMethod string) { if pflag.CommandLine.Lookup("mysql_server_ssl_ca").Value.String() == "" { log.Info("Not configuring AuthServerClientCert because mysql_server_ssl_ca is empty") return @@ -50,11 +41,11 @@ func InitAuthServerClientCert() { log.Exitf("Invalid mysql_clientcert_auth_method value: only support mysql_clear_password or dialog") } - ascc := newAuthServerClientCert() + ascc := newAuthServerClientCert(clientcertAuthMethod) RegisterAuthServer("clientcert", ascc) } -func newAuthServerClientCert() *AuthServerClientCert { +func newAuthServerClientCert(clientcertAuthMethod string) *AuthServerClientCert { ascc := &AuthServerClientCert{ Method: AuthMethodDescription(clientcertAuthMethod), } diff --git a/go/mysql/auth_server_clientcert_test.go b/go/mysql/auth_server_clientcert_test.go index 28ed19fd9c5..3314116e953 100644 --- a/go/mysql/auth_server_clientcert_test.go +++ b/go/mysql/auth_server_clientcert_test.go @@ -33,19 +33,13 @@ import ( const clientCertUsername = "Client Cert" -func init() { - // These tests do not invoke the servenv.Parse codepaths, so this default - // does not get set by the OnParseFor hook. - clientcertAuthMethod = string(MysqlClearPassword) -} - func TestValidCert(t *testing.T) { th := &testHandler{} - authServer := newAuthServerClientCert() + authServer := newAuthServerClientCert(string(MysqlClearPassword)) // Create the listener, so we can get its host. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() @@ -111,10 +105,10 @@ func TestValidCert(t *testing.T) { func TestNoCert(t *testing.T) { th := &testHandler{} - authServer := newAuthServerClientCert() + authServer := newAuthServerClientCert(string(MysqlClearPassword)) // Create the listener, so we can get its host. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() diff --git a/go/mysql/auth_server_static.go b/go/mysql/auth_server_static.go index fae886039f0..6e3a9693c69 100644 --- a/go/mysql/auth_server_static.go +++ b/go/mysql/auth_server_static.go @@ -27,34 +27,15 @@ import ( "syscall" "time" - "github.com/spf13/pflag" - "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vterrors" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/vtrpc" ) -var ( - mysqlAuthServerStaticFile string - mysqlAuthServerStaticString string - mysqlAuthServerStaticReloadInterval time.Duration - mysqlServerFlushDelay = 100 * time.Millisecond -) - -func init() { - servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) { - fs.StringVar(&mysqlAuthServerStaticFile, "mysql_auth_server_static_file", "", "JSON File to read the users/passwords from.") - fs.StringVar(&mysqlAuthServerStaticString, "mysql_auth_server_static_string", "", "JSON representation of the users/passwords config.") - fs.DurationVar(&mysqlAuthServerStaticReloadInterval, "mysql_auth_static_reload_interval", 0, "Ticker to reload credentials") - fs.DurationVar(&mysqlServerFlushDelay, "mysql_server_flush_delay", mysqlServerFlushDelay, "Delay after which buffered response will be flushed to the client.") - }) -} - const ( localhostName = "localhost" ) @@ -94,7 +75,7 @@ type AuthServerStaticEntry struct { } // InitAuthServerStatic Handles initializing the AuthServerStatic if necessary. -func InitAuthServerStatic() { +func InitAuthServerStatic(mysqlAuthServerStaticFile, mysqlAuthServerStaticString string, mysqlAuthServerStaticReloadInterval time.Duration) { // Check parameters. if mysqlAuthServerStaticFile == "" && mysqlAuthServerStaticString == "" { // Not configured, nothing to do. diff --git a/go/mysql/client.go b/go/mysql/client.go index c4dd87d95cc..db1fd0cb68f 100644 --- a/go/mysql/client.go +++ b/go/mysql/client.go @@ -106,7 +106,7 @@ func Connect(ctx context.Context, params *ConnParams) (*Conn, error) { } // Send the connection back, so the other side can close it. - c := newConn(conn) + c := newConn(conn, params.FlushDelay) status <- connectResult{ c: c, } diff --git a/go/mysql/client_test.go b/go/mysql/client_test.go index c349cdcd531..057a8584679 100644 --- a/go/mysql/client_test.go +++ b/go/mysql/client_test.go @@ -151,7 +151,7 @@ func TestTLSClientDisabled(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -223,7 +223,7 @@ func TestTLSClientPreferredDefault(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -296,7 +296,7 @@ func TestTLSClientRequired(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -343,7 +343,7 @@ func TestTLSClientVerifyCA(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -426,7 +426,7 @@ func TestTLSClientVerifyIdentity(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 1908875db49..85a8ffd4027 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -43,6 +43,8 @@ import ( ) const ( + DefaultFlushDelay = 100 * time.Millisecond + // connBufferSize is how much we buffer for reading and // writing. It is also how much we allocate for ephemeral buffers. connBufferSize = 16 * 1024 @@ -128,6 +130,7 @@ type Conn struct { bufferedReader *bufio.Reader flushTimer *time.Timer + flushDelay time.Duration header [packetHeaderSize]byte // Keep track of how and of the buffer we allocated for an @@ -246,10 +249,14 @@ var readersPool = sync.Pool{New: func() any { return bufio.NewReaderSize(nil, co // newConn is an internal method to create a Conn. Used by client and server // side for common creation code. -func newConn(conn net.Conn) *Conn { +func newConn(conn net.Conn, flushDelay time.Duration) *Conn { + if flushDelay == 0 { + flushDelay = DefaultFlushDelay + } return &Conn{ conn: conn, bufferedReader: bufio.NewReaderSize(conn, connBufferSize), + flushDelay: flushDelay, } } @@ -274,6 +281,7 @@ func newServerConn(conn net.Conn, listener *Listener) *Conn { listener: listener, PrepareData: make(map[uint32]*PrepareData), keepAliveOn: enabledKeepAlive, + flushDelay: listener.flushDelay, } if listener.connReadBufferSize > 0 { @@ -347,7 +355,7 @@ func (c *Conn) returnReader() { // startFlushTimer must be called while holding lock on bufMu. func (c *Conn) startFlushTimer() { if c.flushTimer == nil { - c.flushTimer = time.AfterFunc(mysqlServerFlushDelay, func() { + c.flushTimer = time.AfterFunc(c.flushDelay, func() { c.bufMu.Lock() defer c.bufMu.Unlock() @@ -357,7 +365,7 @@ func (c *Conn) startFlushTimer() { c.bufferedWriter.Flush() }) } else { - c.flushTimer.Reset(mysqlServerFlushDelay) + c.flushTimer.Reset(c.flushDelay) } } diff --git a/go/mysql/conn_fake.go b/go/mysql/conn_fake.go index e61f90d33f1..c20d09a2f6d 100644 --- a/go/mysql/conn_fake.go +++ b/go/mysql/conn_fake.go @@ -84,7 +84,7 @@ var _ net.Addr = (*mockAddress)(nil) // GetTestConn returns a conn for testing purpose only. func GetTestConn() *Conn { - return newConn(testConn{}) + return newConn(testConn{}, DefaultFlushDelay) } // GetTestServerConn is only meant to be used for testing. diff --git a/go/mysql/conn_flaky_test.go b/go/mysql/conn_flaky_test.go index 9df52a47589..0057aff5aa6 100644 --- a/go/mysql/conn_flaky_test.go +++ b/go/mysql/conn_flaky_test.go @@ -77,8 +77,8 @@ func createSocketPair(t *testing.T) (net.Listener, *Conn, *Conn) { require.Nil(t, serverErr, "Accept failed: %v", serverErr) // Create a Conn on both sides. - cConn := newConn(clientConn) - sConn := newConn(serverConn) + cConn := newConn(clientConn, DefaultFlushDelay) + sConn := newConn(serverConn, DefaultFlushDelay) sConn.PrepareData = map[uint32]*PrepareData{} return listener, sConn, cConn @@ -942,7 +942,7 @@ func TestConnectionErrorWhileWritingComQuery(t *testing.T) { 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}, - }) + }, DefaultFlushDelay) // this handler will return an error on the first run, and fail the test if it's run more times errorString := make([]byte, 17000) @@ -958,7 +958,7 @@ func TestConnectionErrorWhileWritingComStmtSendLongData(t *testing.T) { 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}, - }) + }, DefaultFlushDelay) // this handler will return an error on the first run, and fail the test if it's run more times handler := &testRun{t: t, err: fmt.Errorf("not used")} @@ -972,7 +972,7 @@ func TestConnectionErrorWhileWritingComPrepare(t *testing.T) { writeToPass: []bool{false}, pos: -1, queryPacket: []byte{0x01, 0x00, 0x00, 0x00, ComPrepare}, - }) + }, DefaultFlushDelay) 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 := &testRun{t: t, err: fmt.Errorf("not used")} @@ -987,7 +987,7 @@ func TestConnectionErrorWhileWritingComStmtExecute(t *testing.T) { 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}, - }) + }, DefaultFlushDelay) // this handler will return an error on the first run, and fail the test if it's run more times handler := &testRun{t: t, err: fmt.Errorf("not used")} res := sConn.handleNextCommand(handler) diff --git a/go/mysql/conn_params.go b/go/mysql/conn_params.go index 061aa23f220..83b2dc78304 100644 --- a/go/mysql/conn_params.go +++ b/go/mysql/conn_params.go @@ -17,6 +17,8 @@ limitations under the License. package mysql import ( + "time" + "vitess.io/vitess/go/vt/vttls" ) @@ -57,6 +59,9 @@ type ConnParams struct { // for informative purposes. It has no programmatic value. Returning this field is // disabled by default. EnableQueryInfo bool + + // FlushDelay is the delay after which buffered response will be flushed to the client. + FlushDelay time.Duration } // EnableSSL will set the right flag on the parameters. diff --git a/go/mysql/fakesqldb/server.go b/go/mysql/fakesqldb/server.go index cb3d20ae04b..bd5435e6988 100644 --- a/go/mysql/fakesqldb/server.go +++ b/go/mysql/fakesqldb/server.go @@ -189,7 +189,7 @@ func New(t testing.TB) *DB { authServer := mysql.NewAuthServerNone() // Start listening. - db.listener, err = mysql.NewListener("unix", socketFile, authServer, db, 0, 0, false, false, 0) + db.listener, err = mysql.NewListener("unix", socketFile, authServer, db, 0, 0, false, false, 0, 0, "8.0.30-Vitess") if err != nil { t.Fatalf("NewListener failed: %v", err) } diff --git a/go/mysql/handshake_test.go b/go/mysql/handshake_test.go index c2b27d6f6d4..57ed604daae 100644 --- a/go/mysql/handshake_test.go +++ b/go/mysql/handshake_test.go @@ -45,7 +45,7 @@ func TestClearTextClientAuth(t *testing.T) { defer authServer.close() // Create the listener. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() @@ -99,7 +99,7 @@ func TestSSLConnection(t *testing.T) { defer authServer.close() // Create the listener, so we can get its host. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() diff --git a/go/mysql/ldapauthserver/auth_server_ldap.go b/go/mysql/ldapauthserver/auth_server_ldap.go index d5fcea027ac..5e6010fac0e 100644 --- a/go/mysql/ldapauthserver/auth_server_ldap.go +++ b/go/mysql/ldapauthserver/auth_server_ldap.go @@ -24,32 +24,16 @@ import ( "sync" "time" - "github.com/spf13/pflag" - ldap "gopkg.in/ldap.v2" + "gopkg.in/ldap.v2" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vttls" querypb "vitess.io/vitess/go/vt/proto/query" ) -var ( - ldapAuthConfigFile string - ldapAuthConfigString string - ldapAuthMethod string -) - -func init() { - servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) { - fs.StringVar(&ldapAuthConfigFile, "mysql_ldap_auth_config_file", "", "JSON File from which to read LDAP server config.") - fs.StringVar(&ldapAuthConfigString, "mysql_ldap_auth_config_string", "", "JSON representation of LDAP server config.") - fs.StringVar(&ldapAuthMethod, "mysql_ldap_auth_method", string(mysql.MysqlClearPassword), "client-side authentication method to use. Supported values: mysql_clear_password, dialog.") - }) -} - // AuthServerLdap implements AuthServer with an LDAP backend type AuthServerLdap struct { Client @@ -63,7 +47,7 @@ type AuthServerLdap struct { } // Init is public so it can be called from plugin_auth_ldap.go (go/cmd/vtgate) -func Init() { +func Init(ldapAuthConfigFile, ldapAuthConfigString, ldapAuthMethod string) { if ldapAuthConfigFile == "" && ldapAuthConfigString == "" { log.Infof("Not configuring AuthServerLdap because mysql_ldap_auth_config_file and mysql_ldap_auth_config_string are empty") return diff --git a/go/mysql/mysql_fuzzer.go b/go/mysql/mysql_fuzzer.go index 2a3e797a797..057f2ac01c3 100644 --- a/go/mysql/mysql_fuzzer.go +++ b/go/mysql/mysql_fuzzer.go @@ -76,8 +76,8 @@ func createFuzzingSocketPair() (net.Listener, *Conn, *Conn) { } // Create a Conn on both sides. - cConn := newConn(clientConn) - sConn := newConn(serverConn) + cConn := newConn(clientConn, DefaultFlushDelay) + sConn := newConn(serverConn, DefaultFlushDelay) return listener, sConn, cConn } @@ -196,7 +196,7 @@ func FuzzHandleNextCommand(data []byte) int { writeToPass: []bool{false}, pos: -1, queryPacket: data, - }) + }, DefaultFlushDelay) sConn.PrepareData = map[uint32]*PrepareData{} handler := &fuzztestRun{} @@ -327,7 +327,7 @@ func FuzzTLSServer(data []byte) int { Password: "password1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, 0, "8.0.30-Vitess") if err != nil { return -1 } diff --git a/go/mysql/server.go b/go/mysql/server.go index ec2d7538daa..1e321bae9d4 100644 --- a/go/mysql/server.go +++ b/go/mysql/server.go @@ -39,7 +39,6 @@ import ( "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vterrors" ) @@ -212,6 +211,9 @@ type Listener struct { // handled further by the MySQL handler. An non-nil error will stop // processing the connection by the MySQL handler. PreHandleFunc func(context.Context, net.Conn, uint32) (net.Conn, error) + + // flushDelay is the delay after which buffered response will be flushed to the client. + flushDelay time.Duration } // NewFromListener creates a new mysql listener from an existing net.Listener @@ -223,6 +225,8 @@ func NewFromListener( connWriteTimeout time.Duration, connBufferPooling bool, keepAlivePeriod time.Duration, + flushDelay time.Duration, + mysqlServerVersion string, ) (*Listener, error) { cfg := ListenerConfig{ Listener: l, @@ -233,6 +237,8 @@ func NewFromListener( ConnReadBufferSize: connBufferSize, ConnBufferPooling: connBufferPooling, ConnKeepAlivePeriod: keepAlivePeriod, + FlushDelay: flushDelay, + MySQLServerVersion: mysqlServerVersion, } return NewListenerWithConfig(cfg) } @@ -247,6 +253,8 @@ func NewListener( proxyProtocol bool, connBufferPooling bool, keepAlivePeriod time.Duration, + flushDelay time.Duration, + mysqlServerVersion string, ) (*Listener, error) { listener, err := net.Listen(protocol, address) if err != nil { @@ -254,10 +262,10 @@ func NewListener( } if proxyProtocol { proxyListener := &proxyproto.Listener{Listener: listener} - return NewFromListener(proxyListener, authServer, handler, connReadTimeout, connWriteTimeout, connBufferPooling, keepAlivePeriod) + return NewFromListener(proxyListener, authServer, handler, connReadTimeout, connWriteTimeout, connBufferPooling, keepAlivePeriod, flushDelay, mysqlServerVersion) } - return NewFromListener(listener, authServer, handler, connReadTimeout, connWriteTimeout, connBufferPooling, keepAlivePeriod) + return NewFromListener(listener, authServer, handler, connReadTimeout, connWriteTimeout, connBufferPooling, keepAlivePeriod, flushDelay, mysqlServerVersion) } // ListenerConfig should be used with NewListenerWithConfig to specify listener parameters. @@ -273,6 +281,8 @@ type ListenerConfig struct { ConnReadBufferSize int ConnBufferPooling bool ConnKeepAlivePeriod time.Duration + FlushDelay time.Duration + MySQLServerVersion string } // NewListenerWithConfig creates new listener using provided config. There are @@ -293,13 +303,14 @@ func NewListenerWithConfig(cfg ListenerConfig) (*Listener, error) { authServer: cfg.AuthServer, handler: cfg.Handler, listener: l, - ServerVersion: servenv.AppVersion.MySQLVersion(), + ServerVersion: cfg.MySQLServerVersion, connectionID: 1, connReadTimeout: cfg.ConnReadTimeout, connWriteTimeout: cfg.ConnWriteTimeout, connReadBufferSize: cfg.ConnReadBufferSize, connBufferPooling: cfg.ConnBufferPooling, connKeepAlivePeriod: cfg.ConnKeepAlivePeriod, + flushDelay: cfg.FlushDelay, }, nil } diff --git a/go/mysql/server_flaky_test.go b/go/mysql/server_flaky_test.go index 509fccaa47a..e68eab37e9a 100644 --- a/go/mysql/server_flaky_test.go +++ b/go/mysql/server_flaky_test.go @@ -263,6 +263,8 @@ func getHostPort(t *testing.T, a net.Addr) (string, int) { return host, port } +const mysqlVersion = "8.0.30-Vitess" + func TestConnectionFromListener(t *testing.T) { th := &testHandler{} @@ -277,7 +279,7 @@ func TestConnectionFromListener(t *testing.T) { listener, err := net.Listen("tcp", "127.0.0.1:") require.NoError(t, err, "net.Listener failed") - l, err := NewFromListener(listener, authServer, th, 0, 0, false, 0) + l, err := NewFromListener(listener, authServer, th, 0, 0, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -306,7 +308,7 @@ func TestConnectionWithoutSourceHost(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -339,7 +341,7 @@ func TestConnectionWithSourceHost(t *testing.T) { } defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -372,7 +374,7 @@ func TestConnectionUseMysqlNativePasswordWithSourceHost(t *testing.T) { } defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -410,7 +412,7 @@ func TestConnectionUnixSocket(t *testing.T) { os.Remove(unixSocket.Name()) - l, err := NewListener("unix", unixSocket.Name(), authServer, th, 0, 0, false, false, 0) + l, err := NewListener("unix", unixSocket.Name(), authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -436,7 +438,7 @@ func TestClientFoundRows(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -485,7 +487,7 @@ func TestConnCounts(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed") defer l.Close() go l.Accept() @@ -542,7 +544,7 @@ func TestServer(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) l.SlowConnectWarnThreshold.Store(time.Nanosecond.Nanoseconds()) defer l.Close() @@ -642,7 +644,7 @@ func TestServerStats(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) l.SlowConnectWarnThreshold.Store(time.Nanosecond.Nanoseconds()) defer l.Close() @@ -716,7 +718,7 @@ func TestClearTextServer(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() go l.Accept() @@ -789,7 +791,7 @@ func TestDialogServer(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) l.AllowClearTextWithoutTLS.Store(true) defer l.Close() @@ -832,7 +834,7 @@ func TestTLSServer(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -930,7 +932,7 @@ func TestTLSRequired(t *testing.T) { // Below, we are enabling --ssl-verify-server-cert, which adds // a check that the common name of the certificate matches the // server host name we connect to. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() @@ -1019,7 +1021,7 @@ func TestCachingSha2PasswordAuthWithTLS(t *testing.T) { defer authServer.close() // Create the listener, so we can get its host. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() @@ -1113,7 +1115,7 @@ func TestCachingSha2PasswordAuthWithMoreData(t *testing.T) { defer authServer.close() // Create the listener, so we can get its host. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() @@ -1182,7 +1184,7 @@ func TestCachingSha2PasswordAuthWithoutTLS(t *testing.T) { defer authServer.close() // Create the listener. - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err, "NewListener failed: %v", err) defer l.Close() host := l.Addr().(*net.TCPAddr).IP.String() @@ -1224,7 +1226,7 @@ func TestErrorCodes(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() go l.Accept() @@ -1402,7 +1404,7 @@ func TestListenerShutdown(t *testing.T) { UserData: "userData1", }} defer authServer.close() - l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", authServer, th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() go l.Accept() @@ -1470,12 +1472,10 @@ func TestParseConnAttrs(t *testing.T) { } func TestServerFlush(t *testing.T) { - defer func(saved time.Duration) { mysqlServerFlushDelay = saved }(mysqlServerFlushDelay) - mysqlServerFlushDelay = 10 * time.Millisecond - + mysqlServerFlushDelay := 10 * time.Millisecond th := &testHandler{} - l, err := NewListener("tcp", "127.0.0.1:", NewAuthServerNone(), th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", NewAuthServerNone(), th, 0, 0, false, false, 0, mysqlServerFlushDelay, mysqlVersion) require.NoError(t, err) defer l.Close() go l.Accept() @@ -1521,7 +1521,7 @@ func TestServerFlush(t *testing.T) { func TestTcpKeepAlive(t *testing.T) { th := &testHandler{} - l, err := NewListener("tcp", "127.0.0.1:", NewAuthServerNone(), th, 0, 0, false, false, 0) + l, err := NewListener("tcp", "127.0.0.1:", NewAuthServerNone(), th, 0, 0, false, false, 0, 0, mysqlVersion) require.NoError(t, err) defer l.Close() go l.Accept() diff --git a/go/mysql/vault/auth_server_vault.go b/go/mysql/vault/auth_server_vault.go index ccdef9f1d53..d2bc2548817 100644 --- a/go/mysql/vault/auth_server_vault.go +++ b/go/mysql/vault/auth_server_vault.go @@ -28,41 +28,12 @@ import ( "time" vaultapi "github.com/aquarapid/vaultlib" - "github.com/spf13/pflag" - - "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/servenv" ) -var ( - vaultAddr string - vaultTimeout time.Duration - vaultCACert string - vaultPath string - vaultCacheTTL time.Duration - vaultTokenFile string - vaultRoleID string - vaultRoleSecretIDFile string - vaultRoleMountPoint string -) - -func init() { - servenv.OnParseFor("vtgate", func(fs *pflag.FlagSet) { - fs.StringVar(&vaultAddr, "mysql_auth_vault_addr", "", "URL to Vault server") - fs.DurationVar(&vaultTimeout, "mysql_auth_vault_timeout", 10*time.Second, "Timeout for vault API operations") - fs.StringVar(&vaultCACert, "mysql_auth_vault_tls_ca", "", "Path to CA PEM for validating Vault server certificate") - fs.StringVar(&vaultPath, "mysql_auth_vault_path", "", "Vault path to vtgate credentials JSON blob, e.g.: secret/data/prod/vtgatecreds") - fs.DurationVar(&vaultCacheTTL, "mysql_auth_vault_ttl", 30*time.Minute, "How long to cache vtgate credentials from the Vault server") - fs.StringVar(&vaultTokenFile, "mysql_auth_vault_tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") - fs.StringVar(&vaultRoleID, "mysql_auth_vault_roleid", "", "Vault AppRole id; can also be passed using VAULT_ROLEID environment variable") - fs.StringVar(&vaultRoleSecretIDFile, "mysql_auth_vault_role_secretidfile", "", "Path to file containing Vault AppRole secret_id; can also be passed using VAULT_SECRETID environment variable") - fs.StringVar(&vaultRoleMountPoint, "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 { methods []mysql.AuthMethod @@ -80,7 +51,7 @@ type AuthServerVault struct { } // InitAuthServerVault - entrypoint for initialization of Vault AuthServer implementation -func InitAuthServerVault() { +func InitAuthServerVault(vaultAddr string, vaultTimeout time.Duration, vaultCACert, vaultPath string, vaultCacheTTL time.Duration, vaultTokenFile, vaultRoleID, vaultRoleSecretIDFile, vaultRoleMountPoint string) { // Check critical parameters. if vaultAddr == "" { log.Infof("Not configuring AuthServerVault, as --mysql_auth_vault_addr is empty.") diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 00eb5e1b605..c3a67b1d7e1 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -74,6 +74,8 @@ var ( mysqlDefaultWorkloadName = "OLTP" mysqlDefaultWorkload int32 + + mysqlServerFlushDelay = 100 * time.Millisecond ) func registerPluginFlags(fs *pflag.FlagSet) { @@ -97,6 +99,7 @@ func registerPluginFlags(fs *pflag.FlagSet) { fs.DurationVar(&mysqlQueryTimeout, "mysql_server_query_timeout", mysqlQueryTimeout, "mysql query timeout") fs.BoolVar(&mysqlConnBufferPooling, "mysql-server-pool-conn-read-buffers", mysqlConnBufferPooling, "If set, the server will pool incoming connection read buffers") fs.DurationVar(&mysqlKeepAlivePeriod, "mysql-server-keepalive-period", mysqlKeepAlivePeriod, "TCP period between keep-alives") + fs.DurationVar(&mysqlServerFlushDelay, "mysql_server_flush_delay", mysqlServerFlushDelay, "Delay after which buffered response will be flushed to the client.") fs.StringVar(&mysqlDefaultWorkloadName, "mysql_default_workload", mysqlDefaultWorkloadName, "Default session workload (OLTP, OLAP, DBA)") } @@ -526,11 +529,12 @@ func initMySQLProtocol(vtgate *VTGate) *mysqlServer { mysqlProxyProtocol, mysqlConnBufferPooling, mysqlKeepAlivePeriod, + mysqlServerFlushDelay, + servenv.MySQLServerVersion(), ) if err != nil { log.Exitf("mysql.NewListener failed: %v", err) } - srv.tcpListener.ServerVersion = servenv.MySQLServerVersion() if mysqlSslCert != "" && mysqlSslKey != "" { tlsVersion, err := vttls.TLSVersionToNumber(mysqlTLSMinVersion) if err != nil { @@ -571,6 +575,8 @@ func newMysqlUnixSocket(address string, authServer mysql.AuthServer, handler mys false, mysqlConnBufferPooling, mysqlKeepAlivePeriod, + mysqlServerFlushDelay, + servenv.MySQLServerVersion(), ) switch err := err.(type) { @@ -603,6 +609,8 @@ func newMysqlUnixSocket(address string, authServer mysql.AuthServer, handler mys false, mysqlConnBufferPooling, mysqlKeepAlivePeriod, + mysqlServerFlushDelay, + servenv.MySQLServerVersion(), ) return listener, listenerErr default: diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index 1aa201b5d4c..21375050a4d 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -348,7 +348,7 @@ func TestGracefulShutdown(t *testing.T) { vh := newVtgateHandler(&VTGate{executor: executor, timings: timings, rowsReturned: rowsReturned, rowsAffected: rowsAffected}) th := &testHandler{} - listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0) + listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0, 0, "8.0.30-Vitess") require.NoError(t, err) defer listener.Close() @@ -378,7 +378,7 @@ func TestGracefulShutdownWithTransaction(t *testing.T) { vh := newVtgateHandler(&VTGate{executor: executor, timings: timings, rowsReturned: rowsReturned, rowsAffected: rowsAffected}) th := &testHandler{} - listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0) + listener, err := mysql.NewListener("tcp", "127.0.0.1:", mysql.NewAuthServerNone(), th, 0, 0, false, false, 0, 0, "8.0.30-Vitess") require.NoError(t, err) defer listener.Close() From 30ee1336ed09da04d81d6484fc8258cc7ca100ff Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Sat, 9 Dec 2023 08:42:18 -0500 Subject: [PATCH 105/119] TabletServer: Handle nil targets properly everywhere (#14734) Signed-off-by: Matt Lord --- .../tabletserver/messager/message_manager.go | 6 +- go/vt/vttablet/tabletserver/state_manager.go | 4 +- go/vt/vttablet/tabletserver/tabletserver.go | 77 ++++++++++++++++--- .../tabletserver/tabletserver_test.go | 72 +++++++++++++++++ 4 files changed, 144 insertions(+), 15 deletions(-) diff --git a/go/vt/vttablet/tabletserver/messager/message_manager.go b/go/vt/vttablet/tabletserver/messager/message_manager.go index be2e0cf7034..845eaf8df40 100644 --- a/go/vt/vttablet/tabletserver/messager/message_manager.go +++ b/go/vt/vttablet/tabletserver/messager/message_manager.go @@ -28,17 +28,17 @@ import ( "golang.org/x/sync/semaphore" "vitess.io/vitess/go/mysql/replication" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/timer" "vitess.io/vitess/go/vt/log" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" ) var ( diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index 75d1a7c7c3b..98ed846600c 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -66,6 +66,8 @@ func (state servingState) String() string { var transitionRetryInterval = 1 * time.Second var logInitTime sync.Once +var ErrNoTarget = vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No target") + // stateManager manages state transition for all the TabletServer // subcomponents. type stateManager struct { @@ -433,7 +435,7 @@ func (sm *stateManager) verifyTargetLocked(ctx context.Context, target *querypb. } } else { if !tabletenv.IsLocalContext(ctx) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No target") + return ErrNoTarget } } return nil diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 5f9310add84..295a85c31fd 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -166,7 +166,7 @@ func NewTabletServer(ctx context.Context, name string, config *tabletenv.TabletC tsOnce.Do(func() { srvTopoServer = srvtopo.NewResilientServer(ctx, topoServer, "TabletSrvTopo") }) tabletTypeFunc := func() topodatapb.TabletType { - if tsv.sm == nil { + if tsv.sm == nil || tsv.sm.Target() == nil { return topodatapb.TabletType_UNKNOWN } return tsv.sm.Target().TabletType @@ -551,7 +551,11 @@ func (tsv *TabletServer) begin(ctx context.Context, target *querypb.Target, save logStats.OriginalSQL = beginSQL if beginSQL != "" { tsv.stats.QueryTimings.Record("BEGIN", startTime) - tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), startTime) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), startTime) } else { logStats.Method = "" } @@ -585,6 +589,24 @@ func (tsv *TabletServer) getPriorityFromOptions(options *querypb.ExecuteOptions) return optionsPriority } +// resolveTargetType returns the appropriate target tablet type for a +// TabletServer request. If the caller has a local context then it's +// an internal request and the target is the local tablet's current +// target. If it's not a local context then there should always be a +// non-nil target specified. +func (tsv *TabletServer) resolveTargetType(ctx context.Context, target *querypb.Target) (topodatapb.TabletType, error) { + if target != nil { + return target.TabletType, nil + } + if !tabletenv.IsLocalContext(ctx) { + return topodatapb.TabletType_UNKNOWN, ErrNoTarget + } + if tsv.sm.Target() == nil { + return topodatapb.TabletType_UNKNOWN, nil // This is true, and does not block the request + } + return tsv.sm.Target().TabletType, nil +} + // Commit commits the specified transaction. func (tsv *TabletServer) Commit(ctx context.Context, target *querypb.Target, transactionID int64) (newReservedID int64, err error) { err = tsv.execRequest( @@ -607,7 +629,11 @@ func (tsv *TabletServer) Commit(ctx context.Context, target *querypb.Target, tra // handlePanicAndSendLogStats doesn't log the no-op. if commitSQL != "" { tsv.stats.QueryTimings.Record("COMMIT", startTime) - tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), startTime) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), startTime) } else { logStats.Method = "" } @@ -625,7 +651,11 @@ func (tsv *TabletServer) Rollback(ctx context.Context, target *querypb.Target, t target, nil, true, /* allowOnShutdown */ func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("ROLLBACK", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) logStats.TransactionID = transactionID newReservedID, err = tsv.te.Rollback(ctx, transactionID) if newReservedID > 0 { @@ -836,6 +866,10 @@ func (tsv *TabletServer) execute(ctx context.Context, target *querypb.Target, sq return err } } + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } qre := &QueryExecutor{ query: query, marginComments: comments, @@ -846,7 +880,7 @@ func (tsv *TabletServer) execute(ctx context.Context, target *querypb.Target, sq ctx: ctx, logStats: logStats, tsv: tsv, - tabletType: target.GetTabletType(), + tabletType: targetType, setting: connSetting, } result, err = qre.Execute() @@ -1240,7 +1274,11 @@ func (tsv *TabletServer) ReserveBeginExecute(ctx context.Context, target *queryp target, options, false, /* allowOnShutdown */ func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("RESERVE", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) connID, sessionStateChanges, err = tsv.te.ReserveBegin(ctx, options, preQueries, postBeginQueries) if err != nil { return err @@ -1286,7 +1324,11 @@ func (tsv *TabletServer) ReserveBeginStreamExecute( target, options, false, /* allowOnShutdown */ func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("RESERVE", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) connID, sessionStateChanges, err = tsv.te.ReserveBegin(ctx, options, preQueries, postBeginQueries) if err != nil { return err @@ -1340,7 +1382,11 @@ func (tsv *TabletServer) ReserveExecute(ctx context.Context, target *querypb.Tar target, options, allowOnShutdown, func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("RESERVE", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) state.ReservedID, err = tsv.te.Reserve(ctx, options, transactionID, preQueries) if err != nil { return err @@ -1391,7 +1437,11 @@ func (tsv *TabletServer) ReserveStreamExecute( target, options, allowOnShutdown, func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("RESERVE", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) state.ReservedID, err = tsv.te.Reserve(ctx, options, transactionID, preQueries) if err != nil { return err @@ -1421,7 +1471,11 @@ func (tsv *TabletServer) Release(ctx context.Context, target *querypb.Target, tr target, nil, true, /* allowOnShutdown */ func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tsv.stats.QueryTimings.Record("RELEASE", time.Now()) - defer tsv.stats.QueryTimingsByTabletType.Record(target.TabletType.String(), time.Now()) + targetType, err := tsv.resolveTargetType(ctx, target) + if err != nil { + return err + } + defer tsv.stats.QueryTimingsByTabletType.Record(targetType.String(), time.Now()) logStats.TransactionID = transactionID logStats.ReservedID = reservedID if reservedID != 0 { @@ -1429,7 +1483,7 @@ func (tsv *TabletServer) Release(ctx context.Context, target *querypb.Target, tr return tsv.te.Release(reservedID) } // Rollback to cleanup the transaction before returning to the pool. - _, err := tsv.te.Rollback(ctx, transactionID) + _, err = tsv.te.Rollback(ctx, transactionID) return err }, ) @@ -1505,6 +1559,7 @@ func (tsv *TabletServer) execRequest( span.Annotate("workload_name", options.WorkloadName) } trace.AnnotateSQL(span, sqlparser.Preview(sql)) + // With a tabletenv.LocalContext() the target will be nil. if target != nil { span.Annotate("cell", target.Cell) span.Annotate("shard", target.Shard) diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index a72a1aa76db..d8595630480 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -566,6 +566,78 @@ func TestTabletServerCommitPrepared(t *testing.T) { require.NoError(t, err) } +// TestTabletServerWithNilTarget confirms that a nil target is +// handled correctly. This means that when a local context is +// used, the target type is inferred from the local tablet's +// latest target type. +// And if it's not a local context then we return an error. +func TestTabletServerWithNilTarget(t *testing.T) { + // A non-nil target is required when not using a local context. + ctx := tabletenv.LocalContext() + db, tsv := setupTabletServerTest(t, ctx, "") + defer tsv.StopService() + defer db.Close() + + // With a nil target, the local tablet's latest target type is + // what should be used as the inferred target type for our local + // calls. + target := (*querypb.Target)(nil) + localTargetType := topodatapb.TabletType_RDONLY // Use a non-default type + err := tsv.SetServingType(localTargetType, time.Now(), true, "test") + require.NoError(t, err) + + baseKey := "TabletServerTest" // Our TabletServer's name + fullKey := fmt.Sprintf("%s.%s", baseKey, localTargetType.String()) + + executeSQL := "select * from test_table limit 1000" + executeSQLResult := &sqltypes.Result{ + Fields: []*querypb.Field{ + {Type: sqltypes.VarBinary}, + }, + Rows: [][]sqltypes.Value{ + {sqltypes.NewVarBinary("row01")}, + }, + } + // BEGIN gets transmuted to this since it's a RDONLY tablet. + db.AddQuery("start transaction read only", &sqltypes.Result{}) + db.AddQuery(executeSQL, executeSQLResult) + + expectedCount := tsv.stats.QueryTimingsByTabletType.Counts()[fullKey] + + state, err := tsv.Begin(ctx, target, nil) + require.NoError(t, err) + expectedCount++ + require.Equal(t, expectedCount, tsv.stats.QueryTimingsByTabletType.Counts()[fullKey]) + + _, err = tsv.Execute(ctx, target, executeSQL, nil, state.TransactionID, 0, nil) + require.NoError(t, err) + expectedCount++ + require.Equal(t, expectedCount, tsv.stats.QueryTimingsByTabletType.Counts()[fullKey]) + + _, err = tsv.Rollback(ctx, target, state.TransactionID) + require.NoError(t, err) + expectedCount++ + require.Equal(t, expectedCount, tsv.stats.QueryTimingsByTabletType.Counts()[fullKey]) + + state, err = tsv.Begin(ctx, target, nil) + require.NoError(t, err) + expectedCount++ + require.Equal(t, expectedCount, tsv.stats.QueryTimingsByTabletType.Counts()[fullKey]) + + _, err = tsv.Commit(ctx, target, state.TransactionID) + require.NoError(t, err) + expectedCount++ + require.Equal(t, expectedCount, tsv.stats.QueryTimingsByTabletType.Counts()[fullKey]) + + // Finally be sure that we return an error now as expected when NOT + // using a local context but passing a nil target. + nonLocalCtx := context.Background() + _, err = tsv.Begin(nonLocalCtx, target, nil) + require.True(t, errors.Is(err, ErrNoTarget)) + _, err = tsv.resolveTargetType(nonLocalCtx, target) + require.True(t, errors.Is(err, ErrNoTarget)) +} + func TestSmallerTimeout(t *testing.T) { testcases := []struct { t1, t2, want time.Duration From 76081ef5e1bbd0da0de57c5cc3fd7893d3cea9b9 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Mon, 11 Dec 2023 03:50:21 -0500 Subject: [PATCH 106/119] Replication: Have the DB flavor process waiting for a pos (#14745) Signed-off-by: Matt Lord --- go/mysql/flavor.go | 33 ++++++++++----------- go/mysql/flavor_filepos.go | 44 ++++++++++++++++++++++++---- go/mysql/flavor_mariadb.go | 42 +++++++++++++++++++++------ go/mysql/flavor_mysql.go | 44 +++++++++++++++++++++------- go/vt/mysqlctl/replication.go | 54 +++++++++-------------------------- 5 files changed, 134 insertions(+), 83 deletions(-) diff --git a/go/mysql/flavor.go b/go/mysql/flavor.go index a8c2de2e114..2c6fb2b867f 100644 --- a/go/mysql/flavor.go +++ b/go/mysql/flavor.go @@ -146,11 +146,10 @@ type flavor interface { // with parsed executed position. primaryStatus(c *Conn) (replication.PrimaryStatus, error) - // waitUntilPositionCommand returns the SQL command to issue - // to wait until the given position, until the context - // expires. The command returns -1 if it times out. It - // returns NULL if GTIDs are not enabled. - waitUntilPositionCommand(ctx context.Context, pos replication.Position) (string, error) + // waitUntilPosition waits until the given position is reached or + // until the context expires. It returns an error if we did not + // succeed. + waitUntilPosition(ctx context.Context, c *Conn, pos replication.Position) error baseShowTables() string baseShowTablesWithSizes() string @@ -166,7 +165,8 @@ type CapableOf func(capability FlavorCapability) (bool, error) var flavors = make(map[string]func() flavor) // ServerVersionAtLeast returns true if current server is at least given value. -// Example: if input is []int{8, 0, 23}... the function returns 'true' if we're on MySQL 8.0.23, 8.0.24, ... +// Example: if input is []int{8, 0, 23}... the function returns 'true' if we're +// on MySQL 8.0.23, 8.0.24, ... func ServerVersionAtLeast(serverVersion string, parts ...int) (bool, error) { versionPrefix := strings.Split(serverVersion, "-")[0] versionTokens := strings.Split(versionPrefix, ".") @@ -448,21 +448,18 @@ func (c *Conn) ShowPrimaryStatus() (replication.PrimaryStatus, error) { return c.flavor.primaryStatus(c) } -// WaitUntilPositionCommand returns the SQL command to issue -// to wait until the given position, until the context -// expires. The command returns -1 if it times out. It -// returns NULL if GTIDs are not enabled. -func (c *Conn) WaitUntilPositionCommand(ctx context.Context, pos replication.Position) (string, error) { - return c.flavor.waitUntilPositionCommand(ctx, pos) +// WaitUntilPosition waits until the given position is reached or until the +// context expires. It returns an error if we did not succeed. +func (c *Conn) WaitUntilPosition(ctx context.Context, pos replication.Position) error { + return c.flavor.waitUntilPosition(ctx, c, pos) } -// WaitUntilFilePositionCommand returns the SQL command to issue -// to wait until the given position, until the context -// expires for the file position flavor. The command returns -1 if it times out. It -// returns NULL if GTIDs are not enabled. -func (c *Conn) WaitUntilFilePositionCommand(ctx context.Context, pos replication.Position) (string, error) { +// WaitUntilFilePosition waits until the given position is reached or until +// the context expires for the file position flavor. It returns an error if +// we did not succeed. +func (c *Conn) WaitUntilFilePosition(ctx context.Context, pos replication.Position) error { filePosFlavor := filePosFlavor{} - return filePosFlavor.waitUntilPositionCommand(ctx, pos) + return filePosFlavor.waitUntilPosition(ctx, c, pos) } // BaseShowTables returns a query that shows tables diff --git a/go/mysql/flavor_filepos.go b/go/mysql/flavor_filepos.go index bf4076b85b1..96939faf3c4 100644 --- a/go/mysql/flavor_filepos.go +++ b/go/mysql/flavor_filepos.go @@ -266,22 +266,54 @@ func (flv *filePosFlavor) primaryStatus(c *Conn) (replication.PrimaryStatus, err return replication.ParseFilePosPrimaryStatus(resultMap) } -// waitUntilPositionCommand is part of the Flavor interface. -func (flv *filePosFlavor) waitUntilPositionCommand(ctx context.Context, pos replication.Position) (string, error) { +// waitUntilPosition is part of the Flavor interface. +func (flv *filePosFlavor) waitUntilPosition(ctx context.Context, c *Conn, pos replication.Position) error { filePosPos, ok := pos.GTIDSet.(replication.FilePosGTID) if !ok { - return "", fmt.Errorf("Position is not filePos compatible: %#v", pos.GTIDSet) + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "position is not filePos compatible: %#v", pos.GTIDSet) } + query := fmt.Sprintf("SELECT MASTER_POS_WAIT('%s', %d)", filePosPos.File, filePosPos.Pos) if deadline, ok := ctx.Deadline(); ok { timeout := time.Until(deadline) if timeout <= 0 { - return "", fmt.Errorf("timed out waiting for position %v", pos) + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) } - return fmt.Sprintf("SELECT MASTER_POS_WAIT('%s', %d, %.6f)", filePosPos.File, filePosPos.Pos, timeout.Seconds()), nil + query = fmt.Sprintf("SELECT MASTER_POS_WAIT('%s', %d, %.6f)", filePosPos.File, filePosPos.Pos, timeout.Seconds()) } - return fmt.Sprintf("SELECT MASTER_POS_WAIT('%s', %d)", filePosPos.File, filePosPos.Pos), nil + result, err := c.ExecuteFetch(query, 1, false) + if err != nil { + return err + } + + // For MASTER_POS_WAIT(), the return value is the number of log events + // the replica had to wait for to advance to the specified position. + // The function returns NULL if the replica SQL thread is not started, + // the replica's source information is not initialized, the arguments + // are incorrect, or an error occurs. It returns -1 if the timeout has + // been exceeded. If the replica SQL thread stops while MASTER_POS_WAIT() + // is waiting, the function returns NULL. If the replica is past the + // specified position, the function returns immediately. + if len(result.Rows) != 1 || len(result.Rows[0]) != 1 { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid results: %#v", result) + } + val := result.Rows[0][0] + if val.IsNull() { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "replication is not running") + } + state, err := val.ToInt64() + if err != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %#v", val) + } + switch { + case state == -1: + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) + case state >= 0: + return nil + default: + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %d", state) + } } func (*filePosFlavor) startReplicationUntilAfter(pos replication.Position) string { diff --git a/go/mysql/flavor_mariadb.go b/go/mysql/flavor_mariadb.go index 15718542b45..77b1b4f1399 100644 --- a/go/mysql/flavor_mariadb.go +++ b/go/mysql/flavor_mariadb.go @@ -25,8 +25,9 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // mariadbFlavor implements the Flavor interface for MariaDB. @@ -48,7 +49,7 @@ func (mariadbFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { return nil, err } if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected result format for gtid_binlog_pos: %#v", qr) + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result format for gtid_binlog_pos: %#v", qr) } return replication.ParseMariadbGTIDSet(qr.Rows[0][0].ToString()) @@ -223,22 +224,45 @@ func (m mariadbFlavor) primaryStatus(c *Conn) (replication.PrimaryStatus, error) return status, err } -// waitUntilPositionCommand is part of the Flavor interface. +// waitUntilPosition is part of the Flavor interface. // // Note: Unlike MASTER_POS_WAIT(), MASTER_GTID_WAIT() will continue waiting even // if the sql thread stops. If that is a problem, we'll have to change this. -func (mariadbFlavor) waitUntilPositionCommand(ctx context.Context, pos replication.Position) (string, error) { +func (mariadbFlavor) waitUntilPosition(ctx context.Context, c *Conn, pos replication.Position) error { + // Omit the timeout to wait indefinitely. In MariaDB, a timeout of 0 means + // return immediately. + query := fmt.Sprintf("SELECT MASTER_GTID_WAIT('%s')", pos) if deadline, ok := ctx.Deadline(); ok { timeout := time.Until(deadline) if timeout <= 0 { - return "", vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) } - return fmt.Sprintf("SELECT MASTER_GTID_WAIT('%s', %.6f)", pos, timeout.Seconds()), nil + query = fmt.Sprintf("SELECT MASTER_GTID_WAIT('%s', %.6f)", pos, timeout.Seconds()) } - // Omit the timeout to wait indefinitely. In MariaDB, a timeout of 0 means - // return immediately. - return fmt.Sprintf("SELECT MASTER_GTID_WAIT('%s')", pos), nil + result, err := c.ExecuteFetch(query, 1, false) + if err != nil { + return err + } + + // For MASTER_GTID_WAIT(), if the wait completes without a timeout 0 is + // returned and -1 if there was a timeout. + if len(result.Rows) != 1 || len(result.Rows[0]) != 1 { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid results: %#v", result) + } + val := result.Rows[0][0] + state, err := val.ToInt64() + if err != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %#v", val) + } + switch state { + case 0: + return nil + case -1: + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) + default: + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %d", state) + } } // readBinlogEvent is part of the Flavor interface. diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index be11126ff9c..a3a449f5490 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -24,8 +24,9 @@ import ( "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // mysqlFlavor implements the Flavor interface for Mysql. @@ -52,7 +53,7 @@ func (mysqlFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { return nil, err } if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected result format for gtid_executed: %#v", qr) + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result format for gtid_executed: %#v", qr) } return replication.ParseMysql56GTIDSet(qr.Rows[0][0].ToString()) } @@ -65,7 +66,7 @@ func (mysqlFlavor) purgedGTIDSet(c *Conn) (replication.GTIDSet, error) { return nil, err } if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected result format for gtid_purged: %#v", qr) + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result format for gtid_purged: %#v", qr) } return replication.ParseMysql56GTIDSet(qr.Rows[0][0].ToString()) } @@ -78,7 +79,7 @@ func (mysqlFlavor) serverUUID(c *Conn) (string, error) { return "", err } if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return "", vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected result format for server_uuid: %#v", qr) + return "", vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result format for server_uuid: %#v", qr) } return qr.Rows[0][0].ToString(), nil } @@ -90,7 +91,7 @@ func (mysqlFlavor) gtidMode(c *Conn) (string, error) { return "", err } if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return "", vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected result format for gtid_mode: %#v", qr) + return "", vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result format for gtid_mode: %#v", qr) } return qr.Rows[0][0].ToString(), nil } @@ -135,7 +136,7 @@ func (mysqlFlavor) startSQLThreadCommand() string { func (mysqlFlavor) sendBinlogDumpCommand(c *Conn, serverID uint32, binlogFilename string, startPos replication.Position) error { gtidSet, ok := startPos.GTIDSet.(replication.Mysql56GTIDSet) if !ok { - return vterrors.Errorf(vtrpc.Code_INTERNAL, "startPos.GTIDSet is wrong type - expected Mysql56GTIDSet, got: %#v", startPos.GTIDSet) + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "startPos.GTIDSet is wrong type - expected Mysql56GTIDSet, got: %#v", startPos.GTIDSet) } // Build the command. @@ -216,14 +217,14 @@ func (mysqlFlavor) primaryStatus(c *Conn) (replication.PrimaryStatus, error) { return replication.ParseMysqlPrimaryStatus(resultMap) } -// waitUntilPositionCommand is part of the Flavor interface. -func (mysqlFlavor) waitUntilPositionCommand(ctx context.Context, pos replication.Position) (string, error) { +// waitUntilPosition is part of the Flavor interface. +func (mysqlFlavor) waitUntilPosition(ctx context.Context, c *Conn, pos replication.Position) error { // A timeout of 0 means wait indefinitely. timeoutSeconds := 0 if deadline, ok := ctx.Deadline(); ok { timeout := time.Until(deadline) if timeout <= 0 { - return "", vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) } // Only whole numbers of seconds are supported. @@ -234,7 +235,30 @@ func (mysqlFlavor) waitUntilPositionCommand(ctx context.Context, pos replication } } - return fmt.Sprintf("SELECT WAIT_FOR_EXECUTED_GTID_SET('%s', %v)", pos, timeoutSeconds), nil + query := fmt.Sprintf("SELECT WAIT_FOR_EXECUTED_GTID_SET('%s', %v)", pos, timeoutSeconds) + result, err := c.ExecuteFetch(query, 1, false) + if err != nil { + return err + } + + // For WAIT_FOR_EXECUTED_GTID_SET(), the return value is the state of the query, where + // 0 represents success, and 1 represents timeout. Any other failures generate an error. + if len(result.Rows) != 1 || len(result.Rows[0]) != 1 { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid results: %#v", result) + } + val := result.Rows[0][0] + state, err := val.ToInt64() + if err != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %#v", val) + } + switch state { + case 0: + return nil + case 1: + return vterrors.Errorf(vtrpcpb.Code_DEADLINE_EXCEEDED, "timed out waiting for position %v", pos) + default: + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid result of %d", state) + } } // readBinlogEvent is part of the Flavor interface. diff --git a/go/vt/mysqlctl/replication.go b/go/vt/mysqlctl/replication.go index 23b19669f16..1dd03d901cb 100644 --- a/go/vt/mysqlctl/replication.go +++ b/go/vt/mysqlctl/replication.go @@ -33,6 +33,7 @@ import ( "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/vt/hook" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vterrors" ) type ResetSuperReadOnlyFunc func() error @@ -315,7 +316,8 @@ func (mysqld *Mysqld) SetSuperReadOnly(on bool) (ResetSuperReadOnlyFunc, error) return resetFunc, nil } -// WaitSourcePos lets replicas wait to given replication position +// WaitSourcePos lets replicas wait for the given replication position to +// be reached. func (mysqld *Mysqld) WaitSourcePos(ctx context.Context, targetPos replication.Position) error { // Get a connection. conn, err := getPoolReconnect(ctx, mysqld.dbaPool) @@ -324,61 +326,33 @@ func (mysqld *Mysqld) WaitSourcePos(ctx context.Context, targetPos replication.P } defer conn.Recycle() - // First check if filePos flavored Position was passed in. If so, we can't defer to the flavor in the connection, - // unless that flavor is also filePos. - waitCommandName := "WaitUntilPositionCommand" - var query string + // First check if filePos flavored Position was passed in. If so, we + // can't defer to the flavor in the connection, unless that flavor is + // also filePos. if targetPos.MatchesFlavor(replication.FilePosFlavorID) { - // If we are the primary, WaitUntilFilePositionCommand will fail. - // But position is most likely reached. So, check the position - // first. + // If we are the primary, WaitUntilFilePosition will fail. But + // position is most likely reached. So, check the position first. mpos, err := conn.Conn.PrimaryFilePosition() if err != nil { - return fmt.Errorf("WaitSourcePos: PrimaryFilePosition failed: %v", err) + return vterrors.Wrapf(err, "WaitSourcePos: PrimaryFilePosition failed") } if mpos.AtLeast(targetPos) { return nil } - - // Find the query to run, run it. - query, err = conn.Conn.WaitUntilFilePositionCommand(ctx, targetPos) - if err != nil { - return err - } - waitCommandName = "WaitUntilFilePositionCommand" } else { - // If we are the primary, WaitUntilPositionCommand will fail. - // But position is most likely reached. So, check the position - // first. + // If we are the primary, WaitUntilPosition will fail. But + // position is most likely reached. So, check the position first. mpos, err := conn.Conn.PrimaryPosition() if err != nil { - return fmt.Errorf("WaitSourcePos: PrimaryPosition failed: %v", err) + return vterrors.Wrapf(err, "WaitSourcePos: PrimaryPosition failed") } if mpos.AtLeast(targetPos) { return nil } - - // Find the query to run, run it. - query, err = conn.Conn.WaitUntilPositionCommand(ctx, targetPos) - if err != nil { - return err - } } - qr, err := mysqld.FetchSuperQuery(ctx, query) - if err != nil { - return fmt.Errorf("%v(%v) failed: %v", waitCommandName, query, err) - } - - if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return fmt.Errorf("unexpected result format from %v(%v): %#v", waitCommandName, query, qr) - } - result := qr.Rows[0][0] - if result.IsNull() { - return fmt.Errorf("%v(%v) failed: replication is probably stopped", waitCommandName, query) - } - if result.ToString() == "-1" { - return fmt.Errorf("timed out waiting for position %v", targetPos) + if err := conn.Conn.WaitUntilPosition(ctx, targetPos); err != nil { + return vterrors.Wrapf(err, "WaitSourcePos failed") } return nil } From ff40d039b4c3279da68c646bbbe14285e62a3488 Mon Sep 17 00:00:00 2001 From: Tyler Date: Mon, 11 Dec 2023 09:52:03 -0800 Subject: [PATCH 107/119] Debug vars: Expose build version in `/debug/vars` (#14713) Signed-off-by: Tyler Coleman --- changelog/19.0/19.0.0/summary.md | 5 +++++ go/vt/servenv/buildinfo.go | 3 +++ go/vt/servenv/buildinfo_test.go | 5 +++++ go/vt/vtgate/vtgate.go | 2 +- test/README.md | 2 +- web/vtadmin/src/util/tabletDebugVars.ts | 1 + 6 files changed, 16 insertions(+), 2 deletions(-) diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index a303dff02cc..eafea7b163e 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -10,6 +10,7 @@ - [New MySQL Image](#mysql-image) - **[New Stats](#new-stats)** - [Stream Consolidations](#stream-consolidations) + - [Build Version in `/debug/vars`](#build-version-in-debug-vars) - **[VTGate](#vtgate)** - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) - **[Vttestserver](#vttestserver)** @@ -53,6 +54,10 @@ Several tags are available to let you choose what version of MySQL you want to u Prior to 19.0 VTTablet reported how much time non-streaming executions spend waiting for consolidations to occur. In 19.0, VTTablet reports a similar stat for streaming executions in `/debug/vars` stat `Waits.Histograms.StreamConsolidations`. +#### Build Version in `/debug/vars` + +The build version (e.g., `19.0.0-SNAPSHOT`) has been added to `/debug/vars`, allowing users to programmatically inspect Vitess components' build version at runtime. + ### VTGate #### `FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable diff --git a/go/vt/servenv/buildinfo.go b/go/vt/servenv/buildinfo.go index 15e34217dae..d55e01d84c0 100644 --- a/go/vt/servenv/buildinfo.go +++ b/go/vt/servenv/buildinfo.go @@ -33,6 +33,7 @@ var ( buildTime = "" buildGitRev = "" buildGitBranch = "" + statsBuildVersion *stats.String jenkinsBuildNumberStr = "" // version registers the command line flag to expose build info. @@ -121,6 +122,8 @@ func init() { stats.NewString("BuildHost").Set(AppVersion.buildHost) stats.NewString("BuildUser").Set(AppVersion.buildUser) stats.NewGauge("BuildTimestamp", "build timestamp").Set(AppVersion.buildTime) + statsBuildVersion = stats.NewString("BuildVersion") + statsBuildVersion.Set(AppVersion.version) stats.NewString("BuildGitRev").Set(AppVersion.buildGitRev) stats.NewString("BuildGitBranch").Set(AppVersion.buildGitBranch) stats.NewGauge("BuildNumber", "build number").Set(AppVersion.jenkinsBuildNumber) diff --git a/go/vt/servenv/buildinfo_test.go b/go/vt/servenv/buildinfo_test.go index be35511a036..bc972df03ea 100644 --- a/go/vt/servenv/buildinfo_test.go +++ b/go/vt/servenv/buildinfo_test.go @@ -47,3 +47,8 @@ func TestVersionString(t *testing.T) { assert.Equal(t, "8.0.30-Vitess", v.MySQLVersion()) } + +func TestBuildVersionStats(t *testing.T) { + buildVersion := statsBuildVersion.Get() + assert.Equal(t, buildVersion, versionName) +} diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index a5ace194c2f..64260e628f0 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -190,7 +190,7 @@ var ( vstreamSkewDelayCount = stats.NewCounter("VStreamEventsDelayedBySkewAlignment", "Number of events that had to wait because the skew across shards was too high") - vindexUnknownParams = stats.NewGauge("VindexUnknownParameters", "Number of parameterss unrecognized by Vindexes") + vindexUnknownParams = stats.NewGauge("VindexUnknownParameters", "Number of parameters unrecognized by Vindexes") timings = stats.NewMultiTimings( "VtgateApi", diff --git a/test/README.md b/test/README.md index 5fd5fadbedb..6579245ef45 100644 --- a/test/README.md +++ b/test/README.md @@ -1,4 +1,4 @@ -##Github CI Workflows +## Github CI Workflows This document has a short outline of how tests are run in CI, how to add new tests and where these are configured. diff --git a/web/vtadmin/src/util/tabletDebugVars.ts b/web/vtadmin/src/util/tabletDebugVars.ts index 37ea08e49b1..1d01ec16bee 100644 --- a/web/vtadmin/src/util/tabletDebugVars.ts +++ b/web/vtadmin/src/util/tabletDebugVars.ts @@ -33,6 +33,7 @@ export type TabletDebugVars = Partial<{ BuildNumber: string; BuildTimestamp: string; BuildUser: string; + BuildVersion: string; QPS: { [k: string]: number[] }; From a8550d85ca42fe1c67cced5de617944e06a83043 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:31:44 +0100 Subject: [PATCH 108/119] Keyspace ServedFrom: remove this deprecated attribute and related code (#14694) Signed-off-by: Rohit Nayak --- go/cmd/vtctldclient/command/keyspaces.go | 17 - .../vtcombo/recreate/recreate_test.go | 3 +- .../endtoend/vtcombo/vttest_sample_test.go | 14 - go/vt/discovery/keyspace_events_test.go | 9 +- go/vt/proto/topodata/topodata.pb.go | 582 +-- go/vt/proto/topodata/topodata_vtproto.pb.go | 536 -- go/vt/proto/vtctldata/vtctldata.pb.go | 4614 ++++++++--------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 534 -- go/vt/proto/vttest/vttest.pb.go | 50 +- go/vt/proto/vttest/vttest_vtproto.pb.go | 44 - go/vt/srvtopo/resolver.go | 14 +- go/vt/srvtopo/status.go | 6 - go/vt/topo/keyspace.go | 104 - go/vt/topo/keyspace_test.go | 177 - go/vt/topo/locks.go | 15 - go/vt/topo/test/keyspace.go | 15 +- go/vt/topo/test/serving.go | 6 - go/vt/topotools/keyspace.go | 18 +- go/vt/topotools/rebuild_keyspace.go | 3 +- .../fakevtctldclient/vtctldclient.go | 1 - go/vt/vtcombo/tablet_map.go | 127 +- go/vt/vtctl/grpcvtctldserver/server.go | 42 - go/vt/vtctl/vtctl.go | 14 - go/vt/vtctld/api_test.go | 5 +- go/vt/vtgate/sandbox_test.go | 39 +- go/vt/vttest/local_cluster.go | 8 - go/vt/vttest/randomdata.go | 3 - proto/topodata.proto | 31 +- proto/vtctldata.proto | 18 +- proto/vttest.proto | 6 +- web/vtadmin/src/proto/vtadmin.d.ts | 451 -- web/vtadmin/src/proto/vtadmin.js | 1344 +---- 32 files changed, 2506 insertions(+), 6344 deletions(-) delete mode 100644 go/vt/topo/keyspace_test.go diff --git a/go/cmd/vtctldclient/command/keyspaces.go b/go/cmd/vtctldclient/command/keyspaces.go index 420c274ddd5..6330220d773 100644 --- a/go/cmd/vtctldclient/command/keyspaces.go +++ b/go/cmd/vtctldclient/command/keyspaces.go @@ -30,8 +30,6 @@ import ( "vitess.io/vitess/go/cmd/vtctldclient/cli" "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/topo" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" "vitess.io/vitess/go/vt/proto/vttime" @@ -135,8 +133,6 @@ var createKeyspaceOptions = struct { Force bool AllowEmptyVSchema bool - ServedFromsMap cli.StringMapValue - KeyspaceType cli.KeyspaceTypeFlag BaseKeyspace string SnapshotTimestamp string @@ -203,18 +199,6 @@ func commandCreateKeyspace(cmd *cobra.Command, args []string) error { SidecarDbName: createKeyspaceOptions.SidecarDBName, } - for n, v := range createKeyspaceOptions.ServedFromsMap.StringMapValue { - tt, err := topo.ParseServingTabletType(n) - if err != nil { - return err - } - - req.ServedFroms = append(req.ServedFroms, &topodatapb.Keyspace_ServedFrom{ - TabletType: tt, - Keyspace: v, - }) - } - resp, err := client.CreateKeyspace(commandCtx, req) if err != nil { return err @@ -422,7 +406,6 @@ func commandValidateVersionKeyspace(cmd *cobra.Command, args []string) error { func init() { CreateKeyspace.Flags().BoolVarP(&createKeyspaceOptions.Force, "force", "f", false, "Proceeds even if the keyspace already exists. Does not overwrite the existing keyspace record.") CreateKeyspace.Flags().BoolVarP(&createKeyspaceOptions.AllowEmptyVSchema, "allow-empty-vschema", "e", false, "Allows a new keyspace to have no vschema.") - CreateKeyspace.Flags().Var(&createKeyspaceOptions.ServedFromsMap, "served-from", "Specifies a set of db_type:keyspace pairs used to serve traffic for the keyspace.") CreateKeyspace.Flags().Var(&createKeyspaceOptions.KeyspaceType, "type", "The type of the keyspace.") CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.BaseKeyspace, "base-keyspace", "", "The base keyspace for a snapshot keyspace.") CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.SnapshotTimestamp, "snapshot-timestamp", "", "The snapshot time for a snapshot keyspace, as a timestamp in RFC3339 format.") diff --git a/go/test/endtoend/vtcombo/recreate/recreate_test.go b/go/test/endtoend/vtcombo/recreate/recreate_test.go index a454adbd7e1..e66edb7688a 100644 --- a/go/test/endtoend/vtcombo/recreate/recreate_test.go +++ b/go/test/endtoend/vtcombo/recreate/recreate_test.go @@ -60,8 +60,7 @@ func TestMain(m *testing.M) { ReplicaCount: 2, }, { - Name: redirected, - ServedFrom: ks1, + Name: redirected, }, } diff --git a/go/test/endtoend/vtcombo/vttest_sample_test.go b/go/test/endtoend/vtcombo/vttest_sample_test.go index 91db0f8a2c0..daeb5e8deb9 100644 --- a/go/test/endtoend/vtcombo/vttest_sample_test.go +++ b/go/test/endtoend/vtcombo/vttest_sample_test.go @@ -48,7 +48,6 @@ var ( vtctldAddr string mysqlAddress string ks1 = "test_keyspace" - redirected = "redirected" jsonTopo = ` { "keyspaces": [ @@ -58,10 +57,6 @@ var ( "rdonlyCount": 1, "replicaCount": 2 }, - { - "name": "redirected", - "servedFrom": "test_keyspace" - }, { "name": "routed", "shards": [{"name": "0"}] @@ -174,15 +169,6 @@ func assertInsertedRowsExist(ctx context.Context, t *testing.T, conn *vtgateconn require.NoError(t, err) assert.Equal(t, rowCount, len(res.Rows)) - - cur = conn.Session(redirected+":-80@replica", nil) - bindVariables = map[string]*querypb.BindVariable{ - "id_start": {Type: querypb.Type_UINT64, Value: []byte(strconv.FormatInt(int64(idStart), 10))}, - } - res, err = cur.Execute(ctx, "select * from test_table where id = :id_start", bindVariables) - require.NoError(t, err) - require.Equal(t, 1, len(res.Rows)) - assert.Equal(t, "VARCHAR(\"test1000\")", res.Rows[0][1].String()) } func assertRouting(ctx context.Context, t *testing.T, db *sql.DB) { diff --git a/go/vt/discovery/keyspace_events_test.go b/go/vt/discovery/keyspace_events_test.go index 43af4bf49de..af60479a42b 100644 --- a/go/vt/discovery/keyspace_events_test.go +++ b/go/vt/discovery/keyspace_events_test.go @@ -49,14 +49,7 @@ func TestSrvKeyspaceWithNilNewKeyspace(t *testing.T) { keyspace: keyspace, shards: make(map[string]*shardState), } - kss.lastKeyspace = &topodatapb.SrvKeyspace{ - ServedFrom: []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: keyspace, - }, - }, - } + kss.lastKeyspace = &topodatapb.SrvKeyspace{} require.True(t, kss.onSrvKeyspace(nil, nil)) } diff --git a/go/vt/proto/topodata/topodata.pb.go b/go/vt/proto/topodata/topodata.pb.go index e2a97369ba7..95178a8eb30 100644 --- a/go/vt/proto/topodata/topodata.pb.go +++ b/go/vt/proto/topodata/topodata.pb.go @@ -656,9 +656,6 @@ type Keyspace struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // ServedFrom will redirect the appropriate traffic to - // another keyspace. - ServedFroms []*Keyspace_ServedFrom `protobuf:"bytes,4,rep,name=served_froms,json=servedFroms,proto3" json:"served_froms,omitempty"` // keyspace_type will determine how this keyspace is treated by // vtgate / vschema. Normal keyspaces are routable by // any query. Snapshot keyspaces are only accessible @@ -716,13 +713,6 @@ func (*Keyspace) Descriptor() ([]byte, []int) { return file_topodata_proto_rawDescGZIP(), []int{4} } -func (x *Keyspace) GetServedFroms() []*Keyspace_ServedFrom { - if x != nil { - return x.ServedFroms - } - return nil -} - func (x *Keyspace) GetKeyspaceType() KeyspaceType { if x != nil { return x.KeyspaceType @@ -1172,7 +1162,6 @@ type SrvKeyspace struct { // The partitions this keyspace is serving, per tablet type. Partitions []*SrvKeyspace_KeyspacePartition `protobuf:"bytes,1,rep,name=partitions,proto3" json:"partitions,omitempty"` - ServedFrom []*SrvKeyspace_ServedFrom `protobuf:"bytes,4,rep,name=served_from,json=servedFrom,proto3" json:"served_from,omitempty"` // ThrottlerConfig has the configuration for the tablet server's // lag throttler, and applies to the entire keyspace, across all // shards and tablets. This is copied from the global keyspace @@ -1219,13 +1208,6 @@ func (x *SrvKeyspace) GetPartitions() []*SrvKeyspace_KeyspacePartition { return nil } -func (x *SrvKeyspace) GetServedFrom() []*SrvKeyspace_ServedFrom { - if x != nil { - return x.ServedFrom - } - return nil -} - func (x *SrvKeyspace) GetThrottlerConfig() *ThrottlerConfig { if x != nil { return x.ThrottlerConfig @@ -1666,74 +1648,6 @@ func (x *Shard_TabletControl) GetFrozen() bool { return false } -// ServedFrom indicates a relationship between a TabletType and the -// keyspace name that's serving it. -type Keyspace_ServedFrom struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // the tablet type (key for the map) - TabletType TabletType `protobuf:"varint,1,opt,name=tablet_type,json=tabletType,proto3,enum=topodata.TabletType" json:"tablet_type,omitempty"` - // the cells to limit this to - Cells []string `protobuf:"bytes,2,rep,name=cells,proto3" json:"cells,omitempty"` - // the keyspace name that's serving it - Keyspace string `protobuf:"bytes,3,opt,name=keyspace,proto3" json:"keyspace,omitempty"` -} - -func (x *Keyspace_ServedFrom) Reset() { - *x = Keyspace_ServedFrom{} - if protoimpl.UnsafeEnabled { - mi := &file_topodata_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Keyspace_ServedFrom) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Keyspace_ServedFrom) ProtoMessage() {} - -func (x *Keyspace_ServedFrom) ProtoReflect() protoreflect.Message { - mi := &file_topodata_proto_msgTypes[21] - 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 Keyspace_ServedFrom.ProtoReflect.Descriptor instead. -func (*Keyspace_ServedFrom) Descriptor() ([]byte, []int) { - return file_topodata_proto_rawDescGZIP(), []int{4, 0} -} - -func (x *Keyspace_ServedFrom) GetTabletType() TabletType { - if x != nil { - return x.TabletType - } - return TabletType_UNKNOWN -} - -func (x *Keyspace_ServedFrom) GetCells() []string { - if x != nil { - return x.Cells - } - return nil -} - -func (x *Keyspace_ServedFrom) GetKeyspace() string { - if x != nil { - return x.Keyspace - } - return "" -} - // Node describes a tablet instance within the cell type ShardReplication_Node struct { state protoimpl.MessageState @@ -1746,7 +1660,7 @@ type ShardReplication_Node struct { func (x *ShardReplication_Node) Reset() { *x = ShardReplication_Node{} if protoimpl.UnsafeEnabled { - mi := &file_topodata_proto_msgTypes[22] + mi := &file_topodata_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1759,7 +1673,7 @@ func (x *ShardReplication_Node) String() string { func (*ShardReplication_Node) ProtoMessage() {} func (x *ShardReplication_Node) ProtoReflect() protoreflect.Message { - mi := &file_topodata_proto_msgTypes[22] + mi := &file_topodata_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1798,7 +1712,7 @@ type SrvKeyspace_KeyspacePartition struct { func (x *SrvKeyspace_KeyspacePartition) Reset() { *x = SrvKeyspace_KeyspacePartition{} if protoimpl.UnsafeEnabled { - mi := &file_topodata_proto_msgTypes[24] + mi := &file_topodata_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1811,7 +1725,7 @@ func (x *SrvKeyspace_KeyspacePartition) String() string { func (*SrvKeyspace_KeyspacePartition) ProtoMessage() {} func (x *SrvKeyspace_KeyspacePartition) ProtoReflect() protoreflect.Message { - mi := &file_topodata_proto_msgTypes[24] + mi := &file_topodata_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1848,65 +1762,6 @@ func (x *SrvKeyspace_KeyspacePartition) GetShardTabletControls() []*ShardTabletC return nil } -// ServedFrom indicates a relationship between a TabletType and the -// keyspace name that's serving it. -type SrvKeyspace_ServedFrom struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // the tablet type - TabletType TabletType `protobuf:"varint,1,opt,name=tablet_type,json=tabletType,proto3,enum=topodata.TabletType" json:"tablet_type,omitempty"` - // the keyspace name that's serving it - Keyspace string `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` -} - -func (x *SrvKeyspace_ServedFrom) Reset() { - *x = SrvKeyspace_ServedFrom{} - if protoimpl.UnsafeEnabled { - mi := &file_topodata_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SrvKeyspace_ServedFrom) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SrvKeyspace_ServedFrom) ProtoMessage() {} - -func (x *SrvKeyspace_ServedFrom) ProtoReflect() protoreflect.Message { - mi := &file_topodata_proto_msgTypes[25] - 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 SrvKeyspace_ServedFrom.ProtoReflect.Descriptor instead. -func (*SrvKeyspace_ServedFrom) Descriptor() ([]byte, []int) { - return file_topodata_proto_rawDescGZIP(), []int{11, 1} -} - -func (x *SrvKeyspace_ServedFrom) GetTabletType() TabletType { - if x != nil { - return x.TabletType - } - return TabletType_UNKNOWN -} - -func (x *SrvKeyspace_ServedFrom) GetKeyspace() string { - if x != nil { - return x.Keyspace - } - return "" -} - var File_topodata_proto protoreflect.FileDescriptor var file_topodata_proto_rawDesc = []byte{ @@ -2006,181 +1861,160 @@ var file_topodata_proto_rawDesc = []byte{ 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x03, 0x10, - 0x04, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x85, 0x04, - 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x73, 0x18, 0x04, 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, 0x3b, 0x0a, 0x0d, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 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, 0x0c, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 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, - 0x07, 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, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, - 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x44, - 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x0f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, - 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, - 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x75, 0x0a, 0x0a, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 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, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, - 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x6e, 0x6f, - 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, - 0x73, 0x1a, 0x40, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 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, 0xc6, 0x01, 0x0a, 0x15, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 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, 0x39, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, - 0x55, 0x4e, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, - 0x59, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x02, 0x22, 0x55, 0x0a, 0x0e, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 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, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, - 0x02, 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, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, - 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 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, - 0x34, 0x0a, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x14, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x12, 0x2b, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, - 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x22, 0xce, 0x02, 0x0a, 0x0f, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x53, 0x0a, 0x0e, 0x74, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x1a, 0x5c, 0x0a, 0x12, - 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 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, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb6, 0x04, 0x0a, 0x0b, 0x53, - 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x66, 0x72, - 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x44, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, - 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, - 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x74, 0x68, 0x72, - 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xe1, 0x01, 0x0a, - 0x11, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 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, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x50, - 0x0a, 0x15, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x13, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, - 0x1a, 0x5f, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x35, - 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 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, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, - 0x05, 0x10, 0x06, 0x22, 0x4b, 0x0a, 0x08, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, - 0x22, 0x22, 0x0a, 0x0a, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x55, 0x0a, 0x0a, 0x54, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x4e, 0x0a, 0x15, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x69, 0x74, 0x65, 0x73, 0x73, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5a, 0x0a, 0x10, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, - 0x46, 0x0a, 0x0e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2a, 0x28, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, - 0x4c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, - 0x01, 0x2a, 0x9d, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, - 0x07, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, - 0x53, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, - 0x41, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x03, 0x12, - 0x09, 0x0a, 0x05, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, - 0x41, 0x52, 0x45, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, 0x4d, - 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x41, 0x43, 0x4b, 0x55, - 0x50, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x10, 0x07, - 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x52, 0x41, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x08, 0x1a, 0x02, 0x10, - 0x01, 0x42, 0x38, 0x0a, 0x0f, 0x69, 0x6f, 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 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, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x04, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xd2, 0x02, + 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 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, 0x0c, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 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, 0x07, 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, 0x12, + 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x44, 0x0a, 0x10, + 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x0f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, 0x64, 0x62, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x69, 0x64, + 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, + 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, + 0x10, 0x05, 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x1a, 0x40, + 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 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, 0xc6, 0x01, 0x0a, 0x15, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, + 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 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, 0x39, + 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, + 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x02, 0x22, 0x55, 0x0a, 0x0e, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 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, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 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, + 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6b, + 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 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, 0x34, 0x0a, 0x16, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, + 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x12, 0x2b, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x22, 0xce, 0x02, 0x0a, 0x0f, 0x54, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, + 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x53, 0x65, 0x6c, 0x66, 0x12, 0x53, 0x0a, 0x0e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x64, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x1a, 0x5c, 0x0a, 0x12, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 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, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x98, 0x03, 0x0a, 0x0b, 0x53, 0x72, 0x76, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x44, 0x0a, 0x10, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xe1, 0x01, 0x0a, 0x11, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 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, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x15, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, + 0x10, 0x06, 0x22, 0x4b, 0x0a, 0x08, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, + 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, + 0x22, 0x0a, 0x0a, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x22, 0x55, 0x0a, 0x0a, 0x54, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x22, 0x4e, 0x0a, 0x15, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x69, 0x74, 0x65, 0x73, 0x73, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, + 0x74, 0x6f, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5a, 0x0a, 0x10, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x46, + 0x0a, 0x0e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x69, 0x74, 0x65, 0x73, 0x73, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2a, 0x28, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, + 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x01, + 0x2a, 0x9d, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x53, + 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, 0x41, + 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x03, 0x12, 0x09, + 0x0a, 0x05, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, 0x41, + 0x52, 0x45, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x58, 0x50, 0x45, 0x52, 0x49, 0x4d, 0x45, + 0x4e, 0x54, 0x41, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, + 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x10, 0x07, 0x12, + 0x0b, 0x0a, 0x07, 0x44, 0x52, 0x41, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x08, 0x1a, 0x02, 0x10, 0x01, + 0x42, 0x38, 0x0a, 0x0f, 0x69, 0x6f, 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 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, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -2196,7 +2030,7 @@ func file_topodata_proto_rawDescGZIP() []byte { } var file_topodata_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_topodata_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_topodata_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_topodata_proto_goTypes = []interface{}{ (KeyspaceType)(0), // 0: topodata.KeyspaceType (TabletType)(0), // 1: topodata.TabletType @@ -2222,12 +2056,10 @@ var file_topodata_proto_goTypes = []interface{}{ nil, // 21: topodata.Tablet.TagsEntry (*Shard_SourceShard)(nil), // 22: topodata.Shard.SourceShard (*Shard_TabletControl)(nil), // 23: topodata.Shard.TabletControl - (*Keyspace_ServedFrom)(nil), // 24: topodata.Keyspace.ServedFrom - (*ShardReplication_Node)(nil), // 25: topodata.ShardReplication.Node - nil, // 26: topodata.ThrottlerConfig.ThrottledAppsEntry - (*SrvKeyspace_KeyspacePartition)(nil), // 27: topodata.SrvKeyspace.KeyspacePartition - (*SrvKeyspace_ServedFrom)(nil), // 28: topodata.SrvKeyspace.ServedFrom - (*vttime.Time)(nil), // 29: vttime.Time + (*ShardReplication_Node)(nil), // 24: topodata.ShardReplication.Node + nil, // 25: topodata.ThrottlerConfig.ThrottledAppsEntry + (*SrvKeyspace_KeyspacePartition)(nil), // 26: topodata.SrvKeyspace.KeyspacePartition + (*vttime.Time)(nil), // 27: vttime.Time } var file_topodata_proto_depIdxs = []int32{ 4, // 0: topodata.Tablet.alias:type_name -> topodata.TabletAlias @@ -2235,42 +2067,38 @@ var file_topodata_proto_depIdxs = []int32{ 3, // 2: topodata.Tablet.key_range:type_name -> topodata.KeyRange 1, // 3: topodata.Tablet.type:type_name -> topodata.TabletType 21, // 4: topodata.Tablet.tags:type_name -> topodata.Tablet.TagsEntry - 29, // 5: topodata.Tablet.primary_term_start_time:type_name -> vttime.Time + 27, // 5: topodata.Tablet.primary_term_start_time:type_name -> vttime.Time 4, // 6: topodata.Shard.primary_alias:type_name -> topodata.TabletAlias - 29, // 7: topodata.Shard.primary_term_start_time:type_name -> vttime.Time + 27, // 7: topodata.Shard.primary_term_start_time:type_name -> vttime.Time 3, // 8: topodata.Shard.key_range:type_name -> topodata.KeyRange 22, // 9: topodata.Shard.source_shards:type_name -> topodata.Shard.SourceShard 23, // 10: topodata.Shard.tablet_controls:type_name -> topodata.Shard.TabletControl - 24, // 11: topodata.Keyspace.served_froms:type_name -> topodata.Keyspace.ServedFrom - 0, // 12: topodata.Keyspace.keyspace_type:type_name -> topodata.KeyspaceType - 29, // 13: topodata.Keyspace.snapshot_time:type_name -> vttime.Time - 13, // 14: topodata.Keyspace.throttler_config:type_name -> topodata.ThrottlerConfig - 25, // 15: topodata.ShardReplication.nodes:type_name -> topodata.ShardReplication.Node - 2, // 16: topodata.ShardReplicationError.type:type_name -> topodata.ShardReplicationError.Type - 4, // 17: topodata.ShardReplicationError.tablet_alias:type_name -> topodata.TabletAlias - 3, // 18: topodata.ShardReference.key_range:type_name -> topodata.KeyRange - 3, // 19: topodata.ShardTabletControl.key_range:type_name -> topodata.KeyRange - 29, // 20: topodata.ThrottledAppRule.expires_at:type_name -> vttime.Time - 26, // 21: topodata.ThrottlerConfig.throttled_apps:type_name -> topodata.ThrottlerConfig.ThrottledAppsEntry - 27, // 22: topodata.SrvKeyspace.partitions:type_name -> topodata.SrvKeyspace.KeyspacePartition - 28, // 23: topodata.SrvKeyspace.served_from:type_name -> topodata.SrvKeyspace.ServedFrom - 13, // 24: topodata.SrvKeyspace.throttler_config:type_name -> topodata.ThrottlerConfig - 17, // 25: topodata.ExternalVitessCluster.topo_config:type_name -> topodata.TopoConfig - 18, // 26: topodata.ExternalClusters.vitess_cluster:type_name -> topodata.ExternalVitessCluster - 3, // 27: topodata.Shard.SourceShard.key_range:type_name -> topodata.KeyRange - 1, // 28: topodata.Shard.TabletControl.tablet_type:type_name -> topodata.TabletType - 1, // 29: topodata.Keyspace.ServedFrom.tablet_type:type_name -> topodata.TabletType - 4, // 30: topodata.ShardReplication.Node.tablet_alias:type_name -> topodata.TabletAlias - 12, // 31: topodata.ThrottlerConfig.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule - 1, // 32: topodata.SrvKeyspace.KeyspacePartition.served_type:type_name -> topodata.TabletType - 10, // 33: topodata.SrvKeyspace.KeyspacePartition.shard_references:type_name -> topodata.ShardReference - 11, // 34: topodata.SrvKeyspace.KeyspacePartition.shard_tablet_controls:type_name -> topodata.ShardTabletControl - 1, // 35: topodata.SrvKeyspace.ServedFrom.tablet_type:type_name -> topodata.TabletType - 36, // [36:36] is the sub-list for method output_type - 36, // [36:36] is the sub-list for method input_type - 36, // [36:36] is the sub-list for extension type_name - 36, // [36:36] is the sub-list for extension extendee - 0, // [0:36] is the sub-list for field type_name + 0, // 11: topodata.Keyspace.keyspace_type:type_name -> topodata.KeyspaceType + 27, // 12: topodata.Keyspace.snapshot_time:type_name -> vttime.Time + 13, // 13: topodata.Keyspace.throttler_config:type_name -> topodata.ThrottlerConfig + 24, // 14: topodata.ShardReplication.nodes:type_name -> topodata.ShardReplication.Node + 2, // 15: topodata.ShardReplicationError.type:type_name -> topodata.ShardReplicationError.Type + 4, // 16: topodata.ShardReplicationError.tablet_alias:type_name -> topodata.TabletAlias + 3, // 17: topodata.ShardReference.key_range:type_name -> topodata.KeyRange + 3, // 18: topodata.ShardTabletControl.key_range:type_name -> topodata.KeyRange + 27, // 19: topodata.ThrottledAppRule.expires_at:type_name -> vttime.Time + 25, // 20: topodata.ThrottlerConfig.throttled_apps:type_name -> topodata.ThrottlerConfig.ThrottledAppsEntry + 26, // 21: topodata.SrvKeyspace.partitions:type_name -> topodata.SrvKeyspace.KeyspacePartition + 13, // 22: topodata.SrvKeyspace.throttler_config:type_name -> topodata.ThrottlerConfig + 17, // 23: topodata.ExternalVitessCluster.topo_config:type_name -> topodata.TopoConfig + 18, // 24: topodata.ExternalClusters.vitess_cluster:type_name -> topodata.ExternalVitessCluster + 3, // 25: topodata.Shard.SourceShard.key_range:type_name -> topodata.KeyRange + 1, // 26: topodata.Shard.TabletControl.tablet_type:type_name -> topodata.TabletType + 4, // 27: topodata.ShardReplication.Node.tablet_alias:type_name -> topodata.TabletAlias + 12, // 28: topodata.ThrottlerConfig.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule + 1, // 29: topodata.SrvKeyspace.KeyspacePartition.served_type:type_name -> topodata.TabletType + 10, // 30: topodata.SrvKeyspace.KeyspacePartition.shard_references:type_name -> topodata.ShardReference + 11, // 31: topodata.SrvKeyspace.KeyspacePartition.shard_tablet_controls:type_name -> topodata.ShardTabletControl + 32, // [32:32] is the sub-list for method output_type + 32, // [32:32] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_topodata_proto_init() } @@ -2508,18 +2336,6 @@ func file_topodata_proto_init() { } } file_topodata_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Keyspace_ServedFrom); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_topodata_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplication_Node); i { case 0: return &v.state @@ -2531,7 +2347,7 @@ func file_topodata_proto_init() { return nil } } - file_topodata_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_topodata_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SrvKeyspace_KeyspacePartition); i { case 0: return &v.state @@ -2543,18 +2359,6 @@ func file_topodata_proto_init() { return nil } } - file_topodata_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SrvKeyspace_ServedFrom); 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{ @@ -2562,7 +2366,7 @@ func file_topodata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_topodata_proto_rawDesc, NumEnums: 3, - NumMessages: 26, + NumMessages: 24, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/topodata/topodata_vtproto.pb.go b/go/vt/proto/topodata/topodata_vtproto.pb.go index 5e675bb4ea0..78971f9db9a 100644 --- a/go/vt/proto/topodata/topodata_vtproto.pb.go +++ b/go/vt/proto/topodata/topodata_vtproto.pb.go @@ -199,30 +199,6 @@ func (m *Shard) CloneMessageVT() proto.Message { return m.CloneVT() } -func (m *Keyspace_ServedFrom) CloneVT() *Keyspace_ServedFrom { - if m == nil { - return (*Keyspace_ServedFrom)(nil) - } - r := &Keyspace_ServedFrom{ - TabletType: m.TabletType, - Keyspace: m.Keyspace, - } - if rhs := m.Cells; rhs != nil { - tmpContainer := make([]string, len(rhs)) - copy(tmpContainer, rhs) - r.Cells = tmpContainer - } - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *Keyspace_ServedFrom) CloneMessageVT() proto.Message { - return m.CloneVT() -} - func (m *Keyspace) CloneVT() *Keyspace { if m == nil { return (*Keyspace)(nil) @@ -235,13 +211,6 @@ func (m *Keyspace) CloneVT() *Keyspace { ThrottlerConfig: m.ThrottlerConfig.CloneVT(), SidecarDbName: m.SidecarDbName, } - if rhs := m.ServedFroms; rhs != nil { - tmpContainer := make([]*Keyspace_ServedFrom, len(rhs)) - for k, v := range rhs { - tmpContainer[k] = v.CloneVT() - } - r.ServedFroms = tmpContainer - } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -433,25 +402,6 @@ func (m *SrvKeyspace_KeyspacePartition) CloneMessageVT() proto.Message { return m.CloneVT() } -func (m *SrvKeyspace_ServedFrom) CloneVT() *SrvKeyspace_ServedFrom { - if m == nil { - return (*SrvKeyspace_ServedFrom)(nil) - } - r := &SrvKeyspace_ServedFrom{ - TabletType: m.TabletType, - Keyspace: m.Keyspace, - } - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *SrvKeyspace_ServedFrom) CloneMessageVT() proto.Message { - return m.CloneVT() -} - func (m *SrvKeyspace) CloneVT() *SrvKeyspace { if m == nil { return (*SrvKeyspace)(nil) @@ -466,13 +416,6 @@ func (m *SrvKeyspace) CloneVT() *SrvKeyspace { } r.Partitions = tmpContainer } - if rhs := m.ServedFrom; rhs != nil { - tmpContainer := make([]*SrvKeyspace_ServedFrom, len(rhs)) - for k, v := range rhs { - tmpContainer[k] = v.CloneVT() - } - r.ServedFrom = tmpContainer - } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -1062,60 +1005,6 @@ func (m *Shard) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Keyspace_ServedFrom) 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 *Keyspace_ServedFrom) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *Keyspace_ServedFrom) 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.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.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] = 0x12 - } - } - if m.TabletType != 0 { - i = encodeVarint(dAtA, i, uint64(m.TabletType)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func (m *Keyspace) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1192,18 +1081,6 @@ func (m *Keyspace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0x28 } - if len(m.ServedFroms) > 0 { - for iNdEx := len(m.ServedFroms) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.ServedFroms[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x22 - } - } return len(dAtA) - i, nil } @@ -1669,51 +1546,6 @@ func (m *SrvKeyspace_KeyspacePartition) MarshalToSizedBufferVT(dAtA []byte) (int return len(dAtA) - i, nil } -func (m *SrvKeyspace_ServedFrom) 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 *SrvKeyspace_ServedFrom) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *SrvKeyspace_ServedFrom) 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.Keyspace) > 0 { - i -= len(m.Keyspace) - copy(dAtA[i:], m.Keyspace) - i = encodeVarint(dAtA, i, uint64(len(m.Keyspace))) - i-- - dAtA[i] = 0x12 - } - if m.TabletType != 0 { - i = encodeVarint(dAtA, i, uint64(m.TabletType)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func (m *SrvKeyspace) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1754,18 +1586,6 @@ func (m *SrvKeyspace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - if len(m.ServedFrom) > 0 { - for iNdEx := len(m.ServedFrom) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.ServedFrom[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x22 - } - } if len(m.Partitions) > 0 { for iNdEx := len(m.Partitions) - 1; iNdEx >= 0; iNdEx-- { size, err := m.Partitions[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) @@ -2221,41 +2041,12 @@ func (m *Shard) SizeVT() (n int) { return n } -func (m *Keyspace_ServedFrom) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.TabletType != 0 { - n += 1 + sov(uint64(m.TabletType)) - } - if len(m.Cells) > 0 { - for _, s := range m.Cells { - l = len(s) - n += 1 + l + sov(uint64(l)) - } - } - l = len(m.Keyspace) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - func (m *Keyspace) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.ServedFroms) > 0 { - for _, e := range m.ServedFroms { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } if m.KeyspaceType != 0 { n += 1 + sov(uint64(m.KeyspaceType)) } @@ -2454,23 +2245,6 @@ func (m *SrvKeyspace_KeyspacePartition) SizeVT() (n int) { return n } -func (m *SrvKeyspace_ServedFrom) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.TabletType != 0 { - n += 1 + sov(uint64(m.TabletType)) - } - l = len(m.Keyspace) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - func (m *SrvKeyspace) SizeVT() (n int) { if m == nil { return 0 @@ -2483,12 +2257,6 @@ func (m *SrvKeyspace) SizeVT() (n int) { n += 1 + l + sov(uint64(l)) } } - if len(m.ServedFrom) > 0 { - for _, e := range m.ServedFrom { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } if m.ThrottlerConfig != nil { l = m.ThrottlerConfig.SizeVT() n += 1 + l + sov(uint64(l)) @@ -4029,140 +3797,6 @@ func (m *Shard) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *Keyspace_ServedFrom) 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: Keyspace_ServedFrom: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Keyspace_ServedFrom: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TabletType", wireType) - } - m.TabletType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TabletType |= TabletType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - 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 - 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 - 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 *Keyspace) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4192,40 +3826,6 @@ func (m *Keyspace) UnmarshalVT(dAtA []byte) error { return fmt.Errorf("proto: Keyspace: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServedFroms", 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.ServedFroms = append(m.ServedFroms, &Keyspace_ServedFrom{}) - if err := m.ServedFroms[len(m.ServedFroms)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field KeyspaceType", wireType) @@ -5522,108 +5122,6 @@ func (m *SrvKeyspace_KeyspacePartition) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *SrvKeyspace_ServedFrom) 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: SrvKeyspace_ServedFrom: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SrvKeyspace_ServedFrom: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TabletType", wireType) - } - m.TabletType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TabletType |= TabletType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - 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 - 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 *SrvKeyspace) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5687,40 +5185,6 @@ func (m *SrvKeyspace) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServedFrom", 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.ServedFrom = append(m.ServedFrom, &SrvKeyspace_ServedFrom{}) - if err := m.ServedFrom[len(m.ServedFrom)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ThrottlerConfig", wireType) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index f7252e2d8ec..6e17040a13b 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -2742,9 +2742,6 @@ type CreateKeyspaceRequest struct { Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` // AllowEmptyVSchema allows a keyspace to be created with no vschema. AllowEmptyVSchema bool `protobuf:"varint,3,opt,name=allow_empty_v_schema,json=allowEmptyVSchema,proto3" json:"allow_empty_v_schema,omitempty"` - // ServedFroms specifies a set of db_type:keyspace pairs used to serve - // traffic for the keyspace. - ServedFroms []*topodata.Keyspace_ServedFrom `protobuf:"bytes,6,rep,name=served_froms,json=servedFroms,proto3" json:"served_froms,omitempty"` // Type is the type of the keyspace to create. Type topodata.KeyspaceType `protobuf:"varint,7,opt,name=type,proto3,enum=topodata.KeyspaceType" json:"type,omitempty"` // BaseKeyspace specifies the base keyspace for SNAPSHOT keyspaces. It is @@ -2814,13 +2811,6 @@ func (x *CreateKeyspaceRequest) GetAllowEmptyVSchema() bool { return false } -func (x *CreateKeyspaceRequest) GetServedFroms() []*topodata.Keyspace_ServedFrom { - if x != nil { - return x.ServedFroms - } - return nil -} - func (x *CreateKeyspaceRequest) GetType() topodata.KeyspaceType { if x != nil { return x.Type @@ -10630,133 +10620,6 @@ func (x *SetKeyspaceDurabilityPolicyResponse) GetKeyspace() *topodata.Keyspace { return nil } -type SetKeyspaceServedFromRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` - TabletType topodata.TabletType `protobuf:"varint,2,opt,name=tablet_type,json=tabletType,proto3,enum=topodata.TabletType" json:"tablet_type,omitempty"` - Cells []string `protobuf:"bytes,3,rep,name=cells,proto3" json:"cells,omitempty"` - Remove bool `protobuf:"varint,4,opt,name=remove,proto3" json:"remove,omitempty"` - SourceKeyspace string `protobuf:"bytes,5,opt,name=source_keyspace,json=sourceKeyspace,proto3" json:"source_keyspace,omitempty"` -} - -func (x *SetKeyspaceServedFromRequest) Reset() { - *x = SetKeyspaceServedFromRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[166] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SetKeyspaceServedFromRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetKeyspaceServedFromRequest) ProtoMessage() {} - -func (x *SetKeyspaceServedFromRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[166] - 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 SetKeyspaceServedFromRequest.ProtoReflect.Descriptor instead. -func (*SetKeyspaceServedFromRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{166} -} - -func (x *SetKeyspaceServedFromRequest) GetKeyspace() string { - if x != nil { - return x.Keyspace - } - return "" -} - -func (x *SetKeyspaceServedFromRequest) GetTabletType() topodata.TabletType { - if x != nil { - return x.TabletType - } - return topodata.TabletType(0) -} - -func (x *SetKeyspaceServedFromRequest) GetCells() []string { - if x != nil { - return x.Cells - } - return nil -} - -func (x *SetKeyspaceServedFromRequest) GetRemove() bool { - if x != nil { - return x.Remove - } - return false -} - -func (x *SetKeyspaceServedFromRequest) GetSourceKeyspace() string { - if x != nil { - return x.SourceKeyspace - } - return "" -} - -type SetKeyspaceServedFromResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Keyspace is the updated keyspace record. - Keyspace *topodata.Keyspace `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` -} - -func (x *SetKeyspaceServedFromResponse) Reset() { - *x = SetKeyspaceServedFromResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[167] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SetKeyspaceServedFromResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetKeyspaceServedFromResponse) ProtoMessage() {} - -func (x *SetKeyspaceServedFromResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[167] - 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 SetKeyspaceServedFromResponse.ProtoReflect.Descriptor instead. -func (*SetKeyspaceServedFromResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{167} -} - -func (x *SetKeyspaceServedFromResponse) GetKeyspace() *topodata.Keyspace { - if x != nil { - return x.Keyspace - } - return nil -} - type SetKeyspaceShardingInfoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -10769,7 +10632,7 @@ type SetKeyspaceShardingInfoRequest struct { func (x *SetKeyspaceShardingInfoRequest) Reset() { *x = SetKeyspaceShardingInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10782,7 +10645,7 @@ func (x *SetKeyspaceShardingInfoRequest) String() string { func (*SetKeyspaceShardingInfoRequest) ProtoMessage() {} func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[166] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10795,7 +10658,7 @@ func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoRequest.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{168} + return file_vtctldata_proto_rawDescGZIP(), []int{166} } func (x *SetKeyspaceShardingInfoRequest) GetKeyspace() string { @@ -10824,7 +10687,7 @@ type SetKeyspaceShardingInfoResponse struct { func (x *SetKeyspaceShardingInfoResponse) Reset() { *x = SetKeyspaceShardingInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10837,7 +10700,7 @@ func (x *SetKeyspaceShardingInfoResponse) String() string { func (*SetKeyspaceShardingInfoResponse) ProtoMessage() {} func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[167] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10850,7 +10713,7 @@ func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoResponse.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{169} + return file_vtctldata_proto_rawDescGZIP(), []int{167} } func (x *SetKeyspaceShardingInfoResponse) GetKeyspace() *topodata.Keyspace { @@ -10873,7 +10736,7 @@ type SetShardIsPrimaryServingRequest struct { func (x *SetShardIsPrimaryServingRequest) Reset() { *x = SetShardIsPrimaryServingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10886,7 +10749,7 @@ func (x *SetShardIsPrimaryServingRequest) String() string { func (*SetShardIsPrimaryServingRequest) ProtoMessage() {} func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[168] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10899,7 +10762,7 @@ func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingRequest.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{170} + return file_vtctldata_proto_rawDescGZIP(), []int{168} } func (x *SetShardIsPrimaryServingRequest) GetKeyspace() string { @@ -10935,7 +10798,7 @@ type SetShardIsPrimaryServingResponse struct { func (x *SetShardIsPrimaryServingResponse) Reset() { *x = SetShardIsPrimaryServingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10948,7 +10811,7 @@ func (x *SetShardIsPrimaryServingResponse) String() string { func (*SetShardIsPrimaryServingResponse) ProtoMessage() {} func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[169] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10961,7 +10824,7 @@ func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingResponse.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{171} + return file_vtctldata_proto_rawDescGZIP(), []int{169} } func (x *SetShardIsPrimaryServingResponse) GetShard() *topodata.Shard { @@ -11002,7 +10865,7 @@ type SetShardTabletControlRequest struct { func (x *SetShardTabletControlRequest) Reset() { *x = SetShardTabletControlRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11015,7 +10878,7 @@ func (x *SetShardTabletControlRequest) String() string { func (*SetShardTabletControlRequest) ProtoMessage() {} func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[170] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11028,7 +10891,7 @@ func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlRequest.ProtoReflect.Descriptor instead. func (*SetShardTabletControlRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{172} + return file_vtctldata_proto_rawDescGZIP(), []int{170} } func (x *SetShardTabletControlRequest) GetKeyspace() string { @@ -11092,7 +10955,7 @@ type SetShardTabletControlResponse struct { func (x *SetShardTabletControlResponse) Reset() { *x = SetShardTabletControlResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11105,7 +10968,7 @@ func (x *SetShardTabletControlResponse) String() string { func (*SetShardTabletControlResponse) ProtoMessage() {} func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[171] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11118,7 +10981,7 @@ func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlResponse.ProtoReflect.Descriptor instead. func (*SetShardTabletControlResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{173} + return file_vtctldata_proto_rawDescGZIP(), []int{171} } func (x *SetShardTabletControlResponse) GetShard() *topodata.Shard { @@ -11140,7 +11003,7 @@ type SetWritableRequest struct { func (x *SetWritableRequest) Reset() { *x = SetWritableRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11153,7 +11016,7 @@ func (x *SetWritableRequest) String() string { func (*SetWritableRequest) ProtoMessage() {} func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[172] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11166,7 +11029,7 @@ func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableRequest.ProtoReflect.Descriptor instead. func (*SetWritableRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{174} + return file_vtctldata_proto_rawDescGZIP(), []int{172} } func (x *SetWritableRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11192,7 +11055,7 @@ type SetWritableResponse struct { func (x *SetWritableResponse) Reset() { *x = SetWritableResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11205,7 +11068,7 @@ func (x *SetWritableResponse) String() string { func (*SetWritableResponse) ProtoMessage() {} func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[173] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11218,7 +11081,7 @@ func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableResponse.ProtoReflect.Descriptor instead. func (*SetWritableResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{175} + return file_vtctldata_proto_rawDescGZIP(), []int{173} } type ShardReplicationAddRequest struct { @@ -11234,7 +11097,7 @@ type ShardReplicationAddRequest struct { func (x *ShardReplicationAddRequest) Reset() { *x = ShardReplicationAddRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11247,7 +11110,7 @@ func (x *ShardReplicationAddRequest) String() string { func (*ShardReplicationAddRequest) ProtoMessage() {} func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[174] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11260,7 +11123,7 @@ func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{176} + return file_vtctldata_proto_rawDescGZIP(), []int{174} } func (x *ShardReplicationAddRequest) GetKeyspace() string { @@ -11293,7 +11156,7 @@ type ShardReplicationAddResponse struct { func (x *ShardReplicationAddResponse) Reset() { *x = ShardReplicationAddResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11306,7 +11169,7 @@ func (x *ShardReplicationAddResponse) String() string { func (*ShardReplicationAddResponse) ProtoMessage() {} func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[175] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11319,7 +11182,7 @@ func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{177} + return file_vtctldata_proto_rawDescGZIP(), []int{175} } type ShardReplicationFixRequest struct { @@ -11335,7 +11198,7 @@ type ShardReplicationFixRequest struct { func (x *ShardReplicationFixRequest) Reset() { *x = ShardReplicationFixRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11348,7 +11211,7 @@ func (x *ShardReplicationFixRequest) String() string { func (*ShardReplicationFixRequest) ProtoMessage() {} func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[176] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11361,7 +11224,7 @@ func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationFixRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{178} + return file_vtctldata_proto_rawDescGZIP(), []int{176} } func (x *ShardReplicationFixRequest) GetKeyspace() string { @@ -11399,7 +11262,7 @@ type ShardReplicationFixResponse struct { func (x *ShardReplicationFixResponse) Reset() { *x = ShardReplicationFixResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11412,7 +11275,7 @@ func (x *ShardReplicationFixResponse) String() string { func (*ShardReplicationFixResponse) ProtoMessage() {} func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[177] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11425,7 +11288,7 @@ func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationFixResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{179} + return file_vtctldata_proto_rawDescGZIP(), []int{177} } func (x *ShardReplicationFixResponse) GetError() *topodata.ShardReplicationError { @@ -11447,7 +11310,7 @@ type ShardReplicationPositionsRequest struct { func (x *ShardReplicationPositionsRequest) Reset() { *x = ShardReplicationPositionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11460,7 +11323,7 @@ func (x *ShardReplicationPositionsRequest) String() string { func (*ShardReplicationPositionsRequest) ProtoMessage() {} func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[178] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11473,7 +11336,7 @@ func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationPositionsRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{180} + return file_vtctldata_proto_rawDescGZIP(), []int{178} } func (x *ShardReplicationPositionsRequest) GetKeyspace() string { @@ -11506,7 +11369,7 @@ type ShardReplicationPositionsResponse struct { func (x *ShardReplicationPositionsResponse) Reset() { *x = ShardReplicationPositionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11519,7 +11382,7 @@ func (x *ShardReplicationPositionsResponse) String() string { func (*ShardReplicationPositionsResponse) ProtoMessage() {} func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[179] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11532,7 +11395,7 @@ func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ShardReplicationPositionsResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{181} + return file_vtctldata_proto_rawDescGZIP(), []int{179} } func (x *ShardReplicationPositionsResponse) GetReplicationStatuses() map[string]*replicationdata.Status { @@ -11562,7 +11425,7 @@ type ShardReplicationRemoveRequest struct { func (x *ShardReplicationRemoveRequest) Reset() { *x = ShardReplicationRemoveRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11575,7 +11438,7 @@ func (x *ShardReplicationRemoveRequest) String() string { func (*ShardReplicationRemoveRequest) ProtoMessage() {} func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[180] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11588,7 +11451,7 @@ func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{182} + return file_vtctldata_proto_rawDescGZIP(), []int{180} } func (x *ShardReplicationRemoveRequest) GetKeyspace() string { @@ -11621,7 +11484,7 @@ type ShardReplicationRemoveResponse struct { func (x *ShardReplicationRemoveResponse) Reset() { *x = ShardReplicationRemoveResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11634,7 +11497,7 @@ func (x *ShardReplicationRemoveResponse) String() string { func (*ShardReplicationRemoveResponse) ProtoMessage() {} func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[181] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11647,7 +11510,7 @@ func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{183} + return file_vtctldata_proto_rawDescGZIP(), []int{181} } type SleepTabletRequest struct { @@ -11662,7 +11525,7 @@ type SleepTabletRequest struct { func (x *SleepTabletRequest) Reset() { *x = SleepTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11675,7 +11538,7 @@ func (x *SleepTabletRequest) String() string { func (*SleepTabletRequest) ProtoMessage() {} func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[182] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11688,7 +11551,7 @@ func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletRequest.ProtoReflect.Descriptor instead. func (*SleepTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{184} + return file_vtctldata_proto_rawDescGZIP(), []int{182} } func (x *SleepTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11714,7 +11577,7 @@ type SleepTabletResponse struct { func (x *SleepTabletResponse) Reset() { *x = SleepTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11727,7 +11590,7 @@ func (x *SleepTabletResponse) String() string { func (*SleepTabletResponse) ProtoMessage() {} func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[183] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11740,7 +11603,7 @@ func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletResponse.ProtoReflect.Descriptor instead. func (*SleepTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{185} + return file_vtctldata_proto_rawDescGZIP(), []int{183} } type SourceShardAddRequest struct { @@ -11764,7 +11627,7 @@ type SourceShardAddRequest struct { func (x *SourceShardAddRequest) Reset() { *x = SourceShardAddRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11777,7 +11640,7 @@ func (x *SourceShardAddRequest) String() string { func (*SourceShardAddRequest) ProtoMessage() {} func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[184] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11790,7 +11653,7 @@ func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddRequest.ProtoReflect.Descriptor instead. func (*SourceShardAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{186} + return file_vtctldata_proto_rawDescGZIP(), []int{184} } func (x *SourceShardAddRequest) GetKeyspace() string { @@ -11854,7 +11717,7 @@ type SourceShardAddResponse struct { func (x *SourceShardAddResponse) Reset() { *x = SourceShardAddResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11867,7 +11730,7 @@ func (x *SourceShardAddResponse) String() string { func (*SourceShardAddResponse) ProtoMessage() {} func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[185] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11880,7 +11743,7 @@ func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddResponse.ProtoReflect.Descriptor instead. func (*SourceShardAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{187} + return file_vtctldata_proto_rawDescGZIP(), []int{185} } func (x *SourceShardAddResponse) GetShard() *topodata.Shard { @@ -11903,7 +11766,7 @@ type SourceShardDeleteRequest struct { func (x *SourceShardDeleteRequest) Reset() { *x = SourceShardDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[186] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11916,7 +11779,7 @@ func (x *SourceShardDeleteRequest) String() string { func (*SourceShardDeleteRequest) ProtoMessage() {} func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[186] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11929,7 +11792,7 @@ func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteRequest.ProtoReflect.Descriptor instead. func (*SourceShardDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{188} + return file_vtctldata_proto_rawDescGZIP(), []int{186} } func (x *SourceShardDeleteRequest) GetKeyspace() string { @@ -11965,7 +11828,7 @@ type SourceShardDeleteResponse struct { func (x *SourceShardDeleteResponse) Reset() { *x = SourceShardDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[187] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11978,7 +11841,7 @@ func (x *SourceShardDeleteResponse) String() string { func (*SourceShardDeleteResponse) ProtoMessage() {} func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[187] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11991,7 +11854,7 @@ func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteResponse.ProtoReflect.Descriptor instead. func (*SourceShardDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{189} + return file_vtctldata_proto_rawDescGZIP(), []int{187} } func (x *SourceShardDeleteResponse) GetShard() *topodata.Shard { @@ -12012,7 +11875,7 @@ type StartReplicationRequest struct { func (x *StartReplicationRequest) Reset() { *x = StartReplicationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[188] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12025,7 +11888,7 @@ func (x *StartReplicationRequest) String() string { func (*StartReplicationRequest) ProtoMessage() {} func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[188] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12038,7 +11901,7 @@ func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationRequest.ProtoReflect.Descriptor instead. func (*StartReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{190} + return file_vtctldata_proto_rawDescGZIP(), []int{188} } func (x *StartReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -12057,7 +11920,7 @@ type StartReplicationResponse struct { func (x *StartReplicationResponse) Reset() { *x = StartReplicationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[189] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12070,7 +11933,7 @@ func (x *StartReplicationResponse) String() string { func (*StartReplicationResponse) ProtoMessage() {} func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[189] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12083,7 +11946,7 @@ func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationResponse.ProtoReflect.Descriptor instead. func (*StartReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{191} + return file_vtctldata_proto_rawDescGZIP(), []int{189} } type StopReplicationRequest struct { @@ -12097,7 +11960,7 @@ type StopReplicationRequest struct { func (x *StopReplicationRequest) Reset() { *x = StopReplicationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[190] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12110,7 +11973,7 @@ func (x *StopReplicationRequest) String() string { func (*StopReplicationRequest) ProtoMessage() {} func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[190] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12123,7 +11986,7 @@ func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationRequest.ProtoReflect.Descriptor instead. func (*StopReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{192} + return file_vtctldata_proto_rawDescGZIP(), []int{190} } func (x *StopReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -12142,7 +12005,7 @@ type StopReplicationResponse struct { func (x *StopReplicationResponse) Reset() { *x = StopReplicationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[191] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12155,7 +12018,7 @@ func (x *StopReplicationResponse) String() string { func (*StopReplicationResponse) ProtoMessage() {} func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[191] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12168,7 +12031,7 @@ func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationResponse.ProtoReflect.Descriptor instead. func (*StopReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{193} + return file_vtctldata_proto_rawDescGZIP(), []int{191} } type TabletExternallyReparentedRequest struct { @@ -12184,7 +12047,7 @@ type TabletExternallyReparentedRequest struct { func (x *TabletExternallyReparentedRequest) Reset() { *x = TabletExternallyReparentedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[192] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12197,7 +12060,7 @@ func (x *TabletExternallyReparentedRequest) String() string { func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[192] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12210,7 +12073,7 @@ func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedRequest.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{194} + return file_vtctldata_proto_rawDescGZIP(), []int{192} } func (x *TabletExternallyReparentedRequest) GetTablet() *topodata.TabletAlias { @@ -12234,7 +12097,7 @@ type TabletExternallyReparentedResponse struct { func (x *TabletExternallyReparentedResponse) Reset() { *x = TabletExternallyReparentedResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[193] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12247,7 +12110,7 @@ func (x *TabletExternallyReparentedResponse) String() string { func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[193] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12260,7 +12123,7 @@ func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedResponse.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{195} + return file_vtctldata_proto_rawDescGZIP(), []int{193} } func (x *TabletExternallyReparentedResponse) GetKeyspace() string { @@ -12303,7 +12166,7 @@ type UpdateCellInfoRequest struct { func (x *UpdateCellInfoRequest) Reset() { *x = UpdateCellInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[194] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12316,7 +12179,7 @@ func (x *UpdateCellInfoRequest) String() string { func (*UpdateCellInfoRequest) ProtoMessage() {} func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[194] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12329,7 +12192,7 @@ func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoRequest.ProtoReflect.Descriptor instead. func (*UpdateCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{196} + return file_vtctldata_proto_rawDescGZIP(), []int{194} } func (x *UpdateCellInfoRequest) GetName() string { @@ -12358,7 +12221,7 @@ type UpdateCellInfoResponse struct { func (x *UpdateCellInfoResponse) Reset() { *x = UpdateCellInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[195] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12371,7 +12234,7 @@ func (x *UpdateCellInfoResponse) String() string { func (*UpdateCellInfoResponse) ProtoMessage() {} func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[195] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12384,7 +12247,7 @@ func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoResponse.ProtoReflect.Descriptor instead. func (*UpdateCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{197} + return file_vtctldata_proto_rawDescGZIP(), []int{195} } func (x *UpdateCellInfoResponse) GetName() string { @@ -12413,7 +12276,7 @@ type UpdateCellsAliasRequest struct { func (x *UpdateCellsAliasRequest) Reset() { *x = UpdateCellsAliasRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[196] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12426,7 +12289,7 @@ func (x *UpdateCellsAliasRequest) String() string { func (*UpdateCellsAliasRequest) ProtoMessage() {} func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[196] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12439,7 +12302,7 @@ func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasRequest.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{198} + return file_vtctldata_proto_rawDescGZIP(), []int{196} } func (x *UpdateCellsAliasRequest) GetName() string { @@ -12468,7 +12331,7 @@ type UpdateCellsAliasResponse struct { func (x *UpdateCellsAliasResponse) Reset() { *x = UpdateCellsAliasResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[197] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12481,7 +12344,7 @@ func (x *UpdateCellsAliasResponse) String() string { func (*UpdateCellsAliasResponse) ProtoMessage() {} func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[197] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12494,7 +12357,7 @@ func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasResponse.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{199} + return file_vtctldata_proto_rawDescGZIP(), []int{197} } func (x *UpdateCellsAliasResponse) GetName() string { @@ -12522,7 +12385,7 @@ type ValidateRequest struct { func (x *ValidateRequest) Reset() { *x = ValidateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[198] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12535,7 +12398,7 @@ func (x *ValidateRequest) String() string { func (*ValidateRequest) ProtoMessage() {} func (x *ValidateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[198] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12548,7 +12411,7 @@ func (x *ValidateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRequest.ProtoReflect.Descriptor instead. func (*ValidateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{200} + return file_vtctldata_proto_rawDescGZIP(), []int{198} } func (x *ValidateRequest) GetPingTablets() bool { @@ -12570,7 +12433,7 @@ type ValidateResponse struct { func (x *ValidateResponse) Reset() { *x = ValidateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[199] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12583,7 +12446,7 @@ func (x *ValidateResponse) String() string { func (*ValidateResponse) ProtoMessage() {} func (x *ValidateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[199] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12596,7 +12459,7 @@ func (x *ValidateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateResponse.ProtoReflect.Descriptor instead. func (*ValidateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{201} + return file_vtctldata_proto_rawDescGZIP(), []int{199} } func (x *ValidateResponse) GetResults() []string { @@ -12625,7 +12488,7 @@ type ValidateKeyspaceRequest struct { func (x *ValidateKeyspaceRequest) Reset() { *x = ValidateKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[200] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12638,7 +12501,7 @@ func (x *ValidateKeyspaceRequest) String() string { func (*ValidateKeyspaceRequest) ProtoMessage() {} func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[200] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12651,7 +12514,7 @@ func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{202} + return file_vtctldata_proto_rawDescGZIP(), []int{200} } func (x *ValidateKeyspaceRequest) GetKeyspace() string { @@ -12680,7 +12543,7 @@ type ValidateKeyspaceResponse struct { func (x *ValidateKeyspaceResponse) Reset() { *x = ValidateKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[201] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12693,7 +12556,7 @@ func (x *ValidateKeyspaceResponse) String() string { func (*ValidateKeyspaceResponse) ProtoMessage() {} func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[201] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12706,7 +12569,7 @@ func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{203} + return file_vtctldata_proto_rawDescGZIP(), []int{201} } func (x *ValidateKeyspaceResponse) GetResults() []string { @@ -12738,7 +12601,7 @@ type ValidateSchemaKeyspaceRequest struct { func (x *ValidateSchemaKeyspaceRequest) Reset() { *x = ValidateSchemaKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12751,7 +12614,7 @@ func (x *ValidateSchemaKeyspaceRequest) String() string { func (*ValidateSchemaKeyspaceRequest) ProtoMessage() {} func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[202] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12764,7 +12627,7 @@ func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{204} + return file_vtctldata_proto_rawDescGZIP(), []int{202} } func (x *ValidateSchemaKeyspaceRequest) GetKeyspace() string { @@ -12814,7 +12677,7 @@ type ValidateSchemaKeyspaceResponse struct { func (x *ValidateSchemaKeyspaceResponse) Reset() { *x = ValidateSchemaKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[203] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12827,7 +12690,7 @@ func (x *ValidateSchemaKeyspaceResponse) String() string { func (*ValidateSchemaKeyspaceResponse) ProtoMessage() {} func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[203] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12840,7 +12703,7 @@ func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{205} + return file_vtctldata_proto_rawDescGZIP(), []int{203} } func (x *ValidateSchemaKeyspaceResponse) GetResults() []string { @@ -12870,7 +12733,7 @@ type ValidateShardRequest struct { func (x *ValidateShardRequest) Reset() { *x = ValidateShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12883,7 +12746,7 @@ func (x *ValidateShardRequest) String() string { func (*ValidateShardRequest) ProtoMessage() {} func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[204] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12896,7 +12759,7 @@ func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardRequest.ProtoReflect.Descriptor instead. func (*ValidateShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{206} + return file_vtctldata_proto_rawDescGZIP(), []int{204} } func (x *ValidateShardRequest) GetKeyspace() string { @@ -12931,7 +12794,7 @@ type ValidateShardResponse struct { func (x *ValidateShardResponse) Reset() { *x = ValidateShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12944,7 +12807,7 @@ func (x *ValidateShardResponse) String() string { func (*ValidateShardResponse) ProtoMessage() {} func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[205] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12957,7 +12820,7 @@ func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardResponse.ProtoReflect.Descriptor instead. func (*ValidateShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{207} + return file_vtctldata_proto_rawDescGZIP(), []int{205} } func (x *ValidateShardResponse) GetResults() []string { @@ -12978,7 +12841,7 @@ type ValidateVersionKeyspaceRequest struct { func (x *ValidateVersionKeyspaceRequest) Reset() { *x = ValidateVersionKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[206] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12991,7 +12854,7 @@ func (x *ValidateVersionKeyspaceRequest) String() string { func (*ValidateVersionKeyspaceRequest) ProtoMessage() {} func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[206] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13004,7 +12867,7 @@ func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{208} + return file_vtctldata_proto_rawDescGZIP(), []int{206} } func (x *ValidateVersionKeyspaceRequest) GetKeyspace() string { @@ -13026,7 +12889,7 @@ type ValidateVersionKeyspaceResponse struct { func (x *ValidateVersionKeyspaceResponse) Reset() { *x = ValidateVersionKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[207] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13039,7 +12902,7 @@ func (x *ValidateVersionKeyspaceResponse) String() string { func (*ValidateVersionKeyspaceResponse) ProtoMessage() {} func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[207] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13052,7 +12915,7 @@ func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{209} + return file_vtctldata_proto_rawDescGZIP(), []int{207} } func (x *ValidateVersionKeyspaceResponse) GetResults() []string { @@ -13081,7 +12944,7 @@ type ValidateVersionShardRequest struct { func (x *ValidateVersionShardRequest) Reset() { *x = ValidateVersionShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[208] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13094,7 +12957,7 @@ func (x *ValidateVersionShardRequest) String() string { func (*ValidateVersionShardRequest) ProtoMessage() {} func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[208] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13107,7 +12970,7 @@ func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{210} + return file_vtctldata_proto_rawDescGZIP(), []int{208} } func (x *ValidateVersionShardRequest) GetKeyspace() string { @@ -13135,7 +12998,7 @@ type ValidateVersionShardResponse struct { func (x *ValidateVersionShardResponse) Reset() { *x = ValidateVersionShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13148,7 +13011,7 @@ func (x *ValidateVersionShardResponse) String() string { func (*ValidateVersionShardResponse) ProtoMessage() {} func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[209] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13161,7 +13024,7 @@ func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{211} + return file_vtctldata_proto_rawDescGZIP(), []int{209} } func (x *ValidateVersionShardResponse) GetResults() []string { @@ -13185,7 +13048,7 @@ type ValidateVSchemaRequest struct { func (x *ValidateVSchemaRequest) Reset() { *x = ValidateVSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13198,7 +13061,7 @@ func (x *ValidateVSchemaRequest) String() string { func (*ValidateVSchemaRequest) ProtoMessage() {} func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[210] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13211,7 +13074,7 @@ func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaRequest.ProtoReflect.Descriptor instead. func (*ValidateVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{212} + return file_vtctldata_proto_rawDescGZIP(), []int{210} } func (x *ValidateVSchemaRequest) GetKeyspace() string { @@ -13254,7 +13117,7 @@ type ValidateVSchemaResponse struct { func (x *ValidateVSchemaResponse) Reset() { *x = ValidateVSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13267,7 +13130,7 @@ func (x *ValidateVSchemaResponse) String() string { func (*ValidateVSchemaResponse) ProtoMessage() {} func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[211] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13280,7 +13143,7 @@ func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaResponse.ProtoReflect.Descriptor instead. func (*ValidateVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{213} + return file_vtctldata_proto_rawDescGZIP(), []int{211} } func (x *ValidateVSchemaResponse) GetResults() []string { @@ -13326,7 +13189,7 @@ type VDiffCreateRequest struct { func (x *VDiffCreateRequest) Reset() { *x = VDiffCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13339,7 +13202,7 @@ func (x *VDiffCreateRequest) String() string { func (*VDiffCreateRequest) ProtoMessage() {} func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[212] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13352,7 +13215,7 @@ func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateRequest.ProtoReflect.Descriptor instead. func (*VDiffCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{214} + return file_vtctldata_proto_rawDescGZIP(), []int{212} } func (x *VDiffCreateRequest) GetWorkflow() string { @@ -13501,7 +13364,7 @@ type VDiffCreateResponse struct { func (x *VDiffCreateResponse) Reset() { *x = VDiffCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13514,7 +13377,7 @@ func (x *VDiffCreateResponse) String() string { func (*VDiffCreateResponse) ProtoMessage() {} func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[213] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13527,7 +13390,7 @@ func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateResponse.ProtoReflect.Descriptor instead. func (*VDiffCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{215} + return file_vtctldata_proto_rawDescGZIP(), []int{213} } func (x *VDiffCreateResponse) GetUUID() string { @@ -13551,7 +13414,7 @@ type VDiffDeleteRequest struct { func (x *VDiffDeleteRequest) Reset() { *x = VDiffDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[214] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13564,7 +13427,7 @@ func (x *VDiffDeleteRequest) String() string { func (*VDiffDeleteRequest) ProtoMessage() {} func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[214] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13577,7 +13440,7 @@ func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteRequest.ProtoReflect.Descriptor instead. func (*VDiffDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{216} + return file_vtctldata_proto_rawDescGZIP(), []int{214} } func (x *VDiffDeleteRequest) GetWorkflow() string { @@ -13610,7 +13473,7 @@ type VDiffDeleteResponse struct { func (x *VDiffDeleteResponse) Reset() { *x = VDiffDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[215] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13623,7 +13486,7 @@ func (x *VDiffDeleteResponse) String() string { func (*VDiffDeleteResponse) ProtoMessage() {} func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[215] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13636,7 +13499,7 @@ func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteResponse.ProtoReflect.Descriptor instead. func (*VDiffDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{217} + return file_vtctldata_proto_rawDescGZIP(), []int{215} } type VDiffResumeRequest struct { @@ -13652,7 +13515,7 @@ type VDiffResumeRequest struct { func (x *VDiffResumeRequest) Reset() { *x = VDiffResumeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[216] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13665,7 +13528,7 @@ func (x *VDiffResumeRequest) String() string { func (*VDiffResumeRequest) ProtoMessage() {} func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[216] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13678,7 +13541,7 @@ func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeRequest.ProtoReflect.Descriptor instead. func (*VDiffResumeRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{218} + return file_vtctldata_proto_rawDescGZIP(), []int{216} } func (x *VDiffResumeRequest) GetWorkflow() string { @@ -13711,7 +13574,7 @@ type VDiffResumeResponse struct { func (x *VDiffResumeResponse) Reset() { *x = VDiffResumeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[217] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13724,7 +13587,7 @@ func (x *VDiffResumeResponse) String() string { func (*VDiffResumeResponse) ProtoMessage() {} func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[217] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13737,7 +13600,7 @@ func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeResponse.ProtoReflect.Descriptor instead. func (*VDiffResumeResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{219} + return file_vtctldata_proto_rawDescGZIP(), []int{217} } type VDiffShowRequest struct { @@ -13754,7 +13617,7 @@ type VDiffShowRequest struct { func (x *VDiffShowRequest) Reset() { *x = VDiffShowRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[218] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13767,7 +13630,7 @@ func (x *VDiffShowRequest) String() string { func (*VDiffShowRequest) ProtoMessage() {} func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[218] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13780,7 +13643,7 @@ func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowRequest.ProtoReflect.Descriptor instead. func (*VDiffShowRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{220} + return file_vtctldata_proto_rawDescGZIP(), []int{218} } func (x *VDiffShowRequest) GetWorkflow() string { @@ -13816,7 +13679,7 @@ type VDiffShowResponse struct { func (x *VDiffShowResponse) Reset() { *x = VDiffShowResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[219] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13829,7 +13692,7 @@ func (x *VDiffShowResponse) String() string { func (*VDiffShowResponse) ProtoMessage() {} func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[219] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13842,7 +13705,7 @@ func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowResponse.ProtoReflect.Descriptor instead. func (*VDiffShowResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{221} + return file_vtctldata_proto_rawDescGZIP(), []int{219} } func (x *VDiffShowResponse) GetTabletResponses() map[string]*tabletmanagerdata.VDiffResponse { @@ -13865,7 +13728,7 @@ type VDiffStopRequest struct { func (x *VDiffStopRequest) Reset() { *x = VDiffStopRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[220] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13878,7 +13741,7 @@ func (x *VDiffStopRequest) String() string { func (*VDiffStopRequest) ProtoMessage() {} func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[220] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13891,7 +13754,7 @@ func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopRequest.ProtoReflect.Descriptor instead. func (*VDiffStopRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{222} + return file_vtctldata_proto_rawDescGZIP(), []int{220} } func (x *VDiffStopRequest) GetWorkflow() string { @@ -13924,7 +13787,7 @@ type VDiffStopResponse struct { func (x *VDiffStopResponse) Reset() { *x = VDiffStopResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[221] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13937,7 +13800,7 @@ func (x *VDiffStopResponse) String() string { func (*VDiffStopResponse) ProtoMessage() {} func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[221] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13950,7 +13813,7 @@ func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopResponse.ProtoReflect.Descriptor instead. func (*VDiffStopResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{223} + return file_vtctldata_proto_rawDescGZIP(), []int{221} } type WorkflowDeleteRequest struct { @@ -13967,7 +13830,7 @@ type WorkflowDeleteRequest struct { func (x *WorkflowDeleteRequest) Reset() { *x = WorkflowDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[222] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13980,7 +13843,7 @@ func (x *WorkflowDeleteRequest) String() string { func (*WorkflowDeleteRequest) ProtoMessage() {} func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[222] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13993,7 +13856,7 @@ func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteRequest.ProtoReflect.Descriptor instead. func (*WorkflowDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{224} + return file_vtctldata_proto_rawDescGZIP(), []int{222} } func (x *WorkflowDeleteRequest) GetKeyspace() string { @@ -14036,7 +13899,7 @@ type WorkflowDeleteResponse struct { func (x *WorkflowDeleteResponse) Reset() { *x = WorkflowDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[223] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14049,7 +13912,7 @@ func (x *WorkflowDeleteResponse) String() string { func (*WorkflowDeleteResponse) ProtoMessage() {} func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[223] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14062,7 +13925,7 @@ func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteResponse.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225} + return file_vtctldata_proto_rawDescGZIP(), []int{223} } func (x *WorkflowDeleteResponse) GetSummary() string { @@ -14091,7 +13954,7 @@ type WorkflowStatusRequest struct { func (x *WorkflowStatusRequest) Reset() { *x = WorkflowStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[224] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14104,7 +13967,7 @@ func (x *WorkflowStatusRequest) String() string { func (*WorkflowStatusRequest) ProtoMessage() {} func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[224] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14117,7 +13980,7 @@ func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusRequest.ProtoReflect.Descriptor instead. func (*WorkflowStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{226} + return file_vtctldata_proto_rawDescGZIP(), []int{224} } func (x *WorkflowStatusRequest) GetKeyspace() string { @@ -14148,7 +14011,7 @@ type WorkflowStatusResponse struct { func (x *WorkflowStatusResponse) Reset() { *x = WorkflowStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[225] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14161,7 +14024,7 @@ func (x *WorkflowStatusResponse) String() string { func (*WorkflowStatusResponse) ProtoMessage() {} func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[225] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14174,7 +14037,7 @@ func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusResponse.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227} + return file_vtctldata_proto_rawDescGZIP(), []int{225} } func (x *WorkflowStatusResponse) GetTableCopyState() map[string]*WorkflowStatusResponse_TableCopyState { @@ -14218,7 +14081,7 @@ type WorkflowSwitchTrafficRequest struct { func (x *WorkflowSwitchTrafficRequest) Reset() { *x = WorkflowSwitchTrafficRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[226] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14231,7 +14094,7 @@ func (x *WorkflowSwitchTrafficRequest) String() string { func (*WorkflowSwitchTrafficRequest) ProtoMessage() {} func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[226] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14244,7 +14107,7 @@ func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficRequest.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{228} + return file_vtctldata_proto_rawDescGZIP(), []int{226} } func (x *WorkflowSwitchTrafficRequest) GetKeyspace() string { @@ -14331,7 +14194,7 @@ type WorkflowSwitchTrafficResponse struct { func (x *WorkflowSwitchTrafficResponse) Reset() { *x = WorkflowSwitchTrafficResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[227] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14344,7 +14207,7 @@ func (x *WorkflowSwitchTrafficResponse) String() string { func (*WorkflowSwitchTrafficResponse) ProtoMessage() {} func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[227] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14357,7 +14220,7 @@ func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficResponse.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{229} + return file_vtctldata_proto_rawDescGZIP(), []int{227} } func (x *WorkflowSwitchTrafficResponse) GetSummary() string { @@ -14402,7 +14265,7 @@ type WorkflowUpdateRequest struct { func (x *WorkflowUpdateRequest) Reset() { *x = WorkflowUpdateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[230] + mi := &file_vtctldata_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14415,7 +14278,7 @@ func (x *WorkflowUpdateRequest) String() string { func (*WorkflowUpdateRequest) ProtoMessage() {} func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[230] + mi := &file_vtctldata_proto_msgTypes[228] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14428,7 +14291,7 @@ func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateRequest.ProtoReflect.Descriptor instead. func (*WorkflowUpdateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{230} + return file_vtctldata_proto_rawDescGZIP(), []int{228} } func (x *WorkflowUpdateRequest) GetKeyspace() string { @@ -14457,7 +14320,7 @@ type WorkflowUpdateResponse struct { func (x *WorkflowUpdateResponse) Reset() { *x = WorkflowUpdateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14470,7 +14333,7 @@ func (x *WorkflowUpdateResponse) String() string { func (*WorkflowUpdateResponse) ProtoMessage() {} func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[229] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14483,7 +14346,7 @@ func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateResponse.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{231} + return file_vtctldata_proto_rawDescGZIP(), []int{229} } func (x *WorkflowUpdateResponse) GetSummary() string { @@ -14512,7 +14375,7 @@ type Workflow_ReplicationLocation struct { func (x *Workflow_ReplicationLocation) Reset() { *x = Workflow_ReplicationLocation{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[231] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14525,7 +14388,7 @@ func (x *Workflow_ReplicationLocation) String() string { func (*Workflow_ReplicationLocation) ProtoMessage() {} func (x *Workflow_ReplicationLocation) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[231] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14568,7 +14431,7 @@ type Workflow_ShardStream struct { func (x *Workflow_ShardStream) Reset() { *x = Workflow_ShardStream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[234] + mi := &file_vtctldata_proto_msgTypes[232] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14581,7 +14444,7 @@ func (x *Workflow_ShardStream) String() string { func (*Workflow_ShardStream) ProtoMessage() {} func (x *Workflow_ShardStream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[234] + mi := &file_vtctldata_proto_msgTypes[232] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14653,7 +14516,7 @@ type Workflow_Stream struct { func (x *Workflow_Stream) Reset() { *x = Workflow_Stream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[235] + mi := &file_vtctldata_proto_msgTypes[233] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14666,7 +14529,7 @@ func (x *Workflow_Stream) String() string { func (*Workflow_Stream) ProtoMessage() {} func (x *Workflow_Stream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[235] + mi := &file_vtctldata_proto_msgTypes[233] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14813,7 +14676,7 @@ type Workflow_Stream_CopyState struct { func (x *Workflow_Stream_CopyState) Reset() { *x = Workflow_Stream_CopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[236] + mi := &file_vtctldata_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14826,7 +14689,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[236] + mi := &file_vtctldata_proto_msgTypes[234] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14874,7 +14737,7 @@ type Workflow_Stream_Log struct { func (x *Workflow_Stream_Log) Reset() { *x = Workflow_Stream_Log{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[237] + mi := &file_vtctldata_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14887,7 +14750,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[237] + mi := &file_vtctldata_proto_msgTypes[235] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14971,7 +14834,7 @@ type Workflow_Stream_ThrottlerStatus struct { func (x *Workflow_Stream_ThrottlerStatus) Reset() { *x = Workflow_Stream_ThrottlerStatus{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[238] + mi := &file_vtctldata_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14984,7 +14847,7 @@ func (x *Workflow_Stream_ThrottlerStatus) String() string { func (*Workflow_Stream_ThrottlerStatus) ProtoMessage() {} func (x *Workflow_Stream_ThrottlerStatus) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[238] + mi := &file_vtctldata_proto_msgTypes[236] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15025,7 +14888,7 @@ type GetSrvKeyspaceNamesResponse_NameList struct { func (x *GetSrvKeyspaceNamesResponse_NameList) Reset() { *x = GetSrvKeyspaceNamesResponse_NameList{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[244] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15038,7 +14901,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) String() string { func (*GetSrvKeyspaceNamesResponse_NameList) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[244] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15074,7 +14937,7 @@ type MoveTablesCreateResponse_TabletInfo struct { func (x *MoveTablesCreateResponse_TabletInfo) Reset() { *x = MoveTablesCreateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[248] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15087,7 +14950,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) String() string { func (*MoveTablesCreateResponse_TabletInfo) ProtoMessage() {} func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[248] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15130,7 +14993,7 @@ type WorkflowDeleteResponse_TabletInfo struct { func (x *WorkflowDeleteResponse_TabletInfo) Reset() { *x = WorkflowDeleteResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[258] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15143,7 +15006,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) String() string { func (*WorkflowDeleteResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[258] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15156,7 +15019,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowDeleteResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{223, 0} } func (x *WorkflowDeleteResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -15189,7 +15052,7 @@ type WorkflowStatusResponse_TableCopyState struct { func (x *WorkflowStatusResponse_TableCopyState) Reset() { *x = WorkflowStatusResponse_TableCopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[259] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15202,7 +15065,7 @@ func (x *WorkflowStatusResponse_TableCopyState) String() string { func (*WorkflowStatusResponse_TableCopyState) ProtoMessage() {} func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[259] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15215,7 +15078,7 @@ func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Mess // Deprecated: Use WorkflowStatusResponse_TableCopyState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_TableCopyState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{225, 0} } func (x *WorkflowStatusResponse_TableCopyState) GetRowsCopied() int64 { @@ -15276,7 +15139,7 @@ type WorkflowStatusResponse_ShardStreamState struct { func (x *WorkflowStatusResponse_ShardStreamState) Reset() { *x = WorkflowStatusResponse_ShardStreamState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[262] + mi := &file_vtctldata_proto_msgTypes[260] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15289,7 +15152,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) String() string { func (*WorkflowStatusResponse_ShardStreamState) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[262] + mi := &file_vtctldata_proto_msgTypes[260] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15302,7 +15165,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Me // Deprecated: Use WorkflowStatusResponse_ShardStreamState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreamState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227, 1} + return file_vtctldata_proto_rawDescGZIP(), []int{225, 1} } func (x *WorkflowStatusResponse_ShardStreamState) GetId() int32 { @@ -15358,7 +15221,7 @@ type WorkflowStatusResponse_ShardStreams struct { func (x *WorkflowStatusResponse_ShardStreams) Reset() { *x = WorkflowStatusResponse_ShardStreams{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[261] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15371,7 +15234,7 @@ func (x *WorkflowStatusResponse_ShardStreams) String() string { func (*WorkflowStatusResponse_ShardStreams) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[261] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15384,7 +15247,7 @@ func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Messag // Deprecated: Use WorkflowStatusResponse_ShardStreams.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreams) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227, 2} + return file_vtctldata_proto_rawDescGZIP(), []int{225, 2} } func (x *WorkflowStatusResponse_ShardStreams) GetStreams() []*WorkflowStatusResponse_ShardStreamState { @@ -15408,7 +15271,7 @@ type WorkflowUpdateResponse_TabletInfo struct { func (x *WorkflowUpdateResponse_TabletInfo) Reset() { *x = WorkflowUpdateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[266] + mi := &file_vtctldata_proto_msgTypes[264] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15421,7 +15284,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) String() string { func (*WorkflowUpdateResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[266] + mi := &file_vtctldata_proto_msgTypes[264] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15434,7 +15297,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowUpdateResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{231, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{229, 0} } func (x *WorkflowUpdateResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -16032,7 +15895,7 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, - 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x03, 0x0a, + 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x02, 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, @@ -16040,130 +15903,141 @@ var file_vtctldata_proto_rawDesc = []byte{ 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, 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, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, - 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, - 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x04, - 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 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, 0x67, 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, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x66, 0x6f, 0x72, 0x63, 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, 0x9b, 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, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x16, - 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, + 0x61, 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, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x5f, 0x64, 0x62, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x69, 0x64, + 0x65, 0x63, 0x61, 0x72, 0x44, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 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, - 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, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, - 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x81, 0x03, 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, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x70, 0x72, - 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x70, - 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x65, 0x6c, 0x6c, 0x50, - 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x41, - 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x1e, 0x45, 0x6d, + 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, 0x67, 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, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 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, 0x9b, 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, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, + 0x63, 0x65, 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, 0x2d, 0x0a, 0x17, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 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, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x81, 0x03, 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, 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, 0xa0, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, + 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, 0x12, 0x3f, 0x0a, 0x1c, 0x70, + 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x63, 0x65, 0x6c, + 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x19, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, + 0x65, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x14, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x77, 0x61, 0x69, 0x74, + 0x46, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 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, 0xa0, 0x01, 0x0a, + 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, + 0x70, 0x70, 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, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, + 0x52, 0x6f, 0x77, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x50, 0x6f, 0x6f, 0x6c, 0x22, + 0x47, 0x0a, 0x19, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, + 0x73, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 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, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 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, @@ -16171,1522 +16045,1490 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, - 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x50, 0x6f, 0x6f, 0x6c, 0x22, 0x47, 0x0a, 0x19, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x18, 0x01, 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, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 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, 0x14, 0x0a, 0x05, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x27, 0x0a, 0x0f, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, - 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x47, 0x0a, 0x19, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x44, 0x42, 0x41, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x01, 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, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, - 0x6f, 0x6f, 0x6b, 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, 0x55, 0x0a, 0x13, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x68, - 0x6f, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x13, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x0a, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 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, + 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x47, + 0x0a, 0x19, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, + 0x44, 0x42, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 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, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 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, 0x55, 0x0a, 0x13, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x5e, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 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, 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, 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, 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, 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 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, 0x4c, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 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, - 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 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, 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, 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, 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x46, 0x75, + 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x4c, 0x0a, 0x15, 0x47, 0x65, 0x74, + 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 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, 0x5a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x40, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 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, 0xb0, 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, 0x22, 0x5a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 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, - 0xb0, 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, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0xb8, 0x02, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 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, - 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x72, - 0x65, 0x63, 0x65, 0x6e, 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, 0x06, 0x72, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, - 0x6b, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x22, - 0x59, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, - 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, - 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 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, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, - 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf3, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x31, 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, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x0a, - 0x4e, 0x61, 0x6d, 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, 0x45, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x20, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf8, 0x02, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x74, 0x12, 0x2d, - 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x2f, 0x0a, - 0x14, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x3f, - 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x22, - 0x1f, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 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, 0xe8, 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, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x06, 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, 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, 0x2c, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x46, 0x0a, 0x17, 0x47, - 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x22, 0x66, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, - 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 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, 0x4d, 0x0a, 0x11, - 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x2e, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, - 0xae, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 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, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 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, 0xb8, 0x02, 0x0a, 0x1a, 0x47, 0x65, 0x74, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 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, 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, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x6c, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x21, 0x0a, - 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, - 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, + 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x28, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 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, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, + 0x6b, 0x69, 0x70, 0x22, 0x59, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 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, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf3, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, + 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x1a, 0x69, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 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, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x20, 0x0a, 0x08, 0x4e, + 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 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, 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, 0x4e, 0x0a, - 0x1c, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdf, 0x01, - 0x0a, 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x76, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x41, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, - 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xff, 0x02, 0x0a, 0x19, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x43, 0x72, 0x65, 0x61, 0x74, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x76, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, - 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x75, 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x77, 0x69, - 0x74, 0x68, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, - 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, - 0x79, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x77, 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 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, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4c, 0x0a, 0x1f, 0x4c, 0x6f, 0x6f, 0x6b, - 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x18, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x1b, - 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x05, 0x0a, 0x14, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, - 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, - 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, - 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, - 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, - 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, - 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x16, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, - 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, - 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, - 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, - 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, - 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, - 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, - 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, - 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, - 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x4d, - 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, - 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, - 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, - 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, - 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, - 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x11, - 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0xbb, 0x06, 0x0a, 0x17, 0x4d, 0x6f, 0x76, 0x65, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, - 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x32, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x13, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, - 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, - 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, - 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, - 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, - 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x63, - 0x6f, 0x70, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x74, 0x6f, 0x6d, 0x69, - 0x63, 0x43, 0x6f, 0x70, 0x79, 0x22, 0xd5, 0x01, 0x0a, 0x18, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x07, - 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xe9, 0x01, - 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, - 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, - 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5e, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, - 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x69, 0x6e, - 0x67, 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, 0x14, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd7, - 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, 0x12, 0x4c, 0x0a, 0x19, 0x74, 0x6f, - 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x17, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 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, + 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, 0xf8, 0x02, 0x0a, 0x1c, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 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, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, + 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x6c, + 0x66, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, + 0x61, 0x70, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, + 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, + 0x41, 0x70, 0x70, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 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, 0xe8, 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, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 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, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, + 0x46, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, + 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, + 0x6c, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x66, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 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, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x52, - 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, + 0x22, 0x4d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x83, 0x01, - 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, 0x12, 0x36, 0x0a, 0x17, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 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, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x0a, - 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, - 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, - 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, 0x6c, 0x6f, - 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 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, - 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, - 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, - 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 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, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x2e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0xae, 0x01, 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, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x61, 0x6d, + 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 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, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 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, 0x8f, 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, - 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, - 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, - 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, - 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, - 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x82, 0x02, 0x0a, 0x18, 0x52, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, - 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, - 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, - 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xad, 0x01, - 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4d, 0x0a, - 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, 0x01, 0x0a, - 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, - 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, - 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, 0x0a, 0x15, - 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 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, - 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, 0x2b, 0x0a, 0x11, 0x64, - 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, - 0xc8, 0x01, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 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, 0x35, 0x0a, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 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, 0x4e, 0x0a, 0x1c, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x22, 0xdf, 0x01, 0x0a, 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, + 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, + 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, + 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xff, 0x02, 0x0a, 0x19, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 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, 0x1a, 0x0a, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, + 0x29, 0x0a, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, + 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x43, 0x6f, 0x70, 0x79, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x37, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4c, 0x0a, 0x1f, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x29, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x18, 0x4d, 0x61, + 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xdd, 0x05, 0x0a, 0x14, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, + 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, + 0x6f, 0x6e, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, + 0x64, 0x64, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, + 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, + 0x6f, 0x70, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, + 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, + 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, + 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, + 0xe6, 0x01, 0x0a, 0x16, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, + 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, + 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, + 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, + 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, + 0x15, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, + 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x26, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, + 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x29, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0xbb, 0x06, 0x0a, 0x17, + 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 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, 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, 0x72, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4f, 0x0a, 0x1d, 0x53, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, - 0x72, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, + 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, + 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, + 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, + 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, + 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, + 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, + 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, + 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x74, 0x6f, 0x6d, + 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, + 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x70, 0x79, 0x22, 0xd5, 0x01, 0x0a, 0x18, 0x4d, 0x6f, + 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x12, 0x48, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, + 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x22, 0xe9, 0x01, 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, + 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5e, 0x0a, + 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, + 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x4d, 0x0a, + 0x11, 0x50, 0x69, 0x6e, 0x67, 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, 0x14, 0x0a, 0x12, + 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xd7, 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, 0x12, 0x4c, + 0x0a, 0x19, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 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, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, - 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, - 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 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, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, - 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x6e, 0x67, 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, - 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x01, 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, 0x8e, 0x02, - 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 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, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, - 0x0a, 0x1d, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, - 0x74, 0x61, 0x62, 0x6c, 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, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 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, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, + 0x68, 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, 0x38, 0x0a, 0x0c, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 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, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, + 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, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, + 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x14, 0x0a, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x22, 0x83, 0x01, 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, 0x12, + 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x15, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, + 0x64, 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, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xa9, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 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, 0x23, 0x0a, 0x0d, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, + 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, + 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 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, 0x8b, 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 0x14, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 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, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, - 0x0a, 0x1e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x7c, 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, 0x70, 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, - 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, - 0x0a, 0x13, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x61, 0x72, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x79, 0x22, 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 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, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, - 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 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, 0x07, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x8f, 0x04, 0x0a, 0x14, 0x52, + 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, + 0x69, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, + 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, + 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, + 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x82, 0x02, 0x0a, + 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, + 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, + 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, + 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, + 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, + 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, + 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x22, 0xdd, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, + 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, + 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x51, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, + 0x63, 0x6b, 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, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, + 0x22, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, + 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, + 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x01, 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, 0x53, 0x0a, - 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 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, 0x1a, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, - 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 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, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, + 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x6e, 0x67, 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, 0x1d, 0x0a, 0x0a, 0x69, + 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x8e, 0x02, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 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, 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, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, + 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, 0x0a, 0x1d, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x01, 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, 0x6a, + 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 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, 0x1a, + 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, + 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 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, 0x38, 0x0a, 0x0c, 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, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1d, 0x0a, 0x1b, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, + 0x69, 0x78, 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, 0x12, 0x0a, 0x04, 0x63, + 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, + 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x8b, 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 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, 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, 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, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, + 0x70, 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, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, + 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 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, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, + 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, + 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x53, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, 0x0a, 0x18, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x19, 0x0a, 0x17, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, - 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, 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, - 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, - 0x16, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 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, + 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, 0x22, 0x34, 0x0a, 0x0f, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 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, - 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, - 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, - 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, - 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, 0x14, 0x0a, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x8a, 0x02, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, - 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, - 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 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, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, + 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, + 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 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, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, + 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, + 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, + 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, + 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 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, 0x14, 0x0a, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x22, 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, - 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 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, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 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, 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x8a, 0x02, + 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x22, 0x38, 0x0a, 0x1c, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 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, 0x16, 0x0a, 0x06, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, + 0x61, 0x72, 0x64, 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, + 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, - 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, - 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, - 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, - 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, - 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, - 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, - 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, - 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, - 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, - 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, - 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, - 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, - 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, - 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, - 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, - 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, + 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, + 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, + 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, + 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, + 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, - 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, - 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, - 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, - 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, - 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, - 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, - 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, + 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, + 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, + 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 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, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, + 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, + 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, + 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, + 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, + 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, + 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, + 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, + 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, + 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, + 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, + 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, - 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, - 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, - 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, - 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, - 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, - 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, + 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 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, 0x1a, + 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, + 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, + 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, - 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, - 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, - 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, - 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, - 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, - 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, - 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, - 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, - 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, - 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, - 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, - 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, - 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, - 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, - 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, - 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, - 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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, + 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, + 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, + 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, + 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, + 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x02, 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 ( @@ -17702,7 +17544,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { } var file_vtctldata_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 267) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 265) var file_vtctldata_proto_goTypes = []interface{}{ (MaterializationIntent)(0), // 0: vtctldata.MaterializationIntent (QueryOrdering)(0), // 1: vtctldata.QueryOrdering @@ -17874,356 +17716,350 @@ var file_vtctldata_proto_goTypes = []interface{}{ (*RunHealthCheckResponse)(nil), // 167: vtctldata.RunHealthCheckResponse (*SetKeyspaceDurabilityPolicyRequest)(nil), // 168: vtctldata.SetKeyspaceDurabilityPolicyRequest (*SetKeyspaceDurabilityPolicyResponse)(nil), // 169: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*SetKeyspaceServedFromRequest)(nil), // 170: vtctldata.SetKeyspaceServedFromRequest - (*SetKeyspaceServedFromResponse)(nil), // 171: vtctldata.SetKeyspaceServedFromResponse - (*SetKeyspaceShardingInfoRequest)(nil), // 172: vtctldata.SetKeyspaceShardingInfoRequest - (*SetKeyspaceShardingInfoResponse)(nil), // 173: vtctldata.SetKeyspaceShardingInfoResponse - (*SetShardIsPrimaryServingRequest)(nil), // 174: vtctldata.SetShardIsPrimaryServingRequest - (*SetShardIsPrimaryServingResponse)(nil), // 175: vtctldata.SetShardIsPrimaryServingResponse - (*SetShardTabletControlRequest)(nil), // 176: vtctldata.SetShardTabletControlRequest - (*SetShardTabletControlResponse)(nil), // 177: vtctldata.SetShardTabletControlResponse - (*SetWritableRequest)(nil), // 178: vtctldata.SetWritableRequest - (*SetWritableResponse)(nil), // 179: vtctldata.SetWritableResponse - (*ShardReplicationAddRequest)(nil), // 180: vtctldata.ShardReplicationAddRequest - (*ShardReplicationAddResponse)(nil), // 181: vtctldata.ShardReplicationAddResponse - (*ShardReplicationFixRequest)(nil), // 182: vtctldata.ShardReplicationFixRequest - (*ShardReplicationFixResponse)(nil), // 183: vtctldata.ShardReplicationFixResponse - (*ShardReplicationPositionsRequest)(nil), // 184: vtctldata.ShardReplicationPositionsRequest - (*ShardReplicationPositionsResponse)(nil), // 185: vtctldata.ShardReplicationPositionsResponse - (*ShardReplicationRemoveRequest)(nil), // 186: vtctldata.ShardReplicationRemoveRequest - (*ShardReplicationRemoveResponse)(nil), // 187: vtctldata.ShardReplicationRemoveResponse - (*SleepTabletRequest)(nil), // 188: vtctldata.SleepTabletRequest - (*SleepTabletResponse)(nil), // 189: vtctldata.SleepTabletResponse - (*SourceShardAddRequest)(nil), // 190: vtctldata.SourceShardAddRequest - (*SourceShardAddResponse)(nil), // 191: vtctldata.SourceShardAddResponse - (*SourceShardDeleteRequest)(nil), // 192: vtctldata.SourceShardDeleteRequest - (*SourceShardDeleteResponse)(nil), // 193: vtctldata.SourceShardDeleteResponse - (*StartReplicationRequest)(nil), // 194: vtctldata.StartReplicationRequest - (*StartReplicationResponse)(nil), // 195: vtctldata.StartReplicationResponse - (*StopReplicationRequest)(nil), // 196: vtctldata.StopReplicationRequest - (*StopReplicationResponse)(nil), // 197: vtctldata.StopReplicationResponse - (*TabletExternallyReparentedRequest)(nil), // 198: vtctldata.TabletExternallyReparentedRequest - (*TabletExternallyReparentedResponse)(nil), // 199: vtctldata.TabletExternallyReparentedResponse - (*UpdateCellInfoRequest)(nil), // 200: vtctldata.UpdateCellInfoRequest - (*UpdateCellInfoResponse)(nil), // 201: vtctldata.UpdateCellInfoResponse - (*UpdateCellsAliasRequest)(nil), // 202: vtctldata.UpdateCellsAliasRequest - (*UpdateCellsAliasResponse)(nil), // 203: vtctldata.UpdateCellsAliasResponse - (*ValidateRequest)(nil), // 204: vtctldata.ValidateRequest - (*ValidateResponse)(nil), // 205: vtctldata.ValidateResponse - (*ValidateKeyspaceRequest)(nil), // 206: vtctldata.ValidateKeyspaceRequest - (*ValidateKeyspaceResponse)(nil), // 207: vtctldata.ValidateKeyspaceResponse - (*ValidateSchemaKeyspaceRequest)(nil), // 208: vtctldata.ValidateSchemaKeyspaceRequest - (*ValidateSchemaKeyspaceResponse)(nil), // 209: vtctldata.ValidateSchemaKeyspaceResponse - (*ValidateShardRequest)(nil), // 210: vtctldata.ValidateShardRequest - (*ValidateShardResponse)(nil), // 211: vtctldata.ValidateShardResponse - (*ValidateVersionKeyspaceRequest)(nil), // 212: vtctldata.ValidateVersionKeyspaceRequest - (*ValidateVersionKeyspaceResponse)(nil), // 213: vtctldata.ValidateVersionKeyspaceResponse - (*ValidateVersionShardRequest)(nil), // 214: vtctldata.ValidateVersionShardRequest - (*ValidateVersionShardResponse)(nil), // 215: vtctldata.ValidateVersionShardResponse - (*ValidateVSchemaRequest)(nil), // 216: vtctldata.ValidateVSchemaRequest - (*ValidateVSchemaResponse)(nil), // 217: vtctldata.ValidateVSchemaResponse - (*VDiffCreateRequest)(nil), // 218: vtctldata.VDiffCreateRequest - (*VDiffCreateResponse)(nil), // 219: vtctldata.VDiffCreateResponse - (*VDiffDeleteRequest)(nil), // 220: vtctldata.VDiffDeleteRequest - (*VDiffDeleteResponse)(nil), // 221: vtctldata.VDiffDeleteResponse - (*VDiffResumeRequest)(nil), // 222: vtctldata.VDiffResumeRequest - (*VDiffResumeResponse)(nil), // 223: vtctldata.VDiffResumeResponse - (*VDiffShowRequest)(nil), // 224: vtctldata.VDiffShowRequest - (*VDiffShowResponse)(nil), // 225: vtctldata.VDiffShowResponse - (*VDiffStopRequest)(nil), // 226: vtctldata.VDiffStopRequest - (*VDiffStopResponse)(nil), // 227: vtctldata.VDiffStopResponse - (*WorkflowDeleteRequest)(nil), // 228: vtctldata.WorkflowDeleteRequest - (*WorkflowDeleteResponse)(nil), // 229: vtctldata.WorkflowDeleteResponse - (*WorkflowStatusRequest)(nil), // 230: vtctldata.WorkflowStatusRequest - (*WorkflowStatusResponse)(nil), // 231: vtctldata.WorkflowStatusResponse - (*WorkflowSwitchTrafficRequest)(nil), // 232: vtctldata.WorkflowSwitchTrafficRequest - (*WorkflowSwitchTrafficResponse)(nil), // 233: vtctldata.WorkflowSwitchTrafficResponse - (*WorkflowUpdateRequest)(nil), // 234: vtctldata.WorkflowUpdateRequest - (*WorkflowUpdateResponse)(nil), // 235: vtctldata.WorkflowUpdateResponse - nil, // 236: vtctldata.Workflow.ShardStreamsEntry - (*Workflow_ReplicationLocation)(nil), // 237: vtctldata.Workflow.ReplicationLocation - (*Workflow_ShardStream)(nil), // 238: vtctldata.Workflow.ShardStream - (*Workflow_Stream)(nil), // 239: vtctldata.Workflow.Stream - (*Workflow_Stream_CopyState)(nil), // 240: vtctldata.Workflow.Stream.CopyState - (*Workflow_Stream_Log)(nil), // 241: vtctldata.Workflow.Stream.Log - (*Workflow_Stream_ThrottlerStatus)(nil), // 242: vtctldata.Workflow.Stream.ThrottlerStatus - nil, // 243: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - nil, // 244: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 245: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 246: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 247: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 248: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 249: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 250: vtctldata.GetSrvKeyspaceNamesResponse.NameList - nil, // 251: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 252: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 253: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - (*MoveTablesCreateResponse_TabletInfo)(nil), // 254: vtctldata.MoveTablesCreateResponse.TabletInfo - nil, // 255: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 256: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 257: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - nil, // 258: vtctldata.ValidateResponse.ResultsByKeyspaceEntry - nil, // 259: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - nil, // 260: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - nil, // 261: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - nil, // 262: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - nil, // 263: vtctldata.VDiffShowResponse.TabletResponsesEntry - (*WorkflowDeleteResponse_TabletInfo)(nil), // 264: vtctldata.WorkflowDeleteResponse.TabletInfo - (*WorkflowStatusResponse_TableCopyState)(nil), // 265: vtctldata.WorkflowStatusResponse.TableCopyState - (*WorkflowStatusResponse_ShardStreamState)(nil), // 266: vtctldata.WorkflowStatusResponse.ShardStreamState - (*WorkflowStatusResponse_ShardStreams)(nil), // 267: vtctldata.WorkflowStatusResponse.ShardStreams - nil, // 268: vtctldata.WorkflowStatusResponse.TableCopyStateEntry - nil, // 269: vtctldata.WorkflowStatusResponse.ShardStreamsEntry - (*WorkflowUpdateResponse_TabletInfo)(nil), // 270: vtctldata.WorkflowUpdateResponse.TabletInfo - (*logutil.Event)(nil), // 271: logutil.Event - (tabletmanagerdata.TabletSelectionPreference)(0), // 272: tabletmanagerdata.TabletSelectionPreference - (*topodata.Keyspace)(nil), // 273: topodata.Keyspace - (*vttime.Time)(nil), // 274: vttime.Time - (*topodata.TabletAlias)(nil), // 275: topodata.TabletAlias - (*vttime.Duration)(nil), // 276: vttime.Duration - (*topodata.Shard)(nil), // 277: topodata.Shard - (*topodata.CellInfo)(nil), // 278: topodata.CellInfo - (*vschema.RoutingRules)(nil), // 279: vschema.RoutingRules - (*vschema.ShardRoutingRules)(nil), // 280: vschema.ShardRoutingRules - (*vtrpc.CallerID)(nil), // 281: vtrpc.CallerID - (*vschema.Keyspace)(nil), // 282: vschema.Keyspace - (topodata.TabletType)(0), // 283: topodata.TabletType - (*topodata.Tablet)(nil), // 284: topodata.Tablet - (*topodata.Keyspace_ServedFrom)(nil), // 285: topodata.Keyspace.ServedFrom - (topodata.KeyspaceType)(0), // 286: topodata.KeyspaceType - (*query.QueryResult)(nil), // 287: query.QueryResult - (*tabletmanagerdata.ExecuteHookRequest)(nil), // 288: tabletmanagerdata.ExecuteHookRequest - (*tabletmanagerdata.ExecuteHookResponse)(nil), // 289: tabletmanagerdata.ExecuteHookResponse - (*mysqlctl.BackupInfo)(nil), // 290: mysqlctl.BackupInfo - (*replicationdata.FullStatus)(nil), // 291: replicationdata.FullStatus - (*tabletmanagerdata.Permissions)(nil), // 292: tabletmanagerdata.Permissions - (*tabletmanagerdata.SchemaDefinition)(nil), // 293: tabletmanagerdata.SchemaDefinition - (*topodata.ThrottledAppRule)(nil), // 294: topodata.ThrottledAppRule - (*vschema.SrvVSchema)(nil), // 295: vschema.SrvVSchema - (*topodata.ShardReplicationError)(nil), // 296: topodata.ShardReplicationError - (*topodata.KeyRange)(nil), // 297: topodata.KeyRange - (*topodata.CellsAlias)(nil), // 298: topodata.CellsAlias - (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 299: tabletmanagerdata.UpdateVReplicationWorkflowRequest - (*topodata.Shard_TabletControl)(nil), // 300: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 301: binlogdata.BinlogSource - (*topodata.SrvKeyspace)(nil), // 302: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 303: replicationdata.Status - (*tabletmanagerdata.VDiffResponse)(nil), // 304: tabletmanagerdata.VDiffResponse + (*SetKeyspaceShardingInfoRequest)(nil), // 170: vtctldata.SetKeyspaceShardingInfoRequest + (*SetKeyspaceShardingInfoResponse)(nil), // 171: vtctldata.SetKeyspaceShardingInfoResponse + (*SetShardIsPrimaryServingRequest)(nil), // 172: vtctldata.SetShardIsPrimaryServingRequest + (*SetShardIsPrimaryServingResponse)(nil), // 173: vtctldata.SetShardIsPrimaryServingResponse + (*SetShardTabletControlRequest)(nil), // 174: vtctldata.SetShardTabletControlRequest + (*SetShardTabletControlResponse)(nil), // 175: vtctldata.SetShardTabletControlResponse + (*SetWritableRequest)(nil), // 176: vtctldata.SetWritableRequest + (*SetWritableResponse)(nil), // 177: vtctldata.SetWritableResponse + (*ShardReplicationAddRequest)(nil), // 178: vtctldata.ShardReplicationAddRequest + (*ShardReplicationAddResponse)(nil), // 179: vtctldata.ShardReplicationAddResponse + (*ShardReplicationFixRequest)(nil), // 180: vtctldata.ShardReplicationFixRequest + (*ShardReplicationFixResponse)(nil), // 181: vtctldata.ShardReplicationFixResponse + (*ShardReplicationPositionsRequest)(nil), // 182: vtctldata.ShardReplicationPositionsRequest + (*ShardReplicationPositionsResponse)(nil), // 183: vtctldata.ShardReplicationPositionsResponse + (*ShardReplicationRemoveRequest)(nil), // 184: vtctldata.ShardReplicationRemoveRequest + (*ShardReplicationRemoveResponse)(nil), // 185: vtctldata.ShardReplicationRemoveResponse + (*SleepTabletRequest)(nil), // 186: vtctldata.SleepTabletRequest + (*SleepTabletResponse)(nil), // 187: vtctldata.SleepTabletResponse + (*SourceShardAddRequest)(nil), // 188: vtctldata.SourceShardAddRequest + (*SourceShardAddResponse)(nil), // 189: vtctldata.SourceShardAddResponse + (*SourceShardDeleteRequest)(nil), // 190: vtctldata.SourceShardDeleteRequest + (*SourceShardDeleteResponse)(nil), // 191: vtctldata.SourceShardDeleteResponse + (*StartReplicationRequest)(nil), // 192: vtctldata.StartReplicationRequest + (*StartReplicationResponse)(nil), // 193: vtctldata.StartReplicationResponse + (*StopReplicationRequest)(nil), // 194: vtctldata.StopReplicationRequest + (*StopReplicationResponse)(nil), // 195: vtctldata.StopReplicationResponse + (*TabletExternallyReparentedRequest)(nil), // 196: vtctldata.TabletExternallyReparentedRequest + (*TabletExternallyReparentedResponse)(nil), // 197: vtctldata.TabletExternallyReparentedResponse + (*UpdateCellInfoRequest)(nil), // 198: vtctldata.UpdateCellInfoRequest + (*UpdateCellInfoResponse)(nil), // 199: vtctldata.UpdateCellInfoResponse + (*UpdateCellsAliasRequest)(nil), // 200: vtctldata.UpdateCellsAliasRequest + (*UpdateCellsAliasResponse)(nil), // 201: vtctldata.UpdateCellsAliasResponse + (*ValidateRequest)(nil), // 202: vtctldata.ValidateRequest + (*ValidateResponse)(nil), // 203: vtctldata.ValidateResponse + (*ValidateKeyspaceRequest)(nil), // 204: vtctldata.ValidateKeyspaceRequest + (*ValidateKeyspaceResponse)(nil), // 205: vtctldata.ValidateKeyspaceResponse + (*ValidateSchemaKeyspaceRequest)(nil), // 206: vtctldata.ValidateSchemaKeyspaceRequest + (*ValidateSchemaKeyspaceResponse)(nil), // 207: vtctldata.ValidateSchemaKeyspaceResponse + (*ValidateShardRequest)(nil), // 208: vtctldata.ValidateShardRequest + (*ValidateShardResponse)(nil), // 209: vtctldata.ValidateShardResponse + (*ValidateVersionKeyspaceRequest)(nil), // 210: vtctldata.ValidateVersionKeyspaceRequest + (*ValidateVersionKeyspaceResponse)(nil), // 211: vtctldata.ValidateVersionKeyspaceResponse + (*ValidateVersionShardRequest)(nil), // 212: vtctldata.ValidateVersionShardRequest + (*ValidateVersionShardResponse)(nil), // 213: vtctldata.ValidateVersionShardResponse + (*ValidateVSchemaRequest)(nil), // 214: vtctldata.ValidateVSchemaRequest + (*ValidateVSchemaResponse)(nil), // 215: vtctldata.ValidateVSchemaResponse + (*VDiffCreateRequest)(nil), // 216: vtctldata.VDiffCreateRequest + (*VDiffCreateResponse)(nil), // 217: vtctldata.VDiffCreateResponse + (*VDiffDeleteRequest)(nil), // 218: vtctldata.VDiffDeleteRequest + (*VDiffDeleteResponse)(nil), // 219: vtctldata.VDiffDeleteResponse + (*VDiffResumeRequest)(nil), // 220: vtctldata.VDiffResumeRequest + (*VDiffResumeResponse)(nil), // 221: vtctldata.VDiffResumeResponse + (*VDiffShowRequest)(nil), // 222: vtctldata.VDiffShowRequest + (*VDiffShowResponse)(nil), // 223: vtctldata.VDiffShowResponse + (*VDiffStopRequest)(nil), // 224: vtctldata.VDiffStopRequest + (*VDiffStopResponse)(nil), // 225: vtctldata.VDiffStopResponse + (*WorkflowDeleteRequest)(nil), // 226: vtctldata.WorkflowDeleteRequest + (*WorkflowDeleteResponse)(nil), // 227: vtctldata.WorkflowDeleteResponse + (*WorkflowStatusRequest)(nil), // 228: vtctldata.WorkflowStatusRequest + (*WorkflowStatusResponse)(nil), // 229: vtctldata.WorkflowStatusResponse + (*WorkflowSwitchTrafficRequest)(nil), // 230: vtctldata.WorkflowSwitchTrafficRequest + (*WorkflowSwitchTrafficResponse)(nil), // 231: vtctldata.WorkflowSwitchTrafficResponse + (*WorkflowUpdateRequest)(nil), // 232: vtctldata.WorkflowUpdateRequest + (*WorkflowUpdateResponse)(nil), // 233: vtctldata.WorkflowUpdateResponse + nil, // 234: vtctldata.Workflow.ShardStreamsEntry + (*Workflow_ReplicationLocation)(nil), // 235: vtctldata.Workflow.ReplicationLocation + (*Workflow_ShardStream)(nil), // 236: vtctldata.Workflow.ShardStream + (*Workflow_Stream)(nil), // 237: vtctldata.Workflow.Stream + (*Workflow_Stream_CopyState)(nil), // 238: vtctldata.Workflow.Stream.CopyState + (*Workflow_Stream_Log)(nil), // 239: vtctldata.Workflow.Stream.Log + (*Workflow_Stream_ThrottlerStatus)(nil), // 240: vtctldata.Workflow.Stream.ThrottlerStatus + nil, // 241: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + nil, // 242: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 243: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 244: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 245: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 246: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 247: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 248: vtctldata.GetSrvKeyspaceNamesResponse.NameList + nil, // 249: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 250: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 251: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + (*MoveTablesCreateResponse_TabletInfo)(nil), // 252: vtctldata.MoveTablesCreateResponse.TabletInfo + nil, // 253: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 254: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 255: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + nil, // 256: vtctldata.ValidateResponse.ResultsByKeyspaceEntry + nil, // 257: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + nil, // 258: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + nil, // 259: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + nil, // 260: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + nil, // 261: vtctldata.VDiffShowResponse.TabletResponsesEntry + (*WorkflowDeleteResponse_TabletInfo)(nil), // 262: vtctldata.WorkflowDeleteResponse.TabletInfo + (*WorkflowStatusResponse_TableCopyState)(nil), // 263: vtctldata.WorkflowStatusResponse.TableCopyState + (*WorkflowStatusResponse_ShardStreamState)(nil), // 264: vtctldata.WorkflowStatusResponse.ShardStreamState + (*WorkflowStatusResponse_ShardStreams)(nil), // 265: vtctldata.WorkflowStatusResponse.ShardStreams + nil, // 266: vtctldata.WorkflowStatusResponse.TableCopyStateEntry + nil, // 267: vtctldata.WorkflowStatusResponse.ShardStreamsEntry + (*WorkflowUpdateResponse_TabletInfo)(nil), // 268: vtctldata.WorkflowUpdateResponse.TabletInfo + (*logutil.Event)(nil), // 269: logutil.Event + (tabletmanagerdata.TabletSelectionPreference)(0), // 270: tabletmanagerdata.TabletSelectionPreference + (*topodata.Keyspace)(nil), // 271: topodata.Keyspace + (*vttime.Time)(nil), // 272: vttime.Time + (*topodata.TabletAlias)(nil), // 273: topodata.TabletAlias + (*vttime.Duration)(nil), // 274: vttime.Duration + (*topodata.Shard)(nil), // 275: topodata.Shard + (*topodata.CellInfo)(nil), // 276: topodata.CellInfo + (*vschema.RoutingRules)(nil), // 277: vschema.RoutingRules + (*vschema.ShardRoutingRules)(nil), // 278: vschema.ShardRoutingRules + (*vtrpc.CallerID)(nil), // 279: vtrpc.CallerID + (*vschema.Keyspace)(nil), // 280: vschema.Keyspace + (topodata.TabletType)(0), // 281: topodata.TabletType + (*topodata.Tablet)(nil), // 282: topodata.Tablet + (topodata.KeyspaceType)(0), // 283: topodata.KeyspaceType + (*query.QueryResult)(nil), // 284: query.QueryResult + (*tabletmanagerdata.ExecuteHookRequest)(nil), // 285: tabletmanagerdata.ExecuteHookRequest + (*tabletmanagerdata.ExecuteHookResponse)(nil), // 286: tabletmanagerdata.ExecuteHookResponse + (*mysqlctl.BackupInfo)(nil), // 287: mysqlctl.BackupInfo + (*replicationdata.FullStatus)(nil), // 288: replicationdata.FullStatus + (*tabletmanagerdata.Permissions)(nil), // 289: tabletmanagerdata.Permissions + (*tabletmanagerdata.SchemaDefinition)(nil), // 290: tabletmanagerdata.SchemaDefinition + (*topodata.ThrottledAppRule)(nil), // 291: topodata.ThrottledAppRule + (*vschema.SrvVSchema)(nil), // 292: vschema.SrvVSchema + (*topodata.ShardReplicationError)(nil), // 293: topodata.ShardReplicationError + (*topodata.KeyRange)(nil), // 294: topodata.KeyRange + (*topodata.CellsAlias)(nil), // 295: topodata.CellsAlias + (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 296: tabletmanagerdata.UpdateVReplicationWorkflowRequest + (*topodata.Shard_TabletControl)(nil), // 297: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 298: binlogdata.BinlogSource + (*topodata.SrvKeyspace)(nil), // 299: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 300: replicationdata.Status + (*tabletmanagerdata.VDiffResponse)(nil), // 301: tabletmanagerdata.VDiffResponse } var file_vtctldata_proto_depIdxs = []int32{ - 271, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 269, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 6, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings 0, // 2: vtctldata.MaterializeSettings.materialization_intent:type_name -> vtctldata.MaterializationIntent - 272, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 273, // 4: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 270, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 271, // 4: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace 2, // 5: vtctldata.SchemaMigration.strategy:type_name -> vtctldata.SchemaMigration.Strategy - 274, // 6: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time - 274, // 7: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time - 274, // 8: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time - 274, // 9: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time - 274, // 10: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time - 274, // 11: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time - 274, // 12: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time + 272, // 6: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time + 272, // 7: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time + 272, // 8: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time + 272, // 9: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time + 272, // 10: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time + 272, // 11: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time + 272, // 12: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time 3, // 13: vtctldata.SchemaMigration.status:type_name -> vtctldata.SchemaMigration.Status - 275, // 14: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias - 276, // 15: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration - 274, // 16: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time - 274, // 17: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time - 274, // 18: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time - 274, // 19: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time - 277, // 20: vtctldata.Shard.shard:type_name -> topodata.Shard - 237, // 21: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 237, // 22: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 236, // 23: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry - 278, // 24: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 279, // 25: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 280, // 26: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 276, // 27: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration - 281, // 28: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID - 243, // 29: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - 282, // 30: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 282, // 31: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 275, // 32: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 33: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 271, // 34: vtctldata.BackupResponse.event:type_name -> logutil.Event - 244, // 35: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - 275, // 36: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 283, // 37: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 284, // 38: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 284, // 39: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 245, // 40: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - 246, // 41: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - 285, // 42: vtctldata.CreateKeyspaceRequest.served_froms:type_name -> topodata.Keyspace.ServedFrom - 286, // 43: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 274, // 44: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time - 8, // 45: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 8, // 46: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace - 10, // 47: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard - 10, // 48: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 275, // 49: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 275, // 50: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 275, // 51: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 276, // 52: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 275, // 53: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 271, // 54: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 275, // 55: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias - 287, // 56: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 275, // 57: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 287, // 58: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult - 275, // 59: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 60: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest - 289, // 61: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse - 247, // 62: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 290, // 63: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 278, // 64: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 248, // 65: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry - 275, // 66: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 291, // 67: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus - 8, // 68: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace - 8, // 69: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 275, // 70: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias - 292, // 71: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 279, // 72: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 275, // 73: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 293, // 74: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition - 3, // 75: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status - 276, // 76: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration - 1, // 77: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering - 9, // 78: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration - 10, // 79: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 280, // 80: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 249, // 81: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - 251, // 82: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 294, // 83: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule - 295, // 84: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 252, // 85: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 275, // 86: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 284, // 87: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 275, // 88: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 283, // 89: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType - 284, // 90: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 103, // 91: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell - 275, // 92: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias - 282, // 93: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 11, // 94: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 275, // 95: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 276, // 96: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 271, // 97: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 253, // 98: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - 282, // 99: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace - 283, // 100: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 101: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 7, // 102: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings - 283, // 103: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 104: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 283, // 105: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 106: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 254, // 107: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo - 275, // 108: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 109: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 275, // 110: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 276, // 111: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 276, // 112: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration - 275, // 113: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 271, // 114: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 275, // 115: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 116: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 271, // 117: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 271, // 118: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 275, // 119: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 275, // 120: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 283, // 121: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 122: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 275, // 123: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 274, // 124: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 274, // 125: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 275, // 126: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 271, // 127: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 255, // 128: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 275, // 129: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 130: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 283, // 131: vtctldata.SetKeyspaceServedFromRequest.tablet_type:type_name -> topodata.TabletType - 273, // 132: vtctldata.SetKeyspaceServedFromResponse.keyspace:type_name -> topodata.Keyspace - 273, // 133: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 277, // 134: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 283, // 135: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 277, // 136: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 275, // 137: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 138: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 296, // 139: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 256, // 140: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 257, // 141: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 275, // 142: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 143: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 276, // 144: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 297, // 145: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 277, // 146: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 277, // 147: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 275, // 148: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 149: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 275, // 150: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 275, // 151: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 275, // 152: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 278, // 153: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 278, // 154: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 298, // 155: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 298, // 156: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 258, // 157: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 259, // 158: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 260, // 159: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 261, // 160: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 262, // 161: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 283, // 162: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 272, // 163: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 276, // 164: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 276, // 165: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 263, // 166: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 264, // 167: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 268, // 168: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 269, // 169: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 283, // 170: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 276, // 171: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 276, // 172: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 299, // 173: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 270, // 174: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 238, // 175: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 239, // 176: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 300, // 177: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 275, // 178: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 301, // 179: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 274, // 180: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 274, // 181: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 240, // 182: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 241, // 183: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 242, // 184: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 274, // 185: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 274, // 186: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 274, // 187: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 10, // 188: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 298, // 189: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 250, // 190: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 302, // 191: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 295, // 192: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 275, // 193: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 303, // 194: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 284, // 195: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 207, // 196: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 211, // 197: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 198: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 199: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 211, // 200: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 304, // 201: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 275, // 202: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 275, // 203: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 266, // 204: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 265, // 205: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 267, // 206: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 275, // 207: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 208, // [208:208] is the sub-list for method output_type - 208, // [208:208] is the sub-list for method input_type - 208, // [208:208] is the sub-list for extension type_name - 208, // [208:208] is the sub-list for extension extendee - 0, // [0:208] is the sub-list for field type_name + 273, // 14: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias + 274, // 15: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration + 272, // 16: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time + 272, // 17: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time + 272, // 18: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time + 272, // 19: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time + 275, // 20: vtctldata.Shard.shard:type_name -> topodata.Shard + 235, // 21: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 235, // 22: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 234, // 23: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 276, // 24: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 277, // 25: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 278, // 26: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 274, // 27: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration + 279, // 28: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID + 241, // 29: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + 280, // 30: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 280, // 31: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 273, // 32: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 33: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 269, // 34: vtctldata.BackupResponse.event:type_name -> logutil.Event + 242, // 35: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + 273, // 36: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 281, // 37: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 282, // 38: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 282, // 39: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 243, // 40: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + 244, // 41: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + 283, // 42: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 272, // 43: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 8, // 44: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace + 8, // 45: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace + 10, // 46: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard + 10, // 47: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard + 273, // 48: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 273, // 49: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 273, // 50: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 274, // 51: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 273, // 52: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 269, // 53: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 273, // 54: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias + 284, // 55: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 273, // 56: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 284, // 57: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult + 273, // 58: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias + 285, // 59: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest + 286, // 60: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse + 245, // 61: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 287, // 62: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 276, // 63: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 246, // 64: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 273, // 65: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 288, // 66: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus + 8, // 67: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace + 8, // 68: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace + 273, // 69: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias + 289, // 70: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions + 277, // 71: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 273, // 72: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 290, // 73: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 3, // 74: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status + 274, // 75: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration + 1, // 76: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering + 9, // 77: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration + 10, // 78: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard + 278, // 79: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 247, // 80: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + 249, // 81: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 291, // 82: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule + 292, // 83: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 250, // 84: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 273, // 85: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 282, // 86: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 273, // 87: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 281, // 88: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType + 282, // 89: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 103, // 90: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell + 273, // 91: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias + 280, // 92: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 11, // 93: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow + 273, // 94: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 274, // 95: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 269, // 96: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 251, // 97: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + 280, // 98: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace + 281, // 99: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType + 270, // 100: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 7, // 101: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings + 281, // 102: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType + 270, // 103: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 281, // 104: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType + 270, // 105: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 252, // 106: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo + 273, // 107: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 108: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 273, // 109: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 274, // 110: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 274, // 111: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 273, // 112: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 269, // 113: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 273, // 114: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 115: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 269, // 116: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 269, // 117: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 273, // 118: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 273, // 119: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 281, // 120: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 270, // 121: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 273, // 122: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 272, // 123: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 272, // 124: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 273, // 125: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 269, // 126: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 253, // 127: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 273, // 128: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 271, // 129: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 271, // 130: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 275, // 131: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 281, // 132: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 275, // 133: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 273, // 134: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 135: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 293, // 136: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 254, // 137: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 255, // 138: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 273, // 139: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 140: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 274, // 141: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 294, // 142: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 275, // 143: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 275, // 144: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 273, // 145: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 146: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 273, // 147: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 273, // 148: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 273, // 149: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 276, // 150: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 276, // 151: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 295, // 152: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 295, // 153: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 256, // 154: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 257, // 155: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 258, // 156: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 259, // 157: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 260, // 158: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 281, // 159: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 270, // 160: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 274, // 161: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 274, // 162: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 261, // 163: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 262, // 164: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 266, // 165: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 267, // 166: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 281, // 167: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 274, // 168: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 274, // 169: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 296, // 170: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 268, // 171: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 236, // 172: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 237, // 173: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 297, // 174: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 273, // 175: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 298, // 176: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 272, // 177: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 272, // 178: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 238, // 179: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 239, // 180: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 240, // 181: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 272, // 182: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 272, // 183: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 272, // 184: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 10, // 185: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 295, // 186: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 248, // 187: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 299, // 188: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 292, // 189: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 273, // 190: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 300, // 191: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 282, // 192: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 205, // 193: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 209, // 194: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 209, // 195: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 209, // 196: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 209, // 197: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 301, // 198: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 273, // 199: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 273, // 200: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 264, // 201: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 263, // 202: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 265, // 203: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 273, // 204: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 205, // [205:205] is the sub-list for method output_type + 205, // [205:205] is the sub-list for method input_type + 205, // [205:205] is the sub-list for extension type_name + 205, // [205:205] is the sub-list for extension extendee + 0, // [0:205] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -20225,30 +20061,6 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[166].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetKeyspaceServedFromRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vtctldata_proto_msgTypes[167].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetKeyspaceServedFromResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vtctldata_proto_msgTypes[168].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceShardingInfoRequest); i { case 0: return &v.state @@ -20260,7 +20072,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[169].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[167].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceShardingInfoResponse); i { case 0: return &v.state @@ -20272,7 +20084,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[170].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[168].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardIsPrimaryServingRequest); i { case 0: return &v.state @@ -20284,7 +20096,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[171].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[169].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardIsPrimaryServingResponse); i { case 0: return &v.state @@ -20296,7 +20108,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[172].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[170].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardTabletControlRequest); i { case 0: return &v.state @@ -20308,7 +20120,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[173].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[171].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardTabletControlResponse); i { case 0: return &v.state @@ -20320,7 +20132,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[174].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[172].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetWritableRequest); i { case 0: return &v.state @@ -20332,7 +20144,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[175].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[173].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetWritableResponse); i { case 0: return &v.state @@ -20344,7 +20156,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[176].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[174].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationAddRequest); i { case 0: return &v.state @@ -20356,7 +20168,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[177].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[175].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationAddResponse); i { case 0: return &v.state @@ -20368,7 +20180,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[178].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[176].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationFixRequest); i { case 0: return &v.state @@ -20380,7 +20192,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[179].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[177].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationFixResponse); i { case 0: return &v.state @@ -20392,7 +20204,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[180].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[178].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationPositionsRequest); i { case 0: return &v.state @@ -20404,7 +20216,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[181].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[179].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationPositionsResponse); i { case 0: return &v.state @@ -20416,7 +20228,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[180].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationRemoveRequest); i { case 0: return &v.state @@ -20428,7 +20240,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[181].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationRemoveResponse); i { case 0: return &v.state @@ -20440,7 +20252,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[184].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SleepTabletRequest); i { case 0: return &v.state @@ -20452,7 +20264,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[185].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SleepTabletResponse); i { case 0: return &v.state @@ -20464,7 +20276,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[186].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[184].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardAddRequest); i { case 0: return &v.state @@ -20476,7 +20288,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[187].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[185].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardAddResponse); i { case 0: return &v.state @@ -20488,7 +20300,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[188].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[186].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardDeleteRequest); i { case 0: return &v.state @@ -20500,7 +20312,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[189].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[187].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardDeleteResponse); i { case 0: return &v.state @@ -20512,7 +20324,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[190].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[188].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StartReplicationRequest); i { case 0: return &v.state @@ -20524,7 +20336,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[191].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[189].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StartReplicationResponse); i { case 0: return &v.state @@ -20536,7 +20348,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[192].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[190].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopReplicationRequest); i { case 0: return &v.state @@ -20548,7 +20360,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[193].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[191].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopReplicationResponse); i { case 0: return &v.state @@ -20560,7 +20372,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[194].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[192].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TabletExternallyReparentedRequest); i { case 0: return &v.state @@ -20572,7 +20384,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[195].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[193].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TabletExternallyReparentedResponse); i { case 0: return &v.state @@ -20584,7 +20396,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[196].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[194].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellInfoRequest); i { case 0: return &v.state @@ -20596,7 +20408,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[197].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[195].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellInfoResponse); i { case 0: return &v.state @@ -20608,7 +20420,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[198].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[196].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellsAliasRequest); i { case 0: return &v.state @@ -20620,7 +20432,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[199].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[197].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellsAliasResponse); i { case 0: return &v.state @@ -20632,7 +20444,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[200].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[198].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateRequest); i { case 0: return &v.state @@ -20644,7 +20456,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[201].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[199].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResponse); i { case 0: return &v.state @@ -20656,7 +20468,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[202].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[200].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateKeyspaceRequest); i { case 0: return &v.state @@ -20668,7 +20480,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[203].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[201].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateKeyspaceResponse); i { case 0: return &v.state @@ -20680,7 +20492,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[204].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[202].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateSchemaKeyspaceRequest); i { case 0: return &v.state @@ -20692,7 +20504,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[205].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[203].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateSchemaKeyspaceResponse); i { case 0: return &v.state @@ -20704,7 +20516,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[206].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[204].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateShardRequest); i { case 0: return &v.state @@ -20716,7 +20528,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[207].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[205].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateShardResponse); i { case 0: return &v.state @@ -20728,7 +20540,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[208].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[206].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionKeyspaceRequest); i { case 0: return &v.state @@ -20740,7 +20552,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[209].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[207].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionKeyspaceResponse); i { case 0: return &v.state @@ -20752,7 +20564,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[210].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[208].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionShardRequest); i { case 0: return &v.state @@ -20764,7 +20576,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[211].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[209].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionShardResponse); i { case 0: return &v.state @@ -20776,7 +20588,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[212].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[210].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVSchemaRequest); i { case 0: return &v.state @@ -20788,7 +20600,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[213].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[211].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVSchemaResponse); i { case 0: return &v.state @@ -20800,7 +20612,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[214].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[212].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffCreateRequest); i { case 0: return &v.state @@ -20812,7 +20624,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[215].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[213].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffCreateResponse); i { case 0: return &v.state @@ -20824,7 +20636,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[216].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[214].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffDeleteRequest); i { case 0: return &v.state @@ -20836,7 +20648,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[217].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[215].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffDeleteResponse); i { case 0: return &v.state @@ -20848,7 +20660,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[218].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[216].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffResumeRequest); i { case 0: return &v.state @@ -20860,7 +20672,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[219].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[217].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffResumeResponse); i { case 0: return &v.state @@ -20872,7 +20684,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[220].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[218].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffShowRequest); i { case 0: return &v.state @@ -20884,7 +20696,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[221].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[219].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffShowResponse); i { case 0: return &v.state @@ -20896,7 +20708,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[222].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[220].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffStopRequest); i { case 0: return &v.state @@ -20908,7 +20720,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[223].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[221].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffStopResponse); i { case 0: return &v.state @@ -20920,7 +20732,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[224].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[222].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteRequest); i { case 0: return &v.state @@ -20932,7 +20744,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[225].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[223].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteResponse); i { case 0: return &v.state @@ -20944,7 +20756,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[226].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[224].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusRequest); i { case 0: return &v.state @@ -20956,7 +20768,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[227].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[225].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse); i { case 0: return &v.state @@ -20968,7 +20780,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[228].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[226].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowSwitchTrafficRequest); i { case 0: return &v.state @@ -20980,7 +20792,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[229].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[227].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowSwitchTrafficResponse); i { case 0: return &v.state @@ -20992,7 +20804,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[230].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[228].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateRequest); i { case 0: return &v.state @@ -21004,7 +20816,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[231].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[229].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateResponse); i { case 0: return &v.state @@ -21016,7 +20828,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[233].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[231].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_ReplicationLocation); i { case 0: return &v.state @@ -21028,7 +20840,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[234].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[232].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_ShardStream); i { case 0: return &v.state @@ -21040,7 +20852,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[235].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[233].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream); i { case 0: return &v.state @@ -21052,7 +20864,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[236].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[234].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_CopyState); i { case 0: return &v.state @@ -21064,7 +20876,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[237].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[235].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_Log); i { case 0: return &v.state @@ -21076,7 +20888,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[238].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[236].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_ThrottlerStatus); i { case 0: return &v.state @@ -21088,7 +20900,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[246].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[244].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSrvKeyspaceNamesResponse_NameList); i { case 0: return &v.state @@ -21100,7 +20912,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[250].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[248].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCreateResponse_TabletInfo); i { case 0: return &v.state @@ -21112,7 +20924,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[260].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[258].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteResponse_TabletInfo); i { case 0: return &v.state @@ -21124,7 +20936,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[261].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[259].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_TableCopyState); i { case 0: return &v.state @@ -21136,7 +20948,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[262].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[260].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreamState); i { case 0: return &v.state @@ -21148,7 +20960,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[263].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[261].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreams); i { case 0: return &v.state @@ -21160,7 +20972,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[266].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[264].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateResponse_TabletInfo); i { case 0: return &v.state @@ -21179,7 +20991,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 4, - NumMessages: 267, + NumMessages: 265, 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 5c8ff40f8f2..0b59d6f8f5c 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -951,13 +951,6 @@ func (m *CreateKeyspaceRequest) CloneVT() *CreateKeyspaceRequest { DurabilityPolicy: m.DurabilityPolicy, SidecarDbName: m.SidecarDbName, } - if rhs := m.ServedFroms; rhs != nil { - tmpContainer := make([]*topodata.Keyspace_ServedFrom, len(rhs)) - for k, v := range rhs { - tmpContainer[k] = v.CloneVT() - } - r.ServedFroms = tmpContainer - } if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -3782,50 +3775,6 @@ func (m *SetKeyspaceDurabilityPolicyResponse) CloneMessageVT() proto.Message { return m.CloneVT() } -func (m *SetKeyspaceServedFromRequest) CloneVT() *SetKeyspaceServedFromRequest { - if m == nil { - return (*SetKeyspaceServedFromRequest)(nil) - } - r := &SetKeyspaceServedFromRequest{ - Keyspace: m.Keyspace, - TabletType: m.TabletType, - Remove: m.Remove, - SourceKeyspace: m.SourceKeyspace, - } - if rhs := m.Cells; rhs != nil { - tmpContainer := make([]string, len(rhs)) - copy(tmpContainer, rhs) - r.Cells = tmpContainer - } - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *SetKeyspaceServedFromRequest) CloneMessageVT() proto.Message { - return m.CloneVT() -} - -func (m *SetKeyspaceServedFromResponse) CloneVT() *SetKeyspaceServedFromResponse { - if m == nil { - return (*SetKeyspaceServedFromResponse)(nil) - } - r := &SetKeyspaceServedFromResponse{ - Keyspace: m.Keyspace.CloneVT(), - } - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *SetKeyspaceServedFromResponse) CloneMessageVT() proto.Message { - return m.CloneVT() -} - func (m *SetKeyspaceShardingInfoRequest) CloneVT() *SetKeyspaceShardingInfoRequest { if m == nil { return (*SetKeyspaceShardingInfoRequest)(nil) @@ -8180,18 +8129,6 @@ func (m *CreateKeyspaceRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) i-- dAtA[i] = 0x38 } - if len(m.ServedFroms) > 0 { - for iNdEx := len(m.ServedFroms) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.ServedFroms[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x32 - } - } if m.AllowEmptyVSchema { i-- if m.AllowEmptyVSchema { @@ -15404,120 +15341,6 @@ func (m *SetKeyspaceDurabilityPolicyResponse) MarshalToSizedBufferVT(dAtA []byte return len(dAtA) - i, nil } -func (m *SetKeyspaceServedFromRequest) 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 *SetKeyspaceServedFromRequest) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *SetKeyspaceServedFromRequest) 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.SourceKeyspace) > 0 { - i -= len(m.SourceKeyspace) - copy(dAtA[i:], m.SourceKeyspace) - i = encodeVarint(dAtA, i, uint64(len(m.SourceKeyspace))) - i-- - dAtA[i] = 0x2a - } - if m.Remove { - i-- - if m.Remove { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x20 - } - 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 m.TabletType != 0 { - i = encodeVarint(dAtA, i, uint64(m.TabletType)) - i-- - dAtA[i] = 0x10 - } - 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 *SetKeyspaceServedFromResponse) 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 *SetKeyspaceServedFromResponse) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *SetKeyspaceServedFromResponse) 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.Keyspace != nil { - size, err := m.Keyspace.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 *SetKeyspaceShardingInfoRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -20479,12 +20302,6 @@ func (m *CreateKeyspaceRequest) SizeVT() (n int) { if m.AllowEmptyVSchema { n += 2 } - if len(m.ServedFroms) > 0 { - for _, e := range m.ServedFroms { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } if m.Type != 0 { n += 1 + sov(uint64(m.Type)) } @@ -23116,50 +22933,6 @@ func (m *SetKeyspaceDurabilityPolicyResponse) SizeVT() (n int) { return n } -func (m *SetKeyspaceServedFromRequest) 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)) - } - if m.TabletType != 0 { - n += 1 + sov(uint64(m.TabletType)) - } - if len(m.Cells) > 0 { - for _, s := range m.Cells { - l = len(s) - n += 1 + l + sov(uint64(l)) - } - } - if m.Remove { - n += 2 - } - l = len(m.SourceKeyspace) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - -func (m *SetKeyspaceServedFromResponse) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Keyspace != nil { - l = m.Keyspace.SizeVT() - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - func (m *SetKeyspaceShardingInfoRequest) SizeVT() (n int) { if m == nil { return 0 @@ -32379,40 +32152,6 @@ func (m *CreateKeyspaceRequest) UnmarshalVT(dAtA []byte) error { } } m.AllowEmptyVSchema = bool(v != 0) - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServedFroms", 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.ServedFroms = append(m.ServedFroms, &topodata.Keyspace_ServedFrom{}) - if err := m.ServedFroms[len(m.ServedFroms)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) @@ -49015,279 +48754,6 @@ func (m *SetKeyspaceDurabilityPolicyResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *SetKeyspaceServedFromRequest) 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: SetKeyspaceServedFromRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SetKeyspaceServedFromRequest: 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 != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TabletType", wireType) - } - m.TabletType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TabletType |= topodata.TabletType(b&0x7F) << shift - if b < 0x80 { - break - } - } - 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 - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Remove", 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.Remove = bool(v != 0) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SourceKeyspace", 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.SourceKeyspace = 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 *SetKeyspaceServedFromResponse) 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: SetKeyspaceServedFromResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SetKeyspaceServedFromResponse: 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 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.Keyspace == nil { - m.Keyspace = &topodata.Keyspace{} - } - if err := m.Keyspace.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 *SetKeyspaceShardingInfoRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go/vt/proto/vttest/vttest.pb.go b/go/vt/proto/vttest/vttest.pb.go index 18ab7a83bb9..c819b3c17fc 100644 --- a/go/vt/proto/vttest/vttest.pb.go +++ b/go/vt/proto/vttest/vttest.pb.go @@ -134,8 +134,6 @@ type Keyspace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // shards inside this keyspace. Ignored if redirect is set. Shards []*Shard `protobuf:"bytes,2,rep,name=shards,proto3" json:"shards,omitempty"` - // redirects all traffic to another keyspace. If set, shards is ignored. - ServedFrom string `protobuf:"bytes,5,opt,name=served_from,json=servedFrom,proto3" json:"served_from,omitempty"` // number of replica tablets to instantiate. This includes the primary tablet. ReplicaCount int32 `protobuf:"varint,6,opt,name=replica_count,json=replicaCount,proto3" json:"replica_count,omitempty"` // number of rdonly tablets to instantiate. @@ -188,13 +186,6 @@ func (x *Keyspace) GetShards() []*Shard { return nil } -func (x *Keyspace) GetServedFrom() string { - if x != nil { - return x.ServedFrom - } - return "" -} - func (x *Keyspace) GetReplicaCount() int32 { if x != nil { return x.ReplicaCount @@ -285,31 +276,30 @@ var file_vttest_proto_rawDesc = []byte{ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x62, - 0x4e, 0x61, 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x22, 0xba, 0x01, 0x0a, + 0x4e, 0x61, 0x6d, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x06, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x66, - 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x64, - 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x0b, 0x72, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x04, 0x08, - 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x56, 0x54, - 0x54, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x2e, 0x0a, 0x09, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x76, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x18, 0x03, 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, 0x42, 0x25, - 0x5a, 0x23, 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, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x64, 0x6f, + 0x6e, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0b, 0x72, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x03, + 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x92, + 0x01, 0x0a, 0x0e, 0x56, 0x54, 0x54, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x12, 0x2e, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 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, 0x42, 0x25, 0x5a, 0x23, 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, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/go/vt/proto/vttest/vttest_vtproto.pb.go b/go/vt/proto/vttest/vttest_vtproto.pb.go index f1dee298011..8000a036a5f 100644 --- a/go/vt/proto/vttest/vttest_vtproto.pb.go +++ b/go/vt/proto/vttest/vttest_vtproto.pb.go @@ -45,7 +45,6 @@ func (m *Keyspace) CloneVT() *Keyspace { } r := &Keyspace{ Name: m.Name, - ServedFrom: m.ServedFrom, ReplicaCount: m.ReplicaCount, RdonlyCount: m.RdonlyCount, } @@ -184,13 +183,6 @@ func (m *Keyspace) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0x30 } - if len(m.ServedFrom) > 0 { - i -= len(m.ServedFrom) - copy(dAtA[i:], m.ServedFrom) - i = encodeVarint(dAtA, i, uint64(len(m.ServedFrom))) - i-- - dAtA[i] = 0x2a - } if len(m.Shards) > 0 { for iNdEx := len(m.Shards) - 1; iNdEx >= 0; iNdEx-- { size, err := m.Shards[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) @@ -322,10 +314,6 @@ func (m *Keyspace) SizeVT() (n int) { n += 1 + l + sov(uint64(l)) } } - l = len(m.ServedFrom) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } if m.ReplicaCount != 0 { n += 1 + sov(uint64(m.ReplicaCount)) } @@ -578,38 +566,6 @@ func (m *Keyspace) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ServedFrom", 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.ServedFrom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ReplicaCount", wireType) diff --git a/go/vt/srvtopo/resolver.go b/go/vt/srvtopo/resolver.go index 98d77e259ef..a9a1f858ec8 100644 --- a/go/vt/srvtopo/resolver.go +++ b/go/vt/srvtopo/resolver.go @@ -114,8 +114,7 @@ func (rs *ResolvedShard) WithKeyspace(newKeyspace string) *ResolvedShard { } } -// GetKeyspaceShards return all the shards in a keyspace. It follows -// redirection if ServedFrom is set. It is only valid for the local cell. +// GetKeyspaceShards return all the shards in a keyspace. It is only valid for the local cell. // Do not use it to further resolve shards, instead use the Resolve* methods. func (r *Resolver) GetKeyspaceShards(ctx context.Context, keyspace string, tabletType topodatapb.TabletType) (string, *topodatapb.SrvKeyspace, []*topodatapb.ShardReference, error) { srvKeyspace, err := r.topoServ.GetSrvKeyspace(ctx, r.localCell, keyspace) @@ -123,17 +122,6 @@ func (r *Resolver) GetKeyspaceShards(ctx context.Context, keyspace string, table return "", nil, nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "keyspace %v fetch error: %v", keyspace, err) } - // check if the keyspace has been redirected for this tabletType. - for _, sf := range srvKeyspace.ServedFrom { - if sf.TabletType == tabletType { - keyspace = sf.Keyspace - srvKeyspace, err = r.topoServ.GetSrvKeyspace(ctx, r.localCell, keyspace) - if err != nil { - return "", nil, nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "keyspace %v fetch error: %v", keyspace, err) - } - } - } - partition := topoproto.SrvKeyspaceGetPartition(srvKeyspace, tabletType) if partition == nil { return "", nil, nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "No partition found for tabletType %v in keyspace %v", topoproto.TabletTypeLString(tabletType), keyspace) diff --git a/go/vt/srvtopo/status.go b/go/vt/srvtopo/status.go index b3069be6c38..9a5e8684b7f 100644 --- a/go/vt/srvtopo/status.go +++ b/go/vt/srvtopo/status.go @@ -133,12 +133,6 @@ var partitions = template.Must(template.New("partitions").Parse(` {{ end }}
{{ end }} -{{if .ServedFrom }} -ServedFrom:
-{{ range .ServedFrom }} - {{ .TabletType }}: {{ .Keyspace}}
-{{ end }} -{{ end }} `)) // StatusAsHTML returns an HTML version of our status. diff --git a/go/vt/topo/keyspace.go b/go/vt/topo/keyspace.go index 2bdd616a261..4ff53e24204 100755 --- a/go/vt/topo/keyspace.go +++ b/go/vt/topo/keyspace.go @@ -61,110 +61,6 @@ func ValidateKeyspaceName(name string) error { return validateObjectName(name) } -// GetServedFrom returns a Keyspace_ServedFrom record if it exists. -func (ki *KeyspaceInfo) GetServedFrom(tabletType topodatapb.TabletType) *topodatapb.Keyspace_ServedFrom { - for _, ksf := range ki.ServedFroms { - if ksf.TabletType == tabletType { - return ksf - } - } - return nil -} - -// CheckServedFromMigration makes sure a requested migration is safe -func (ki *KeyspaceInfo) CheckServedFromMigration(tabletType topodatapb.TabletType, cells []string, keyspace string, remove bool) error { - // primary is a special case with a few extra checks - if tabletType == topodatapb.TabletType_PRIMARY { - // TODO(deepthi): these master references will go away when we delete legacy resharding - if !remove { - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot add master back to %v", ki.keyspace) - } - if len(cells) > 0 { - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot migrate only some cells for master removal in keyspace %v", ki.keyspace) - } - if len(ki.ServedFroms) > 1 { - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot migrate master into %v until everything else is migrated", ki.keyspace) - } - } - - // we can't remove a type we don't have - if ki.GetServedFrom(tabletType) == nil && remove { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "supplied type cannot be migrated") - } - - // check the keyspace is consistent in any case - for _, ksf := range ki.ServedFroms { - if ksf.Keyspace != keyspace { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "inconsistent keyspace specified in migration: %v != %v for type %v", keyspace, ksf.Keyspace, ksf.TabletType) - } - } - - return nil -} - -// UpdateServedFromMap handles ServedFromMap. It can add or remove -// records, cells, ... -func (ki *KeyspaceInfo) UpdateServedFromMap(tabletType topodatapb.TabletType, cells []string, keyspace string, remove bool, allCells []string) error { - // check parameters to be sure - if err := ki.CheckServedFromMigration(tabletType, cells, keyspace, remove); err != nil { - return err - } - - ksf := ki.GetServedFrom(tabletType) - if ksf == nil { - // the record doesn't exist - if remove { - if len(ki.ServedFroms) == 0 { - ki.ServedFroms = nil - } - log.Warningf("Trying to remove KeyspaceServedFrom for missing type %v in keyspace %v", tabletType, ki.keyspace) - } else { - ki.ServedFroms = append(ki.ServedFroms, &topodatapb.Keyspace_ServedFrom{ - TabletType: tabletType, - Cells: cells, - Keyspace: keyspace, - }) - } - return nil - } - - if remove { - result, emptyList := removeCells(ksf.Cells, cells, allCells) - if emptyList { - // we don't have any cell left, we need to clear this record - var newServedFroms []*topodatapb.Keyspace_ServedFrom - for _, k := range ki.ServedFroms { - if k != ksf { - newServedFroms = append(newServedFroms, k) - } - } - ki.ServedFroms = newServedFroms - } else { - ksf.Cells = result - } - } else { - if ksf.Keyspace != keyspace { - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot UpdateServedFromMap on existing record for keyspace %v, different keyspace: %v != %v", ki.keyspace, ksf.Keyspace, keyspace) - } - ksf.Cells = addCells(ksf.Cells, cells) - } - return nil -} - -// ComputeCellServedFrom returns the ServedFrom list for a cell -func (ki *KeyspaceInfo) ComputeCellServedFrom(cell string) []*topodatapb.SrvKeyspace_ServedFrom { - var result []*topodatapb.SrvKeyspace_ServedFrom - for _, ksf := range ki.ServedFroms { - if InCellList(cell, ksf.Cells) { - result = append(result, &topodatapb.SrvKeyspace_ServedFrom{ - TabletType: ksf.TabletType, - Keyspace: ksf.Keyspace, - }) - } - } - return result -} - // CreateKeyspace wraps the underlying Conn.Create // and dispatches the event. func (ts *Server) CreateKeyspace(ctx context.Context, keyspace string, value *topodatapb.Keyspace) error { diff --git a/go/vt/topo/keyspace_test.go b/go/vt/topo/keyspace_test.go deleted file mode 100644 index 1abf873b8e0..00000000000 --- a/go/vt/topo/keyspace_test.go +++ /dev/null @@ -1,177 +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 topo - -import ( - "reflect" - "testing" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -// This file tests the keyspace related object functionalities. - -func TestUpdateServedFromMap(t *testing.T) { - // TODO(deepthi): delete this test once legacy resharding code is deleted - ki := &KeyspaceInfo{ - keyspace: "ks", - version: nil, - Keyspace: &topodatapb.Keyspace{ - ServedFroms: []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Cells: nil, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - }, - }, - } - allCells := []string{"first", "second", "third"} - - // migrate one cell - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, []string{"first"}, "source", true, allCells); err != nil || !reflect.DeepEqual(ki.ServedFroms, []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Cells: []string{"second", "third"}, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - }) { - t.Fatalf("one cell add failed: %v", ki) - } - - // re-add that cell, going back - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, []string{"first"}, "source", false, nil); err != nil || !reflect.DeepEqual(ki.ServedFroms, []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Cells: []string{"second", "third", "first"}, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - }) { - t.Fatalf("going back should have remove the record: %#v", ki.Keyspace.ServedFroms) - } - - // now remove the cell again - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, []string{"first"}, "source", true, allCells); err != nil || !reflect.DeepEqual(ki.ServedFroms, []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Cells: []string{"second", "third"}, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - }) { - t.Fatalf("one cell add failed: %v", ki) - } - - // couple error cases - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, []string{"second"}, "othersource", true, allCells); err == nil || (err.Error() != "inconsistent keyspace specified in migration: othersource != source for type MASTER" && err.Error() != "inconsistent keyspace specified in migration: othersource != source for type RDONLY") { - t.Fatalf("different keyspace should fail: %v", err) - } - if err := ki.UpdateServedFromMap(topodatapb.TabletType_PRIMARY, nil, "source", true, allCells); err == nil || err.Error() != "cannot migrate master into ks until everything else is migrated" { - t.Fatalf("migrate the master early should have failed: %v", err) - } - - // now remove all cells - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, []string{"second", "third"}, "source", true, allCells); err != nil || !reflect.DeepEqual(ki.ServedFroms, []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - }) { - t.Fatalf("remove all cells failed: %v", ki) - } - if err := ki.UpdateServedFromMap(topodatapb.TabletType_RDONLY, nil, "source", true, allCells); err == nil || err.Error() != "supplied type cannot be migrated" { - t.Fatalf("migrate rdonly again should have failed: %v", err) - } - - // finally migrate the primary - if err := ki.UpdateServedFromMap(topodatapb.TabletType_PRIMARY, []string{"second"}, "source", true, allCells); err == nil || err.Error() != "cannot migrate only some cells for master removal in keyspace ks" { - t.Fatalf("migrate master with cells should have failed: %v", err) - } - if err := ki.UpdateServedFromMap(topodatapb.TabletType_PRIMARY, nil, "source", true, allCells); err != nil || ki.ServedFroms != nil { - t.Fatalf("migrate the master failed: %v", ki) - } - - // error case again - if err := ki.UpdateServedFromMap(topodatapb.TabletType_PRIMARY, nil, "source", true, allCells); err == nil || err.Error() != "supplied type cannot be migrated" { - t.Fatalf("migrate the master again should have failed: %v", err) - } -} - -func TestComputeCellServedFrom(t *testing.T) { - ki := &KeyspaceInfo{ - keyspace: "ks", - version: nil, - Keyspace: &topodatapb.Keyspace{ - ServedFroms: []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_REPLICA, - Cells: []string{"c1", "c2"}, - Keyspace: "source", - }, - }, - }, - } - - m := ki.ComputeCellServedFrom("c3") - if !reflect.DeepEqual(m, []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: "source", - }, - }) { - t.Fatalf("c3 failed: %v", m) - } - - m = ki.ComputeCellServedFrom("c2") - if !reflect.DeepEqual(m, []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: "source", - }, - { - TabletType: topodatapb.TabletType_REPLICA, - Keyspace: "source", - }, - }) { - t.Fatalf("c2 failed: %v", m) - } -} diff --git a/go/vt/topo/locks.go b/go/vt/topo/locks.go index 8d30d85e891..6325124c429 100644 --- a/go/vt/topo/locks.go +++ b/go/vt/topo/locks.go @@ -127,21 +127,6 @@ var locksKey locksKeyType // - a context with a locksInfo structure for future reference. // - an unlock method // - an error if anything failed. -// -// We lock a keyspace for the following operations to be guaranteed -// exclusive operation: -// * changing a keyspace sharding info fields (is this one necessary?) -// * changing a keyspace 'ServedFrom' field (is this one necessary?) -// * resharding operations: -// - horizontal resharding: includes changing the shard's 'ServedType', -// as well as the associated horizontal resharding operations. -// - vertical resharding: includes changing the keyspace 'ServedFrom' -// field, as well as the associated vertical resharding operations. -// - 'vtctl SetShardIsPrimaryServing' emergency operations -// - 'vtctl SetShardTabletControl' emergency operations -// - 'vtctl SourceShardAdd' and 'vtctl SourceShardDelete' emergency operations -// -// * keyspace-wide schema changes func (ts *Server) LockKeyspace(ctx context.Context, keyspace, action string) (context.Context, func(*error), error) { i, ok := ctx.Value(locksKey).(*locksInfo) if !ok { diff --git a/go/vt/topo/test/keyspace.go b/go/vt/topo/test/keyspace.go index 0458e7fd2d7..9c7b99d016e 100644 --- a/go/vt/topo/test/keyspace.go +++ b/go/vt/topo/test/keyspace.go @@ -61,20 +61,7 @@ func checkKeyspace(t *testing.T, ctx context.Context, ts *topo.Server) { t.Errorf("GetKeyspaces: want %v, got %v", []string{"test_keyspace"}, keyspaces) } - k := &topodatapb.Keyspace{ - ServedFroms: []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_REPLICA, - Cells: []string{"c1", "c2"}, - Keyspace: "test_keyspace3", - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Cells: nil, - Keyspace: "test_keyspace3", - }, - }, - } + k := &topodatapb.Keyspace{} if err := ts.CreateKeyspace(ctx, "test_keyspace2", k); err != nil { t.Errorf("CreateKeyspace: %v", err) } diff --git a/go/vt/topo/test/serving.go b/go/vt/topo/test/serving.go index dd00f3da370..62cbca99a99 100644 --- a/go/vt/topo/test/serving.go +++ b/go/vt/topo/test/serving.go @@ -50,12 +50,6 @@ func checkSrvKeyspace(t *testing.T, ctx context.Context, ts *topo.Server) { }, }, }, - ServedFrom: []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_REPLICA, - Keyspace: "other_keyspace", - }, - }, } if err := ts.UpdateSrvKeyspace(ctx, LocalCellName, "test_keyspace", srvKeyspace); err != nil { t.Errorf("UpdateSrvKeyspace(1): %v", err) diff --git a/go/vt/topotools/keyspace.go b/go/vt/topotools/keyspace.go index d8a5740f3ae..cab326397ff 100644 --- a/go/vt/topotools/keyspace.go +++ b/go/vt/topotools/keyspace.go @@ -141,22 +141,12 @@ func UpdateShardRecords( return nil } -// KeyspaceEquality returns true iff two KeyspaceInformations are identical for testing purposes +// KeyspaceEquality returns true iff two Keyspace fields are identical for testing purposes. func KeyspaceEquality(left, right *topodatapb.Keyspace) bool { if left.KeyspaceType != right.KeyspaceType { return false } - if len(left.ServedFroms) != len(right.ServedFroms) { - return false - } - for i := range left.ServedFroms { - if left.ServedFroms[i] != right.ServedFroms[i] { - return false - } - } - if left.KeyspaceType != right.KeyspaceType { - return false - } + if left.BaseKeyspace != right.BaseKeyspace { return false } @@ -165,5 +155,9 @@ func KeyspaceEquality(left, right *topodatapb.Keyspace) bool { return false } + if left.SidecarDbName != right.SidecarDbName { + return false + } + return left.DurabilityPolicy == right.DurabilityPolicy } diff --git a/go/vt/topotools/rebuild_keyspace.go b/go/vt/topotools/rebuild_keyspace.go index 09df8b8fadc..72e060b79e2 100644 --- a/go/vt/topotools/rebuild_keyspace.go +++ b/go/vt/topotools/rebuild_keyspace.go @@ -99,9 +99,8 @@ func RebuildKeyspaceLocked(ctx context.Context, log logutil.Logger, ts *topo.Ser return err } srvKeyspaceMap[cell] = &topodatapb.SrvKeyspace{ - ServedFrom: ki.ComputeCellServedFrom(cell), + ThrottlerConfig: ki.ThrottlerConfig, } - srvKeyspaceMap[cell].ThrottlerConfig = ki.ThrottlerConfig } servedTypes := []topodatapb.TabletType{topodatapb.TabletType_PRIMARY, topodatapb.TabletType_REPLICA, topodatapb.TabletType_RDONLY} diff --git a/go/vt/vtadmin/vtctldclient/fakevtctldclient/vtctldclient.go b/go/vt/vtadmin/vtctldclient/fakevtctldclient/vtctldclient.go index e2701a1f594..c81aef0ef99 100644 --- a/go/vt/vtadmin/vtctldclient/fakevtctldclient/vtctldclient.go +++ b/go/vt/vtadmin/vtctldclient/fakevtctldclient/vtctldclient.go @@ -159,7 +159,6 @@ func (fake *VtctldClient) CreateKeyspace(ctx context.Context, req *vtctldatapb.C } ks := &topodatapb.Keyspace{ - ServedFroms: req.ServedFroms, KeyspaceType: req.Type, BaseKeyspace: req.BaseKeyspace, SnapshotTime: req.SnapshotTime, diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index b9fc4af294b..c83fd562731 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -291,95 +291,72 @@ func CreateKs( ) (uint32, error) { keyspace := kpb.Name - if kpb.ServedFrom != "" { - // if we have a redirect, create a completely redirected - // keyspace and no tablet - if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{ - ServedFroms: []*topodatapb.Keyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: kpb.ServedFrom, - }, - { - TabletType: topodatapb.TabletType_REPLICA, - Keyspace: kpb.ServedFrom, - }, - { - TabletType: topodatapb.TabletType_RDONLY, - Keyspace: kpb.ServedFrom, - }, - }, - }); err != nil { - return 0, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) - } - } else { - // create a regular keyspace - if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { - return 0, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) + // create a regular keyspace + if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { + return 0, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err) + } + + // iterate through the shards + for _, spb := range kpb.Shards { + shard := spb.Name + if err := ts.CreateShard(ctx, keyspace, shard); err != nil { + return 0, fmt.Errorf("CreateShard(%v:%v) failed: %v", keyspace, shard, err) } - // iterate through the shards - for _, spb := range kpb.Shards { - shard := spb.Name - if err := ts.CreateShard(ctx, keyspace, shard); err != nil { - return 0, fmt.Errorf("CreateShard(%v:%v) failed: %v", keyspace, shard, err) + for _, cell := range tpb.Cells { + dbname := spb.DbNameOverride + if dbname == "" { + dbname = fmt.Sprintf("vt_%v_%v", keyspace, shard) } - for _, cell := range tpb.Cells { - dbname := spb.DbNameOverride - if dbname == "" { - dbname = fmt.Sprintf("vt_%v_%v", keyspace, shard) - } + replicas := int(kpb.ReplicaCount) + if replicas == 0 { + // 2 replicas in order to ensure the primary cell has a primary and a replica + replicas = 2 + } + rdonlys := int(kpb.RdonlyCount) + if rdonlys == 0 { + rdonlys = 1 + } - replicas := int(kpb.ReplicaCount) - if replicas == 0 { - // 2 replicas in order to ensure the primary cell has a primary and a replica - replicas = 2 - } - rdonlys := int(kpb.RdonlyCount) - if rdonlys == 0 { - rdonlys = 1 + if ensureDatabase { + // Create Database if not exist + conn, err := mysqld.GetDbaConnection(context.TODO()) + if err != nil { + return 0, fmt.Errorf("GetConnection failed: %v", err) } + defer conn.Close() - if ensureDatabase { - // Create Database if not exist - conn, err := mysqld.GetDbaConnection(context.TODO()) - if err != nil { - return 0, fmt.Errorf("GetConnection failed: %v", err) - } - defer conn.Close() + _, err = conn.ExecuteFetch("CREATE DATABASE IF NOT EXISTS `"+dbname+"`", 1, false) + if err != nil { + return 0, fmt.Errorf("error ensuring database exists: %v", err) + } - _, err = conn.ExecuteFetch("CREATE DATABASE IF NOT EXISTS `"+dbname+"`", 1, false) - if err != nil { - return 0, fmt.Errorf("error ensuring database exists: %v", err) - } + } + if cell == tpb.Cells[0] { + replicas-- + // create the primary + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_PRIMARY, mysqld, dbcfgs.Clone()); err != nil { + return 0, err } - if cell == tpb.Cells[0] { - replicas-- - - // create the primary - if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_PRIMARY, mysqld, dbcfgs.Clone()); err != nil { - return 0, err - } - uid++ - } + uid++ + } - for i := 0; i < replicas; i++ { - // create a replica tablet - if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs.Clone()); err != nil { - return 0, err - } - uid++ + for i := 0; i < replicas; i++ { + // create a replica tablet + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs.Clone()); err != nil { + return 0, err } + uid++ + } - for i := 0; i < rdonlys; i++ { - // create a rdonly tablet - if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs.Clone()); err != nil { - return 0, err - } - uid++ + for i := 0; i < rdonlys; i++ { + // create a rdonly tablet + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs.Clone()); err != nil { + return 0, err } + uid++ } } } diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 8ec786322da..feee4e30ed2 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -744,7 +744,6 @@ func (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.Crea ki := &topodatapb.Keyspace{ KeyspaceType: req.Type, - ServedFroms: req.ServedFroms, BaseKeyspace: req.BaseKeyspace, SnapshotTime: req.SnapshotTime, DurabilityPolicy: req.DurabilityPolicy, @@ -3329,47 +3328,6 @@ func (s *VtctldServer) SetKeyspaceDurabilityPolicy(ctx context.Context, req *vtc }, nil } -// SetKeyspaceServedFrom is part of the vtctlservicepb.VtctldServer interface. -func (s *VtctldServer) SetKeyspaceServedFrom(ctx context.Context, req *vtctldatapb.SetKeyspaceServedFromRequest) (resp *vtctldatapb.SetKeyspaceServedFromResponse, err error) { - span, ctx := trace.NewSpan(ctx, "VtctldServer.SetKeyspaceServedFrom") - defer span.Finish() - - defer panicHandler(&err) - - span.Annotate("keyspace", req.Keyspace) - span.Annotate("tablet_type", topoproto.TabletTypeLString(req.TabletType)) - span.Annotate("cells", strings.Join(req.Cells, ",")) - span.Annotate("remove", req.Remove) - span.Annotate("source_keyspace", req.SourceKeyspace) - - ctx, unlock, lockErr := s.ts.LockKeyspace(ctx, req.Keyspace, "SetKeyspaceServedFrom") - if lockErr != nil { - err = lockErr - return nil, err - } - - defer unlock(&err) - - ki, err := s.ts.GetKeyspace(ctx, req.Keyspace) - if err != nil { - return nil, err - } - - err = ki.UpdateServedFromMap(req.TabletType, req.Cells, req.SourceKeyspace, req.Remove, nil) - if err != nil { - return nil, err - } - - err = s.ts.UpdateKeyspace(ctx, ki) - if err != nil { - return nil, err - } - - return &vtctldatapb.SetKeyspaceServedFromResponse{ - Keyspace: ki.Keyspace, - }, nil -} - // SetShardIsPrimaryServing is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) SetShardIsPrimaryServing(ctx context.Context, req *vtctldatapb.SetShardIsPrimaryServingRequest) (resp *vtctldatapb.SetShardIsPrimaryServingResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.SetShardIsPrimaryServing") diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index c340485b597..96d8bf9e9be 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1814,8 +1814,6 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags force := subFlags.Bool("force", false, "Proceeds even if the keyspace already exists") allowEmptyVSchema := subFlags.Bool("allow_empty_vschema", false, "If set this will allow a new keyspace to have no vschema") - var servedFrom flagutil.StringMapValue - subFlags.Var(&servedFrom, "served_from", "Specifies a comma-separated list of tablet_type:keyspace pairs used to serve traffic") keyspaceType := subFlags.String("keyspace_type", "", "Specifies the type of the keyspace") baseKeyspace := subFlags.String("base_keyspace", "", "Specifies the base keyspace for a snapshot keyspace") timestampStr := subFlags.String("snapshot_time", "", "Specifies the snapshot time for this keyspace") @@ -1870,18 +1868,6 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags DurabilityPolicy: *durabilityPolicy, SidecarDbName: *sidecarDBName, } - if len(servedFrom) > 0 { - for name, value := range servedFrom { - tt, err := topo.ParseServingTabletType(name) - if err != nil { - return err - } - ki.ServedFroms = append(ki.ServedFroms, &topodatapb.Keyspace_ServedFrom{ - TabletType: tt, - Keyspace: value, - }) - } - } err := wr.TopoServer().CreateKeyspace(ctx, keyspace, ki) if *force && topo.IsErrType(err, topo.NodeExists) { wr.Logger().Infof("keyspace %v already exists (ignoring error with --force)", keyspace) diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index 6443d89a56b..45d75752afd 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -237,7 +237,6 @@ func TestAPI(t *testing.T) { // Keyspaces {"GET", "keyspaces", "", `["ks1", "ks3"]`, http.StatusOK}, {"GET", "keyspaces/ks1", "", `{ - "served_froms": [], "keyspace_type":0, "base_keyspace":"", "snapshot_time":null, @@ -324,11 +323,11 @@ func TestAPI(t *testing.T) { // vtctl RunCommand {"POST", "vtctl/", `["GetKeyspace","ks1"]`, `{ "Error": "", - "Output": "{\n \"served_froms\": [],\n \"keyspace_type\": 0,\n \"base_keyspace\": \"\",\n \"snapshot_time\": null,\n \"durability_policy\": \"semi_sync\",\n \"throttler_config\": null,\n \"sidecar_db_name\": \"_vt_sidecar_ks1\"\n}\n\n" + "Output": "{\n \"keyspace_type\": 0,\n \"base_keyspace\": \"\",\n \"snapshot_time\": null,\n \"durability_policy\": \"semi_sync\",\n \"throttler_config\": null,\n \"sidecar_db_name\": \"_vt_sidecar_ks1\"\n}\n\n" }`, http.StatusOK}, {"POST", "vtctl/", `["GetKeyspace","ks3"]`, `{ "Error": "", - "Output": "{\n \"served_froms\": [],\n \"keyspace_type\": 1,\n \"base_keyspace\": \"ks1\",\n \"snapshot_time\": {\n \"seconds\": \"1136214245\",\n \"nanoseconds\": 0\n },\n \"durability_policy\": \"none\",\n \"throttler_config\": null,\n \"sidecar_db_name\": \"_vt\"\n}\n\n" + "Output": "{\n \"keyspace_type\": 1,\n \"base_keyspace\": \"ks1\",\n \"snapshot_time\": {\n \"seconds\": \"1136214245\",\n \"nanoseconds\": 0\n },\n \"durability_policy\": \"none\",\n \"throttler_config\": null,\n \"sidecar_db_name\": \"_vt\"\n}\n\n" }`, http.StatusOK}, {"POST", "vtctl/", `["GetVSchema","ks3"]`, `{ "Error": "", diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index 1629e9a4faa..3ceee09d5f7 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -41,10 +41,9 @@ import ( // sandbox_test.go provides a sandbox for unit testing VTGate. const ( - KsTestSharded = "TestExecutor" - KsTestUnsharded = "TestUnsharded" - KsTestUnshardedServedFrom = "TestUnshardedServedFrom" - KsTestBadVSchema = "TestXBadVSchema" + KsTestSharded = "TestExecutor" + KsTestUnsharded = "TestUnsharded" + KsTestBadVSchema = "TestXBadVSchema" ) func init() { @@ -172,18 +171,6 @@ func createShardedSrvKeyspace(shardSpec, servedFromKeyspace string) (*topodatapb }, }, } - if servedFromKeyspace != "" { - shardedSrvKeyspace.ServedFrom = []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Keyspace: servedFromKeyspace, - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: servedFromKeyspace, - }, - } - } return shardedSrvKeyspace, nil } @@ -259,27 +246,11 @@ func (sct *sandboxTopo) GetSrvKeyspace(ctx context.Context, cell, keyspace strin return nil, fmt.Errorf("topo error GetSrvKeyspace") } switch keyspace { - case KsTestUnshardedServedFrom: - servedFromKeyspace, err := createUnshardedKeyspace() - if err != nil { - return nil, err - } - servedFromKeyspace.ServedFrom = []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_RDONLY, - Keyspace: KsTestUnsharded, - }, - { - TabletType: topodatapb.TabletType_PRIMARY, - Keyspace: KsTestUnsharded, - }, - } - return servedFromKeyspace, nil case KsTestUnsharded: return createUnshardedKeyspace() + default: + return createShardedSrvKeyspace(sand.ShardSpec, sand.KeyspaceServedFrom) } - - return createShardedSrvKeyspace(sand.ShardSpec, sand.KeyspaceServedFrom) } func (sct *sandboxTopo) WatchSrvKeyspace(ctx context.Context, cell, keyspace string, callback func(*topodatapb.SrvKeyspace, error) bool) { diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index fcf164df187..5ef0ea2c314 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -492,11 +492,6 @@ func (db *LocalCluster) loadSchema(shouldRunDatabaseMigrations bool) error { } for _, kpb := range db.Topology.Keyspaces { - if kpb.ServedFrom != "" { - // redirected keyspaces have no underlying database - continue - } - keyspace := kpb.Name keyspaceDir := path.Join(db.SchemaDir, keyspace) @@ -569,9 +564,6 @@ func (db *LocalCluster) createDatabases() error { var sql []string for _, kpb := range db.Topology.Keyspaces { - if kpb.ServedFrom != "" { - continue - } for _, dbname := range db.shardNames(kpb) { sql = append(sql, fmt.Sprintf("create database `%s`", dbname)) } diff --git a/go/vt/vttest/randomdata.go b/go/vt/vttest/randomdata.go index 19eaeb98fb0..0848f8cb709 100644 --- a/go/vt/vttest/randomdata.go +++ b/go/vt/vttest/randomdata.go @@ -151,9 +151,6 @@ func (db *LocalCluster) populateShard(dbname string, rng *rand.Rand) error { func (db *LocalCluster) populateWithRandomData() error { rng := rand.New(rand.NewSource(int64(db.Seed.RngSeed))) for _, kpb := range db.Topology.Keyspaces { - if kpb.ServedFrom != "" { - continue - } for _, dbname := range db.shardNames(kpb) { if err := db.populateShard(dbname, rng); err != nil { return err diff --git a/proto/topodata.proto b/proto/topodata.proto index c921f72dfa4..364095be0ee 100644 --- a/proto/topodata.proto +++ b/proto/topodata.proto @@ -267,22 +267,8 @@ message Keyspace { // OBSOLETE int32 split_shard_count = 3; reserved 3; - // ServedFrom indicates a relationship between a TabletType and the - // keyspace name that's serving it. - message ServedFrom { - // the tablet type (key for the map) - TabletType tablet_type = 1; - - // the cells to limit this to - repeated string cells = 2; - - // the keyspace name that's serving it - string keyspace = 3; - } - - // ServedFrom will redirect the appropriate traffic to - // another keyspace. - repeated ServedFrom served_froms = 4; + // OBSOLETE ServedFrom served_froms = 4; + reserved 4; // keyspace_type will determine how this keyspace is treated by // vtgate / vschema. Normal keyspaces are routable by @@ -417,16 +403,6 @@ message SrvKeyspace { // The partitions this keyspace is serving, per tablet type. repeated KeyspacePartition partitions = 1; - // ServedFrom indicates a relationship between a TabletType and the - // keyspace name that's serving it. - message ServedFrom { - // the tablet type - TabletType tablet_type = 1; - - // the keyspace name that's serving it - string keyspace = 2; - } - // copied from Keyspace // OBSOLETE string sharding_column_name = 2; reserved 2; @@ -434,7 +410,8 @@ message SrvKeyspace { // OBSOLETE KeyspaceIdType sharding_column_type = 3; reserved 3; - repeated ServedFrom served_from = 4; + // OBSOLETE repeated ServedFrom served_from = 4; + reserved 4; // OBSOLETE int32 split_shard_count = 5; reserved 5; diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index c16f9b5d0ea..61b75ce4e09 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -473,9 +473,8 @@ message CreateKeyspaceRequest { // OBSOLETE topodata.KeyspaceIdType sharding_column_type = 5; reserved 5; - // ServedFroms specifies a set of db_type:keyspace pairs used to serve - // traffic for the keyspace. - repeated topodata.Keyspace.ServedFrom served_froms = 6; + // OBSOLETE: repeated topodata.Keyspace.ServedFrom served_froms = 6; + reserved 6; // Type is the type of the keyspace to create. topodata.KeyspaceType type = 7; @@ -1433,19 +1432,6 @@ message SetKeyspaceDurabilityPolicyResponse { topodata.Keyspace keyspace = 1; } -message SetKeyspaceServedFromRequest { - string keyspace = 1; - topodata.TabletType tablet_type = 2; - repeated string cells = 3; - bool remove = 4; - string source_keyspace = 5; -} - -message SetKeyspaceServedFromResponse { - // Keyspace is the updated keyspace record. - topodata.Keyspace keyspace = 1; -} - message SetKeyspaceShardingInfoRequest { string keyspace = 1; // OBSOLETE string column_name = 2; diff --git a/proto/vttest.proto b/proto/vttest.proto index 3b3413979d4..b48107044d7 100644 --- a/proto/vttest.proto +++ b/proto/vttest.proto @@ -74,9 +74,9 @@ message Keyspace { // OBSOLETE string sharding_column_type = 4; reserved 4; - // redirects all traffic to another keyspace. If set, shards is ignored. - string served_from = 5; - + // OBSOLETE string served_from = 5; + reserved 5; + // number of replica tablets to instantiate. This includes the primary tablet. int32 replica_count = 6; diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index d19221fe676..39add452fd6 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -15096,9 +15096,6 @@ export namespace topodata { /** Properties of a Keyspace. */ interface IKeyspace { - /** Keyspace served_froms */ - served_froms?: (topodata.Keyspace.IServedFrom[]|null); - /** Keyspace keyspace_type */ keyspace_type?: (topodata.KeyspaceType|null); @@ -15127,9 +15124,6 @@ export namespace topodata { */ constructor(properties?: topodata.IKeyspace); - /** Keyspace served_froms. */ - public served_froms: topodata.Keyspace.IServedFrom[]; - /** Keyspace keyspace_type. */ public keyspace_type: topodata.KeyspaceType; @@ -15226,118 +15220,6 @@ export namespace topodata { public static getTypeUrl(typeUrlPrefix?: string): string; } - namespace Keyspace { - - /** Properties of a ServedFrom. */ - interface IServedFrom { - - /** ServedFrom tablet_type */ - tablet_type?: (topodata.TabletType|null); - - /** ServedFrom cells */ - cells?: (string[]|null); - - /** ServedFrom keyspace */ - keyspace?: (string|null); - } - - /** Represents a ServedFrom. */ - class ServedFrom implements IServedFrom { - - /** - * Constructs a new ServedFrom. - * @param [properties] Properties to set - */ - constructor(properties?: topodata.Keyspace.IServedFrom); - - /** ServedFrom tablet_type. */ - public tablet_type: topodata.TabletType; - - /** ServedFrom cells. */ - public cells: string[]; - - /** ServedFrom keyspace. */ - public keyspace: string; - - /** - * Creates a new ServedFrom instance using the specified properties. - * @param [properties] Properties to set - * @returns ServedFrom instance - */ - public static create(properties?: topodata.Keyspace.IServedFrom): topodata.Keyspace.ServedFrom; - - /** - * Encodes the specified ServedFrom message. Does not implicitly {@link topodata.Keyspace.ServedFrom.verify|verify} messages. - * @param message ServedFrom message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: topodata.Keyspace.IServedFrom, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ServedFrom message, length delimited. Does not implicitly {@link topodata.Keyspace.ServedFrom.verify|verify} messages. - * @param message ServedFrom message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: topodata.Keyspace.IServedFrom, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ServedFrom message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ServedFrom - * @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): topodata.Keyspace.ServedFrom; - - /** - * Decodes a ServedFrom message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ServedFrom - * @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)): topodata.Keyspace.ServedFrom; - - /** - * Verifies a ServedFrom 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 ServedFrom message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ServedFrom - */ - public static fromObject(object: { [k: string]: any }): topodata.Keyspace.ServedFrom; - - /** - * Creates a plain object from a ServedFrom message. Also converts values to other types if specified. - * @param message ServedFrom - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: topodata.Keyspace.ServedFrom, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ServedFrom to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for ServedFrom - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } - } - /** Properties of a ShardReplication. */ interface IShardReplication { @@ -16102,9 +15984,6 @@ export namespace topodata { /** SrvKeyspace partitions */ partitions?: (topodata.SrvKeyspace.IKeyspacePartition[]|null); - /** SrvKeyspace served_from */ - served_from?: (topodata.SrvKeyspace.IServedFrom[]|null); - /** SrvKeyspace throttler_config */ throttler_config?: (topodata.IThrottlerConfig|null); } @@ -16121,9 +16000,6 @@ export namespace topodata { /** SrvKeyspace partitions. */ public partitions: topodata.SrvKeyspace.IKeyspacePartition[]; - /** SrvKeyspace served_from. */ - public served_from: topodata.SrvKeyspace.IServedFrom[]; - /** SrvKeyspace throttler_config. */ public throttler_config?: (topodata.IThrottlerConfig|null); @@ -16315,109 +16191,6 @@ export namespace topodata { */ public static getTypeUrl(typeUrlPrefix?: string): string; } - - /** Properties of a ServedFrom. */ - interface IServedFrom { - - /** ServedFrom tablet_type */ - tablet_type?: (topodata.TabletType|null); - - /** ServedFrom keyspace */ - keyspace?: (string|null); - } - - /** Represents a ServedFrom. */ - class ServedFrom implements IServedFrom { - - /** - * Constructs a new ServedFrom. - * @param [properties] Properties to set - */ - constructor(properties?: topodata.SrvKeyspace.IServedFrom); - - /** ServedFrom tablet_type. */ - public tablet_type: topodata.TabletType; - - /** ServedFrom keyspace. */ - public keyspace: string; - - /** - * Creates a new ServedFrom instance using the specified properties. - * @param [properties] Properties to set - * @returns ServedFrom instance - */ - public static create(properties?: topodata.SrvKeyspace.IServedFrom): topodata.SrvKeyspace.ServedFrom; - - /** - * Encodes the specified ServedFrom message. Does not implicitly {@link topodata.SrvKeyspace.ServedFrom.verify|verify} messages. - * @param message ServedFrom message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: topodata.SrvKeyspace.IServedFrom, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ServedFrom message, length delimited. Does not implicitly {@link topodata.SrvKeyspace.ServedFrom.verify|verify} messages. - * @param message ServedFrom message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: topodata.SrvKeyspace.IServedFrom, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ServedFrom message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ServedFrom - * @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): topodata.SrvKeyspace.ServedFrom; - - /** - * Decodes a ServedFrom message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ServedFrom - * @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)): topodata.SrvKeyspace.ServedFrom; - - /** - * Verifies a ServedFrom 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 ServedFrom message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ServedFrom - */ - public static fromObject(object: { [k: string]: any }): topodata.SrvKeyspace.ServedFrom; - - /** - * Creates a plain object from a ServedFrom message. Also converts values to other types if specified. - * @param message ServedFrom - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: topodata.SrvKeyspace.ServedFrom, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ServedFrom to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for ServedFrom - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } } /** Properties of a CellInfo. */ @@ -46570,9 +46343,6 @@ export namespace vtctldata { /** CreateKeyspaceRequest allow_empty_v_schema */ allow_empty_v_schema?: (boolean|null); - /** CreateKeyspaceRequest served_froms */ - served_froms?: (topodata.Keyspace.IServedFrom[]|null); - /** CreateKeyspaceRequest type */ type?: (topodata.KeyspaceType|null); @@ -46607,9 +46377,6 @@ export namespace vtctldata { /** CreateKeyspaceRequest allow_empty_v_schema. */ public allow_empty_v_schema: boolean; - /** CreateKeyspaceRequest served_froms. */ - public served_froms: topodata.Keyspace.IServedFrom[]; - /** CreateKeyspaceRequest type. */ public type: topodata.KeyspaceType; @@ -60861,224 +60628,6 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } - /** Properties of a SetKeyspaceServedFromRequest. */ - interface ISetKeyspaceServedFromRequest { - - /** SetKeyspaceServedFromRequest keyspace */ - keyspace?: (string|null); - - /** SetKeyspaceServedFromRequest tablet_type */ - tablet_type?: (topodata.TabletType|null); - - /** SetKeyspaceServedFromRequest cells */ - cells?: (string[]|null); - - /** SetKeyspaceServedFromRequest remove */ - remove?: (boolean|null); - - /** SetKeyspaceServedFromRequest source_keyspace */ - source_keyspace?: (string|null); - } - - /** Represents a SetKeyspaceServedFromRequest. */ - class SetKeyspaceServedFromRequest implements ISetKeyspaceServedFromRequest { - - /** - * Constructs a new SetKeyspaceServedFromRequest. - * @param [properties] Properties to set - */ - constructor(properties?: vtctldata.ISetKeyspaceServedFromRequest); - - /** SetKeyspaceServedFromRequest keyspace. */ - public keyspace: string; - - /** SetKeyspaceServedFromRequest tablet_type. */ - public tablet_type: topodata.TabletType; - - /** SetKeyspaceServedFromRequest cells. */ - public cells: string[]; - - /** SetKeyspaceServedFromRequest remove. */ - public remove: boolean; - - /** SetKeyspaceServedFromRequest source_keyspace. */ - public source_keyspace: string; - - /** - * Creates a new SetKeyspaceServedFromRequest instance using the specified properties. - * @param [properties] Properties to set - * @returns SetKeyspaceServedFromRequest instance - */ - public static create(properties?: vtctldata.ISetKeyspaceServedFromRequest): vtctldata.SetKeyspaceServedFromRequest; - - /** - * Encodes the specified SetKeyspaceServedFromRequest message. Does not implicitly {@link vtctldata.SetKeyspaceServedFromRequest.verify|verify} messages. - * @param message SetKeyspaceServedFromRequest message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: vtctldata.ISetKeyspaceServedFromRequest, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SetKeyspaceServedFromRequest message, length delimited. Does not implicitly {@link vtctldata.SetKeyspaceServedFromRequest.verify|verify} messages. - * @param message SetKeyspaceServedFromRequest message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: vtctldata.ISetKeyspaceServedFromRequest, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SetKeyspaceServedFromRequest message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SetKeyspaceServedFromRequest - * @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.SetKeyspaceServedFromRequest; - - /** - * Decodes a SetKeyspaceServedFromRequest message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SetKeyspaceServedFromRequest - * @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.SetKeyspaceServedFromRequest; - - /** - * Verifies a SetKeyspaceServedFromRequest 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 SetKeyspaceServedFromRequest message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SetKeyspaceServedFromRequest - */ - public static fromObject(object: { [k: string]: any }): vtctldata.SetKeyspaceServedFromRequest; - - /** - * Creates a plain object from a SetKeyspaceServedFromRequest message. Also converts values to other types if specified. - * @param message SetKeyspaceServedFromRequest - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: vtctldata.SetKeyspaceServedFromRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SetKeyspaceServedFromRequest to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for SetKeyspaceServedFromRequest - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } - - /** Properties of a SetKeyspaceServedFromResponse. */ - interface ISetKeyspaceServedFromResponse { - - /** SetKeyspaceServedFromResponse keyspace */ - keyspace?: (topodata.IKeyspace|null); - } - - /** Represents a SetKeyspaceServedFromResponse. */ - class SetKeyspaceServedFromResponse implements ISetKeyspaceServedFromResponse { - - /** - * Constructs a new SetKeyspaceServedFromResponse. - * @param [properties] Properties to set - */ - constructor(properties?: vtctldata.ISetKeyspaceServedFromResponse); - - /** SetKeyspaceServedFromResponse keyspace. */ - public keyspace?: (topodata.IKeyspace|null); - - /** - * Creates a new SetKeyspaceServedFromResponse instance using the specified properties. - * @param [properties] Properties to set - * @returns SetKeyspaceServedFromResponse instance - */ - public static create(properties?: vtctldata.ISetKeyspaceServedFromResponse): vtctldata.SetKeyspaceServedFromResponse; - - /** - * Encodes the specified SetKeyspaceServedFromResponse message. Does not implicitly {@link vtctldata.SetKeyspaceServedFromResponse.verify|verify} messages. - * @param message SetKeyspaceServedFromResponse message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: vtctldata.ISetKeyspaceServedFromResponse, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SetKeyspaceServedFromResponse message, length delimited. Does not implicitly {@link vtctldata.SetKeyspaceServedFromResponse.verify|verify} messages. - * @param message SetKeyspaceServedFromResponse message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: vtctldata.ISetKeyspaceServedFromResponse, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SetKeyspaceServedFromResponse message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SetKeyspaceServedFromResponse - * @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.SetKeyspaceServedFromResponse; - - /** - * Decodes a SetKeyspaceServedFromResponse message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SetKeyspaceServedFromResponse - * @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.SetKeyspaceServedFromResponse; - - /** - * Verifies a SetKeyspaceServedFromResponse 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 SetKeyspaceServedFromResponse message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SetKeyspaceServedFromResponse - */ - public static fromObject(object: { [k: string]: any }): vtctldata.SetKeyspaceServedFromResponse; - - /** - * Creates a plain object from a SetKeyspaceServedFromResponse message. Also converts values to other types if specified. - * @param message SetKeyspaceServedFromResponse - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: vtctldata.SetKeyspaceServedFromResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SetKeyspaceServedFromResponse to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for SetKeyspaceServedFromResponse - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } - /** Properties of a SetKeyspaceShardingInfoRequest. */ interface ISetKeyspaceShardingInfoRequest { diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 7de0fde463a..4d314e2b299 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -35057,7 +35057,6 @@ export const topodata = $root.topodata = (() => { * Properties of a Keyspace. * @memberof topodata * @interface IKeyspace - * @property {Array.|null} [served_froms] Keyspace served_froms * @property {topodata.KeyspaceType|null} [keyspace_type] Keyspace keyspace_type * @property {string|null} [base_keyspace] Keyspace base_keyspace * @property {vttime.ITime|null} [snapshot_time] Keyspace snapshot_time @@ -35075,21 +35074,12 @@ export const topodata = $root.topodata = (() => { * @param {topodata.IKeyspace=} [properties] Properties to set */ function Keyspace(properties) { - this.served_froms = []; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } - /** - * Keyspace served_froms. - * @member {Array.} served_froms - * @memberof topodata.Keyspace - * @instance - */ - Keyspace.prototype.served_froms = $util.emptyArray; - /** * Keyspace keyspace_type. * @member {topodata.KeyspaceType} keyspace_type @@ -35162,9 +35152,6 @@ export const topodata = $root.topodata = (() => { Keyspace.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.served_froms != null && message.served_froms.length) - for (let i = 0; i < message.served_froms.length; ++i) - $root.topodata.Keyspace.ServedFrom.encode(message.served_froms[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); if (message.keyspace_type != null && Object.hasOwnProperty.call(message, "keyspace_type")) writer.uint32(/* id 5, wireType 0 =*/40).int32(message.keyspace_type); if (message.base_keyspace != null && Object.hasOwnProperty.call(message, "base_keyspace")) @@ -35211,12 +35198,6 @@ export const topodata = $root.topodata = (() => { while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { - case 4: { - if (!(message.served_froms && message.served_froms.length)) - message.served_froms = []; - message.served_froms.push($root.topodata.Keyspace.ServedFrom.decode(reader, reader.uint32())); - break; - } case 5: { message.keyspace_type = reader.int32(); break; @@ -35276,15 +35257,6 @@ export const topodata = $root.topodata = (() => { Keyspace.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.served_froms != null && message.hasOwnProperty("served_froms")) { - if (!Array.isArray(message.served_froms)) - return "served_froms: array expected"; - for (let i = 0; i < message.served_froms.length; ++i) { - let error = $root.topodata.Keyspace.ServedFrom.verify(message.served_froms[i]); - if (error) - return "served_froms." + error; - } - } if (message.keyspace_type != null && message.hasOwnProperty("keyspace_type")) switch (message.keyspace_type) { default: @@ -35327,16 +35299,6 @@ export const topodata = $root.topodata = (() => { if (object instanceof $root.topodata.Keyspace) return object; let message = new $root.topodata.Keyspace(); - if (object.served_froms) { - if (!Array.isArray(object.served_froms)) - throw TypeError(".topodata.Keyspace.served_froms: array expected"); - message.served_froms = []; - for (let i = 0; i < object.served_froms.length; ++i) { - if (typeof object.served_froms[i] !== "object") - throw TypeError(".topodata.Keyspace.served_froms: object expected"); - message.served_froms[i] = $root.topodata.Keyspace.ServedFrom.fromObject(object.served_froms[i]); - } - } switch (object.keyspace_type) { default: if (typeof object.keyspace_type === "number") { @@ -35385,8 +35347,6 @@ export const topodata = $root.topodata = (() => { if (!options) options = {}; let object = {}; - if (options.arrays || options.defaults) - object.served_froms = []; if (options.defaults) { object.keyspace_type = options.enums === String ? "NORMAL" : 0; object.base_keyspace = ""; @@ -35395,11 +35355,6 @@ export const topodata = $root.topodata = (() => { object.throttler_config = null; object.sidecar_db_name = ""; } - if (message.served_froms && message.served_froms.length) { - object.served_froms = []; - for (let j = 0; j < message.served_froms.length; ++j) - object.served_froms[j] = $root.topodata.Keyspace.ServedFrom.toObject(message.served_froms[j], options); - } if (message.keyspace_type != null && message.hasOwnProperty("keyspace_type")) object.keyspace_type = options.enums === String ? $root.topodata.KeyspaceType[message.keyspace_type] === undefined ? message.keyspace_type : $root.topodata.KeyspaceType[message.keyspace_type] : message.keyspace_type; if (message.base_keyspace != null && message.hasOwnProperty("base_keyspace")) @@ -35441,337 +35396,6 @@ export const topodata = $root.topodata = (() => { return typeUrlPrefix + "/topodata.Keyspace"; }; - Keyspace.ServedFrom = (function() { - - /** - * Properties of a ServedFrom. - * @memberof topodata.Keyspace - * @interface IServedFrom - * @property {topodata.TabletType|null} [tablet_type] ServedFrom tablet_type - * @property {Array.|null} [cells] ServedFrom cells - * @property {string|null} [keyspace] ServedFrom keyspace - */ - - /** - * Constructs a new ServedFrom. - * @memberof topodata.Keyspace - * @classdesc Represents a ServedFrom. - * @implements IServedFrom - * @constructor - * @param {topodata.Keyspace.IServedFrom=} [properties] Properties to set - */ - function ServedFrom(properties) { - this.cells = []; - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ServedFrom tablet_type. - * @member {topodata.TabletType} tablet_type - * @memberof topodata.Keyspace.ServedFrom - * @instance - */ - ServedFrom.prototype.tablet_type = 0; - - /** - * ServedFrom cells. - * @member {Array.} cells - * @memberof topodata.Keyspace.ServedFrom - * @instance - */ - ServedFrom.prototype.cells = $util.emptyArray; - - /** - * ServedFrom keyspace. - * @member {string} keyspace - * @memberof topodata.Keyspace.ServedFrom - * @instance - */ - ServedFrom.prototype.keyspace = ""; - - /** - * Creates a new ServedFrom instance using the specified properties. - * @function create - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {topodata.Keyspace.IServedFrom=} [properties] Properties to set - * @returns {topodata.Keyspace.ServedFrom} ServedFrom instance - */ - ServedFrom.create = function create(properties) { - return new ServedFrom(properties); - }; - - /** - * Encodes the specified ServedFrom message. Does not implicitly {@link topodata.Keyspace.ServedFrom.verify|verify} messages. - * @function encode - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {topodata.Keyspace.IServedFrom} message ServedFrom message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServedFrom.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.tablet_type != null && Object.hasOwnProperty.call(message, "tablet_type")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.tablet_type); - if (message.cells != null && message.cells.length) - for (let i = 0; i < message.cells.length; ++i) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.cells[i]); - if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.keyspace); - return writer; - }; - - /** - * Encodes the specified ServedFrom message, length delimited. Does not implicitly {@link topodata.Keyspace.ServedFrom.verify|verify} messages. - * @function encodeDelimited - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {topodata.Keyspace.IServedFrom} message ServedFrom message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServedFrom.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ServedFrom message from the specified reader or buffer. - * @function decode - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {topodata.Keyspace.ServedFrom} ServedFrom - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServedFrom.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.topodata.Keyspace.ServedFrom(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - message.tablet_type = reader.int32(); - break; - } - case 2: { - if (!(message.cells && message.cells.length)) - message.cells = []; - message.cells.push(reader.string()); - break; - } - case 3: { - message.keyspace = reader.string(); - break; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ServedFrom message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {topodata.Keyspace.ServedFrom} ServedFrom - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServedFrom.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ServedFrom message. - * @function verify - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ServedFrom.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.tablet_type != null && message.hasOwnProperty("tablet_type")) - switch (message.tablet_type) { - default: - return "tablet_type: enum value expected"; - case 0: - case 1: - case 1: - case 2: - case 3: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - break; - } - if (message.cells != null && message.hasOwnProperty("cells")) { - if (!Array.isArray(message.cells)) - return "cells: array expected"; - for (let i = 0; i < message.cells.length; ++i) - if (!$util.isString(message.cells[i])) - return "cells: string[] expected"; - } - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - if (!$util.isString(message.keyspace)) - return "keyspace: string expected"; - return null; - }; - - /** - * Creates a ServedFrom message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {Object.} object Plain object - * @returns {topodata.Keyspace.ServedFrom} ServedFrom - */ - ServedFrom.fromObject = function fromObject(object) { - if (object instanceof $root.topodata.Keyspace.ServedFrom) - return object; - let message = new $root.topodata.Keyspace.ServedFrom(); - switch (object.tablet_type) { - default: - if (typeof object.tablet_type === "number") { - message.tablet_type = object.tablet_type; - break; - } - break; - case "UNKNOWN": - case 0: - message.tablet_type = 0; - break; - case "PRIMARY": - case 1: - message.tablet_type = 1; - break; - case "MASTER": - case 1: - message.tablet_type = 1; - break; - case "REPLICA": - case 2: - message.tablet_type = 2; - break; - case "RDONLY": - case 3: - message.tablet_type = 3; - break; - case "BATCH": - case 3: - message.tablet_type = 3; - break; - case "SPARE": - case 4: - message.tablet_type = 4; - break; - case "EXPERIMENTAL": - case 5: - message.tablet_type = 5; - break; - case "BACKUP": - case 6: - message.tablet_type = 6; - break; - case "RESTORE": - case 7: - message.tablet_type = 7; - break; - case "DRAINED": - case 8: - message.tablet_type = 8; - break; - } - if (object.cells) { - if (!Array.isArray(object.cells)) - throw TypeError(".topodata.Keyspace.ServedFrom.cells: array expected"); - message.cells = []; - for (let i = 0; i < object.cells.length; ++i) - message.cells[i] = String(object.cells[i]); - } - if (object.keyspace != null) - message.keyspace = String(object.keyspace); - return message; - }; - - /** - * Creates a plain object from a ServedFrom message. Also converts values to other types if specified. - * @function toObject - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {topodata.Keyspace.ServedFrom} message ServedFrom - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ServedFrom.toObject = function toObject(message, options) { - if (!options) - options = {}; - let object = {}; - if (options.arrays || options.defaults) - object.cells = []; - if (options.defaults) { - object.tablet_type = options.enums === String ? "UNKNOWN" : 0; - object.keyspace = ""; - } - if (message.tablet_type != null && message.hasOwnProperty("tablet_type")) - object.tablet_type = options.enums === String ? $root.topodata.TabletType[message.tablet_type] === undefined ? message.tablet_type : $root.topodata.TabletType[message.tablet_type] : message.tablet_type; - if (message.cells && message.cells.length) { - object.cells = []; - for (let j = 0; j < message.cells.length; ++j) - object.cells[j] = message.cells[j]; - } - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - object.keyspace = message.keyspace; - return object; - }; - - /** - * Converts this ServedFrom to JSON. - * @function toJSON - * @memberof topodata.Keyspace.ServedFrom - * @instance - * @returns {Object.} JSON object - */ - ServedFrom.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for ServedFrom - * @function getTypeUrl - * @memberof topodata.Keyspace.ServedFrom - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - ServedFrom.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/topodata.Keyspace.ServedFrom"; - }; - - return ServedFrom; - })(); - return Keyspace; })(); @@ -37590,7 +37214,6 @@ export const topodata = $root.topodata = (() => { * @memberof topodata * @interface ISrvKeyspace * @property {Array.|null} [partitions] SrvKeyspace partitions - * @property {Array.|null} [served_from] SrvKeyspace served_from * @property {topodata.IThrottlerConfig|null} [throttler_config] SrvKeyspace throttler_config */ @@ -37604,7 +37227,6 @@ export const topodata = $root.topodata = (() => { */ function SrvKeyspace(properties) { this.partitions = []; - this.served_from = []; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -37619,14 +37241,6 @@ export const topodata = $root.topodata = (() => { */ SrvKeyspace.prototype.partitions = $util.emptyArray; - /** - * SrvKeyspace served_from. - * @member {Array.} served_from - * @memberof topodata.SrvKeyspace - * @instance - */ - SrvKeyspace.prototype.served_from = $util.emptyArray; - /** * SrvKeyspace throttler_config. * @member {topodata.IThrottlerConfig|null|undefined} throttler_config @@ -37662,9 +37276,6 @@ export const topodata = $root.topodata = (() => { if (message.partitions != null && message.partitions.length) for (let i = 0; i < message.partitions.length; ++i) $root.topodata.SrvKeyspace.KeyspacePartition.encode(message.partitions[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.served_from != null && message.served_from.length) - for (let i = 0; i < message.served_from.length; ++i) - $root.topodata.SrvKeyspace.ServedFrom.encode(message.served_from[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); if (message.throttler_config != null && Object.hasOwnProperty.call(message, "throttler_config")) $root.topodata.ThrottlerConfig.encode(message.throttler_config, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); return writer; @@ -37707,12 +37318,6 @@ export const topodata = $root.topodata = (() => { message.partitions.push($root.topodata.SrvKeyspace.KeyspacePartition.decode(reader, reader.uint32())); break; } - case 4: { - if (!(message.served_from && message.served_from.length)) - message.served_from = []; - message.served_from.push($root.topodata.SrvKeyspace.ServedFrom.decode(reader, reader.uint32())); - break; - } case 6: { message.throttler_config = $root.topodata.ThrottlerConfig.decode(reader, reader.uint32()); break; @@ -37761,15 +37366,6 @@ export const topodata = $root.topodata = (() => { return "partitions." + error; } } - if (message.served_from != null && message.hasOwnProperty("served_from")) { - if (!Array.isArray(message.served_from)) - return "served_from: array expected"; - for (let i = 0; i < message.served_from.length; ++i) { - let error = $root.topodata.SrvKeyspace.ServedFrom.verify(message.served_from[i]); - if (error) - return "served_from." + error; - } - } if (message.throttler_config != null && message.hasOwnProperty("throttler_config")) { let error = $root.topodata.ThrottlerConfig.verify(message.throttler_config); if (error) @@ -37800,16 +37396,6 @@ export const topodata = $root.topodata = (() => { message.partitions[i] = $root.topodata.SrvKeyspace.KeyspacePartition.fromObject(object.partitions[i]); } } - if (object.served_from) { - if (!Array.isArray(object.served_from)) - throw TypeError(".topodata.SrvKeyspace.served_from: array expected"); - message.served_from = []; - for (let i = 0; i < object.served_from.length; ++i) { - if (typeof object.served_from[i] !== "object") - throw TypeError(".topodata.SrvKeyspace.served_from: object expected"); - message.served_from[i] = $root.topodata.SrvKeyspace.ServedFrom.fromObject(object.served_from[i]); - } - } if (object.throttler_config != null) { if (typeof object.throttler_config !== "object") throw TypeError(".topodata.SrvKeyspace.throttler_config: object expected"); @@ -37831,10 +37417,8 @@ export const topodata = $root.topodata = (() => { if (!options) options = {}; let object = {}; - if (options.arrays || options.defaults) { + if (options.arrays || options.defaults) object.partitions = []; - object.served_from = []; - } if (options.defaults) object.throttler_config = null; if (message.partitions && message.partitions.length) { @@ -37842,11 +37426,6 @@ export const topodata = $root.topodata = (() => { for (let j = 0; j < message.partitions.length; ++j) object.partitions[j] = $root.topodata.SrvKeyspace.KeyspacePartition.toObject(message.partitions[j], options); } - if (message.served_from && message.served_from.length) { - object.served_from = []; - for (let j = 0; j < message.served_from.length; ++j) - object.served_from[j] = $root.topodata.SrvKeyspace.ServedFrom.toObject(message.served_from[j], options); - } if (message.throttler_config != null && message.hasOwnProperty("throttler_config")) object.throttler_config = $root.topodata.ThrottlerConfig.toObject(message.throttler_config, options); return object; @@ -38235,297 +37814,6 @@ export const topodata = $root.topodata = (() => { return KeyspacePartition; })(); - SrvKeyspace.ServedFrom = (function() { - - /** - * Properties of a ServedFrom. - * @memberof topodata.SrvKeyspace - * @interface IServedFrom - * @property {topodata.TabletType|null} [tablet_type] ServedFrom tablet_type - * @property {string|null} [keyspace] ServedFrom keyspace - */ - - /** - * Constructs a new ServedFrom. - * @memberof topodata.SrvKeyspace - * @classdesc Represents a ServedFrom. - * @implements IServedFrom - * @constructor - * @param {topodata.SrvKeyspace.IServedFrom=} [properties] Properties to set - */ - function ServedFrom(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ServedFrom tablet_type. - * @member {topodata.TabletType} tablet_type - * @memberof topodata.SrvKeyspace.ServedFrom - * @instance - */ - ServedFrom.prototype.tablet_type = 0; - - /** - * ServedFrom keyspace. - * @member {string} keyspace - * @memberof topodata.SrvKeyspace.ServedFrom - * @instance - */ - ServedFrom.prototype.keyspace = ""; - - /** - * Creates a new ServedFrom instance using the specified properties. - * @function create - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {topodata.SrvKeyspace.IServedFrom=} [properties] Properties to set - * @returns {topodata.SrvKeyspace.ServedFrom} ServedFrom instance - */ - ServedFrom.create = function create(properties) { - return new ServedFrom(properties); - }; - - /** - * Encodes the specified ServedFrom message. Does not implicitly {@link topodata.SrvKeyspace.ServedFrom.verify|verify} messages. - * @function encode - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {topodata.SrvKeyspace.IServedFrom} message ServedFrom message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServedFrom.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.tablet_type != null && Object.hasOwnProperty.call(message, "tablet_type")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.tablet_type); - if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.keyspace); - return writer; - }; - - /** - * Encodes the specified ServedFrom message, length delimited. Does not implicitly {@link topodata.SrvKeyspace.ServedFrom.verify|verify} messages. - * @function encodeDelimited - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {topodata.SrvKeyspace.IServedFrom} message ServedFrom message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServedFrom.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ServedFrom message from the specified reader or buffer. - * @function decode - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {topodata.SrvKeyspace.ServedFrom} ServedFrom - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServedFrom.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.topodata.SrvKeyspace.ServedFrom(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - message.tablet_type = reader.int32(); - break; - } - case 2: { - message.keyspace = reader.string(); - break; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ServedFrom message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {topodata.SrvKeyspace.ServedFrom} ServedFrom - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServedFrom.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ServedFrom message. - * @function verify - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ServedFrom.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.tablet_type != null && message.hasOwnProperty("tablet_type")) - switch (message.tablet_type) { - default: - return "tablet_type: enum value expected"; - case 0: - case 1: - case 1: - case 2: - case 3: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - break; - } - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - if (!$util.isString(message.keyspace)) - return "keyspace: string expected"; - return null; - }; - - /** - * Creates a ServedFrom message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {Object.} object Plain object - * @returns {topodata.SrvKeyspace.ServedFrom} ServedFrom - */ - ServedFrom.fromObject = function fromObject(object) { - if (object instanceof $root.topodata.SrvKeyspace.ServedFrom) - return object; - let message = new $root.topodata.SrvKeyspace.ServedFrom(); - switch (object.tablet_type) { - default: - if (typeof object.tablet_type === "number") { - message.tablet_type = object.tablet_type; - break; - } - break; - case "UNKNOWN": - case 0: - message.tablet_type = 0; - break; - case "PRIMARY": - case 1: - message.tablet_type = 1; - break; - case "MASTER": - case 1: - message.tablet_type = 1; - break; - case "REPLICA": - case 2: - message.tablet_type = 2; - break; - case "RDONLY": - case 3: - message.tablet_type = 3; - break; - case "BATCH": - case 3: - message.tablet_type = 3; - break; - case "SPARE": - case 4: - message.tablet_type = 4; - break; - case "EXPERIMENTAL": - case 5: - message.tablet_type = 5; - break; - case "BACKUP": - case 6: - message.tablet_type = 6; - break; - case "RESTORE": - case 7: - message.tablet_type = 7; - break; - case "DRAINED": - case 8: - message.tablet_type = 8; - break; - } - if (object.keyspace != null) - message.keyspace = String(object.keyspace); - return message; - }; - - /** - * Creates a plain object from a ServedFrom message. Also converts values to other types if specified. - * @function toObject - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {topodata.SrvKeyspace.ServedFrom} message ServedFrom - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ServedFrom.toObject = function toObject(message, options) { - if (!options) - options = {}; - let object = {}; - if (options.defaults) { - object.tablet_type = options.enums === String ? "UNKNOWN" : 0; - object.keyspace = ""; - } - if (message.tablet_type != null && message.hasOwnProperty("tablet_type")) - object.tablet_type = options.enums === String ? $root.topodata.TabletType[message.tablet_type] === undefined ? message.tablet_type : $root.topodata.TabletType[message.tablet_type] : message.tablet_type; - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - object.keyspace = message.keyspace; - return object; - }; - - /** - * Converts this ServedFrom to JSON. - * @function toJSON - * @memberof topodata.SrvKeyspace.ServedFrom - * @instance - * @returns {Object.} JSON object - */ - ServedFrom.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for ServedFrom - * @function getTypeUrl - * @memberof topodata.SrvKeyspace.ServedFrom - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - ServedFrom.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/topodata.SrvKeyspace.ServedFrom"; - }; - - return ServedFrom; - })(); - return SrvKeyspace; })(); @@ -114780,7 +114068,6 @@ export const vtctldata = $root.vtctldata = (() => { * @property {string|null} [name] CreateKeyspaceRequest name * @property {boolean|null} [force] CreateKeyspaceRequest force * @property {boolean|null} [allow_empty_v_schema] CreateKeyspaceRequest allow_empty_v_schema - * @property {Array.|null} [served_froms] CreateKeyspaceRequest served_froms * @property {topodata.KeyspaceType|null} [type] CreateKeyspaceRequest type * @property {string|null} [base_keyspace] CreateKeyspaceRequest base_keyspace * @property {vttime.ITime|null} [snapshot_time] CreateKeyspaceRequest snapshot_time @@ -114797,7 +114084,6 @@ export const vtctldata = $root.vtctldata = (() => { * @param {vtctldata.ICreateKeyspaceRequest=} [properties] Properties to set */ function CreateKeyspaceRequest(properties) { - this.served_froms = []; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -114828,14 +114114,6 @@ export const vtctldata = $root.vtctldata = (() => { */ CreateKeyspaceRequest.prototype.allow_empty_v_schema = false; - /** - * CreateKeyspaceRequest served_froms. - * @member {Array.} served_froms - * @memberof vtctldata.CreateKeyspaceRequest - * @instance - */ - CreateKeyspaceRequest.prototype.served_froms = $util.emptyArray; - /** * CreateKeyspaceRequest type. * @member {topodata.KeyspaceType} type @@ -114906,9 +114184,6 @@ export const vtctldata = $root.vtctldata = (() => { writer.uint32(/* id 2, wireType 0 =*/16).bool(message.force); if (message.allow_empty_v_schema != null && Object.hasOwnProperty.call(message, "allow_empty_v_schema")) writer.uint32(/* id 3, wireType 0 =*/24).bool(message.allow_empty_v_schema); - if (message.served_froms != null && message.served_froms.length) - for (let i = 0; i < message.served_froms.length; ++i) - $root.topodata.Keyspace.ServedFrom.encode(message.served_froms[i], writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); if (message.type != null && Object.hasOwnProperty.call(message, "type")) writer.uint32(/* id 7, wireType 0 =*/56).int32(message.type); if (message.base_keyspace != null && Object.hasOwnProperty.call(message, "base_keyspace")) @@ -114965,12 +114240,6 @@ export const vtctldata = $root.vtctldata = (() => { message.allow_empty_v_schema = reader.bool(); break; } - case 6: { - if (!(message.served_froms && message.served_froms.length)) - message.served_froms = []; - message.served_froms.push($root.topodata.Keyspace.ServedFrom.decode(reader, reader.uint32())); - break; - } case 7: { message.type = reader.int32(); break; @@ -115035,15 +114304,6 @@ export const vtctldata = $root.vtctldata = (() => { if (message.allow_empty_v_schema != null && message.hasOwnProperty("allow_empty_v_schema")) if (typeof message.allow_empty_v_schema !== "boolean") return "allow_empty_v_schema: boolean expected"; - if (message.served_froms != null && message.hasOwnProperty("served_froms")) { - if (!Array.isArray(message.served_froms)) - return "served_froms: array expected"; - for (let i = 0; i < message.served_froms.length; ++i) { - let error = $root.topodata.Keyspace.ServedFrom.verify(message.served_froms[i]); - if (error) - return "served_froms." + error; - } - } if (message.type != null && message.hasOwnProperty("type")) switch (message.type) { default: @@ -115087,16 +114347,6 @@ export const vtctldata = $root.vtctldata = (() => { message.force = Boolean(object.force); if (object.allow_empty_v_schema != null) message.allow_empty_v_schema = Boolean(object.allow_empty_v_schema); - if (object.served_froms) { - if (!Array.isArray(object.served_froms)) - throw TypeError(".vtctldata.CreateKeyspaceRequest.served_froms: array expected"); - message.served_froms = []; - for (let i = 0; i < object.served_froms.length; ++i) { - if (typeof object.served_froms[i] !== "object") - throw TypeError(".vtctldata.CreateKeyspaceRequest.served_froms: object expected"); - message.served_froms[i] = $root.topodata.Keyspace.ServedFrom.fromObject(object.served_froms[i]); - } - } switch (object.type) { default: if (typeof object.type === "number") { @@ -115140,8 +114390,6 @@ export const vtctldata = $root.vtctldata = (() => { if (!options) options = {}; let object = {}; - if (options.arrays || options.defaults) - object.served_froms = []; if (options.defaults) { object.name = ""; object.force = false; @@ -115158,11 +114406,6 @@ export const vtctldata = $root.vtctldata = (() => { object.force = message.force; if (message.allow_empty_v_schema != null && message.hasOwnProperty("allow_empty_v_schema")) object.allow_empty_v_schema = message.allow_empty_v_schema; - if (message.served_froms && message.served_froms.length) { - object.served_froms = []; - for (let j = 0; j < message.served_froms.length; ++j) - object.served_froms[j] = $root.topodata.Keyspace.ServedFrom.toObject(message.served_froms[j], options); - } if (message.type != null && message.hasOwnProperty("type")) object.type = options.enums === String ? $root.topodata.KeyspaceType[message.type] === undefined ? message.type : $root.topodata.KeyspaceType[message.type] : message.type; if (message.base_keyspace != null && message.hasOwnProperty("base_keyspace")) @@ -148374,591 +147617,6 @@ export const vtctldata = $root.vtctldata = (() => { return SetKeyspaceDurabilityPolicyResponse; })(); - vtctldata.SetKeyspaceServedFromRequest = (function() { - - /** - * Properties of a SetKeyspaceServedFromRequest. - * @memberof vtctldata - * @interface ISetKeyspaceServedFromRequest - * @property {string|null} [keyspace] SetKeyspaceServedFromRequest keyspace - * @property {topodata.TabletType|null} [tablet_type] SetKeyspaceServedFromRequest tablet_type - * @property {Array.|null} [cells] SetKeyspaceServedFromRequest cells - * @property {boolean|null} [remove] SetKeyspaceServedFromRequest remove - * @property {string|null} [source_keyspace] SetKeyspaceServedFromRequest source_keyspace - */ - - /** - * Constructs a new SetKeyspaceServedFromRequest. - * @memberof vtctldata - * @classdesc Represents a SetKeyspaceServedFromRequest. - * @implements ISetKeyspaceServedFromRequest - * @constructor - * @param {vtctldata.ISetKeyspaceServedFromRequest=} [properties] Properties to set - */ - function SetKeyspaceServedFromRequest(properties) { - this.cells = []; - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SetKeyspaceServedFromRequest keyspace. - * @member {string} keyspace - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - */ - SetKeyspaceServedFromRequest.prototype.keyspace = ""; - - /** - * SetKeyspaceServedFromRequest tablet_type. - * @member {topodata.TabletType} tablet_type - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - */ - SetKeyspaceServedFromRequest.prototype.tablet_type = 0; - - /** - * SetKeyspaceServedFromRequest cells. - * @member {Array.} cells - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - */ - SetKeyspaceServedFromRequest.prototype.cells = $util.emptyArray; - - /** - * SetKeyspaceServedFromRequest remove. - * @member {boolean} remove - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - */ - SetKeyspaceServedFromRequest.prototype.remove = false; - - /** - * SetKeyspaceServedFromRequest source_keyspace. - * @member {string} source_keyspace - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - */ - SetKeyspaceServedFromRequest.prototype.source_keyspace = ""; - - /** - * Creates a new SetKeyspaceServedFromRequest instance using the specified properties. - * @function create - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {vtctldata.ISetKeyspaceServedFromRequest=} [properties] Properties to set - * @returns {vtctldata.SetKeyspaceServedFromRequest} SetKeyspaceServedFromRequest instance - */ - SetKeyspaceServedFromRequest.create = function create(properties) { - return new SetKeyspaceServedFromRequest(properties); - }; - - /** - * Encodes the specified SetKeyspaceServedFromRequest message. Does not implicitly {@link vtctldata.SetKeyspaceServedFromRequest.verify|verify} messages. - * @function encode - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {vtctldata.ISetKeyspaceServedFromRequest} message SetKeyspaceServedFromRequest message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SetKeyspaceServedFromRequest.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.tablet_type != null && Object.hasOwnProperty.call(message, "tablet_type")) - writer.uint32(/* id 2, wireType 0 =*/16).int32(message.tablet_type); - if (message.cells != null && message.cells.length) - for (let i = 0; i < message.cells.length; ++i) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.cells[i]); - if (message.remove != null && Object.hasOwnProperty.call(message, "remove")) - writer.uint32(/* id 4, wireType 0 =*/32).bool(message.remove); - if (message.source_keyspace != null && Object.hasOwnProperty.call(message, "source_keyspace")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.source_keyspace); - return writer; - }; - - /** - * Encodes the specified SetKeyspaceServedFromRequest message, length delimited. Does not implicitly {@link vtctldata.SetKeyspaceServedFromRequest.verify|verify} messages. - * @function encodeDelimited - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {vtctldata.ISetKeyspaceServedFromRequest} message SetKeyspaceServedFromRequest message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SetKeyspaceServedFromRequest.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SetKeyspaceServedFromRequest message from the specified reader or buffer. - * @function decode - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {vtctldata.SetKeyspaceServedFromRequest} SetKeyspaceServedFromRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SetKeyspaceServedFromRequest.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.SetKeyspaceServedFromRequest(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - message.keyspace = reader.string(); - break; - } - case 2: { - message.tablet_type = reader.int32(); - break; - } - case 3: { - if (!(message.cells && message.cells.length)) - message.cells = []; - message.cells.push(reader.string()); - break; - } - case 4: { - message.remove = reader.bool(); - break; - } - case 5: { - message.source_keyspace = reader.string(); - break; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SetKeyspaceServedFromRequest message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {vtctldata.SetKeyspaceServedFromRequest} SetKeyspaceServedFromRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SetKeyspaceServedFromRequest.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SetKeyspaceServedFromRequest message. - * @function verify - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SetKeyspaceServedFromRequest.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.tablet_type != null && message.hasOwnProperty("tablet_type")) - switch (message.tablet_type) { - default: - return "tablet_type: enum value expected"; - case 0: - case 1: - case 1: - case 2: - case 3: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - break; - } - if (message.cells != null && message.hasOwnProperty("cells")) { - if (!Array.isArray(message.cells)) - return "cells: array expected"; - for (let i = 0; i < message.cells.length; ++i) - if (!$util.isString(message.cells[i])) - return "cells: string[] expected"; - } - if (message.remove != null && message.hasOwnProperty("remove")) - if (typeof message.remove !== "boolean") - return "remove: boolean expected"; - if (message.source_keyspace != null && message.hasOwnProperty("source_keyspace")) - if (!$util.isString(message.source_keyspace)) - return "source_keyspace: string expected"; - return null; - }; - - /** - * Creates a SetKeyspaceServedFromRequest message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {Object.} object Plain object - * @returns {vtctldata.SetKeyspaceServedFromRequest} SetKeyspaceServedFromRequest - */ - SetKeyspaceServedFromRequest.fromObject = function fromObject(object) { - if (object instanceof $root.vtctldata.SetKeyspaceServedFromRequest) - return object; - let message = new $root.vtctldata.SetKeyspaceServedFromRequest(); - if (object.keyspace != null) - message.keyspace = String(object.keyspace); - switch (object.tablet_type) { - default: - if (typeof object.tablet_type === "number") { - message.tablet_type = object.tablet_type; - break; - } - break; - case "UNKNOWN": - case 0: - message.tablet_type = 0; - break; - case "PRIMARY": - case 1: - message.tablet_type = 1; - break; - case "MASTER": - case 1: - message.tablet_type = 1; - break; - case "REPLICA": - case 2: - message.tablet_type = 2; - break; - case "RDONLY": - case 3: - message.tablet_type = 3; - break; - case "BATCH": - case 3: - message.tablet_type = 3; - break; - case "SPARE": - case 4: - message.tablet_type = 4; - break; - case "EXPERIMENTAL": - case 5: - message.tablet_type = 5; - break; - case "BACKUP": - case 6: - message.tablet_type = 6; - break; - case "RESTORE": - case 7: - message.tablet_type = 7; - break; - case "DRAINED": - case 8: - message.tablet_type = 8; - break; - } - if (object.cells) { - if (!Array.isArray(object.cells)) - throw TypeError(".vtctldata.SetKeyspaceServedFromRequest.cells: array expected"); - message.cells = []; - for (let i = 0; i < object.cells.length; ++i) - message.cells[i] = String(object.cells[i]); - } - if (object.remove != null) - message.remove = Boolean(object.remove); - if (object.source_keyspace != null) - message.source_keyspace = String(object.source_keyspace); - return message; - }; - - /** - * Creates a plain object from a SetKeyspaceServedFromRequest message. Also converts values to other types if specified. - * @function toObject - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {vtctldata.SetKeyspaceServedFromRequest} message SetKeyspaceServedFromRequest - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SetKeyspaceServedFromRequest.toObject = function toObject(message, options) { - if (!options) - options = {}; - let object = {}; - if (options.arrays || options.defaults) - object.cells = []; - if (options.defaults) { - object.keyspace = ""; - object.tablet_type = options.enums === String ? "UNKNOWN" : 0; - object.remove = false; - object.source_keyspace = ""; - } - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - object.keyspace = message.keyspace; - if (message.tablet_type != null && message.hasOwnProperty("tablet_type")) - object.tablet_type = options.enums === String ? $root.topodata.TabletType[message.tablet_type] === undefined ? message.tablet_type : $root.topodata.TabletType[message.tablet_type] : message.tablet_type; - if (message.cells && message.cells.length) { - object.cells = []; - for (let j = 0; j < message.cells.length; ++j) - object.cells[j] = message.cells[j]; - } - if (message.remove != null && message.hasOwnProperty("remove")) - object.remove = message.remove; - if (message.source_keyspace != null && message.hasOwnProperty("source_keyspace")) - object.source_keyspace = message.source_keyspace; - return object; - }; - - /** - * Converts this SetKeyspaceServedFromRequest to JSON. - * @function toJSON - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @instance - * @returns {Object.} JSON object - */ - SetKeyspaceServedFromRequest.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for SetKeyspaceServedFromRequest - * @function getTypeUrl - * @memberof vtctldata.SetKeyspaceServedFromRequest - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - SetKeyspaceServedFromRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/vtctldata.SetKeyspaceServedFromRequest"; - }; - - return SetKeyspaceServedFromRequest; - })(); - - vtctldata.SetKeyspaceServedFromResponse = (function() { - - /** - * Properties of a SetKeyspaceServedFromResponse. - * @memberof vtctldata - * @interface ISetKeyspaceServedFromResponse - * @property {topodata.IKeyspace|null} [keyspace] SetKeyspaceServedFromResponse keyspace - */ - - /** - * Constructs a new SetKeyspaceServedFromResponse. - * @memberof vtctldata - * @classdesc Represents a SetKeyspaceServedFromResponse. - * @implements ISetKeyspaceServedFromResponse - * @constructor - * @param {vtctldata.ISetKeyspaceServedFromResponse=} [properties] Properties to set - */ - function SetKeyspaceServedFromResponse(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SetKeyspaceServedFromResponse keyspace. - * @member {topodata.IKeyspace|null|undefined} keyspace - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @instance - */ - SetKeyspaceServedFromResponse.prototype.keyspace = null; - - /** - * Creates a new SetKeyspaceServedFromResponse instance using the specified properties. - * @function create - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {vtctldata.ISetKeyspaceServedFromResponse=} [properties] Properties to set - * @returns {vtctldata.SetKeyspaceServedFromResponse} SetKeyspaceServedFromResponse instance - */ - SetKeyspaceServedFromResponse.create = function create(properties) { - return new SetKeyspaceServedFromResponse(properties); - }; - - /** - * Encodes the specified SetKeyspaceServedFromResponse message. Does not implicitly {@link vtctldata.SetKeyspaceServedFromResponse.verify|verify} messages. - * @function encode - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {vtctldata.ISetKeyspaceServedFromResponse} message SetKeyspaceServedFromResponse message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SetKeyspaceServedFromResponse.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) - $root.topodata.Keyspace.encode(message.keyspace, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SetKeyspaceServedFromResponse message, length delimited. Does not implicitly {@link vtctldata.SetKeyspaceServedFromResponse.verify|verify} messages. - * @function encodeDelimited - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {vtctldata.ISetKeyspaceServedFromResponse} message SetKeyspaceServedFromResponse message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SetKeyspaceServedFromResponse.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SetKeyspaceServedFromResponse message from the specified reader or buffer. - * @function decode - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {vtctldata.SetKeyspaceServedFromResponse} SetKeyspaceServedFromResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SetKeyspaceServedFromResponse.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.SetKeyspaceServedFromResponse(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - message.keyspace = $root.topodata.Keyspace.decode(reader, reader.uint32()); - break; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SetKeyspaceServedFromResponse message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {vtctldata.SetKeyspaceServedFromResponse} SetKeyspaceServedFromResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SetKeyspaceServedFromResponse.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SetKeyspaceServedFromResponse message. - * @function verify - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SetKeyspaceServedFromResponse.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.keyspace != null && message.hasOwnProperty("keyspace")) { - let error = $root.topodata.Keyspace.verify(message.keyspace); - if (error) - return "keyspace." + error; - } - return null; - }; - - /** - * Creates a SetKeyspaceServedFromResponse message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {Object.} object Plain object - * @returns {vtctldata.SetKeyspaceServedFromResponse} SetKeyspaceServedFromResponse - */ - SetKeyspaceServedFromResponse.fromObject = function fromObject(object) { - if (object instanceof $root.vtctldata.SetKeyspaceServedFromResponse) - return object; - let message = new $root.vtctldata.SetKeyspaceServedFromResponse(); - if (object.keyspace != null) { - if (typeof object.keyspace !== "object") - throw TypeError(".vtctldata.SetKeyspaceServedFromResponse.keyspace: object expected"); - message.keyspace = $root.topodata.Keyspace.fromObject(object.keyspace); - } - return message; - }; - - /** - * Creates a plain object from a SetKeyspaceServedFromResponse message. Also converts values to other types if specified. - * @function toObject - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {vtctldata.SetKeyspaceServedFromResponse} message SetKeyspaceServedFromResponse - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SetKeyspaceServedFromResponse.toObject = function toObject(message, options) { - if (!options) - options = {}; - let object = {}; - if (options.defaults) - object.keyspace = null; - if (message.keyspace != null && message.hasOwnProperty("keyspace")) - object.keyspace = $root.topodata.Keyspace.toObject(message.keyspace, options); - return object; - }; - - /** - * Converts this SetKeyspaceServedFromResponse to JSON. - * @function toJSON - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @instance - * @returns {Object.} JSON object - */ - SetKeyspaceServedFromResponse.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for SetKeyspaceServedFromResponse - * @function getTypeUrl - * @memberof vtctldata.SetKeyspaceServedFromResponse - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - SetKeyspaceServedFromResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/vtctldata.SetKeyspaceServedFromResponse"; - }; - - return SetKeyspaceServedFromResponse; - })(); - vtctldata.SetKeyspaceShardingInfoRequest = (function() { /** From 8dc7600f83f45062b6ebf7cabd6e7fa1ec00805d Mon Sep 17 00:00:00 2001 From: wlx5575 <116170461+wlx5575@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:21:30 +0800 Subject: [PATCH 109/119] fix: insert on duplicate key update missing BindVars (#14728) Co-authored-by: wlx5575 --- go/test/endtoend/vtgate/misc_test.go | 10 + go/test/endtoend/vtgate/schema.sql | 10 + go/test/endtoend/vtgate/vschema.json | 23 +- go/vt/vtgate/engine/cached_size.go | 13 +- go/vt/vtgate/engine/insert.go | 29 +- go/vt/vtgate/engine/insert_common.go | 4 +- go/vt/vtgate/engine/insert_select.go | 6 +- go/vt/vtgate/engine/insert_test.go | 294 +++++++++++++----- .../planbuilder/operator_transformers.go | 12 +- .../planbuilder/testdata/dml_cases.json | 28 ++ 10 files changed, 327 insertions(+), 102 deletions(-) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index f0c063b1caf..d3eaf8479e0 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -31,6 +31,16 @@ import ( "github.com/stretchr/testify/require" ) +func TestInsertOnDuplicateKey(t *testing.T) { + conn, closer := start(t) + defer closer() + + utils.Exec(t, conn, "insert into t11(id, sharding_key, col1, col2, col3) values(1, 2, 'a', 1, 2)") + utils.Exec(t, conn, "insert into t11(id, sharding_key, col1, col2, col3) values(1, 2, 'a', 1, 2) on duplicate key update id=10;") + utils.AssertMatches(t, conn, "select id, sharding_key from t11 where id=10", "[[INT64(10) INT64(2)]]") + +} + func TestInsertNeg(t *testing.T) { conn, closer := start(t) defer closer() diff --git a/go/test/endtoend/vtgate/schema.sql b/go/test/endtoend/vtgate/schema.sql index a883a26519f..4c9ed46fe9a 100644 --- a/go/test/endtoend/vtgate/schema.sql +++ b/go/test/endtoend/vtgate/schema.sql @@ -155,3 +155,13 @@ create table t10_id_to_keyspace_id_idx keyspace_id varbinary(10), primary key (id) ) Engine = InnoDB; + +create table t11 +( + id bigint, + sharding_key bigint, + col1 varchar(50), + col2 int, + col3 int, + primary key (id) +) Engine = InnoDB; \ No newline at end of file diff --git a/go/test/endtoend/vtgate/vschema.json b/go/test/endtoend/vtgate/vschema.json index 8d16beec2a6..07b6e76550f 100644 --- a/go/test/endtoend/vtgate/vschema.json +++ b/go/test/endtoend/vtgate/vschema.json @@ -1,11 +1,10 @@ - { "sharded": true, "vindexes": { - "unicode_loose_xxhash" : { + "unicode_loose_xxhash": { "type": "unicode_loose_xxhash" }, - "unicode_loose_md5" : { + "unicode_loose_md5": { "type": "unicode_loose_md5" }, "hash": { @@ -159,7 +158,10 @@ "name": "hash" }, { - "columns": ["id2", "id1"], + "columns": [ + "id2", + "id1" + ], "name": "t4_id2_vdx" } ] @@ -179,7 +181,10 @@ "name": "hash" }, { - "columns": ["id2", "id1"], + "columns": [ + "id2", + "id1" + ], "name": "t6_id2_vdx" } ] @@ -301,6 +306,14 @@ "name": "hash" } ] + }, + "t11": { + "column_vindexes": [ + { + "column": "sharding_key", + "name": "hash" + } + ] } } } diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 807c7604412..ee84317bc00 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -386,7 +386,7 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(192) + size += int64(208) } // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon size += cached.InsertCommon.CachedSize(false) @@ -433,7 +433,7 @@ func (cached *InsertCommon) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(128) + size += int64(144) } // field Keyspace *vitess.io/vitess/go/vt/vtgate/vindexes.Keyspace size += cached.Keyspace.CachedSize(true) @@ -450,8 +450,13 @@ func (cached *InsertCommon) CachedSize(alloc bool) int64 { } // field Prefix string size += hack.RuntimeAllocSize(int64(len(cached.Prefix))) - // field Suffix string - size += hack.RuntimeAllocSize(int64(len(cached.Suffix))) + // field Suffix vitess.io/vitess/go/vt/sqlparser.OnDup + { + size += hack.RuntimeAllocSize(int64(cap(cached.Suffix)) * int64(8)) + for _, elem := range cached.Suffix { + size += elem.CachedSize(true) + } + } return size } func (cached *InsertSelect) CachedSize(alloc bool) int64 { diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 46043413732..a1d3a462c1a 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -78,7 +78,7 @@ func newInsert( table *vindexes.Table, prefix string, mid sqlparser.Values, - suffix string, + suffix sqlparser.OnDup, ) *Insert { ins := &Insert{ InsertCommon: InsertCommon{ @@ -265,25 +265,30 @@ func (ins *Insert) getInsertShardedQueries( for _, indexValue := range indexesPerRss[i] { index, _ := strconv.ParseInt(string(indexValue.Value), 0, 64) if keyspaceIDs[index] != nil { + walkFunc := func(node sqlparser.SQLNode) (kontinue bool, err error) { + if arg, ok := node.(*sqlparser.Argument); ok { + bv, exists := bindVars[arg.Name] + if !exists { + return false, vterrors.VT03026(arg.Name) + } + shardBindVars[arg.Name] = bv + } + return true, nil + } mids = append(mids, sqlparser.String(ins.Mid[index])) for _, expr := range ins.Mid[index] { - err = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - if arg, ok := node.(*sqlparser.Argument); ok { - bv, exists := bindVars[arg.Name] - if !exists { - return false, vterrors.VT03026(arg.Name) - } - shardBindVars[arg.Name] = bv - } - return true, nil - }, expr, nil) + err = sqlparser.Walk(walkFunc, expr, nil) if err != nil { return nil, nil, err } } + err = sqlparser.Walk(walkFunc, ins.Suffix, nil) + if err != nil { + return nil, nil, err + } } } - rewritten := ins.Prefix + strings.Join(mids, ",") + ins.Suffix + rewritten := ins.Prefix + strings.Join(mids, ",") + sqlparser.String(ins.Suffix) queries[i] = &querypb.BoundQuery{ Sql: rewritten, BindVariables: shardBindVars, diff --git a/go/vt/vtgate/engine/insert_common.go b/go/vt/vtgate/engine/insert_common.go index d0a14feec26..64b56e35d4e 100644 --- a/go/vt/vtgate/engine/insert_common.go +++ b/go/vt/vtgate/engine/insert_common.go @@ -23,6 +23,8 @@ import ( "strconv" "strings" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" querypb "vitess.io/vitess/go/vt/proto/query" @@ -73,7 +75,7 @@ type ( // Prefix, Suffix are for sharded insert plans. Prefix string - Suffix string + Suffix sqlparser.OnDup // Insert needs tx handling txNeeded diff --git a/go/vt/vtgate/engine/insert_select.go b/go/vt/vtgate/engine/insert_select.go index d36176922dc..88767420508 100644 --- a/go/vt/vtgate/engine/insert_select.go +++ b/go/vt/vtgate/engine/insert_select.go @@ -56,7 +56,7 @@ func newInsertSelect( keyspace *vindexes.Keyspace, table *vindexes.Table, prefix string, - suffix string, + suffix sqlparser.OnDup, vv [][]int, input Primitive, ) *InsertSelect { @@ -172,7 +172,7 @@ func (ins *InsertSelect) getInsertUnshardedQuery(rows []sqltypes.Row, bindVars m } mids = append(mids, row) } - return ins.Prefix + sqlparser.String(mids) + ins.Suffix + return ins.Prefix + sqlparser.String(mids) + sqlparser.String(ins.Suffix) } func (ins *InsertSelect) insertIntoShardedTable( @@ -270,7 +270,7 @@ func (ins *InsertSelect) getInsertShardedQueries( mids = append(mids, row) } } - rewritten := ins.Prefix + sqlparser.String(mids) + ins.Suffix + rewritten := ins.Prefix + sqlparser.String(mids) + sqlparser.String(ins.Suffix) queries[i] = &querypb.BoundQuery{ Sql: rewritten, BindVariables: bvs, diff --git a/go/vt/vtgate/engine/insert_test.go b/go/vt/vtgate/engine/insert_test.go index 4ee8431f083..217492a529f 100644 --- a/go/vt/vtgate/engine/insert_test.go +++ b/go/vt/vtgate/engine/insert_test.go @@ -213,7 +213,7 @@ func TestInsertShardedSimple(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -227,7 +227,7 @@ func TestInsertShardedSimple(t *testing.T) { `ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, // Row 2 will go to -20, rows 1 & 3 will go to 20- `ExecuteMultiShard ` + - `sharded.20-: prefix(:_id_0 /* INT64 */) suffix {_id_0: type:INT64 value:"1"} ` + + `sharded.20-: prefix(:_id_0 /* INT64 */) {_id_0: type:INT64 value:"1"} ` + `true true`, }) @@ -252,7 +252,7 @@ func TestInsertShardedSimple(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc = newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -266,8 +266,8 @@ func TestInsertShardedSimple(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, // Row 2 will go to -20, rows 1 & 3 will go to 20- `ExecuteMultiShard ` + - `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) suffix {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + - `sharded.-20: prefix(:_id_1 /* INT64 */) suffix {_id_1: type:INT64 value:"2"} ` + + `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + + `sharded.-20: prefix(:_id_1 /* INT64 */) {_id_1: type:INT64 value:"2"} ` + `true false`, }) @@ -293,7 +293,7 @@ func TestInsertShardedSimple(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) ins.MultiShardAutocommit = true @@ -309,8 +309,156 @@ func TestInsertShardedSimple(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, // Row 2 will go to -20, rows 1 & 3 will go to 20- `ExecuteMultiShard ` + - `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) suffix {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + - `sharded.-20: prefix(:_id_1 /* INT64 */) suffix {_id_1: type:INT64 value:"2"} ` + + `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + + `sharded.-20: prefix(:_id_1 /* INT64 */) {_id_1: type:INT64 value:"2"} ` + + `true true`, + }) +} + +func TestInsertShardWithONDuplicateKey(t *testing.T) { + invschema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "sharded": { + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "hash", + Columns: []string{"id"}, + }}, + }, + }, + }, + }, + } + vs := vindexes.BuildVSchema(invschema) + ks := vs.Keyspaces["sharded"] + + // A single row insert should be autocommitted + ins := newInsert( + InsertSharded, + false, + ks.Keyspace, + [][][]evalengine.Expr{{ + // colVindex columns: id + { + evalengine.NewLiteralInt(1), + }, + }}, + ks.Tables["t1"], + "prefix", + sqlparser.Values{ + {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + }, + sqlparser.OnDup{ + &sqlparser.UpdateExpr{Name: sqlparser.NewColName("suffix"), Expr: &sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + }, + ) + vc := newDMLTestVCursor("-20", "20-") + vc.shardForKsid = []string{"20-", "-20", "20-"} + + _, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) + if err != nil { + t.Fatal(err) + } + vc.ExpectLog(t, []string{ + // Based on shardForKsid, values returned will be 20-. + `ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, + // Row 2 will go to -20, rows 1 & 3 will go to 20- + `ExecuteMultiShard ` + + `sharded.20-: prefix(:_id_0 /* INT64 */) on duplicate key update suffix = :_id_0 /* INT64 */ {_id_0: type:INT64 value:"1"} ` + + `true true`, + }) + + // Multiple rows are not autocommitted by default + ins = newInsert( + InsertSharded, + false, + ks.Keyspace, + [][][]evalengine.Expr{{ + // colVindex columns: id + // 3 rows. + { + evalengine.NewLiteralInt(1), + evalengine.NewLiteralInt(2), + evalengine.NewLiteralInt(3), + }, + }}, + ks.Tables["t1"], + "prefix", + sqlparser.Values{ + {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}}, + {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}}, + }, + sqlparser.OnDup{ + &sqlparser.UpdateExpr{Name: sqlparser.NewColName("suffix"), Expr: &sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + }, + ) + vc = newDMLTestVCursor("-20", "20-") + vc.shardForKsid = []string{"20-", "-20", "20-"} + + _, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) + if err != nil { + t.Fatal(err) + } + vc.ExpectLog(t, []string{ + // Based on shardForKsid, values returned will be 20-, -20, 20-. + `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, + // Row 2 will go to -20, rows 1 & 3 will go to 20- + `ExecuteMultiShard ` + + `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) on duplicate key update suffix = :_id_0 /* INT64 */ {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + + `sharded.-20: prefix(:_id_1 /* INT64 */) on duplicate key update suffix = :_id_0 /* INT64 */ {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2"} ` + + `true false`, + }) + + // Optional flag overrides autocommit + ins = newInsert( + InsertSharded, + false, + ks.Keyspace, + [][][]evalengine.Expr{{ + // colVindex columns: id + // 3 rows. + { + evalengine.NewLiteralInt(1), + evalengine.NewLiteralInt(2), + evalengine.NewLiteralInt(3), + }, + }}, + + ks.Tables["t1"], + "prefix", + sqlparser.Values{ + {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}}, + {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}}, + }, + sqlparser.OnDup{ + &sqlparser.UpdateExpr{Name: sqlparser.NewColName("suffix"), Expr: &sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, + }, + ) + ins.MultiShardAutocommit = true + + vc = newDMLTestVCursor("-20", "20-") + vc.shardForKsid = []string{"20-", "-20", "20-"} + + _, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) + if err != nil { + t.Fatal(err) + } + vc.ExpectLog(t, []string{ + // Based on shardForKsid, values returned will be 20-, -20, 20-. + `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, + // Row 2 will go to -20, rows 1 & 3 will go to 20- + `ExecuteMultiShard ` + + `sharded.20-: prefix(:_id_0 /* INT64 */),(:_id_2 /* INT64 */) on duplicate key update suffix = :_id_0 /* INT64 */ {_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + + `sharded.-20: prefix(:_id_1 /* INT64 */) on duplicate key update suffix = :_id_0 /* INT64 */ {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2"} ` + `true true`, }) } @@ -360,7 +508,7 @@ func TestInsertShardedFail(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc := &loggingVCursor{} @@ -414,7 +562,7 @@ func TestInsertShardedGenerate(t *testing.T) { {&sqlparser.Argument{Name: "__seq1", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "__seq2", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) ins.Generate = &Generate{ @@ -454,9 +602,9 @@ func TestInsertShardedGenerate(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, // Row 2 will go to -20, rows 1 & 3 will go to 20- `ExecuteMultiShard ` + - `sharded.20-: prefix(:__seq0 /* INT64 */),(:__seq2 /* INT64 */) suffix ` + + `sharded.20-: prefix(:__seq0 /* INT64 */),(:__seq2 /* INT64 */) ` + `{__seq0: type:INT64 value:"1" __seq2: type:INT64 value:"3"} ` + - `sharded.-20: prefix(:__seq1 /* INT64 */) suffix ` + + `sharded.-20: prefix(:__seq1 /* INT64 */) ` + `{__seq1: type:INT64 value:"2"} ` + `true false`, }) @@ -552,7 +700,7 @@ func TestInsertShardedOwned(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_1", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_2", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") @@ -574,12 +722,12 @@ func TestInsertShardedOwned(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + `sharded.20-: prefix(:_id_0 /* INT64 */, :_c1_0 /* INT64 */, :_c2_0 /* INT64 */, :_c3_0 /* INT64 */)` + - `,(:_id_2 /* INT64 */, :_c1_2 /* INT64 */, :_c2_2 /* INT64 */, :_c3_2 /* INT64 */) suffix ` + + `,(:_id_2 /* INT64 */, :_c1_2 /* INT64 */, :_c2_2 /* INT64 */, :_c3_2 /* INT64 */) ` + `{_c1_0: type:INT64 value:"4" _c1_2: type:INT64 value:"6" ` + `_c2_0: type:INT64 value:"7" _c2_2: type:INT64 value:"9" ` + `_c3_0: type:INT64 value:"10" _c3_2: type:INT64 value:"12" ` + `_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + - `sharded.-20: prefix(:_id_1 /* INT64 */, :_c1_1 /* INT64 */, :_c2_1 /* INT64 */, :_c3_1 /* INT64 */) suffix ` + + `sharded.-20: prefix(:_id_1 /* INT64 */, :_c1_1 /* INT64 */, :_c2_1 /* INT64 */, :_c3_1 /* INT64 */) ` + `{_c1_1: type:INT64 value:"5" _c2_1: type:INT64 value:"8" _c3_1: type:INT64 value:"11" ` + `_id_1: type:INT64 value:"2"} ` + `true false`, @@ -644,7 +792,7 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_0", Type: sqltypes.Null}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") @@ -656,7 +804,7 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { } vc.ExpectLog(t, []string{ `ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sharded.20-: prefix(:_id_0 /* INT64 */, :_c3_0 /* NULL_TYPE */) suffix ` + + `ExecuteMultiShard sharded.20-: prefix(:_id_0 /* INT64 */, :_c3_0 /* NULL_TYPE */) ` + `{_c3_0: _id_0: type:INT64 value:"1"} true true`, }) } @@ -730,7 +878,7 @@ func TestInsertShardedGeo(t *testing.T) { {&sqlparser.Argument{Name: "_region_0", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_region_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") @@ -745,9 +893,9 @@ func TestInsertShardedGeo(t *testing.T) { `id_0: type:INT64 value:"1" id_1: type:INT64 value:"1" ` + `keyspace_id_0: type:VARBINARY value:"\x01\x16k@\xb4J\xbaK\xd6" keyspace_id_1: type:VARBINARY value:"\xff\x16k@\xb4J\xbaK\xd6" true`, `ResolveDestinations sharded [value:"0" value:"1"] Destinations:DestinationKeyspaceID(01166b40b44aba4bd6),DestinationKeyspaceID(ff166b40b44aba4bd6)`, - `ExecuteMultiShard sharded.20-: prefix(:_region_0 /* INT64 */, :_id_0 /* INT64 */) suffix ` + + `ExecuteMultiShard sharded.20-: prefix(:_region_0 /* INT64 */, :_id_0 /* INT64 */) ` + `{_id_0: type:INT64 value:"1" _region_0: type:INT64 value:"1"} ` + - `sharded.-20: prefix(:_region_1 /* INT64 */, :_id_1 /* INT64 */) suffix ` + + `sharded.-20: prefix(:_region_1 /* INT64 */, :_id_1 /* INT64 */) ` + `{_id_1: type:INT64 value:"1" _region_1: type:INT64 value:"255"} ` + `true false`, }) @@ -854,7 +1002,7 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_2", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_id_3", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_3", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_3", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_3", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) ksid0Lookup := sqltypes.MakeTestResult( @@ -917,9 +1065,9 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"3"] Destinations:DestinationKeyspaceID(00),DestinationKeyspaceID(00)`, // Bind vars for rows 2 & 3 may be missing because they were not sent. `ExecuteMultiShard ` + - `sharded.20-: prefix(:_id_0 /* INT64 */, :_c1_0 /* INT64 */, :_c2_0 /* INT64 */, :_c3_0 /* INT64 */) suffix ` + + `sharded.20-: prefix(:_id_0 /* INT64 */, :_c1_0 /* INT64 */, :_c2_0 /* INT64 */, :_c3_0 /* INT64 */) ` + `{_c1_0: type:INT64 value:"5" _c2_0: type:INT64 value:"9" _c3_0: type:INT64 value:"13" _id_0: type:INT64 value:"1"} ` + - `sharded.-20: prefix(:_id_3 /* INT64 */, :_c1_3 /* INT64 */, :_c2_3 /* INT64 */, :_c3_3 /* INT64 */) suffix ` + + `sharded.-20: prefix(:_id_3 /* INT64 */, :_c1_3 /* INT64 */, :_c2_3 /* INT64 */, :_c3_3 /* INT64 */) ` + `{_c1_3: type:INT64 value:"8" _c2_3: type:INT64 value:"12" _c3_3: type:INT64 value:"16" _id_3: type:INT64 value:"4"} ` + `true false`, }) @@ -984,7 +1132,7 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_0", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) ksid0 := sqltypes.MakeTestResult( @@ -1009,7 +1157,7 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { vc.ExpectLog(t, []string{ `Execute select from from lkp1 where from = :from and toc = :toc from: toc: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" false`, `ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sharded.-20: prefix(:_id_0 /* INT64 */, :_c3_0 /* INT64 */) suffix ` + + `ExecuteMultiShard sharded.-20: prefix(:_id_0 /* INT64 */, :_c3_0 /* INT64 */) ` + `{_c3_0: _id_0: type:INT64 value:"1"} true true`, }) } @@ -1102,7 +1250,7 @@ func TestInsertShardedUnownedVerify(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_1", Type: sqltypes.Int64}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c2_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_2", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) // nonemptyResult will cause the lookup verify queries to succeed. @@ -1141,12 +1289,12 @@ func TestInsertShardedUnownedVerify(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + `sharded.20-: prefix(:_id_0 /* INT64 */, :_c1_0 /* INT64 */, :_c2_0 /* INT64 */, :_c3_0 /* INT64 */),` + - `(:_id_2 /* INT64 */, :_c1_2 /* INT64 */, :_c2_2 /* INT64 */, :_c3_2 /* INT64 */) suffix ` + + `(:_id_2 /* INT64 */, :_c1_2 /* INT64 */, :_c2_2 /* INT64 */, :_c3_2 /* INT64 */) ` + `{_c1_0: type:INT64 value:"4" _c1_2: type:INT64 value:"6" ` + `_c2_0: type:INT64 value:"7" _c2_2: type:INT64 value:"9" ` + `_c3_0: type:INT64 value:"10" _c3_2: type:INT64 value:"12" ` + `_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + - `sharded.-20: prefix(:_id_1 /* INT64 */, :_c1_1 /* INT64 */, :_c2_1 /* INT64 */, :_c3_1 /* INT64 */) suffix ` + + `sharded.-20: prefix(:_id_1 /* INT64 */, :_c1_1 /* INT64 */, :_c2_1 /* INT64 */, :_c3_1 /* INT64 */) ` + `{_c1_1: type:INT64 value:"5" _c2_1: type:INT64 value:"8" ` + `_c3_1: type:INT64 value:"11" _id_1: type:INT64 value:"2"} ` + `true false`, @@ -1216,7 +1364,7 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "v2", Type: sqltypes.VarChar}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "v3", Type: sqltypes.VarChar}}, }, - " suffix", + nil, ) // nonemptyResult will cause the lookup verify queries to succeed. @@ -1251,9 +1399,9 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { // Based on shardForKsid, values returned will be 20-, -20. `ResolveDestinations sharded [value:"0" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + - `sharded.20-: prefix(:_id_0 /* INT64 */, :_c3_0 /* INT64 */, :v1 /* VARCHAR */) suffix ` + + `sharded.20-: prefix(:_id_0 /* INT64 */, :_c3_0 /* INT64 */, :v1 /* VARCHAR */) ` + `{_c3_0: type:INT64 value:"10" _id_0: type:INT64 value:"1" v1: type:VARCHAR value:"a"} ` + - `sharded.-20: prefix(:_id_2 /* INT64 */, :_c3_2 /* INT64 */, :v3 /* VARCHAR */) suffix ` + + `sharded.-20: prefix(:_id_2 /* INT64 */, :_c3_2 /* INT64 */, :v3 /* VARCHAR */) ` + `{_c3_2: type:INT64 value:"12" _id_2: type:INT64 value:"3" v3: type:VARCHAR value:"c"} ` + `true false`, }) @@ -1316,7 +1464,7 @@ func TestInsertShardedIgnoreUnownedVerifyFail(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_0", Type: sqltypes.Int64}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") @@ -1413,7 +1561,7 @@ func TestInsertShardedUnownedReverseMap(t *testing.T) { {&sqlparser.Argument{Name: "_id_1", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_1", Type: sqltypes.Null}, &sqlparser.Argument{Name: "_c2_1", Type: sqltypes.Null}, &sqlparser.Argument{Name: "_c3_1", Type: sqltypes.Null}}, {&sqlparser.Argument{Name: "_id_2", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c1_2", Type: sqltypes.Null}, &sqlparser.Argument{Name: "_c2_2", Type: sqltypes.Null}, &sqlparser.Argument{Name: "_c3_2", Type: sqltypes.Null}}, }, - " suffix", + nil, ) // nonemptyResult will cause the lookup verify queries to succeed. @@ -1439,13 +1587,13 @@ func TestInsertShardedUnownedReverseMap(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard sharded.20-: ` + `prefix(:_id_0 /* INT64 */, :_c1_0 /* NULL_TYPE */, :_c2_0 /* NULL_TYPE */, :_c3_0 /* NULL_TYPE */),` + - `(:_id_2 /* INT64 */, :_c1_2 /* NULL_TYPE */, :_c2_2 /* NULL_TYPE */, :_c3_2 /* NULL_TYPE */) suffix ` + + `(:_id_2 /* INT64 */, :_c1_2 /* NULL_TYPE */, :_c2_2 /* NULL_TYPE */, :_c3_2 /* NULL_TYPE */) ` + `{_c1_0: type:UINT64 value:"1" _c1_2: type:UINT64 value:"3" ` + `_c2_0: _c2_2: ` + `_c3_0: type:UINT64 value:"1" _c3_2: type:UINT64 value:"3" ` + `_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` + `sharded.-20: ` + - `prefix(:_id_1 /* INT64 */, :_c1_1 /* NULL_TYPE */, :_c2_1 /* NULL_TYPE */, :_c3_1 /* NULL_TYPE */) suffix ` + + `prefix(:_id_1 /* INT64 */, :_c1_1 /* NULL_TYPE */, :_c2_1 /* NULL_TYPE */, :_c3_1 /* NULL_TYPE */) ` + `{_c1_1: type:UINT64 value:"2" _c2_1: _c3_1: type:UINT64 value:"2" _id_1: type:INT64 value:"2"} true false`, }) } @@ -1507,7 +1655,7 @@ func TestInsertShardedUnownedReverseMapSuccess(t *testing.T) { sqlparser.Values{ {&sqlparser.Argument{Name: "_id_0", Type: sqltypes.Int64}, &sqlparser.Argument{Name: "_c3_0", Type: sqltypes.Null}}, }, - " suffix", + nil, ) vc := newDMLTestVCursor("-20", "20-") @@ -1539,7 +1687,7 @@ func TestInsertSelectSimple(t *testing.T) { RoutingParameters: &RoutingParameters{ Opcode: Scatter, Keyspace: ks.Keyspace}} - ins := newInsertSelect(false, ks.Keyspace, ks.Tables["t1"], "prefix ", " suffix", [][]int{{1}}, rb) + ins := newInsertSelect(false, ks.Keyspace, ks.Tables["t1"], "prefix ", nil, [][]int{{1}}, rb) vc := newDMLTestVCursor("-20", "20-") vc.shardForKsid = []string{"20-", "-20", "20-"} @@ -1563,10 +1711,10 @@ func TestInsertSelectSimple(t *testing.T) { // two rows go to the 20- shard, and one row go to the -20 shard `ExecuteMultiShard ` + - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1"` + ` _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` + - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix` + + `sharded.-20: prefix values (:_c1_0, :_c1_1)` + ` {_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} true false`}) vc.Rewind() @@ -1583,10 +1731,10 @@ func TestInsertSelectSimple(t *testing.T) { // two rows go to the 20- shard, and one row go to the -20 shard `ExecuteMultiShard ` + - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1"` + ` _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` + - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix` + + `sharded.-20: prefix values (:_c1_0, :_c1_1)` + ` {_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} true false`}) } @@ -1627,7 +1775,7 @@ func TestInsertSelectOwned(t *testing.T) { ks.Keyspace, ks.Tables["t1"], "prefix ", - " suffix", + nil, [][]int{ {1}, // The primary vindex has a single column as sharding key {0}}, // the onecol vindex uses the 'name' column @@ -1662,11 +1810,11 @@ func TestInsertSelectOwned(t *testing.T) { // insert values into the main table `ExecuteMultiShard ` + // first we insert two rows on the 20- shard - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` + // next we insert one row on the -20 shard - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} ` + `true false`}) @@ -1690,11 +1838,11 @@ func TestInsertSelectOwned(t *testing.T) { // insert values into the main table `ExecuteMultiShard ` + // first we insert two rows on the 20- shard - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` + // next we insert one row on the -20 shard - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} ` + `true false`}) } @@ -1728,7 +1876,7 @@ func TestInsertSelectGenerate(t *testing.T) { ks.Keyspace, ks.Tables["t1"], "prefix ", - " suffix", + nil, [][]int{{1}}, // The primary vindex has a single column as sharding key rb, ) @@ -1776,13 +1924,13 @@ func TestInsertSelectGenerate(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + // first we send the insert to the 20- shard - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" ` + `_c0_1: type:INT64 value:"1" ` + `_c2_0: type:VARCHAR value:"b" ` + `_c2_1: type:INT64 value:"3"} ` + // next we send the insert to the -20 shard - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2"} ` + `true false`, }) @@ -1820,7 +1968,7 @@ func TestStreamingInsertSelectGenerate(t *testing.T) { ks.Keyspace, ks.Tables["t1"], "prefix ", - " suffix", + nil, [][]int{ {1}}, // The primary vindex has a single column as sharding key rb, @@ -1873,13 +2021,13 @@ func TestStreamingInsertSelectGenerate(t *testing.T) { `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + // first we send the insert to the 20- shard - `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) ` + `{_c0_0: type:VARCHAR value:"a" ` + `_c0_1: type:INT64 value:"1" ` + `_c2_0: type:VARCHAR value:"b" ` + `_c2_1: type:INT64 value:"3"} ` + // next we send the insert to the -20 shard - `sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2"} ` + `true false`, }) @@ -1916,7 +2064,7 @@ func TestInsertSelectGenerateNotProvided(t *testing.T) { ks.Keyspace, ks.Tables["t1"], "prefix ", - " suffix", + nil, [][]int{{1}}, // The primary vindex has a single column as sharding key, rb, ) @@ -1963,10 +2111,10 @@ func TestInsertSelectGenerateNotProvided(t *testing.T) { `ExecuteStandalone dummy_generate n: type:INT64 value:"3" ks2 -20`, `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + - `sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c0_2: type:INT64 value:"10" ` + `_c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"3" _c2_2: type:INT64 value:"12"} ` + - `sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2" _c1_2: type:INT64 value:"11"} ` + `true false`, }) @@ -2003,7 +2151,7 @@ func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { ks.Keyspace, ks.Tables["t1"], "prefix ", - " suffix", + nil, [][]int{{1}}, // The primary vindex has a single column as sharding key, rb, ) @@ -2054,10 +2202,10 @@ func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) { `ExecuteStandalone dummy_generate n: type:INT64 value:"3" ks2 -20`, `ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`, `ExecuteMultiShard ` + - `sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) suffix ` + + `sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) ` + `{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c0_2: type:INT64 value:"10" ` + `_c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"3" _c2_2: type:INT64 value:"12"} ` + - `sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) suffix ` + + `sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) ` + `{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2" _c1_2: type:INT64 value:"11"} ` + `true false`, }) @@ -2100,7 +2248,7 @@ func TestInsertSelectUnowned(t *testing.T) { ks.Keyspace, ks.Tables["t2"], "prefix ", - " suffix", + nil, [][]int{{0}}, // // the onecol vindex as unowned lookup sharding column rb, ) @@ -2130,11 +2278,11 @@ func TestInsertSelectUnowned(t *testing.T) { // insert values into the main table `ExecuteMultiShard ` + // first we insert two rows on the 20- shard - `sharded.20-: prefix values (:_c0_0), (:_c2_0) suffix ` + + `sharded.20-: prefix values (:_c0_0), (:_c2_0) ` + `{_c0_0: type:INT64 value:"1" _c2_0: type:INT64 value:"2"} ` + // next we insert one row on the -20 shard - `sharded.-20: prefix values (:_c1_0) suffix ` + + `sharded.-20: prefix values (:_c1_0) ` + `{_c1_0: type:INT64 value:"3"} ` + `true false`}) @@ -2158,11 +2306,11 @@ func TestInsertSelectUnowned(t *testing.T) { // insert values into the main table `ExecuteMultiShard ` + // first we insert two rows on the 20- shard - `sharded.20-: prefix values (:_c0_0), (:_c2_0) suffix ` + + `sharded.20-: prefix values (:_c0_0), (:_c2_0) ` + `{_c0_0: type:INT64 value:"1" _c2_0: type:INT64 value:"2"} ` + // next we insert one row on the -20 shard - `sharded.-20: prefix values (:_c1_0) suffix ` + + `sharded.-20: prefix values (:_c1_0) ` + `{_c1_0: type:INT64 value:"3"} ` + `true false`}) } @@ -2214,7 +2362,7 @@ func TestInsertSelectShardingCases(t *testing.T) { sks1.Keyspace, sks1.Tables["s1"], "prefix ", - " suffix", + nil, [][]int{{0}}, sRoute, ) @@ -2240,7 +2388,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) vc.Rewind() err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error { @@ -2254,7 +2402,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) // sks1 and uks2 ins.Input = uRoute @@ -2269,7 +2417,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) vc.Rewind() err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error { @@ -2283,7 +2431,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`, - `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard sks1.-20: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) // uks1 and sks2 ins = newInsertSelect( @@ -2291,7 +2439,7 @@ func TestInsertSelectShardingCases(t *testing.T) { uks1.Keyspace, nil, "prefix ", - " suffix", + nil, nil, sRoute, ) @@ -2306,7 +2454,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations uks1 [] Destinations:DestinationAllShards()`, - `ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard uks1.0: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) vc.Rewind() err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error { @@ -2320,7 +2468,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations uks1 [] Destinations:DestinationAllShards()`, - `ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard uks1.0: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) // uks1 and uks2 ins.Input = uRoute @@ -2335,7 +2483,7 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations uks1 [] Destinations:DestinationAllShards()`, - `ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard uks1.0: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) vc.Rewind() err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error { @@ -2349,5 +2497,5 @@ func TestInsertSelectShardingCases(t *testing.T) { // the query exec `ResolveDestinations uks1 [] Destinations:DestinationAllShards()`, - `ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`}) + `ExecuteMultiShard uks1.0: prefix values (:_c0_0) {_c0_0: type:INT64 value:"1"} true true`}) } diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 7d3eb05549a..3b117411921 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -590,7 +590,7 @@ func autoIncGenerate(gen *operators.Generate) *engine.Generate { } } -func generateInsertShardedQuery(ins *sqlparser.Insert) (prefix string, mids sqlparser.Values, suffix string) { +func generateInsertShardedQuery(ins *sqlparser.Insert) (prefix string, mids sqlparser.Values, suffix sqlparser.OnDup) { mids, isValues := ins.Rows.(sqlparser.Values) prefixFormat := "insert %v%sinto %v%v " if isValues { @@ -605,9 +605,13 @@ func generateInsertShardedQuery(ins *sqlparser.Insert) (prefix string, mids sqlp ins.Table, ins.Columns) prefix = prefixBuf.String() - suffixBuf := sqlparser.NewTrackedBuffer(dmlFormatter) - suffixBuf.Myprintf("%v", ins.OnDup) - suffix = suffixBuf.String() + suffix = sqlparser.CopyOnRewrite(ins.OnDup, nil, func(cursor *sqlparser.CopyOnWriteCursor) { + if tblName, ok := cursor.Node().(sqlparser.TableName); ok { + if tblName.Qualifier != sqlparser.NewIdentifierCS("") { + cursor.Replace(sqlparser.NewTableName(tblName.Name.String())) + } + } + }, nil).(sqlparser.OnDup) return } diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index ec39db0b158..511ce9fb954 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -4899,5 +4899,33 @@ "comment": "insert row values greater than number of columns", "query": "insert into user(one, two, three) values (1, 2, 3, 4)", "plan": "VT03006: column count does not match value count at row 1" + }, + { + "comment": "insert on duplicate key update with database qualifier", + "query": "insert into user.music(id, user_id, col) values (1, 2, 3) on duplicate key update user.music.col = 5", + "plan": { + "QueryType": "INSERT", + "Original": "insert into user.music(id, user_id, col) values (1, 2, 3) on duplicate key update user.music.col = 5", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Sharded", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "InsertIgnore": true, + "Query": "insert into music(id, user_id, col) values (:_id_0, :_user_id_0, 3) on duplicate key update music.col = 5", + "TableName": "music", + "VindexValues": { + "music_user_map": "1", + "user_index": "2" + } + }, + "TablesUsed": [ + "user.music" + ] + } } + ] From a0239ea3db6367cdd7e40b707404093a94a8293d Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:28:28 -0600 Subject: [PATCH 110/119] Add a retry to remove the vttablet directory during upgrade/downgrade backup tests (#14753) --- .../upgrade_downgrade_test_backups_manual.yml | 1 + ...grade_test_backups_manual_next_release.yml | 1 + examples/backups/stop_tablets.sh | 20 ++++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 039e416cb1c..82d243066e4 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -82,6 +82,7 @@ jobs: - 'config/**' - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_backups_manual.yml' + - 'examples/**' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index e4a9bd11fb3..f00b53c9313 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -85,6 +85,7 @@ jobs: - 'config/**' - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml' + - 'examples/**' - name: Set up Go if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/examples/backups/stop_tablets.sh b/examples/backups/stop_tablets.sh index 6a3ced6ab74..d387128309c 100755 --- a/examples/backups/stop_tablets.sh +++ b/examples/backups/stop_tablets.sh @@ -30,7 +30,25 @@ for tablet in 100 200 300; do CELL=zone1 TABLET_UID=$uid ../common/scripts/mysqlctl-down.sh echo "Removing tablet directory zone1-$uid" vtctldclient DeleteTablets --allow-primary zone1-$uid - rm -Rf $VTDATAROOT/vt_0000000$uid + + for ((i=0; i<30; i++)); do + # Redirect stderr to a temporary file + temp_file=$(mktemp) + rm -Rf $VTDATAROOT/vt_0000000$uid 2>"$temp_file" + + if grep -q 'Directory not empty' "$temp_file"; then + echo "Directory not empty, retrying..." + elif [ ! -s "$temp_file" ]; then + echo "Deletion succeeded." + rm -f "$temp_file" + break + else + echo "An error occurred." + cat "$temp_file" + fi + rm -f "$temp_file" + sleep 1 + done done fi done From 75e06dfaae7acbc0a4e49c970ef73609774d3707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Tue, 12 Dec 2023 08:57:35 +0100 Subject: [PATCH 111/119] Optimise hash joins (#14644) Co-authored-by: Manan Gupta --- .../queries/aggregation/aggregation_test.go | 26 ++ .../operators/aggregation_pushing.go | 436 +++++------------- .../operators/aggregation_pushing_helper.go | 320 +++++++++++++ .../planbuilder/operators/apply_join.go | 84 ++-- .../vtgate/planbuilder/operators/ast_to_op.go | 2 +- .../planbuilder/operators/expressions.go | 4 +- .../vtgate/planbuilder/operators/hash_join.go | 198 ++++++-- .../planbuilder/operators/hash_join_test.go | 2 + .../planbuilder/operators/offset_planning.go | 5 +- .../planbuilder/operators/operator_funcs.go | 102 ---- .../planbuilder/operators/plan_query.go | 11 +- .../planbuilder/operators/projection.go | 10 +- .../planbuilder/operators/query_planning.go | 43 +- .../vtgate/planbuilder/operators/subquery.go | 6 +- .../planbuilder/operators/subquery_builder.go | 8 +- go/vt/vtgate/planbuilder/plan_test.go | 1 + .../planbuilder/testdata/aggr_cases.json | 120 +++++ .../planbuilder/testdata/from_cases.json | 207 ++++++--- 18 files changed, 993 insertions(+), 592 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go delete mode 100644 go/vt/vtgate/planbuilder/operators/operator_funcs.go diff --git a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go index b1123e634e8..e7a55369f8c 100644 --- a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go +++ b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go @@ -417,6 +417,32 @@ func TestAggregateLeftJoin(t *testing.T) { mcmp.AssertMatches("SELECT avg(t1.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(0.5000)]]`) mcmp.AssertMatches("SELECT avg(t2.shardkey) FROM t1 LEFT JOIN t2 ON t1.t1_id = t2.id", `[[DECIMAL(1.0000)]]`) mcmp.AssertMatches("SELECT count(*) FROM t2 LEFT JOIN t1 ON t1.t1_id = t2.id WHERE IFNULL(t1.name, 'NOTSET') = 'r'", `[[INT64(1)]]`) + + aggregations := []string{ + "count(t1.shardkey)", + "count(t2.shardkey)", + "sum(t1.shardkey)", + "sum(t2.shardkey)", + "avg(t1.shardkey)", + "avg(t2.shardkey)", + "count(*)", + } + + grouping := []string{ + "t1.t1_id", + "t1.shardKey", + "t1.value", + "t2.id", + "t2.shardKey", + } + + // quickly construct a big number of left join aggregation queries that have to be executed using the hash join + for _, agg := range aggregations { + for _, gb := range grouping { + query := fmt.Sprintf("SELECT %s FROM t1 LEFT JOIN (select id, shardkey from t2 limit 100) as t2 ON t1.t1_id = t2.id group by %s", agg, gb) + mcmp.Exec(query) + } + } } // TestScalarAggregate tests validates that only count is returned and no additional field is returned.gst diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index b0fdf683121..a1eaf2d18c7 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -25,7 +25,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/vt/vtgate/semantics" ) func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) (output Operator, applyResult *ApplyResult) { @@ -54,7 +53,9 @@ func tryPushAggregator(ctx *plancontext.PlanningContext, aggregator *Aggregator) // if we have a single sharded route, we can push it down output, applyResult = pushAggregationThroughRoute(ctx, aggregator, src) case *ApplyJoin: - output, applyResult = pushAggregationThroughJoin(ctx, aggregator, src) + output, applyResult = pushAggregationThroughApplyJoin(ctx, aggregator, src) + case *HashJoin: + output, applyResult = pushAggregationThroughHashJoin(ctx, aggregator, src) case *Filter: output, applyResult = pushAggregationThroughFilter(ctx, aggregator, src) case *SubQueryContainer: @@ -309,64 +310,46 @@ func exprHasVindex(ctx *plancontext.PlanningContext, expr sqlparser.Expr, hasToB } /* -We push down aggregations using the logic from the paper Orthogonal Optimization of Subqueries and Aggregation, by -Cesar A. Galindo-Legaria and Milind M. Joshi from Microsoft Corp. +Using techniques from "Orthogonal Optimization of Subqueries and Aggregation" by Cesar A. Galindo-Legaria +and Milind M. Joshi (Microsoft Corp), we push down aggregations. It splits an aggregation +into local aggregates depending on one side of a join, and pushes these into the inputs of the join. +These then combine to form the final group by/aggregate query. -It explains how one can split an aggregation into local aggregates that depend on only one side of the join. -The local aggregates can then be gathered together to produce the global -group by/aggregate query that the user asked for. +In Vitess, this technique is extremely useful. It enables pushing aggregations to routes, +even with joins at the vtgate level. Thus, rather than handling all grouping and +aggregation at vtgate, most work is offloaded to MySQL, with vtgate summarizing results. -In Vitess, this is particularly useful because it allows us to push aggregation down to the routes, even when -we have to join the results at the vtgate level. Instead of doing all the grouping and aggregation at the -vtgate level, we can offload most of the work to MySQL, and at the vtgate just summarize the results. +# For a query like: -# For a query, such as - -select count(*) from R1 JOIN R2 on R1.id = R2.id +select count(*) from L JOIN R on L.id = R.id Original: - GB <- This is the original grouping, doing count(*) - | - JOIN + Aggr <- Original grouping, doing count(*) + | + Join / \ - R1 R2 + L R Transformed: - rootAggr <- This grouping is now SUMing together the distributed `count(*)` we got back - | - Proj <- This projection makes sure that the columns are lined up as expected + rootAggr <- New grouping SUMs distributed `count(*)` | - Sort <- Here we are sorting the input so that the OrderedAggregate can do its thing + Proj <- Projection multiplying `count(*)` from each side of the join | - JOIN + Join / \ - lAggr rAggr + lhsAggr rhsAggr <- `count(*)` aggregation can now be pushed under a route / \ - R1 R2 + L R */ -func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin) (Operator, *ApplyResult) { - lhs := &joinPusher{ - orig: rootAggr, - pushed: &Aggregator{ - Source: join.LHS, - QP: rootAggr.QP, - }, - columns: initColReUse(len(rootAggr.Columns)), - tableID: TableID(join.LHS), - } - rhs := &joinPusher{ - orig: rootAggr, - pushed: &Aggregator{ - Source: join.RHS, - QP: rootAggr.QP, - }, - columns: initColReUse(len(rootAggr.Columns)), - tableID: TableID(join.RHS), - } +func pushAggregationThroughApplyJoin(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin) (Operator, *ApplyResult) { + lhs := createJoinPusher(rootAggr, join.LHS) + rhs := createJoinPusher(rootAggr, join.RHS) - joinColumns, output, err := splitAggrColumnsToLeftAndRight(ctx, rootAggr, join, lhs, rhs) + columns := &applyJoinColumns{} + output, err := splitAggrColumnsToLeftAndRight(ctx, rootAggr, join, join.LeftJoin, columns, lhs, rhs) + join.JoinColumns = columns if err != nil { // if we get this error, we just abort the splitting and fall back on simpler ways of solving the same query if errors.Is(err, errAbortAggrPushing) { @@ -375,15 +358,13 @@ func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggr panic(err) } - groupingJCs := splitGroupingToLeftAndRight(ctx, rootAggr, lhs, rhs) - joinColumns = append(joinColumns, groupingJCs...) + splitGroupingToLeftAndRight(ctx, rootAggr, lhs, rhs, join.JoinColumns) // We need to add any columns coming from the lhs of the join to the group by on that side // If we don't, the LHS will not be able to return the column, and it can't be used to send down to the RHS addColumnsFromLHSInJoinPredicates(ctx, rootAggr, join, lhs) join.LHS, join.RHS = lhs.pushed, rhs.pushed - join.JoinColumns = joinColumns if !rootAggr.Original { // we only keep the root aggregation, if this aggregator was created @@ -396,10 +377,82 @@ func pushAggregationThroughJoin(ctx *plancontext.PlanningContext, rootAggr *Aggr return rootAggr, Rewrote("push Aggregation under join") } +// pushAggregationThroughHashJoin pushes aggregation through a hash-join in a similar way to pushAggregationThroughApplyJoin +func pushAggregationThroughHashJoin(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *HashJoin) (Operator, *ApplyResult) { + lhs := createJoinPusher(rootAggr, join.LHS) + rhs := createJoinPusher(rootAggr, join.RHS) + + columns := &hashJoinColumns{} + output, err := splitAggrColumnsToLeftAndRight(ctx, rootAggr, join, join.LeftJoin, columns, lhs, rhs) + if err != nil { + // if we get this error, we just abort the splitting and fall back on simpler ways of solving the same query + if errors.Is(err, errAbortAggrPushing) { + return nil, nil + } + panic(err) + } + + // The two sides of the hash comparisons are added as grouping expressions + for _, cmp := range join.JoinComparisons { + lhs.addGrouping(ctx, NewGroupBy(cmp.LHS, cmp.LHS)) + columns.addLeft(cmp.LHS) + + rhs.addGrouping(ctx, NewGroupBy(cmp.RHS, cmp.RHS)) + columns.addRight(cmp.RHS) + } + + // The grouping columns need to be pushed down as grouping columns on the respective sides + for _, groupBy := range rootAggr.Grouping { + expr, err := rootAggr.QP.GetSimplifiedExpr(ctx, groupBy.Inner) + if err != nil { + panic(err) + } + deps := ctx.SemTable.RecursiveDeps(expr) + switch { + case deps.IsSolvedBy(lhs.tableID): + lhs.addGrouping(ctx, groupBy) + columns.addLeft(expr) + case deps.IsSolvedBy(rhs.tableID): + rhs.addGrouping(ctx, groupBy) + columns.addRight(expr) + case deps.IsSolvedBy(lhs.tableID.Merge(rhs.tableID)): + // TODO: Support this as well + return nil, nil + default: + panic(vterrors.VT13001(fmt.Sprintf("grouping with bad dependencies %s", groupBy.SimplifiedExpr))) + } + } + + join.LHS, join.RHS = lhs.pushed, rhs.pushed + join.columns = columns + + if !rootAggr.Original { + // we only keep the root aggregation, if this aggregator was created + // by splitting one and pushing under a join, we can get rid of this one + return output, Rewrote("push Aggregation under hash join - keep original") + } + + rootAggr.aggregateTheAggregates() + rootAggr.Source = output + return rootAggr, Rewrote("push Aggregation under hash join") +} + var errAbortAggrPushing = fmt.Errorf("abort aggregation pushing") +func createJoinPusher(rootAggr *Aggregator, operator Operator) *joinPusher { + return &joinPusher{ + orig: rootAggr, + pushed: &Aggregator{ + Source: operator, + QP: rootAggr.QP, + }, + columns: initColReUse(len(rootAggr.Columns)), + tableID: TableID(operator), + } +} + func addColumnsFromLHSInJoinPredicates(ctx *plancontext.PlanningContext, rootAggr *Aggregator, join *ApplyJoin, lhs *joinPusher) { - for _, pred := range join.JoinPredicates { + for _, pred := range join.JoinPredicates.columns { for _, bve := range pred.LHSExprs { expr := bve.Expr wexpr, err := rootAggr.QP.GetSimplifiedExpr(ctx, expr) @@ -429,9 +482,12 @@ func addColumnsFromLHSInJoinPredicates(ctx *plancontext.PlanningContext, rootAgg } } -func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Aggregator, lhs, rhs *joinPusher) []JoinColumn { - var groupingJCs []JoinColumn - +func splitGroupingToLeftAndRight( + ctx *plancontext.PlanningContext, + rootAggr *Aggregator, + lhs, rhs *joinPusher, + columns joinColumns, +) { for _, groupBy := range rootAggr.Grouping { expr, err := rootAggr.QP.GetSimplifiedExpr(ctx, groupBy.Inner) if err != nil { @@ -441,16 +497,10 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg switch { case deps.IsSolvedBy(lhs.tableID): lhs.addGrouping(ctx, groupBy) - groupingJCs = append(groupingJCs, JoinColumn{ - Original: expr, - LHSExprs: []BindVarExpr{{Expr: expr}}, - }) + columns.addLeft(expr) case deps.IsSolvedBy(rhs.tableID): rhs.addGrouping(ctx, groupBy) - groupingJCs = append(groupingJCs, JoinColumn{ - Original: expr, - RHSExpr: expr, - }) + columns.addRight(expr) case deps.IsSolvedBy(lhs.tableID.Merge(rhs.tableID)): jc := breakExpressionInLHSandRHSForApplyJoin(ctx, groupBy.SimplifiedExpr, lhs.tableID) for _, lhsExpr := range jc.LHSExprs { @@ -462,7 +512,6 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg panic(vterrors.VT13001(fmt.Sprintf("grouping with bad dependencies %s", groupBy.SimplifiedExpr))) } } - return groupingJCs } // splitAggrColumnsToLeftAndRight pushes all aggregations on the aggregator above a join and @@ -471,16 +520,19 @@ func splitGroupingToLeftAndRight(ctx *plancontext.PlanningContext, rootAggr *Agg func splitAggrColumnsToLeftAndRight( ctx *plancontext.PlanningContext, aggregator *Aggregator, - join *ApplyJoin, + join Operator, + leftJoin bool, + columns joinColumns, lhs, rhs *joinPusher, -) ([]JoinColumn, Operator, error) { +) (Operator, error) { proj := newAliasedProjection(join) proj.FromAggr = true builder := &aggBuilder{ - lhs: lhs, - rhs: rhs, - proj: proj, - outerJoin: join.LeftJoin, + lhs: lhs, + rhs: rhs, + joinColumns: columns, + proj: proj, + outerJoin: leftJoin, } canPushDistinctAggr, distinctExpr := checkIfWeCanPush(ctx, aggregator) @@ -489,7 +541,7 @@ func splitAggrColumnsToLeftAndRight( // We keep node of the distinct aggregation expression to be used later for ordering. if !canPushDistinctAggr { aggregator.DistinctExpr = distinctExpr - return nil, nil, errAbortAggrPushing + return nil, errAbortAggrPushing } outer: @@ -499,203 +551,15 @@ outer: if aggr.ColOffset == colIdx { err := builder.handleAggr(ctx, aggr) if err != nil { - return nil, nil, err + return nil, err } continue outer } } builder.proj.addUnexploredExpr(col, col.Expr) } - return builder.joinColumns, builder.proj, nil -} - -type ( - // aggBuilder is a helper struct that aids in pushing down an Aggregator through a join - // it accumulates the projections (if any) that need to be evaluated on top of the join - aggBuilder struct { - lhs, rhs *joinPusher - joinColumns []JoinColumn - proj *Projection - outerJoin bool - } - // joinPusher is a helper struct that aids in pushing down an Aggregator into one side of a Join. - // It creates a new Aggregator that is pushed down and keeps track of the column dependencies that the new Aggregator has. - joinPusher struct { - orig *Aggregator // The original Aggregator before pushing. - pushed *Aggregator // The new Aggregator created for push-down. - columns []int // List of column offsets used in the new Aggregator. - tableID semantics.TableSet // The TableSet denoting the side of the Join where the new Aggregator is pushed. - - // csAE keeps the copy of the countStar expression that has already been added to split an aggregation. - // No need to have multiple countStars, so we cache it here - csAE *sqlparser.AliasedExpr - } -) - -func (ab *aggBuilder) leftCountStar(ctx *plancontext.PlanningContext) *sqlparser.AliasedExpr { - ae, created := ab.lhs.countStar(ctx) - if created { - ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: ae.Expr, - LHSExprs: []BindVarExpr{{Expr: ae.Expr}}, - }) - } - return ae -} - -func (ab *aggBuilder) rightCountStar(ctx *plancontext.PlanningContext) *sqlparser.AliasedExpr { - ae, created := ab.rhs.countStar(ctx) - if created { - ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: ae.Expr, - RHSExpr: ae.Expr, - }) - } - return ae -} - -func (p *joinPusher) countStar(ctx *plancontext.PlanningContext) (*sqlparser.AliasedExpr, bool) { - if p.csAE != nil { - return p.csAE, false - } - cs := &sqlparser.CountStar{} - ae := aeWrap(cs) - csAggr := NewAggr(opcode.AggregateCountStar, cs, ae, "") - expr := p.addAggr(ctx, csAggr) - p.csAE = aeWrap(expr) - return p.csAE, true -} - -func (ab *aggBuilder) handleAggr(ctx *plancontext.PlanningContext, aggr Aggr) error { - switch aggr.OpCode { - case opcode.AggregateCountStar: - ab.handleCountStar(ctx, aggr) - return nil - case opcode.AggregateCount, opcode.AggregateSum: - return ab.handleAggrWithCountStarMultiplier(ctx, aggr) - case opcode.AggregateMax, opcode.AggregateMin, opcode.AggregateAnyValue: - return ab.handlePushThroughAggregation(ctx, aggr) - case opcode.AggregateGroupConcat: - f := aggr.Func.(*sqlparser.GroupConcatExpr) - if f.Distinct || len(f.OrderBy) > 0 || f.Separator != "" { - panic("fail here") - } - // this needs special handling, currently aborting the push of function - // and later will try pushing the column instead. - // TODO: this should be handled better by pushing the function down. - return errAbortAggrPushing - case opcode.AggregateUnassigned: - return vterrors.VT12001(fmt.Sprintf("in scatter query: aggregation function '%s'", sqlparser.String(aggr.Original))) - case opcode.AggregateGtid: - // this is only used for SHOW GTID queries that will never contain joins - return vterrors.VT13001("cannot do join with vgtid") - case opcode.AggregateSumDistinct, opcode.AggregateCountDistinct: - // we are not going to see values multiple times, so we don't need to multiply with the count(*) from the other side - return ab.handlePushThroughAggregation(ctx, aggr) - default: - return vterrors.VT12001(fmt.Sprintf("aggregation not planned: %s", aggr.OpCode.String())) - } -} - -// pushThroughLeft and Right are used for extremums and random, -// which are not split and then arithmetics is used to aggregate the per-shard aggregations. -// For these, we just copy the aggregation to one side of the join and then pick the max of the max:es returned -func (ab *aggBuilder) pushThroughLeft(aggr Aggr) { - ab.lhs.pushThroughAggr(aggr) - ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: aggr.Original.Expr, - LHSExprs: []BindVarExpr{{Expr: aggr.Original.Expr}}, - }) -} - -func (ab *aggBuilder) pushThroughRight(aggr Aggr) { - ab.rhs.pushThroughAggr(aggr) - ab.joinColumns = append(ab.joinColumns, JoinColumn{ - Original: aggr.Original.Expr, - RHSExpr: aggr.Original.Expr, - }) -} - -func (ab *aggBuilder) handlePushThroughAggregation(ctx *plancontext.PlanningContext, aggr Aggr) error { - ab.proj.addUnexploredExpr(aggr.Original, aggr.Original.Expr) - - deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr) - switch { - case deps.IsSolvedBy(ab.lhs.tableID): - ab.pushThroughLeft(aggr) - case deps.IsSolvedBy(ab.rhs.tableID): - ab.pushThroughRight(aggr) - default: - return errAbortAggrPushing - } - return nil -} - -func (ab *aggBuilder) handleCountStar(ctx *plancontext.PlanningContext, aggr Aggr) { - // Add the aggregate to both sides of the join. - lhsAE := ab.leftCountStar(ctx) - rhsAE := ab.rightCountStar(ctx) - - ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, true) -} - -func (ab *aggBuilder) handleAggrWithCountStarMultiplier(ctx *plancontext.PlanningContext, aggr Aggr) error { - var lhsAE, rhsAE *sqlparser.AliasedExpr - var addCoalesce bool - - deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr) - switch { - case deps.IsSolvedBy(ab.lhs.tableID): - ab.pushThroughLeft(aggr) - lhsAE = aggr.Original - rhsAE = ab.rightCountStar(ctx) - if ab.outerJoin { - addCoalesce = true - } - - case deps.IsSolvedBy(ab.rhs.tableID): - ab.pushThroughRight(aggr) - lhsAE = ab.leftCountStar(ctx) - rhsAE = aggr.Original - - default: - return errAbortAggrPushing - } - ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, addCoalesce) - return nil -} - -func (ab *aggBuilder) buildProjectionForAggr(lhsAE *sqlparser.AliasedExpr, rhsAE *sqlparser.AliasedExpr, aggr Aggr, coalesce bool) { - // We expect the expressions to be different on each side of the join, otherwise it's an error. - if lhsAE.Expr == rhsAE.Expr { - panic(fmt.Sprintf("Need the two produced expressions to be different. %T %T", lhsAE, rhsAE)) - } - - rhsExpr := rhsAE.Expr - - // When dealing with outer joins, we don't want null values from the RHS to ruin the calculations we are doing, - // so we use the MySQL `coalesce` after the join is applied to multiply the count from LHS with 1. - if ab.outerJoin && coalesce { - rhsExpr = coalesceFunc(rhsExpr) - } - - // The final COUNT is obtained by multiplying the counts from both sides. - // This is equivalent to transforming a "select count(*) from t1 join t2" into - // "select count_t1*count_t2 from - // (select count(*) as count_t1 from t1) as x, - // (select count(*) as count_t2 from t2) as y". - projExpr := &sqlparser.BinaryExpr{ - Operator: sqlparser.MultOp, - Left: lhsAE.Expr, - Right: rhsExpr, - } - projAE := &sqlparser.AliasedExpr{ - Expr: aggr.Original.Expr, - As: sqlparser.NewIdentifierCI(aggr.Original.ColumnName()), - } - - ab.proj.addUnexploredExpr(projAE, projExpr) + return builder.proj, nil } func coalesceFunc(e sqlparser.Expr) sqlparser.Expr { @@ -709,64 +573,6 @@ func coalesceFunc(e sqlparser.Expr) sqlparser.Expr { } } -// addAggr creates a copy of the given aggregation, updates its column offset to point to the correct location in the new Aggregator, -// and adds it to the list of Aggregations of the new Aggregator. It also updates the semantic analysis information to reflect the new structure. -// It returns the expression of the aggregation as it should be used in the parent Aggregator. -func (p *joinPusher) addAggr(ctx *plancontext.PlanningContext, aggr Aggr) sqlparser.Expr { - copyAggr := aggr - expr := sqlparser.CloneExpr(aggr.Original.Expr) - copyAggr.Original = aeWrap(expr) - // copy dependencies so we can keep track of which side expressions need to be pushed to - ctx.SemTable.Direct[expr] = p.tableID - ctx.SemTable.Recursive[expr] = p.tableID - copyAggr.ColOffset = len(p.pushed.Columns) - p.pushed.Columns = append(p.pushed.Columns, copyAggr.Original) - p.pushed.Aggregations = append(p.pushed.Aggregations, copyAggr) - return expr -} - -// pushThroughAggr pushes through an aggregation without changing dependencies. -// Can be used for aggregations we can push in one piece -func (p *joinPusher) pushThroughAggr(aggr Aggr) { - newAggr := NewAggr(aggr.OpCode, aggr.Func, aggr.Original, aggr.Alias) - newAggr.ColOffset = len(p.pushed.Columns) - p.pushed.Columns = append(p.pushed.Columns, newAggr.Original) - p.pushed.Aggregations = append(p.pushed.Aggregations, newAggr) -} - -// addGrouping creates a copy of the given GroupBy, updates its column offset to point to the correct location in the new Aggregator, -// and adds it to the list of GroupBy expressions of the new Aggregator. It also updates the semantic analysis information to reflect the new structure. -// It returns the expression of the GroupBy as it should be used in the parent Aggregator. -func (p *joinPusher) addGrouping(ctx *plancontext.PlanningContext, gb GroupBy) sqlparser.Expr { - copyGB := gb - expr := sqlparser.CloneExpr(gb.Inner) - // copy dependencies so we can keep track of which side expressions need to be pushed to - ctx.SemTable.CopyDependencies(gb.Inner, expr) - // if the column exists in the selection then copy it down to the pushed aggregator operator. - if copyGB.ColOffset != -1 { - offset := p.useColumn(copyGB.ColOffset) - copyGB.ColOffset = offset - } else { - copyGB.ColOffset = len(p.pushed.Columns) - p.pushed.Columns = append(p.pushed.Columns, aeWrap(copyGB.Inner)) - } - p.pushed.Grouping = append(p.pushed.Grouping, copyGB) - return expr -} - -// useColumn checks whether the column corresponding to the given offset has been used in the new Aggregator. -// If it has not been used before, it adds the column to the new Aggregator -// and updates the columns mapping to reflect the new location of the column. -// It returns the offset of the column in the new Aggregator. -func (p *joinPusher) useColumn(offset int) int { - if p.columns[offset] == -1 { - p.columns[offset] = len(p.pushed.Columns) - // still haven't used this expression on this side - p.pushed.Columns = append(p.pushed.Columns, p.orig.Columns[offset]) - } - return p.columns[offset] -} - func initColReUse(size int) []int { cols := make([]int, size) for i := 0; i < size; i++ { diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go new file mode 100644 index 00000000000..81b1faf1d72 --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go @@ -0,0 +1,320 @@ +/* +Copyright 2023 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 operators + +import ( + "fmt" + "slices" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/engine/opcode" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" +) + +type ( + // aggBuilder is a helper struct that aids in pushing down an Aggregator through a join + // it accumulates the projections (if any) that need to be evaluated on top of the join + aggBuilder struct { + lhs, rhs *joinPusher + joinColumns joinColumns + proj *Projection + outerJoin bool + } + + // joinPusher is a helper struct that aids in pushing down an Aggregator into one side of a Join. + // It creates a new Aggregator that is pushed down and keeps track of the column dependencies that the new Aggregator has. + joinPusher struct { + orig *Aggregator // The original Aggregator before pushing. + pushed *Aggregator // The new Aggregator created for push-down. + columns []int // List of column offsets used in the new Aggregator. + tableID semantics.TableSet // The TableSet denoting the side of the Join where the new Aggregator is pushed. + + // csAE keeps the copy of the countStar expression that has already been added to split an aggregation. + // No need to have multiple countStars, so we cache it here + csAE *sqlparser.AliasedExpr + } + + joinColumns interface { + addLeft(expr sqlparser.Expr) + addRight(expr sqlparser.Expr) + } + + applyJoinColumns struct { + columns []applyJoinColumn + } + + hashJoinColumns struct { + columns []hashJoinColumn + } +) + +func (jc *applyJoinColumns) addLeft(expr sqlparser.Expr) { + jc.columns = append(jc.columns, applyJoinColumn{ + Original: expr, + LHSExprs: []BindVarExpr{{Expr: expr}}, + }) +} + +func (jc *applyJoinColumns) addRight(expr sqlparser.Expr) { + jc.columns = append(jc.columns, applyJoinColumn{ + Original: expr, + RHSExpr: expr, + }) +} + +func (jc *applyJoinColumns) clone() *applyJoinColumns { + return &applyJoinColumns{columns: slices.Clone(jc.columns)} +} + +func (jc *applyJoinColumns) add(col applyJoinColumn) { + jc.columns = append(jc.columns, col) +} + +func (hj *hashJoinColumns) addLeft(expr sqlparser.Expr) { + hj.columns = append(hj.columns, hashJoinColumn{ + expr: expr, + side: Left, + }) +} + +func (hj *hashJoinColumns) add(expr sqlparser.Expr) { + hj.columns = append(hj.columns, hashJoinColumn{ + expr: expr, + }) +} + +func (hj *hashJoinColumns) addRight(expr sqlparser.Expr) { + hj.columns = append(hj.columns, hashJoinColumn{ + expr: expr, + side: Right, + }) +} + +func (hj *hashJoinColumns) clone() *hashJoinColumns { + return &hashJoinColumns{columns: slices.Clone(hj.columns)} +} + +func (ab *aggBuilder) leftCountStar(ctx *plancontext.PlanningContext) *sqlparser.AliasedExpr { + ae, created := ab.lhs.countStar(ctx) + if created { + ab.joinColumns.addLeft(ae.Expr) + } + return ae +} + +func (ab *aggBuilder) rightCountStar(ctx *plancontext.PlanningContext) *sqlparser.AliasedExpr { + ae, created := ab.rhs.countStar(ctx) + if created { + ab.joinColumns.addRight(ae.Expr) + } + return ae +} + +func (ab *aggBuilder) handleAggr(ctx *plancontext.PlanningContext, aggr Aggr) error { + switch aggr.OpCode { + case opcode.AggregateCountStar: + ab.handleCountStar(ctx, aggr) + return nil + case opcode.AggregateCount, opcode.AggregateSum: + return ab.handleAggrWithCountStarMultiplier(ctx, aggr) + case opcode.AggregateMax, opcode.AggregateMin, opcode.AggregateAnyValue: + return ab.handlePushThroughAggregation(ctx, aggr) + case opcode.AggregateGroupConcat: + f := aggr.Func.(*sqlparser.GroupConcatExpr) + if f.Distinct || len(f.OrderBy) > 0 || f.Separator != "" { + panic("fail here") + } + // this needs special handling, currently aborting the push of function + // and later will try pushing the column instead. + // TODO: this should be handled better by pushing the function down. + return errAbortAggrPushing + case opcode.AggregateUnassigned: + return vterrors.VT12001(fmt.Sprintf("in scatter query: aggregation function '%s'", sqlparser.String(aggr.Original))) + case opcode.AggregateGtid: + // this is only used for SHOW GTID queries that will never contain joins + return vterrors.VT13001("cannot do join with vgtid") + case opcode.AggregateSumDistinct, opcode.AggregateCountDistinct: + // we are not going to see values multiple times, so we don't need to multiply with the count(*) from the other side + return ab.handlePushThroughAggregation(ctx, aggr) + default: + return vterrors.VT12001(fmt.Sprintf("aggregation not planned: %s", aggr.OpCode.String())) + } +} + +// pushThroughLeft and Right are used for extremums and random, +// which are not split and then arithmetics is used to aggregate the per-shard aggregations. +// For these, we just copy the aggregation to one side of the join and then pick the max of the max:es returned +func (ab *aggBuilder) pushThroughLeft(aggr Aggr) { + ab.lhs.pushThroughAggr(aggr) + ab.joinColumns.addLeft(aggr.Original.Expr) +} + +func (ab *aggBuilder) pushThroughRight(aggr Aggr) { + ab.rhs.pushThroughAggr(aggr) + ab.joinColumns.addRight(aggr.Original.Expr) +} + +func (ab *aggBuilder) handlePushThroughAggregation(ctx *plancontext.PlanningContext, aggr Aggr) error { + ab.proj.addUnexploredExpr(aggr.Original, aggr.Original.Expr) + + deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr) + switch { + case deps.IsSolvedBy(ab.lhs.tableID): + ab.pushThroughLeft(aggr) + case deps.IsSolvedBy(ab.rhs.tableID): + ab.pushThroughRight(aggr) + default: + return errAbortAggrPushing + } + return nil +} + +func (ab *aggBuilder) handleCountStar(ctx *plancontext.PlanningContext, aggr Aggr) { + // Add the aggregate to both sides of the join. + lhsAE := ab.leftCountStar(ctx) + rhsAE := ab.rightCountStar(ctx) + + ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, true) +} + +func (ab *aggBuilder) handleAggrWithCountStarMultiplier(ctx *plancontext.PlanningContext, aggr Aggr) error { + var lhsAE, rhsAE *sqlparser.AliasedExpr + var addCoalesce bool + + deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr) + switch { + case deps.IsSolvedBy(ab.lhs.tableID): + ab.pushThroughLeft(aggr) + lhsAE = aggr.Original + rhsAE = ab.rightCountStar(ctx) + if ab.outerJoin { + addCoalesce = true + } + + case deps.IsSolvedBy(ab.rhs.tableID): + ab.pushThroughRight(aggr) + lhsAE = ab.leftCountStar(ctx) + rhsAE = aggr.Original + + default: + return errAbortAggrPushing + } + + ab.buildProjectionForAggr(lhsAE, rhsAE, aggr, addCoalesce) + return nil +} + +func (ab *aggBuilder) buildProjectionForAggr(lhsAE *sqlparser.AliasedExpr, rhsAE *sqlparser.AliasedExpr, aggr Aggr, coalesce bool) { + // We expect the expressions to be different on each side of the join, otherwise it's an error. + if lhsAE.Expr == rhsAE.Expr { + panic(fmt.Sprintf("Need the two produced expressions to be different. %T %T", lhsAE, rhsAE)) + } + + rhsExpr := rhsAE.Expr + + // When dealing with outer joins, we don't want null values from the RHS to ruin the calculations we are doing, + // so we use the MySQL `coalesce` after the join is applied to multiply the count from LHS with 1. + if ab.outerJoin && coalesce { + rhsExpr = coalesceFunc(rhsExpr) + } + + // The final COUNT is obtained by multiplying the counts from both sides. + // This is equivalent to transforming a "select count(*) from t1 join t2" into + // "select count_t1*count_t2 from + // (select count(*) as count_t1 from t1) as x, + // (select count(*) as count_t2 from t2) as y". + projExpr := &sqlparser.BinaryExpr{ + Operator: sqlparser.MultOp, + Left: lhsAE.Expr, + Right: rhsExpr, + } + projAE := &sqlparser.AliasedExpr{ + Expr: aggr.Original.Expr, + As: sqlparser.NewIdentifierCI(aggr.Original.ColumnName()), + } + + ab.proj.addUnexploredExpr(projAE, projExpr) +} + +func (p *joinPusher) countStar(ctx *plancontext.PlanningContext) (*sqlparser.AliasedExpr, bool) { + if p.csAE != nil { + return p.csAE, false + } + cs := &sqlparser.CountStar{} + ae := aeWrap(cs) + csAggr := NewAggr(opcode.AggregateCountStar, cs, ae, "") + expr := p.addAggr(ctx, csAggr) + p.csAE = aeWrap(expr) + return p.csAE, true +} + +// addAggr creates a copy of the given aggregation, updates its column offset to point to the correct location in the new Aggregator, +// and adds it to the list of Aggregations of the new Aggregator. It also updates the semantic analysis information to reflect the new structure. +// It returns the expression of the aggregation as it should be used in the parent Aggregator. +func (p *joinPusher) addAggr(ctx *plancontext.PlanningContext, aggr Aggr) sqlparser.Expr { + copyAggr := aggr + expr := sqlparser.CloneExpr(aggr.Original.Expr) + copyAggr.Original = aeWrap(expr) + // copy dependencies so we can keep track of which side expressions need to be pushed to + ctx.SemTable.Direct[expr] = p.tableID + ctx.SemTable.Recursive[expr] = p.tableID + copyAggr.ColOffset = len(p.pushed.Columns) + p.pushed.Columns = append(p.pushed.Columns, copyAggr.Original) + p.pushed.Aggregations = append(p.pushed.Aggregations, copyAggr) + return expr +} + +// pushThroughAggr pushes through an aggregation without changing dependencies. +// Can be used for aggregations we can push in one piece +func (p *joinPusher) pushThroughAggr(aggr Aggr) { + newAggr := NewAggr(aggr.OpCode, aggr.Func, aggr.Original, aggr.Alias) + newAggr.ColOffset = len(p.pushed.Columns) + p.pushed.Columns = append(p.pushed.Columns, newAggr.Original) + p.pushed.Aggregations = append(p.pushed.Aggregations, newAggr) +} + +// addGrouping creates a copy of the given GroupBy, updates its column offset to point to the correct location in the new Aggregator, +// and adds it to the list of GroupBy expressions of the new Aggregator. It also updates the semantic analysis information to reflect the new structure. +// It returns the expression of the GroupBy as it should be used in the parent Aggregator. +func (p *joinPusher) addGrouping(ctx *plancontext.PlanningContext, gb GroupBy) sqlparser.Expr { + copyGB := gb + expr := sqlparser.CloneExpr(gb.Inner) + // copy dependencies so we can keep track of which side expressions need to be pushed to + ctx.SemTable.CopyDependencies(gb.Inner, expr) + // if the column exists in the selection then copy it down to the pushed aggregator operator. + if copyGB.ColOffset != -1 { + offset := p.useColumn(copyGB.ColOffset) + copyGB.ColOffset = offset + } else { + copyGB.ColOffset = len(p.pushed.Columns) + p.pushed.Columns = append(p.pushed.Columns, aeWrap(copyGB.Inner)) + } + p.pushed.Grouping = append(p.pushed.Grouping, copyGB) + return expr +} + +// useColumn checks whether the column corresponding to the given offset has been used in the new Aggregator. +// If it has not been used before, it adds the column to the new Aggregator +// and updates the columns mapping to reflect the new location of the column. +// It returns the offset of the column in the new Aggregator. +func (p *joinPusher) useColumn(offset int) int { + if p.columns[offset] == -1 { + p.columns[offset] = len(p.pushed.Columns) + // still haven't used this expression on this side + p.pushed.Columns = append(p.pushed.Columns, p.orig.Columns[offset]) + } + return p.columns[offset] +} diff --git a/go/vt/vtgate/planbuilder/operators/apply_join.go b/go/vt/vtgate/planbuilder/operators/apply_join.go index 7e2c100c944..b3838ea3e87 100644 --- a/go/vt/vtgate/planbuilder/operators/apply_join.go +++ b/go/vt/vtgate/planbuilder/operators/apply_join.go @@ -41,10 +41,10 @@ type ( Predicate sqlparser.Expr // JoinColumns keeps track of what AST expression is represented in the Columns array - JoinColumns []JoinColumn + JoinColumns *applyJoinColumns // JoinPredicates are join predicates that have been broken up into left hand side and right hand side parts. - JoinPredicates []JoinColumn + JoinPredicates *applyJoinColumns // ExtraVars are columns we need to copy from left to right not needed by any predicates or projections, // these are needed by other operators further down the right hand side of the join @@ -60,7 +60,7 @@ type ( Vars map[string]int } - // JoinColumn is where we store information about columns passing through the join operator + // applyJoinColumn is where we store information about columns passing through the join operator // It can be in one of three possible configurations: // - Pure left // We are projecting a column that comes from the left. The RHSExpr will be nil for these @@ -70,7 +70,7 @@ type ( // Here we need to transmit columns from the LHS to the RHS, // so they can be used for the result of this expression that is using data from both sides. // All fields will be used for these - JoinColumn struct { + applyJoinColumn struct { Original sqlparser.Expr // this is the original expression being passed through LHSExprs []BindVarExpr RHSExpr sqlparser.Expr @@ -87,11 +87,13 @@ type ( func NewApplyJoin(lhs, rhs Operator, predicate sqlparser.Expr, leftOuterJoin bool) *ApplyJoin { return &ApplyJoin{ - LHS: lhs, - RHS: rhs, - Vars: map[string]int{}, - Predicate: predicate, - LeftJoin: leftOuterJoin, + LHS: lhs, + RHS: rhs, + Vars: map[string]int{}, + Predicate: predicate, + LeftJoin: leftOuterJoin, + JoinColumns: &applyJoinColumns{}, + JoinPredicates: &applyJoinColumns{}, } } @@ -101,8 +103,8 @@ func (aj *ApplyJoin) Clone(inputs []Operator) Operator { kopy.LHS = inputs[0] kopy.RHS = inputs[1] kopy.Columns = slices.Clone(aj.Columns) - kopy.JoinColumns = slices.Clone(aj.JoinColumns) - kopy.JoinPredicates = slices.Clone(aj.JoinPredicates) + kopy.JoinColumns = aj.JoinColumns.clone() + kopy.JoinPredicates = aj.JoinPredicates.clone() kopy.Vars = maps.Clone(aj.Vars) kopy.Predicate = sqlparser.CloneExpr(aj.Predicate) kopy.ExtraLHSVars = slices.Clone(aj.ExtraLHSVars) @@ -151,7 +153,7 @@ func (aj *ApplyJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sql aj.Predicate = ctx.SemTable.AndExpressions(expr, aj.Predicate) col := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, TableID(aj.LHS)) - aj.JoinPredicates = append(aj.JoinPredicates, col) + aj.JoinPredicates.add(col) rhs := aj.RHS.AddPredicate(ctx, col.RHSExpr) aj.RHS = rhs } @@ -162,7 +164,9 @@ func (aj *ApplyJoin) pushColRight(ctx *plancontext.PlanningContext, e *sqlparser } func (aj *ApplyJoin) GetColumns(*plancontext.PlanningContext) []*sqlparser.AliasedExpr { - return slice.Map(aj.JoinColumns, joinColumnToAliasedExpr) + return slice.Map(aj.JoinColumns.columns, func(from applyJoinColumn) *sqlparser.AliasedExpr { + return aeWrap(from.Original) + }) } func (aj *ApplyJoin) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { @@ -173,15 +177,11 @@ func (aj *ApplyJoin) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { return aj.LHS.GetOrdering(ctx) } -func joinColumnToAliasedExpr(c JoinColumn) *sqlparser.AliasedExpr { - return aeWrap(c.Original) -} - -func joinColumnToExpr(column JoinColumn) sqlparser.Expr { +func joinColumnToExpr(column applyJoinColumn) sqlparser.Expr { return column.Original } -func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sqlparser.AliasedExpr, e sqlparser.Expr, addToGroupBy bool) (col JoinColumn) { +func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sqlparser.AliasedExpr, e sqlparser.Expr, addToGroupBy bool) (col applyJoinColumn) { defer func() { col.Original = orig.Expr }() @@ -205,12 +205,14 @@ func (aj *ApplyJoin) getJoinColumnFor(ctx *plancontext.PlanningContext, orig *sq return } -func (aj *ApplyJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, _ bool) int { - offset, found := canReuseColumn(ctx, aj.JoinColumns, expr, joinColumnToExpr) - if !found { - return -1 +func applyJoinCompare(ctx *plancontext.PlanningContext, expr sqlparser.Expr) func(e applyJoinColumn) bool { + return func(e applyJoinColumn) bool { + return ctx.SemTable.EqualsExprWithDeps(e.Original, expr) } - return offset +} + +func (aj *ApplyJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, _ bool) int { + return slices.IndexFunc(aj.JoinColumns.columns, applyJoinCompare(ctx, expr)) } func (aj *ApplyJoin) AddColumn( @@ -226,14 +228,14 @@ func (aj *ApplyJoin) AddColumn( } } col := aj.getJoinColumnFor(ctx, expr, expr.Expr, groupBy) - offset := len(aj.JoinColumns) - aj.JoinColumns = append(aj.JoinColumns, col) + offset := len(aj.JoinColumns.columns) + aj.JoinColumns.add(col) return offset } func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { - for _, col := range aj.JoinColumns { - // Read the type description for JoinColumn to understand the following code + for _, col := range aj.JoinColumns.columns { + // Read the type description for applyJoinColumn to understand the following code for _, lhsExpr := range col.LHSExprs { offset := aj.LHS.AddColumn(ctx, true, col.GroupBy, aeWrap(lhsExpr.Expr)) if col.RHSExpr == nil { @@ -249,7 +251,7 @@ func (aj *ApplyJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { } } - for _, col := range aj.JoinPredicates { + for _, col := range aj.JoinPredicates.columns { for _, lhsExpr := range col.LHSExprs { offset := aj.LHS.AddColumn(ctx, true, false, aeWrap(lhsExpr.Expr)) aj.Vars[lhsExpr.Name] = offset @@ -270,7 +272,7 @@ func (aj *ApplyJoin) addOffset(offset int) { func (aj *ApplyJoin) ShortDescription() string { pred := sqlparser.String(aj.Predicate) - columns := slice.Map(aj.JoinColumns, func(from JoinColumn) string { + columns := slice.Map(aj.JoinColumns.columns, func(from applyJoinColumn) string { return sqlparser.String(from.Original) }) firstPart := fmt.Sprintf("on %s columns: %s", pred, strings.Join(columns, ", ")) @@ -283,14 +285,14 @@ func (aj *ApplyJoin) ShortDescription() string { } func (aj *ApplyJoin) isColNameMovedFromL2R(bindVarName string) bool { - for _, jc := range aj.JoinColumns { + for _, jc := range aj.JoinColumns.columns { for _, bve := range jc.LHSExprs { if bve.Name == bindVarName { return true } } } - for _, jp := range aj.JoinPredicates { + for _, jp := range aj.JoinPredicates.columns { for _, bve := range jp.LHSExprs { if bve.Name == bindVarName { return true @@ -306,9 +308,9 @@ func (aj *ApplyJoin) isColNameMovedFromL2R(bindVarName string) bool { } // findOrAddColNameBindVarName goes through the JoinColumns and looks for the given colName coming from the LHS of the join -// and returns the argument name if found. if it's not found, a new JoinColumn passing this through will be added +// and returns the argument name if found. if it's not found, a new applyJoinColumn passing this through will be added func (aj *ApplyJoin) findOrAddColNameBindVarName(ctx *plancontext.PlanningContext, col *sqlparser.ColName) (string, error) { - for i, thisCol := range aj.JoinColumns { + for i, thisCol := range aj.JoinColumns.columns { idx := slices.IndexFunc(thisCol.LHSExprs, func(e BindVarExpr) bool { return ctx.SemTable.EqualsExpr(e.Expr, col) }) @@ -320,12 +322,12 @@ func (aj *ApplyJoin) findOrAddColNameBindVarName(ctx *plancontext.PlanningContex expr := thisCol.LHSExprs[idx] bvname := ctx.GetReservedArgumentFor(expr.Expr) expr.Name = bvname - aj.JoinColumns[i].LHSExprs[idx] = expr + aj.JoinColumns.columns[i].LHSExprs[idx] = expr } return thisCol.LHSExprs[idx].Name, nil } } - for _, thisCol := range aj.JoinPredicates { + for _, thisCol := range aj.JoinPredicates.columns { idx := slices.IndexFunc(thisCol.LHSExprs, func(e BindVarExpr) bool { return ctx.SemTable.EqualsExpr(e.Expr, col) }) @@ -354,25 +356,25 @@ func (a *ApplyJoin) LHSColumnsNeeded(ctx *plancontext.PlanningContext) (needed s f := func(from BindVarExpr) sqlparser.Expr { return from.Expr } - for _, jc := range a.JoinColumns { + for _, jc := range a.JoinColumns.columns { needed = append(needed, slice.Map(jc.LHSExprs, f)...) } - for _, jc := range a.JoinPredicates { + for _, jc := range a.JoinPredicates.columns { needed = append(needed, slice.Map(jc.LHSExprs, f)...) } needed = append(needed, slice.Map(a.ExtraLHSVars, f)...) return ctx.SemTable.Uniquify(needed) } -func (jc JoinColumn) IsPureLeft() bool { +func (jc applyJoinColumn) IsPureLeft() bool { return jc.RHSExpr == nil } -func (jc JoinColumn) IsPureRight() bool { +func (jc applyJoinColumn) IsPureRight() bool { return len(jc.LHSExprs) == 0 } -func (jc JoinColumn) IsMixedLeftAndRight() bool { +func (jc applyJoinColumn) IsMixedLeftAndRight() bool { return len(jc.LHSExprs) > 0 && jc.RHSExpr != nil } diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index be296d54218..6e037981ced 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -134,7 +134,7 @@ func checkForCorrelatedSubqueries( type joinPredicateCollector struct { predicates sqlparser.Exprs remainingPredicates sqlparser.Exprs - joinColumns []JoinColumn + joinColumns []applyJoinColumn totalID, subqID, diff --git a/go/vt/vtgate/planbuilder/operators/expressions.go b/go/vt/vtgate/planbuilder/operators/expressions.go index 65600155631..35008a3c4ab 100644 --- a/go/vt/vtgate/planbuilder/operators/expressions.go +++ b/go/vt/vtgate/planbuilder/operators/expressions.go @@ -28,10 +28,10 @@ func breakExpressionInLHSandRHSForApplyJoin( ctx *plancontext.PlanningContext, expr sqlparser.Expr, lhs semantics.TableSet, -) (col JoinColumn) { +) (col applyJoinColumn) { rewrittenExpr := sqlparser.CopyOnRewrite(expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) { nodeExpr, ok := cursor.Node().(sqlparser.Expr) - if !ok || !fetchByOffset(nodeExpr) { + if !ok || !mustFetchFromInput(nodeExpr) { return } deps := ctx.SemTable.RecursiveDeps(nodeExpr) diff --git a/go/vt/vtgate/planbuilder/operators/hash_join.go b/go/vt/vtgate/planbuilder/operators/hash_join.go index ce23e510c09..fed0633fbe3 100644 --- a/go/vt/vtgate/planbuilder/operators/hash_join.go +++ b/go/vt/vtgate/planbuilder/operators/hash_join.go @@ -42,7 +42,7 @@ type ( // These columns are the output columns of the hash join. While in operator mode we keep track of complex expression, // but once we move to the engine primitives, the hash join only passes through column from either left or right. // anything more complex will be solved by a projection on top of the hash join - columns []sqlparser.Expr + columns *hashJoinColumns // After offset planning @@ -59,6 +59,19 @@ type ( Comparison struct { LHS, RHS sqlparser.Expr } + + hashJoinColumn struct { + side joinSide + expr sqlparser.Expr + } + + joinSide int +) + +const ( + Unknown joinSide = iota + Left + Right ) var _ Operator = (*HashJoin)(nil) @@ -69,6 +82,7 @@ func NewHashJoin(lhs, rhs Operator, outerJoin bool) *HashJoin { LHS: lhs, RHS: rhs, LeftJoin: outerJoin, + columns: &hashJoinColumns{}, } return hj } @@ -76,9 +90,10 @@ func NewHashJoin(lhs, rhs Operator, outerJoin bool) *HashJoin { func (hj *HashJoin) Clone(inputs []Operator) Operator { kopy := *hj kopy.LHS, kopy.RHS = inputs[0], inputs[1] - kopy.columns = slices.Clone(hj.columns) + kopy.columns = hj.columns.clone() kopy.LHSKeys = slices.Clone(hj.LHSKeys) kopy.RHSKeys = slices.Clone(hj.RHSKeys) + kopy.JoinComparisons = slices.Clone(hj.JoinComparisons) return &kopy } @@ -102,8 +117,8 @@ func (hj *HashJoin) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bo } } - hj.columns = append(hj.columns, expr.Expr) - return len(hj.columns) - 1 + hj.columns.add(expr.Expr) + return len(hj.columns.columns) - 1 } func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { @@ -118,18 +133,40 @@ func (hj *HashJoin) planOffsets(ctx *plancontext.PlanningContext) Operator { hj.RHSKeys = append(hj.RHSKeys, rOffset) } - eexprs := slice.Map(hj.columns, func(in sqlparser.Expr) *ProjExpr { - return hj.addColumn(ctx, in) + needsProj := false + lID := TableID(hj.LHS) + rID := TableID(hj.RHS) + eexprs := slice.Map(hj.columns.columns, func(in hashJoinColumn) *ProjExpr { + var column *ProjExpr + var pureOffset bool + + switch in.side { + case Unknown: + column, pureOffset = hj.addColumn(ctx, in.expr) + case Left: + column, pureOffset = hj.addSingleSidedColumn(ctx, in.expr, lID, hj.LHS, lhsOffset) + case Right: + column, pureOffset = hj.addSingleSidedColumn(ctx, in.expr, rID, hj.RHS, rhsOffset) + default: + panic("not expected") + } + if !pureOffset { + needsProj = true + } + return column }) + if !needsProj { + return nil + } proj := newAliasedProjection(hj) proj.addProjExpr(eexprs...) return proj } func (hj *HashJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, _ bool) int { - for offset, col := range hj.columns { - if ctx.SemTable.EqualsExprWithDeps(expr, col) { + for offset, col := range hj.columns.columns { + if ctx.SemTable.EqualsExprWithDeps(expr, col.expr) { return offset } } @@ -137,7 +174,9 @@ func (hj *HashJoin) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Exp } func (hj *HashJoin) GetColumns(*plancontext.PlanningContext) []*sqlparser.AliasedExpr { - return slice.Map(hj.columns, aeWrap) + return slice.Map(hj.columns.columns, func(from hashJoinColumn) *sqlparser.AliasedExpr { + return aeWrap(from.expr) + }) } func (hj *HashJoin) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { @@ -150,8 +189,20 @@ func (hj *HashJoin) ShortDescription() string { }) cmp := strings.Join(comparisons, " AND ") - if len(hj.columns) > 0 { - return fmt.Sprintf("%s columns %v", cmp, hj.columns) + if len(hj.columns.columns) > 0 { + cols := slice.Map(hj.columns.columns, func(from hashJoinColumn) (result string) { + switch from.side { + case Unknown: + result = "U" + case Left: + result = "L" + case Right: + result = "R" + } + result += fmt.Sprintf("(%s)", sqlparser.String(from.expr)) + return + }) + return fmt.Sprintf("%s columns [%v]", cmp, strings.Join(cols, ", ")) } return cmp @@ -224,10 +275,11 @@ func canBeSolvedWithHashJoin(op sqlparser.ComparisonExprOperator) bool { func (c Comparison) String() string { return sqlparser.String(c.LHS) + " = " + sqlparser.String(c.RHS) } - -func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Expr) *ProjExpr { +func lhsOffset(i int) int { return (i * -1) - 1 } +func rhsOffset(i int) int { return i + 1 } +func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Expr) (*ProjExpr, bool) { lId, rId := TableID(hj.LHS), TableID(hj.RHS) - var replaceExpr sqlparser.Expr // this is the expression we will put in instead of whatever we find there + r := new(replacer) // this is the expression we will put in instead of whatever we find there pre := func(node, parent sqlparser.SQLNode) bool { expr, ok := node.(sqlparser.Expr) if !ok { @@ -240,7 +292,7 @@ func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Exp } inOffset := op.FindCol(ctx, expr, false) if inOffset == -1 { - if !fetchByOffset(expr) { + if !mustFetchFromInput(expr) { return -1 } @@ -265,34 +317,20 @@ func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Exp return len(hj.ColumnOffsets) - 1 } - f := func(i int) int { return (i * -1) - 1 } - if lOffset := check(lId, hj.LHS, f); lOffset >= 0 { - replaceExpr = sqlparser.NewOffset(lOffset, expr) + if lOffset := check(lId, hj.LHS, lhsOffset); lOffset >= 0 { + r.replaceExpr = sqlparser.NewOffset(lOffset, expr) return false // we want to stop going down the expression tree and start coming back up again } - f = func(i int) int { return i + 1 } - if rOffset := check(rId, hj.RHS, f); rOffset >= 0 { - replaceExpr = sqlparser.NewOffset(rOffset, expr) + if rOffset := check(rId, hj.RHS, rhsOffset); rOffset >= 0 { + r.replaceExpr = sqlparser.NewOffset(rOffset, expr) return false } return true } - post := func(cursor *sqlparser.CopyOnWriteCursor) { - if replaceExpr != nil { - node := cursor.Node() - _, ok := node.(sqlparser.Expr) - if !ok { - panic(fmt.Sprintf("can't replace this node with an expression: %s", sqlparser.String(node))) - } - cursor.Replace(replaceExpr) - replaceExpr = nil - } - } - - rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) + rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, r.post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) cfg := &evalengine.Config{ ResolveType: ctx.SemTable.TypeForExpr, Collation: ctx.SemTable.Collation, @@ -302,12 +340,14 @@ func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Exp panic(err) } + _, isPureOffset := rewrittenExpr.(*sqlparser.Offset) + return &ProjExpr{ Original: aeWrap(in), EvalExpr: rewrittenExpr, ColExpr: rewrittenExpr, Info: &EvalEngine{EExpr: eexpr}, - } + }, isPureOffset } // JoinPredicate produces an AST representation of the join condition this join has @@ -320,3 +360,91 @@ func (hj *HashJoin) JoinPredicate() sqlparser.Expr { }) return sqlparser.AndExpressions(exprs...) } + +type replacer struct { + replaceExpr sqlparser.Expr +} + +func (r *replacer) post(cursor *sqlparser.CopyOnWriteCursor) { + if r.replaceExpr != nil { + node := cursor.Node() + _, ok := node.(sqlparser.Expr) + if !ok { + panic(fmt.Sprintf("can't replace this node with an expression: %s", sqlparser.String(node))) + } + cursor.Replace(r.replaceExpr) + r.replaceExpr = nil + } +} + +func (hj *HashJoin) addSingleSidedColumn( + ctx *plancontext.PlanningContext, + in sqlparser.Expr, + tableID semantics.TableSet, + op Operator, + offsetter func(int) int, +) (*ProjExpr, bool) { + r := new(replacer) + pre := func(node, parent sqlparser.SQLNode) bool { + expr, ok := node.(sqlparser.Expr) + if !ok { + return true + } + deps := ctx.SemTable.RecursiveDeps(expr) + check := func(op Operator) int { + if !deps.IsSolvedBy(tableID) { + return -1 + } + inOffset := op.FindCol(ctx, expr, false) + if inOffset == -1 { + if !mustFetchFromInput(expr) { + return -1 + } + + // aha! this is an expression that we have to get from the input. let's force it in there + inOffset = op.AddColumn(ctx, false, false, aeWrap(expr)) + } + + // we have to turn the incoming offset to an outgoing offset of the columns this operator is exposing + internalOffset := offsetter(inOffset) + + // ok, we have an offset from the input operator. Let's check if we already have it + // in our list of incoming columns + for idx, offset := range hj.ColumnOffsets { + if internalOffset == offset { + return idx + } + } + + hj.ColumnOffsets = append(hj.ColumnOffsets, internalOffset) + + return len(hj.ColumnOffsets) - 1 + } + + if offset := check(op); offset >= 0 { + r.replaceExpr = sqlparser.NewOffset(offset, expr) + return false // we want to stop going down the expression tree and start coming back up again + } + + return true + } + + rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, r.post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) + cfg := &evalengine.Config{ + ResolveType: ctx.SemTable.TypeForExpr, + Collation: ctx.SemTable.Collation, + } + eexpr, err := evalengine.Translate(rewrittenExpr, cfg) + if err != nil { + panic(err) + } + + _, isPureOffset := rewrittenExpr.(*sqlparser.Offset) + + return &ProjExpr{ + Original: aeWrap(in), + EvalExpr: rewrittenExpr, + ColExpr: rewrittenExpr, + Info: &EvalEngine{EExpr: eexpr}, + }, isPureOffset +} diff --git a/go/vt/vtgate/planbuilder/operators/hash_join_test.go b/go/vt/vtgate/planbuilder/operators/hash_join_test.go index 69f21bd4b78..6abe43c05df 100644 --- a/go/vt/vtgate/planbuilder/operators/hash_join_test.go +++ b/go/vt/vtgate/planbuilder/operators/hash_join_test.go @@ -41,6 +41,7 @@ func TestJoinPredicates(t *testing.T) { LHS: lhs, RHS: rhs, LeftJoin: false, + columns: &hashJoinColumns{}, } cmp := &sqlparser.ComparisonExpr{ @@ -91,6 +92,7 @@ func TestOffsetPlanning(t *testing.T) { LHS: lhs, RHS: rhs, LeftJoin: false, + columns: &hashJoinColumns{}, } hj.AddColumn(ctx, true, false, aeWrap(test.expr)) hj.planOffsets(ctx) diff --git a/go/vt/vtgate/planbuilder/operators/offset_planning.go b/go/vt/vtgate/planbuilder/operators/offset_planning.go index 6de7a2be2b0..92c86eaf0ca 100644 --- a/go/vt/vtgate/planbuilder/operators/offset_planning.go +++ b/go/vt/vtgate/planbuilder/operators/offset_planning.go @@ -47,7 +47,8 @@ func planOffsets(ctx *plancontext.PlanningContext, root Operator) Operator { return TopDown(root, TableID, visitor, stopAtRoute) } -func fetchByOffset(e sqlparser.SQLNode) bool { +// mustFetchFromInput returns true for expressions that have to be fetched from the input and cannot be evaluated +func mustFetchFromInput(e sqlparser.SQLNode) bool { switch e.(type) { case *sqlparser.ColName, sqlparser.AggrFunc: return true @@ -167,7 +168,7 @@ func getOffsetRewritingVisitor( return false } - if fetchByOffset(e) { + if mustFetchFromInput(e) { err = notFound(e) return false } diff --git a/go/vt/vtgate/planbuilder/operators/operator_funcs.go b/go/vt/vtgate/planbuilder/operators/operator_funcs.go deleted file mode 100644 index cc3007438fa..00000000000 --- a/go/vt/vtgate/planbuilder/operators/operator_funcs.go +++ /dev/null @@ -1,102 +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 operators - -import ( - "fmt" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" -) - -// RemovePredicate is used when we turn a predicate into a plan operator, -// and the predicate needs to be removed as an AST construct -func RemovePredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr, op Operator) (Operator, error) { - switch op := op.(type) { - case *Route: - newSrc, err := RemovePredicate(ctx, expr, op.Source) - if err != nil { - return nil, err - } - op.Source = newSrc - return op, err - case *ApplyJoin: - isRemoved := false - deps := ctx.SemTable.RecursiveDeps(expr) - if deps.IsSolvedBy(TableID(op.LHS)) { - newSrc, err := RemovePredicate(ctx, expr, op.LHS) - if err != nil { - return nil, err - } - op.LHS = newSrc - isRemoved = true - } - - if deps.IsSolvedBy(TableID(op.RHS)) { - newSrc, err := RemovePredicate(ctx, expr, op.RHS) - if err != nil { - return nil, err - } - op.RHS = newSrc - isRemoved = true - } - - var keep []sqlparser.Expr - for _, e := range sqlparser.SplitAndExpression(nil, op.Predicate) { - if ctx.SemTable.EqualsExprWithDeps(expr, e) { - isRemoved = true - } else { - keep = append(keep, e) - } - } - - if !isRemoved { - return nil, vterrors.VT12001(fmt.Sprintf("remove '%s' predicate on cross-shard join query", sqlparser.String(expr))) - } - - op.Predicate = ctx.SemTable.AndExpressions(keep...) - return op, nil - case *Filter: - idx := -1 - for i, predicate := range op.Predicates { - if ctx.SemTable.EqualsExprWithDeps(predicate, expr) { - idx = i - } - } - if idx == -1 { - // the predicate is not here. let's remove it from our source - newSrc, err := RemovePredicate(ctx, expr, op.Source) - if err != nil { - return nil, err - } - op.Source = newSrc - return op, nil - } - if len(op.Predicates) == 1 { - // no predicates left on this operator, so we just remove it - return op.Source, nil - } - - // remove the predicate from this filter - op.Predicates = append(op.Predicates[:idx], op.Predicates[idx+1:]...) - return op, nil - - default: - return nil, vterrors.VT13001("this should not happen - tried to remove predicate from the operator table") - } -} diff --git a/go/vt/vtgate/planbuilder/operators/plan_query.go b/go/vt/vtgate/planbuilder/operators/plan_query.go index 811f0c8dc76..8f3abcdc0ec 100644 --- a/go/vt/vtgate/planbuilder/operators/plan_query.go +++ b/go/vt/vtgate/planbuilder/operators/plan_query.go @@ -37,6 +37,7 @@ package operators import ( "fmt" + "runtime" "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" @@ -86,12 +87,14 @@ func PlanQuery(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) (resu func PanicHandler(err *error) { if r := recover(); r != nil { - badness, ok := r.(error) - if !ok { + switch badness := r.(type) { + case runtime.Error: + panic(r) + case error: + *err = badness + default: panic(r) } - - *err = badness } } diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 12b70d3e4ef..bf9eeac0c33 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -473,27 +473,25 @@ func (p *Projection) compactWithJoin(ctx *plancontext.PlanningContext, join *App } var newColumns []int - var newColumnsAST []JoinColumn + newColumnsAST := &applyJoinColumns{} for _, col := range ap { switch colInfo := col.Info.(type) { case Offset: newColumns = append(newColumns, join.Columns[colInfo]) - newColumnsAST = append(newColumnsAST, join.JoinColumns[colInfo]) + newColumnsAST.add(join.JoinColumns.columns[colInfo]) case nil: if !ctx.SemTable.EqualsExprWithDeps(col.EvalExpr, col.ColExpr) { // the inner expression is different from what we are presenting to the outside - this means we need to evaluate return p, NoRewrite } - offset := slices.IndexFunc(join.JoinColumns, func(jc JoinColumn) bool { - return ctx.SemTable.EqualsExprWithDeps(jc.Original, col.ColExpr) - }) + offset := slices.IndexFunc(join.JoinColumns.columns, applyJoinCompare(ctx, col.ColExpr)) if offset < 0 { return p, NoRewrite } if len(join.Columns) > 0 { newColumns = append(newColumns, join.Columns[offset]) } - newColumnsAST = append(newColumnsAST, join.JoinColumns[offset]) + newColumnsAST.add(join.JoinColumns.columns[offset]) default: return p, NoRewrite } diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 38e4e4cd8c0..658f4225756 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -192,6 +192,11 @@ func tryPushProjection( return p, NoRewrite } return pushProjectionInApplyJoin(ctx, p, src) + case *HashJoin: + if !p.canPush(ctx) { + return p, NoRewrite + } + return pushProjectionThroughHashJoin(ctx, p, src) case *Vindex: if !p.canPush(ctx) { return p, NoRewrite @@ -211,6 +216,17 @@ func tryPushProjection( } } +func pushProjectionThroughHashJoin(ctx *plancontext.PlanningContext, p *Projection, hj *HashJoin) (Operator, *ApplyResult) { + cols := p.Columns.(AliasedProjections) + for _, col := range cols { + if !col.isSameInAndOut(ctx) { + return p, NoRewrite + } + hj.columns.add(col.ColExpr) + } + return hj, Rewrote("merged projection into hash join") +} + func pushProjectionToOuter(ctx *plancontext.PlanningContext, p *Projection, sq *SubQuery) (Operator, *ApplyResult) { ap, err := p.GetAliasedProjections() if err != nil { @@ -284,7 +300,7 @@ func pushProjectionInApplyJoin( rhs.explicitColumnAliases = true } - src.JoinColumns = nil + src.JoinColumns = &applyJoinColumns{} for idx, pe := range ap { var col *sqlparser.IdentifierCI if p.DT != nil && idx < len(p.DT.Columns) { @@ -315,13 +331,12 @@ func splitProjectionAcrossJoin( ) { // Check if the current expression can reuse an existing column in the ApplyJoin. - if _, found := canReuseColumn(ctx, join.JoinColumns, pe.EvalExpr, joinColumnToExpr); found { + if _, found := canReuseColumn(ctx, join.JoinColumns.columns, pe.EvalExpr, joinColumnToExpr); found { return } - // Add the new JoinColumn to the ApplyJoin's JoinPredicates. - join.JoinColumns = append(join.JoinColumns, - splitUnexploredExpression(ctx, join, lhs, rhs, pe, colAlias)) + // Add the new applyJoinColumn to the ApplyJoin's JoinPredicates. + join.JoinColumns.add(splitUnexploredExpression(ctx, join, lhs, rhs, pe, colAlias)) } func splitUnexploredExpression( @@ -330,11 +345,11 @@ func splitUnexploredExpression( lhs, rhs *projector, pe *ProjExpr, colAlias *sqlparser.IdentifierCI, -) JoinColumn { - // Get a JoinColumn for the current expression. +) applyJoinColumn { + // Get a applyJoinColumn for the current expression. col := join.getJoinColumnFor(ctx, pe.Original, pe.ColExpr, false) - // Update the left and right child columns and names based on the JoinColumn type. + // Update the left and right child columns and names based on the applyJoinColumn type. switch { case col.IsPureLeft(): lhs.add(pe, colAlias) @@ -379,7 +394,7 @@ func exposeColumnsThroughDerivedTable(ctx *plancontext.PlanningContext, p *Proje if err != nil { panic(err) } - for _, predicate := range src.JoinPredicates { + for _, predicate := range src.JoinPredicates.columns { for idx, bve := range predicate.LHSExprs { expr := bve.Expr tbl, err := ctx.SemTable.TableInfoForExpr(expr) @@ -511,7 +526,7 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (Operator, case *Projection: // we can move ordering under a projection if it's not introducing a column we're sorting by for _, by := range in.Order { - if !fetchByOffset(by.SimplifiedExpr) { + if !mustFetchFromInput(by.SimplifiedExpr) { return in, NoRewrite } } @@ -683,7 +698,7 @@ func pushFilterUnderProjection(ctx *plancontext.PlanningContext, filter *Filter, for _, p := range filter.Predicates { cantPush := false _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - if !fetchByOffset(node) { + if !mustFetchFromInput(node) { return true, nil } @@ -735,9 +750,9 @@ func tryPushDistinct(in *Distinct) (Operator, *ApplyResult) { in.PushedPerformance = true return in, Rewrote("push down distinct under union") - case *ApplyJoin: - src.LHS = &Distinct{Source: src.LHS} - src.RHS = &Distinct{Source: src.RHS} + case JoinOp: + src.SetLHS(&Distinct{Source: src.GetLHS()}) + src.SetRHS(&Distinct{Source: src.GetRHS()}) in.PushedPerformance = true if in.Required { diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index ab3859eb355..ce33e4dcb9b 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -42,7 +42,7 @@ type SubQuery struct { OuterPredicate sqlparser.Expr // This is the predicate that is using the subquery expression. It will not be empty for projections ArgName string // This is the name of the ColName or Argument used to replace the subquery TopLevel bool // will be false if the subquery is deeply nested - JoinColumns []JoinColumn // Broken up join predicates. + JoinColumns []applyJoinColumn // Broken up join predicates. SubqueryValueName string // Value name returned by the subquery (uncorrelated queries). HasValuesName string // Argument name passed to the subquery (uncorrelated queries). @@ -88,7 +88,7 @@ func (sq *SubQuery) OuterExpressionsNeeded(ctx *plancontext.PlanningContext, out return result } -func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer Operator) ([]JoinColumn, error) { +func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer Operator) ([]applyJoinColumn, error) { if outer == nil { return nil, vterrors.VT13001("outer operator cannot be nil") } @@ -99,7 +99,7 @@ func (sq *SubQuery) GetJoinColumns(ctx *plancontext.PlanningContext, outer Opera } } sq.outerID = outerID - mapper := func(in sqlparser.Expr) (JoinColumn, error) { + mapper := func(in sqlparser.Expr) (applyJoinColumn, error) { return breakExpressionInLHSandRHSForApplyJoin(ctx, in, outerID), nil } joinPredicates, err := slice.MapWithError(sq.Predicates, mapper) diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index 8ca91673398..6540ed10701 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -116,7 +116,7 @@ func createSubqueryOp( // and extracts subqueries into operators func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, -) (sqlparser.Exprs, []JoinColumn) { +) (sqlparser.Exprs, []applyJoinColumn) { switch stmt := stmt.(type) { case *sqlparser.Select: return sqb.inspectSelect(ctx, stmt) @@ -134,7 +134,7 @@ func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext, func (sqb *SubQueryBuilder) inspectSelect( ctx *plancontext.PlanningContext, sel *sqlparser.Select, -) (sqlparser.Exprs, []JoinColumn) { +) (sqlparser.Exprs, []applyJoinColumn) { // first we need to go through all the places where one can find predicates // and search for subqueries newWhere, wherePreds, whereJoinCols := sqb.inspectWhere(ctx, sel.Where) @@ -191,7 +191,7 @@ func createSubquery( func (sqb *SubQueryBuilder) inspectWhere( ctx *plancontext.PlanningContext, in *sqlparser.Where, -) (*sqlparser.Where, sqlparser.Exprs, []JoinColumn) { +) (*sqlparser.Where, sqlparser.Exprs, []applyJoinColumn) { if in == nil { return nil, nil, nil } @@ -221,7 +221,7 @@ func (sqb *SubQueryBuilder) inspectWhere( func (sqb *SubQueryBuilder) inspectOnExpr( ctx *plancontext.PlanningContext, from []sqlparser.TableExpr, -) (newFrom []sqlparser.TableExpr, onPreds sqlparser.Exprs, onJoinCols []JoinColumn) { +) (newFrom []sqlparser.TableExpr, onPreds sqlparser.Exprs, onJoinCols []applyJoinColumn) { for _, tbl := range from { tbl := sqlparser.CopyOnRewrite(tbl, dontEnterSubqueries, func(cursor *sqlparser.CopyOnWriteCursor) { cond, ok := cursor.Node().(*sqlparser.JoinCondition) diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index b5c814b2ea6..247777117b5 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -650,6 +650,7 @@ func readJSONTests(filename string) []planTest { panic(err) } dec := json.NewDecoder(file) + dec.DisallowUnknownFields() err = dec.Decode(&output) if err != nil { panic(err) diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index d1e9c42c1dd..4739045b016 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6442,5 +6442,125 @@ "user.user" ] } + }, + { + "comment": "count(*) push down through left hash join", + "query": "select count(*) from user left join (select col, bar from user_extra limit 10) ue on user.col = ue.col group by user.foo, ue.bar", + "plan": { + "QueryType": "SELECT", + "Original": "select count(*) from user left join (select col, bar from user_extra limit 10) ue on user.col = ue.col group by user.foo, ue.bar", + "Instructions": { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "sum_count_star(0) AS count(*)", + "GroupBy": "(1|2), (3|4)", + "ResultColumns": 1, + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "count(*) * coalesce(count(*), 1) as count(*)", + ":4 as foo", + ":6 as weight_string(`user`.foo)", + ":5 as bar", + ":7 as weight_string(ue.bar)" + ], + "Inputs": [ + { + "OperatorType": "Sort", + "Variant": "Memory", + "OrderBy": "(4|6) ASC, (5|7) ASC", + "Inputs": [ + { + "OperatorType": "Projection", + "Expressions": [ + "count(*) as count(*)", + "count(*) as count(*)", + "`user`.col as col", + "ue.col as col", + "`user`.foo as foo", + "ue.bar as bar", + "weight_string(`user`.foo) as weight_string(`user`.foo)", + "weight_string(ue.bar) as weight_string(ue.bar)" + ], + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "HashLeftJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-1,1,-2,2,-3,3", + "Predicate": "`user`.col = ue.col", + "TableName": "`user`_user_extra", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select count(*), `user`.col, `user`.foo from `user` where 1 != 1 group by `user`.col, `user`.foo", + "Query": "select count(*), `user`.col, `user`.foo from `user` group by `user`.col, `user`.foo", + "Table": "`user`" + }, + { + "OperatorType": "Aggregate", + "Variant": "Ordered", + "Aggregates": "count_star(0)", + "GroupBy": "1, (2|3)", + "Inputs": [ + { + "OperatorType": "SimpleProjection", + "Columns": [ + 2, + 0, + 1, + 3 + ], + "Inputs": [ + { + "OperatorType": "Sort", + "Variant": "Memory", + "OrderBy": "0 ASC, (1|3) ASC", + "Inputs": [ + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col, bar, 1, weight_string(bar) from (select col, bar from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col, bar, 1, weight_string(bar) from (select col, bar from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index 476a16f8a11..508fd4156e7 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -4058,19 +4058,28 @@ "QueryType": "SELECT", "Original": "select id from user left join (select col from user_extra limit 10) ue on user.col = ue.col", "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "id as id" - ], + "OperatorType": "Join", + "Variant": "HashLeftJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-2", + "Predicate": "`user`.col = ue.col", + "TableName": "`user`_user_extra", "Inputs": [ { - "OperatorType": "Join", - "Variant": "HashLeftJoin", - "Collation": "binary", - "ComparisonType": "INT16", - "JoinColumnIndexes": "-2", - "Predicate": "`user`.col = ue.col", - "TableName": "`user`_user_extra", + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col, id from `user` where 1 != 1", + "Query": "select `user`.col, id from `user`", + "Table": "`user`" + }, + { + "OperatorType": "Limit", + "Count": "10", "Inputs": [ { "OperatorType": "Route", @@ -4079,26 +4088,9 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select `user`.col, id from `user` where 1 != 1", - "Query": "select `user`.col, id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Limit", - "Count": "10", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from (select col from user_extra where 1 != 1) as ue where 1 != 1", - "Query": "select col from (select col from user_extra) as ue limit :__upper_limit", - "Table": "user_extra" - } - ] + "FieldQuery": "select col from (select col from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col from (select col from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" } ] } @@ -4117,24 +4109,114 @@ "QueryType": "SELECT", "Original": "select id, user_id from (select id, col from user limit 10) u join (select col, user_id from user_extra limit 10) ue on u.col = ue.col", "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "id as id", - "user_id as user_id" + "OperatorType": "Join", + "Variant": "HashJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-1,2", + "Predicate": "u.col = ue.col", + "TableName": "`user`_user_extra", + "Inputs": [ + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id, col from (select id, col from `user` where 1 != 1) as u where 1 != 1", + "Query": "select id, col from (select id, col from `user`) as u limit :__upper_limit", + "Table": "`user`" + } + ] + }, + { + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col, user_id from (select col, user_id from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col, user_id from (select col, user_id from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" + } + ] + } + ] + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "query that needs a hash join - both sides have limits. check that it can be merged even with the hash join", + "query": "select id, user_id from (select id, col from user where id = 17 limit 10) u join (select col, user_id from user_extra where user_id = 17 limit 10) ue on u.col = ue.col", + "plan": { + "QueryType": "SELECT", + "Original": "select id, user_id from (select id, col from user where id = 17 limit 10) u join (select col, user_id from user_extra where user_id = 17 limit 10) ue on u.col = ue.col", + "Instructions": { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id, user_id from (select id, col from `user` where 1 != 1) as u, (select col, user_id from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select id, user_id from (select id, col from `user` where id = 17 limit 10) as u, (select col, user_id from user_extra where user_id = 17 limit 10) as ue where u.col = ue.col", + "Table": "`user`, user_extra", + "Values": [ + "17" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "query that needs a hash join - outer side has LIMIT. distinct should be pushed down", + "query": "select distinct id, user_id from (select id, col from user) u left join (select col, user_id from user_extra limit 10) ue on u.col = ue.col", + "plan": { + "QueryType": "SELECT", + "Original": "select distinct id, user_id from (select id, col from user) u left join (select col, user_id from user_extra limit 10) ue on u.col = ue.col", + "Instructions": { + "OperatorType": "Distinct", + "Collations": [ + "(0:2)", + "(1:3)" ], + "ResultColumns": 2, "Inputs": [ { - "OperatorType": "Join", - "Variant": "HashJoin", - "Collation": "binary", - "ComparisonType": "INT16", - "JoinColumnIndexes": "-1,2", - "Predicate": "u.col = ue.col", - "TableName": "`user`_user_extra", + "OperatorType": "Projection", + "Expressions": [ + "id as id", + "user_id as user_id", + "weight_string(id) as weight_string(id)", + "weight_string(user_id) as weight_string(user_id)" + ], "Inputs": [ { - "OperatorType": "Limit", - "Count": "10", + "OperatorType": "Join", + "Variant": "HashLeftJoin", + "Collation": "binary", + "ComparisonType": "INT16", + "JoinColumnIndexes": "-1,2", + "Predicate": "u.col = ue.col", + "TableName": "`user`_user_extra", "Inputs": [ { "OperatorType": "Route", @@ -4144,25 +4226,25 @@ "Sharded": true }, "FieldQuery": "select id, col from (select id, col from `user` where 1 != 1) as u where 1 != 1", - "Query": "select id, col from (select id, col from `user`) as u limit :__upper_limit", + "Query": "select distinct id, col from (select id, col from `user`) as u", "Table": "`user`" - } - ] - }, - { - "OperatorType": "Limit", - "Count": "10", - "Inputs": [ + }, { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, user_id from (select col, user_id from user_extra where 1 != 1) as ue where 1 != 1", - "Query": "select col, user_id from (select col, user_id from user_extra) as ue limit :__upper_limit", - "Table": "user_extra" + "OperatorType": "Limit", + "Count": "10", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col, user_id from (select col, user_id from user_extra where 1 != 1) as ue where 1 != 1", + "Query": "select col, user_id from (select col, user_id from user_extra) as ue limit :__upper_limit", + "Table": "user_extra" + } + ] } ] } @@ -4174,6 +4256,5 @@ "user.user", "user.user_extra" ] - } - } + } } ] From d75954fa38b2f26ce5a081b2e04b02446e99a354 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:42:12 +0200 Subject: [PATCH 112/119] schemadiff: additional FK column type matching rules (#14751) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/schema.go | 26 ++++++++++++++++++++------ go/vt/schemadiff/schema_test.go | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 311ccd94896..ec9174dd232 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -350,12 +350,26 @@ func (s *Schema) normalize() error { return errors.Join(errs, err) } } - colTypeEqualForForeignKey := func(a, b *sqlparser.ColumnType) bool { - return a.Type == b.Type && - a.Unsigned == b.Unsigned && - a.Zerofill == b.Zerofill && - sqlparser.Equals.ColumnCharset(a.Charset, b.Charset) && - sqlparser.Equals.SliceOfString(a.EnumValues, b.EnumValues) + colTypeCompatibleForForeignKey := func(child, parent *sqlparser.ColumnType) bool { + if child.Type == parent.Type { + return true + } + if child.Type == "char" && parent.Type == "varchar" { + return true + } + return false + } + colTypeEqualForForeignKey := func(child, parent *sqlparser.ColumnType) bool { + if colTypeCompatibleForForeignKey(child, parent) && + child.Unsigned == parent.Unsigned && + child.Zerofill == parent.Zerofill && + sqlparser.Equals.ColumnCharset(child.Charset, parent.Charset) && + child.Options.Collate == parent.Options.Collate && + sqlparser.Equals.SliceOfString(child.EnumValues, parent.EnumValues) { + // Complete identify (other than precision which is ignored) + return true + } + return false } // Now validate foreign key columns: diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 8c410f54381..a1b55544593 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -378,10 +378,31 @@ func TestInvalidSchema(t *testing.T) { // InnoDB allows different string length schema: "create table t10(id varchar(50) primary key); create table t11 (id int primary key, i varchar(100), key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", }, + { + // explicit charset/collation + schema: "create table t10(id varchar(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i varchar(100) charset utf8mb4 collate utf8mb4_0900_ai_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", + }, + { + // weirdly allowed: varchar->char + schema: "create table t10(id varchar(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i char(100) charset utf8mb4 collate utf8mb4_0900_ai_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", + }, + { + // but weirdly not allowed: char->varchar + schema: "create table t10(id char(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i varchar(50) charset utf8mb4 collate utf8mb4_0900_ai_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", + expectErr: &ForeignKeyColumnTypeMismatchError{Table: "t11", Constraint: "f10", Column: "i", ReferencedTable: "t10", ReferencedColumn: "id"}, + }, { schema: "create table t10(id varchar(50) charset utf8mb3 primary key); create table t11 (id int primary key, i varchar(100) charset utf8mb4, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", expectErr: &ForeignKeyColumnTypeMismatchError{Table: "t11", Constraint: "f10", Column: "i", ReferencedTable: "t10", ReferencedColumn: "id"}, }, + { + schema: "create table t10(id varchar(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i varchar(100) charset utf8mb4 collate utf8mb4_general_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", + expectErr: &ForeignKeyColumnTypeMismatchError{Table: "t11", Constraint: "f10", Column: "i", ReferencedTable: "t10", ReferencedColumn: "id"}, + }, + { + schema: "create table t10(id VARCHAR(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i VARCHAR(100) charset utf8mb4 collate utf8mb4_general_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", + expectErr: &ForeignKeyColumnTypeMismatchError{Table: "t11", Constraint: "f10", Column: "i", ReferencedTable: "t10", ReferencedColumn: "id"}, + }, } for _, ts := range tt { t.Run(ts.schema, func(t *testing.T) { From 4d9ca440d92f8dbf0df03ccb2a2e4c0eac2b156b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:34:07 +0530 Subject: [PATCH 113/119] build(deps): bump com.google.guava:guava from 30.1.1-jre to 32.0.0-jre in /java (#14759) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index e424b304229..a53673ed947 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -94,7 +94,7 @@ com.google.guava guava - 30.1.1-jre + 32.0.0-jre com.google.protobuf From 31b0959ea6c0ecdece166c0e5eee9aa08d38031e Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 12 Dec 2023 18:07:09 +0530 Subject: [PATCH 114/119] Add foreign key support for insert on duplicate key update (#14638) Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/foreignkey/fk_test.go | 31 ++ go/vt/vtgate/engine/cached_size.go | 35 ++ go/vt/vtgate/engine/upsert.go | 138 +++++ .../planbuilder/operator_transformers.go | 27 + go/vt/vtgate/planbuilder/operators/insert.go | 127 +++-- go/vt/vtgate/planbuilder/operators/upsert.go | 143 +++++ .../testdata/foreignkey_cases.json | 522 +++++++++++++++++- .../testdata/foreignkey_checks_on_cases.json | 161 +++++- go/vt/vtgate/planbuilder/upsert.go | 37 ++ 9 files changed, 1161 insertions(+), 60 deletions(-) create mode 100644 go/vt/vtgate/engine/upsert.go create mode 100644 go/vt/vtgate/planbuilder/operators/upsert.go create mode 100644 go/vt/vtgate/planbuilder/upsert.go diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index c3f1d9dc29c..956c268d895 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -1208,6 +1208,37 @@ func TestReplaceWithFK(t *testing.T) { utils.AssertMatches(t, conn, `select * from u_t2`, `[[INT64(1) NULL] [INT64(2) NULL]]`) } +// TestInsertWithFKOnDup tests that insertion with on duplicate key update works as expected. +func TestInsertWithFKOnDup(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + utils.Exec(t, mcmp.VtConn, "use `uks`") + + // insert some data. + mcmp.Exec(`insert into u_t1(id, col1) values (100, 1), (200, 2), (300, 3), (400, 4)`) + mcmp.Exec(`insert into u_t2(id, col2) values (1000, 1), (2000, 2), (3000, 3), (4000, 4)`) + + // updating child to an existing value in parent. + mcmp.Exec(`insert into u_t2(id, col2) values (4000, 50) on duplicate key update col2 = 1`) + mcmp.AssertMatches(`select * from u_t2 order by id`, `[[INT64(1000) INT64(1)] [INT64(2000) INT64(2)] [INT64(3000) INT64(3)] [INT64(4000) INT64(1)]]`) + + // updating parent, value not referred in child. + mcmp.Exec(`insert into u_t1(id, col1) values (400, 50) on duplicate key update col1 = values(col1)`) + mcmp.AssertMatches(`select * from u_t1 order by id`, `[[INT64(100) INT64(1)] [INT64(200) INT64(2)] [INT64(300) INT64(3)] [INT64(400) INT64(50)]]`) + mcmp.AssertMatches(`select * from u_t2 order by id`, `[[INT64(1000) INT64(1)] [INT64(2000) INT64(2)] [INT64(3000) INT64(3)] [INT64(4000) INT64(1)]]`) + + // updating parent, child updated to null. + mcmp.Exec(`insert into u_t1(id, col1) values (100, 75) on duplicate key update col1 = values(col1)`) + mcmp.AssertMatches(`select * from u_t1 order by id`, `[[INT64(100) INT64(75)] [INT64(200) INT64(2)] [INT64(300) INT64(3)] [INT64(400) INT64(50)]]`) + mcmp.AssertMatches(`select * from u_t2 order by id`, `[[INT64(1000) NULL] [INT64(2000) INT64(2)] [INT64(3000) INT64(3)] [INT64(4000) NULL]]`) + + // inserting multiple rows in parent, some child rows updated to null. + mcmp.Exec(`insert into u_t1(id, col1) values (100, 42),(600, 2),(300, 24),(200, 2) on duplicate key update col1 = values(col1)`) + mcmp.AssertMatches(`select * from u_t1 order by id`, `[[INT64(100) INT64(42)] [INT64(200) INT64(2)] [INT64(300) INT64(24)] [INT64(400) INT64(50)] [INT64(600) INT64(2)]]`) + mcmp.AssertMatches(`select * from u_t2 order by id`, `[[INT64(1000) NULL] [INT64(2000) INT64(2)] [INT64(3000) NULL] [INT64(4000) NULL]]`) +} + // TestDDLFk tests that table is created with fk constraint when foreign_key_checks is off. func TestDDLFk(t *testing.T) { mcmp, closer := start(t) diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index ee84317bc00..6da8b1b56d4 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -1267,6 +1267,23 @@ func (cached *UpdateTarget) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Target))) return size } +func (cached *Upsert) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + // field Upserts []vitess.io/vitess/go/vt/vtgate/engine.upsert + { + size += hack.RuntimeAllocSize(int64(cap(cached.Upserts)) * int64(32)) + for _, elem := range cached.Upserts { + size += elem.CachedSize(false) + } + } + return size +} func (cached *UserDefinedVariable) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1478,3 +1495,21 @@ func (cached *shardRoute) CachedSize(alloc bool) int64 { } return size } +func (cached *upsert) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(32) + } + // field Insert vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.Insert.(cachedObject); ok { + size += cc.CachedSize(true) + } + // field Update vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.Update.(cachedObject); ok { + size += cc.CachedSize(true) + } + return size +} diff --git a/go/vt/vtgate/engine/upsert.go b/go/vt/vtgate/engine/upsert.go new file mode 100644 index 00000000000..8542892ada4 --- /dev/null +++ b/go/vt/vtgate/engine/upsert.go @@ -0,0 +1,138 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "fmt" + + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" +) + +var _ Primitive = (*Upsert)(nil) + +// Upsert Primitive will execute the insert primitive first and +// if there is `Duplicate Key` error, it executes the update primitive. +type Upsert struct { + Upserts []upsert + + txNeeded +} + +type upsert struct { + Insert Primitive + Update Primitive +} + +// AddUpsert appends to the Upsert Primitive. +func (u *Upsert) AddUpsert(ins, upd Primitive) { + u.Upserts = append(u.Upserts, upsert{ + Insert: ins, + Update: upd, + }) +} + +// RouteType implements Primitive interface type. +func (u *Upsert) RouteType() string { + return "UPSERT" +} + +// GetKeyspaceName implements Primitive interface type. +func (u *Upsert) GetKeyspaceName() string { + if len(u.Upserts) > 0 { + return u.Upserts[0].Insert.GetKeyspaceName() + } + return "" +} + +// GetTableName implements Primitive interface type. +func (u *Upsert) GetTableName() string { + if len(u.Upserts) > 0 { + return u.Upserts[0].Insert.GetTableName() + } + return "" +} + +// GetFields implements Primitive interface type. +func (u *Upsert) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return nil, vterrors.VT13001("unexpected to receive GetFields call for insert on duplicate key update query") +} + +// TryExecute implements Primitive interface type. +func (u *Upsert) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { + result := &sqltypes.Result{} + for _, up := range u.Upserts { + qr, err := execOne(ctx, vcursor, bindVars, wantfields, up) + if err != nil { + return nil, err + } + result.RowsAffected += qr.RowsAffected + } + return result, nil +} + +func execOne(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, up upsert) (*sqltypes.Result, error) { + insQr, err := vcursor.ExecutePrimitive(ctx, up.Insert, bindVars, wantfields) + if err == nil { + return insQr, nil + } + if vterrors.Code(err) != vtrpcpb.Code_ALREADY_EXISTS { + return nil, err + } + updQr, err := vcursor.ExecutePrimitive(ctx, up.Update, bindVars, wantfields) + if err != nil { + return nil, err + } + // To match mysql, need to report +1 on rows affected if there is any change. + if updQr.RowsAffected > 0 { + updQr.RowsAffected += 1 + } + return updQr, nil +} + +// TryStreamExecute implements Primitive interface type. +func (u *Upsert) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + qr, err := u.TryExecute(ctx, vcursor, bindVars, wantfields) + if err != nil { + return err + } + return callback(qr) +} + +// Inputs implements Primitive interface type. +func (u *Upsert) Inputs() ([]Primitive, []map[string]any) { + var inputs []Primitive + var inputsMap []map[string]any + for i, up := range u.Upserts { + inputs = append(inputs, up.Insert, up.Update) + inputsMap = append(inputsMap, + map[string]any{inputName: fmt.Sprintf("Insert-%d", i+1)}, + map[string]any{inputName: fmt.Sprintf("Update-%d", i+1)}) + } + return inputs, inputsMap +} + +func (u *Upsert) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "Upsert", + TargetTabletType: topodatapb.TabletType_PRIMARY, + } +} diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 3b117411921..1adcc61972a 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -66,6 +66,8 @@ func transformToLogicalPlan(ctx *plancontext.PlanningContext, op operators.Opera return transformFkVerify(ctx, op) case *operators.InsertSelection: return transformInsertionSelection(ctx, op) + case *operators.Upsert: + return transformUpsert(ctx, op) case *operators.HashJoin: return transformHashJoin(ctx, op) case *operators.Sequential: @@ -75,6 +77,31 @@ func transformToLogicalPlan(ctx *plancontext.PlanningContext, op operators.Opera return nil, vterrors.VT13001(fmt.Sprintf("unknown type encountered: %T (transformToLogicalPlan)", op)) } +func transformUpsert(ctx *plancontext.PlanningContext, op *operators.Upsert) (logicalPlan, error) { + u := &upsert{} + for _, source := range op.Sources { + iLp, uLp, err := transformOneUpsert(ctx, source) + if err != nil { + return nil, err + } + u.insert = append(u.insert, iLp) + u.update = append(u.update, uLp) + } + return u, nil +} + +func transformOneUpsert(ctx *plancontext.PlanningContext, source operators.UpsertSource) (iLp, uLp logicalPlan, err error) { + iLp, err = transformToLogicalPlan(ctx, source.Insert) + if err != nil { + return + } + if ins, ok := iLp.(*insert); ok { + ins.eInsert.PreventAutoCommit = true + } + uLp, err = transformToLogicalPlan(ctx, source.Update) + return +} + func transformSequential(ctx *plancontext.PlanningContext, op *operators.Sequential) (logicalPlan, error) { var lps []logicalPlan for _, source := range op.Sources { diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index 5cb25feb66c..a25d9bc471f 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -142,6 +142,42 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I return &Sequential{Sources: []Operator{delOp, insOp}} } +func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) Operator { + insOp := createInsertOperator(ctx, ins, vTbl, routing) + + // Find the foreign key mode and for unmanaged foreign-key-mode, we don't need to do anything. + ksMode, err := ctx.VSchema.ForeignKeyMode(vTbl.Keyspace.Name) + if err != nil { + panic(err) + } + if ksMode != vschemapb.Keyspace_managed { + return insOp + } + + parentFKs := ctx.SemTable.GetParentForeignKeysList() + childFks := ctx.SemTable.GetChildForeignKeysList() + if len(parentFKs) > 0 { + panic(vterrors.VT12002()) + } + if len(childFks) > 0 { + if ins.Action == sqlparser.ReplaceAct { + panic(vterrors.VT12001("REPLACE INTO with foreign keys")) + } + if len(ins.OnDup) > 0 { + rows := getRowsOrError(ins) + return createUpsertOperator(ctx, ins, insOp, rows, vTbl) + } + } + return insOp +} + +func getRowsOrError(ins *sqlparser.Insert) sqlparser.Values { + if rows, ok := ins.Rows.(sqlparser.Values); ok { + return rows + } + panic(vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys with select statement")) +} + func getWhereCondExpr(compExprs []*sqlparser.ComparisonExpr) sqlparser.Expr { var outputExpr sqlparser.Expr for _, expr := range compExprs { @@ -164,25 +200,7 @@ func pkCompExpression(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparse if len(vTbl.PrimaryKey) == 0 { return nil } - type pComp struct { - idx int - def sqlparser.Expr - } - var pIndexes []pComp - var pColTuple sqlparser.ValTuple - for _, pCol := range vTbl.PrimaryKey { - var def sqlparser.Expr - idx := ins.Columns.FindColumn(pCol) - if idx == -1 { - def = findDefault(vTbl, pCol) - if def == nil { - // If default value is empty, nothing to compare as it will always be false. - return nil - } - } - pIndexes = append(pIndexes, pComp{idx, def}) - pColTuple = append(pColTuple, sqlparser.NewColName(pCol.String())) - } + pIndexes, pColTuple := findPKIndexes(vTbl, ins) var pValTuple sqlparser.ValTuple for _, row := range rows { @@ -199,6 +217,29 @@ func pkCompExpression(vTbl *vindexes.Table, ins *sqlparser.Insert, rows sqlparse return sqlparser.NewComparisonExpr(sqlparser.InOp, pColTuple, pValTuple, nil) } +type pComp struct { + idx int + def sqlparser.Expr + col sqlparser.IdentifierCI +} + +func findPKIndexes(vTbl *vindexes.Table, ins *sqlparser.Insert) (pIndexes []pComp, pColTuple sqlparser.ValTuple) { + for _, pCol := range vTbl.PrimaryKey { + var def sqlparser.Expr + idx := ins.Columns.FindColumn(pCol) + if idx == -1 { + def = findDefault(vTbl, pCol) + if def == nil { + // If default value is empty, nothing to compare as it will always be false. + return nil, nil + } + } + pIndexes = append(pIndexes, pComp{idx, def, pCol}) + pColTuple = append(pColTuple, sqlparser.NewColName(pCol.String())) + } + return +} + func findDefault(vTbl *vindexes.Table, pCol sqlparser.IdentifierCI) sqlparser.Expr { for _, column := range vTbl.Columns { if column.Name.Equal(pCol) { @@ -312,42 +353,7 @@ func createUniqueKeyComp(ins *sqlparser.Insert, expr sqlparser.Expr, vTbl *vinde return offsets, false } -func checkAndCreateInsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) Operator { - insOp := createInsertOperator(ctx, ins, vTbl, routing) - - if ins.Comments != nil { - insOp = &LockAndComment{ - Source: insOp, - Comments: ins.Comments, - } - } - - // Find the foreign key mode and for unmanaged foreign-key-mode, we don't need to do anything. - ksMode, err := ctx.VSchema.ForeignKeyMode(vTbl.Keyspace.Name) - if err != nil { - return nil - } - if ksMode != vschemapb.Keyspace_managed { - return insOp - } - - parentFKs := ctx.SemTable.GetParentForeignKeysList() - childFks := ctx.SemTable.GetChildForeignKeysList() - if len(parentFKs) > 0 { - panic(vterrors.VT12002()) - } - if len(childFks) > 0 { - if ins.Action == sqlparser.ReplaceAct { - panic(vterrors.VT12001("REPLACE INTO with foreign keys")) - } - if len(ins.OnDup) > 0 { - panic(vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys")) - } - } - return insOp -} - -func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) Operator { +func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.Insert, vTbl *vindexes.Table, routing Routing) (op Operator) { if _, target := routing.(*TargetedRouting); target { panic(vterrors.VT09017("INSERT with a target destination is not allowed")) } @@ -382,11 +388,18 @@ func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.I insOp.ColVindexes = getColVindexes(insOp) switch rows := insStmt.Rows.(type) { case sqlparser.Values: + op = route route.Source = insertRowsPlan(ctx, insOp, insStmt, rows) case sqlparser.SelectStatement: - return insertSelectPlan(ctx, insOp, route, insStmt, rows) + op = insertSelectPlan(ctx, insOp, route, insStmt, rows) + } + if insStmt.Comments != nil { + op = &LockAndComment{ + Source: op, + Comments: insStmt.Comments, + } } - return route + return op } func insertSelectPlan( diff --git a/go/vt/vtgate/planbuilder/operators/upsert.go b/go/vt/vtgate/planbuilder/operators/upsert.go new file mode 100644 index 00000000000..8f028a790b2 --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/upsert.go @@ -0,0 +1,143 @@ +/* +Copyright 2023 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 operators + +import ( + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +var _ Operator = (*Upsert)(nil) + +// Upsert represents an insert on duplicate key operation on a table. +type Upsert struct { + Sources []UpsertSource + + noColumns + noPredicates +} + +type UpsertSource struct { + Insert Operator + Update Operator +} + +func (u *Upsert) Clone(inputs []Operator) Operator { + up := &Upsert{} + up.setInputs(inputs) + return up +} + +func (u *Upsert) setInputs(inputs []Operator) { + for i := 0; i < len(inputs); i += 2 { + u.Sources = append(u.Sources, UpsertSource{ + Insert: inputs[i], + Update: inputs[i+1], + }) + } +} + +func (u *Upsert) Inputs() []Operator { + var inputs []Operator + for _, source := range u.Sources { + inputs = append(inputs, source.Insert, source.Update) + } + return inputs +} + +func (u *Upsert) SetInputs(inputs []Operator) { + u.Sources = nil + u.setInputs(inputs) +} + +func (u *Upsert) ShortDescription() string { + return "" +} + +func (u *Upsert) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { + return nil +} + +func createUpsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, insOp Operator, rows sqlparser.Values, vTbl *vindexes.Table) Operator { + if len(vTbl.UniqueKeys) != 0 { + panic(vterrors.VT12001("ON DUPLICATE KEY UPDATE with foreign keys with unique keys")) + } + + pIndexes, _ := findPKIndexes(vTbl, ins) + if len(pIndexes) == 0 { + // nothing to compare for update. + // Hence, only perform insert. + return insOp + } + + upsert := &Upsert{} + for _, row := range rows { + var comparisons []sqlparser.Expr + for _, pIdx := range pIndexes { + var expr sqlparser.Expr + if pIdx.idx == -1 { + expr = pIdx.def + } else { + expr = row[pIdx.idx] + } + comparisons = append(comparisons, + sqlparser.NewComparisonExpr(sqlparser.EqualOp, sqlparser.NewColName(pIdx.col.String()), expr, nil)) + } + whereExpr := sqlparser.AndExpressions(comparisons...) + + var updExprs sqlparser.UpdateExprs + for _, ue := range ins.OnDup { + expr := sqlparser.CopyOnRewrite(ue.Expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) { + vfExpr, ok := cursor.Node().(*sqlparser.ValuesFuncExpr) + if !ok { + return + } + idx := ins.Columns.FindColumn(vfExpr.Name.Name) + if idx == -1 { + panic(vterrors.VT03014(sqlparser.String(vfExpr.Name), "field list")) + } + cursor.Replace(row[idx]) + }, nil).(sqlparser.Expr) + updExprs = append(updExprs, &sqlparser.UpdateExpr{ + Name: ue.Name, + Expr: expr, + }) + } + + upd := &sqlparser.Update{ + Comments: ins.Comments, + TableExprs: sqlparser.TableExprs{ins.Table}, + Exprs: updExprs, + Where: sqlparser.NewWhere(sqlparser.WhereClause, whereExpr), + } + updOp := createOpFromStmt(ctx, upd, false, "") + + // replan insert statement without on duplicate key update. + newInsert := sqlparser.CloneRefOfInsert(ins) + newInsert.OnDup = nil + newInsert.Rows = sqlparser.Values{row} + insOp = createOpFromStmt(ctx, newInsert, false, "") + upsert.Sources = append(upsert.Sources, UpsertSource{ + Insert: insOp, + Update: updOp, + }) + } + + return upsert +} diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json index deba02e2009..3ab6ef96118 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json @@ -1658,9 +1658,168 @@ } }, { - "comment": "Insert with on duplicate key update - foreign keys disallowed", + "comment": "Insert with on duplicate key update - foreign key with new value", "query": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = 5", - "plan": "VT12001: unsupported: ON DUPLICATE KEY UPDATE with foreign keys" + "plan": { + "QueryType": "INSERT", + "Original": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = 5", + "Instructions": { + "OperatorType": "Upsert", + "TargetTabletType": "PRIMARY", + "Inputs": [ + { + "InputName": "Insert-1", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl1(id, col1) values (1, 3)", + "TableName": "u_tbl1" + }, + { + "InputName": "Update-1", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where id = 1 for update nowait", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast(5 as CHAR)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = 5 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast(5 as CHAR))) for update nowait", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast(5 as CHAR)))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl1 set col1 = 5 where id = 1", + "Table": "u_tbl1" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } }, { "comment": "Insert with on duplicate key update - foreign keys not on update column - allowed", @@ -2511,5 +2670,364 @@ "sharded_fk_allow.tbl3" ] } + }, + { + "comment": "Insert with on duplicate key update - foreign key with values function", + "query": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = values(col1)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = values(col1)", + "Instructions": { + "OperatorType": "Upsert", + "TargetTabletType": "PRIMARY", + "Inputs": [ + { + "InputName": "Insert-1", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl1(id, col1) values (1, 3)", + "TableName": "u_tbl1" + }, + { + "InputName": "Update-1", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where id = 1 for update nowait", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast(3 as CHAR)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = 3 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast(3 as CHAR))) for update nowait", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast(3 as CHAR)))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl1 set col1 = 3 where id = 1", + "Table": "u_tbl1" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } + }, + { + "comment": "insert with on duplicate key update with multiple rows", + "query": "insert into u_tbl2 (id, col2) values (:v1, :v2),(:v3, :v4), (:v5, :v6) on duplicate key update col2 = values(col2)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into u_tbl2 (id, col2) values (:v1, :v2),(:v3, :v4), (:v5, :v6) on duplicate key update col2 = values(col2)", + "Instructions": { + "OperatorType": "Upsert", + "TargetTabletType": "PRIMARY", + "Inputs": [ + { + "InputName": "Insert-1", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl2(id, col2) values (:v1, :v2)", + "TableName": "u_tbl2" + }, + { + "InputName": "Update-1", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where id = :v1 for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals and (cast(:v2 as CHAR) is null or (col3) not in ((cast(:v2 as CHAR))))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl2 set col2 = :v2 where id = :v1", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "Insert-2", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl2(id, col2) values (:v3, :v4)", + "TableName": "u_tbl2" + }, + { + "InputName": "Update-2", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where id = :v3 for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (cast(:v4 as CHAR) is null or (col3) not in ((cast(:v4 as CHAR))))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl2 set col2 = :v4 where id = :v3", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "Insert-3", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert into u_tbl2(id, col2) values (:v5, :v6)", + "TableName": "u_tbl2" + }, + { + "InputName": "Update-3", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where id = :v5 for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Query": "update u_tbl3 set col3 = null where (col3) in ::fkc_vals2 and (cast(:v6 as CHAR) is null or (col3) not in ((cast(:v6 as CHAR))))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update u_tbl2 set col2 = :v6 where id = :v5", + "Table": "u_tbl2" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3" + ] + } } ] diff --git a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json index a61a035a8d8..e382a83a0ad 100644 --- a/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/foreignkey_checks_on_cases.json @@ -1660,7 +1660,166 @@ { "comment": "Insert with on duplicate key update - foreign keys disallowed", "query": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = 5", - "plan": "VT12001: unsupported: ON DUPLICATE KEY UPDATE with foreign keys" + "plan": { + "QueryType": "INSERT", + "Original": "insert into u_tbl1 (id, col1) values (1, 3) on duplicate key update col1 = 5", + "Instructions": { + "OperatorType": "Upsert", + "TargetTabletType": "PRIMARY", + "Inputs": [ + { + "InputName": "Insert-1", + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "NoAutoCommit": true, + "Query": "insert /*+ SET_VAR(foreign_key_checks=On) */ into u_tbl1(id, col1) values (1, 3)", + "TableName": "u_tbl1" + }, + { + "InputName": "Update-1", + "OperatorType": "FkCascade", + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col1 from u_tbl1 where 1 != 1", + "Query": "select col1 from u_tbl1 where id = 1 for update nowait", + "Table": "u_tbl1" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "FkCascade", + "BvName": "fkc_vals", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col2 from u_tbl2 where 1 != 1", + "Query": "select col2 from u_tbl2 where (col2) in ::fkc_vals for update nowait", + "Table": "u_tbl2" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals1", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl3 set col3 = null where (col3) in ::fkc_vals1 and (col3) not in ((cast(5 as CHAR)))", + "Table": "u_tbl3" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=OFF) */ u_tbl2 set col2 = 5 where (col2) in ::fkc_vals", + "Table": "u_tbl2" + } + ] + }, + { + "InputName": "CascadeChild-2", + "OperatorType": "FkCascade", + "BvName": "fkc_vals2", + "Cols": [ + 0 + ], + "Inputs": [ + { + "InputName": "Selection", + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "FieldQuery": "select col9 from u_tbl9 where 1 != 1", + "Query": "select col9 from u_tbl9 where (col9) in ::fkc_vals2 and (col9) not in ((cast(5 as CHAR))) for update nowait", + "Table": "u_tbl9" + }, + { + "InputName": "CascadeChild-1", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "BvName": "fkc_vals3", + "Cols": [ + 0 + ], + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl8 set col8 = null where (col8) in ::fkc_vals3", + "Table": "u_tbl8" + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=ON) */ u_tbl9 set col9 = null where (col9) in ::fkc_vals2 and (col9) not in ((cast(5 as CHAR)))", + "Table": "u_tbl9" + } + ] + }, + { + "InputName": "Parent", + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_fk_allow", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update /*+ SET_VAR(foreign_key_checks=On) */ u_tbl1 set col1 = 5 where id = 1", + "Table": "u_tbl1" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_fk_allow.u_tbl1", + "unsharded_fk_allow.u_tbl2", + "unsharded_fk_allow.u_tbl3", + "unsharded_fk_allow.u_tbl8", + "unsharded_fk_allow.u_tbl9" + ] + } }, { "comment": "Insert with on duplicate key update - foreign keys not on update column - allowed", diff --git a/go/vt/vtgate/planbuilder/upsert.go b/go/vt/vtgate/planbuilder/upsert.go new file mode 100644 index 00000000000..cd9c127635c --- /dev/null +++ b/go/vt/vtgate/planbuilder/upsert.go @@ -0,0 +1,37 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package planbuilder + +import ( + "vitess.io/vitess/go/vt/vtgate/engine" +) + +type upsert struct { + insert []logicalPlan + update []logicalPlan +} + +var _ logicalPlan = (*upsert)(nil) + +// Primitive implements the logicalPlan interface +func (u *upsert) Primitive() engine.Primitive { + up := &engine.Upsert{} + for i := 0; i < len(u.insert); i++ { + up.AddUpsert(u.insert[i].Primitive(), u.update[i].Primitive()) + } + return up +} From a5cbcd1ea78b400427ceee5583dbcfe34c7b73c6 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Tue, 12 Dec 2023 13:01:31 -0800 Subject: [PATCH 115/119] Use GetTabletsByCell in healthcheck (#14693) Signed-off-by: deepthi --- go/stats/counters.go | 6 +- go/vt/discovery/healthcheck.go | 8 +- go/vt/discovery/tablet_picker.go | 2 +- go/vt/discovery/topology_watcher.go | 83 ++---- go/vt/discovery/topology_watcher_test.go | 240 +++++++----------- go/vt/topo/consultopo/error.go | 9 +- go/vt/topo/errors.go | 3 + go/vt/topo/etcd2topo/error.go | 13 +- go/vt/topo/memorytopo/file.go | 3 + go/vt/topo/memorytopo/memorytopo.go | 10 + go/vt/topo/shard.go | 2 +- go/vt/topo/tablet.go | 68 +++-- go/vt/topo/tablet_test.go | 118 +++++++++ go/vt/topo/zk2topo/error.go | 17 +- go/vt/topotools/tablet.go | 2 +- go/vt/topotools/utils.go | 4 +- go/vt/vtctl/grpcvtctldserver/server.go | 6 +- go/vt/vtctl/grpcvtctldserver/topo.go | 2 +- go/vt/vtctl/workflow/server.go | 2 +- .../tabletserver/txthrottler/tx_throttler.go | 8 - go/vt/wrangler/shard.go | 2 +- go/vt/wrangler/split.go | 2 +- 22 files changed, 345 insertions(+), 265 deletions(-) create mode 100644 go/vt/topo/tablet_test.go diff --git a/go/stats/counters.go b/go/stats/counters.go index e79da39c48b..bcf7fc3a8b6 100644 --- a/go/stats/counters.go +++ b/go/stats/counters.go @@ -62,7 +62,7 @@ func (c *counters) set(name string, value int64) { func (c *counters) reset() { c.mu.Lock() defer c.mu.Unlock() - c.counts = make(map[string]int64) + clear(c.counts) } // ZeroAll zeroes out all values @@ -70,7 +70,9 @@ func (c *counters) ZeroAll() { c.mu.Lock() defer c.mu.Unlock() - clear(c.counts) + for k := range c.counts { + c.counts[k] = 0 + } } // Counts returns a copy of the Counters' map. diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 20e16875748..5e25be60f4f 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -25,7 +25,7 @@ limitations under the License. // Alternatively, use a Watcher implementation which will constantly watch // a source (e.g. the topology) and add and remove tablets as they are // added or removed from the source. -// For a Watcher example have a look at NewCellTabletsWatcher(). +// For a Watcher example have a look at NewTopologyWatcher(). // // Internally, the HealthCheck module is connected to each tablet and has a // streaming RPC (StreamHealth) open to receive periodic health infos. @@ -88,7 +88,7 @@ var ( refreshKnownTablets = true // topoReadConcurrency tells us how many topo reads are allowed in parallel. - topoReadConcurrency = 32 + topoReadConcurrency int64 = 32 // How much to sleep between each check. waitAvailableTabletInterval = 100 * time.Millisecond @@ -176,7 +176,7 @@ func registerWebUIFlags(fs *pflag.FlagSet) { fs.StringVar(&TabletURLTemplateString, "tablet_url_template", "http://{{.GetTabletHostPort}}", "Format string describing debug tablet url formatting. See getTabletDebugURL() for how to customize this.") fs.DurationVar(&refreshInterval, "tablet_refresh_interval", 1*time.Minute, "Tablet refresh interval.") fs.BoolVar(&refreshKnownTablets, "tablet_refresh_known_tablets", true, "Whether to reload the tablet's address/port map from topo in case they change.") - fs.IntVar(&topoReadConcurrency, "topo_read_concurrency", 32, "Concurrency of topo reads.") + fs.Int64Var(&topoReadConcurrency, "topo_read_concurrency", 32, "Concurrency of topo reads.") ParseTabletURLTemplateFromFlag() } @@ -362,7 +362,7 @@ func NewHealthCheck(ctx context.Context, retryDelay, healthCheckTimeout time.Dur } else if len(KeyspacesToWatch) > 0 { filter = NewFilterByKeyspace(KeyspacesToWatch) } - topoWatchers = append(topoWatchers, NewCellTabletsWatcher(ctx, topoServer, hc, filter, c, refreshInterval, refreshKnownTablets, topoReadConcurrency)) + topoWatchers = append(topoWatchers, NewTopologyWatcher(ctx, topoServer, hc, filter, c, refreshInterval, refreshKnownTablets, topoReadConcurrency)) } hc.topoWatchers = topoWatchers diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index a507528d3a2..7525ab82dfc 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -428,7 +428,7 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn shortCtx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer cancel() - tabletMap, err := tp.ts.GetTabletMap(shortCtx, aliases) + tabletMap, err := tp.ts.GetTabletMap(shortCtx, aliases, nil) if err != nil { log.Warningf("Error fetching tablets from topo: %v", err) // If we get a partial result we can still use it, otherwise return. diff --git a/go/vt/discovery/topology_watcher.go b/go/vt/discovery/topology_watcher.go index b3298f55700..dbee11c1610 100644 --- a/go/vt/discovery/topology_watcher.go +++ b/go/vt/discovery/topology_watcher.go @@ -70,8 +70,7 @@ type TopologyWatcher struct { cell string refreshInterval time.Duration refreshKnownTablets bool - getTablets func(tw *TopologyWatcher) ([]*topodata.TabletAlias, error) - sem chan int + concurrency int64 ctx context.Context cancelFunc context.CancelFunc // wg keeps track of all launched Go routines. @@ -92,34 +91,28 @@ type TopologyWatcher struct { } // NewTopologyWatcher returns a TopologyWatcher that monitors all -// the tablets that it is configured to watch, and reloads them periodically if needed. -// As of now there is only one implementation: watch all tablets in a cell. -func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthCheck, filter TabletFilter, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int, getTablets func(tw *TopologyWatcher) ([]*topodata.TabletAlias, error)) *TopologyWatcher { +// the tablets in a cell, and reloads them as needed. +func NewTopologyWatcher(ctx context.Context, topoServer *topo.Server, hc HealthCheck, f TabletFilter, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int64) *TopologyWatcher { tw := &TopologyWatcher{ topoServer: topoServer, healthcheck: hc, - tabletFilter: filter, + tabletFilter: f, cell: cell, refreshInterval: refreshInterval, refreshKnownTablets: refreshKnownTablets, - getTablets: getTablets, - sem: make(chan int, topoReadConcurrency), + concurrency: topoReadConcurrency, tablets: make(map[string]*tabletInfo), } tw.firstLoadChan = make(chan struct{}) - // We want the span from the context, but not the cancelation that comes with it + // We want the span from the context, but not the cancellation that comes with it spanContext := trace.CopySpan(context.Background(), ctx) tw.ctx, tw.cancelFunc = context.WithCancel(spanContext) return tw } -// NewCellTabletsWatcher returns a TopologyWatcher that monitors all -// the tablets in a cell, and reloads them as needed. -func NewCellTabletsWatcher(ctx context.Context, topoServer *topo.Server, hc HealthCheck, f TabletFilter, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int) *TopologyWatcher { - return NewTopologyWatcher(ctx, topoServer, hc, f, cell, refreshInterval, refreshKnownTablets, topoReadConcurrency, func(tw *TopologyWatcher) ([]*topodata.TabletAlias, error) { - return tw.topoServer.GetTabletAliasesByCell(ctx, tw.cell) - }) +func (tw *TopologyWatcher) getTablets() ([]*topo.TabletInfo, error) { + return tw.topoServer.GetTabletsByCell(tw.ctx, tw.cell, &topo.GetTabletsByCellOptions{Concurrency: tw.concurrency}) } // Start starts the topology watcher. @@ -149,30 +142,31 @@ func (tw *TopologyWatcher) Stop() { } func (tw *TopologyWatcher) loadTablets() { - var wg sync.WaitGroup newTablets := make(map[string]*tabletInfo) - // First get the list of relevant tabletAliases. - tabletAliases, err := tw.getTablets(tw) + // First get the list of all tablets. + tabletInfos, err := tw.getTablets() topologyWatcherOperations.Add(topologyWatcherOpListTablets, 1) if err != nil { topologyWatcherErrors.Add(topologyWatcherOpListTablets, 1) - select { - case <-tw.ctx.Done(): + // If we get a partial result error, we just log it and process the tablets that we did manage to fetch. + if topo.IsErrType(err, topo.PartialResult) { + log.Errorf("received partial result from getTablets for cell %v: %v", tw.cell, err) + } else { // For all other errors, just return. + log.Errorf("error getting tablets for cell: %v: %v", tw.cell, err) return - default: } - log.Errorf("cannot get tablets for cell: %v: %v", tw.cell, err) - return } // Accumulate a list of all known alias strings to use later // when sorting. - tabletAliasStrs := make([]string, 0, len(tabletAliases)) + tabletAliasStrs := make([]string, 0, len(tabletInfos)) tw.mu.Lock() - for _, tAlias := range tabletAliases { - aliasStr := topoproto.TabletAliasString(tAlias) + defer tw.mu.Unlock() + + for _, tInfo := range tabletInfos { + aliasStr := topoproto.TabletAliasString(tInfo.Alias) tabletAliasStrs = append(tabletAliasStrs, aliasStr) if !tw.refreshKnownTablets { @@ -182,38 +176,13 @@ func (tw *TopologyWatcher) loadTablets() { continue } } - - wg.Add(1) - go func(alias *topodata.TabletAlias) { - defer wg.Done() - tw.sem <- 1 // Wait for active queue to drain. - tablet, err := tw.topoServer.GetTablet(tw.ctx, alias) - topologyWatcherOperations.Add(topologyWatcherOpGetTablet, 1) - <-tw.sem // Done; enable next request to run. - if err != nil { - topologyWatcherErrors.Add(topologyWatcherOpGetTablet, 1) - select { - case <-tw.ctx.Done(): - return - default: - } - log.Errorf("cannot get tablet for alias %v: %v", alias, err) - return - } - tw.mu.Lock() - aliasStr := topoproto.TabletAliasString(alias) - newTablets[aliasStr] = &tabletInfo{ - alias: aliasStr, - tablet: tablet.Tablet, - } - tw.mu.Unlock() - }(tAlias) + // There's no network call here, so we just do the tablets one at a time instead of in parallel goroutines. + newTablets[aliasStr] = &tabletInfo{ + alias: aliasStr, + tablet: tInfo.Tablet, + } } - tw.mu.Unlock() - wg.Wait() - tw.mu.Lock() - for alias, newVal := range newTablets { if tw.tabletFilter != nil && !tw.tabletFilter.IsIncluded(newVal.tablet) { continue @@ -266,8 +235,6 @@ func (tw *TopologyWatcher) loadTablets() { tw.topoChecksum = crc32.ChecksumIEEE(buf.Bytes()) tw.lastRefresh = time.Now() - tw.mu.Unlock() - } // RefreshLag returns the time since the last refresh. diff --git a/go/vt/discovery/topology_watcher_test.go b/go/vt/discovery/topology_watcher_test.go index 3ac567acef8..bdf2c2dd2da 100644 --- a/go/vt/discovery/topology_watcher_test.go +++ b/go/vt/discovery/topology_watcher_test.go @@ -65,7 +65,7 @@ func TestStartAndCloseTopoWatcher(t *testing.T) { fhc := NewFakeHealthCheck(nil) defer fhc.Close() topologyWatcherOperations.ZeroAll() - tw := NewCellTabletsWatcher(context.Background(), ts, fhc, nil, "aa", 100*time.Microsecond, true, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 100*time.Microsecond, true, 5) done := make(chan bool, 3) result := make(chan bool, 1) @@ -102,9 +102,8 @@ func TestStartAndCloseTopoWatcher(t *testing.T) { done <- true _, ok := <-result - if !ok { - t.Fatal("timed out") - } + require.True(t, ok, "timed out") + } func TestCellTabletsWatcher(t *testing.T) { @@ -125,7 +124,7 @@ func checkWatcher(t *testing.T, refreshKnownTablets bool) { logger := logutil.NewMemoryLogger() topologyWatcherOperations.ZeroAll() counts := topologyWatcherOperations.Counts() - tw := NewCellTabletsWatcher(context.Background(), ts, fhc, nil, "aa", 10*time.Minute, refreshKnownTablets, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, nil, "aa", 10*time.Minute, refreshKnownTablets, 5) counts = checkOpCounts(t, counts, map[string]int64{}) checkChecksum(t, tw, 0) @@ -143,19 +142,18 @@ func checkWatcher(t *testing.T, refreshKnownTablets bool) { Keyspace: "keyspace", Shard: "shard", } - if err := ts.CreateTablet(context.Background(), tablet); err != nil { - t.Fatalf("CreateTablet failed: %v", err) - } + require.NoError(t, ts.CreateTablet(context.Background(), tablet), "CreateTablet failed for %v", tablet.Alias) + tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 1, "AddTablet": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "AddTablet": 1}) checkChecksum(t, tw, 3238442862) // Check the tablet is returned by GetAllTablets(). allTablets := fhc.GetAllTablets() key := TabletToMapKey(tablet) - if _, ok := allTablets[key]; !ok || len(allTablets) != 1 || !proto.Equal(allTablets[key], tablet) { - t.Errorf("fhc.GetAllTablets() = %+v; want %+v", allTablets, tablet) - } + assert.Len(t, allTablets, 1) + assert.Contains(t, allTablets, key) + assert.True(t, proto.Equal(tablet, allTablets[key])) // Add a second tablet to the topology. tablet2 := &topodatapb.Tablet{ @@ -170,75 +168,51 @@ func checkWatcher(t *testing.T, refreshKnownTablets bool) { Keyspace: "keyspace", Shard: "shard", } - if err := ts.CreateTablet(context.Background(), tablet2); err != nil { - t.Fatalf("CreateTablet failed: %v", err) - } + require.NoError(t, ts.CreateTablet(context.Background(), tablet2), "CreateTablet failed for %v", tablet2.Alias) tw.loadTablets() - // If refreshKnownTablets is disabled, only the new tablet is read - // from the topo - if refreshKnownTablets { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "AddTablet": 1}) - } else { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 1, "AddTablet": 1}) - } + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "AddTablet": 1}) checkChecksum(t, tw, 2762153755) // Check the new tablet is returned by GetAllTablets(). allTablets = fhc.GetAllTablets() key = TabletToMapKey(tablet2) - if _, ok := allTablets[key]; !ok || len(allTablets) != 2 || !proto.Equal(allTablets[key], tablet2) { - t.Errorf("fhc.GetAllTablets() = %+v; want %+v", allTablets, tablet2) - } - - // Load the tablets again to show that when refreshKnownTablets is disabled, - // only the list is read from the topo and the checksum doesn't change - tw.loadTablets() - if refreshKnownTablets { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2}) - } else { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1}) - } - checkChecksum(t, tw, 2762153755) + assert.Len(t, allTablets, 2) + assert.Contains(t, allTablets, key) + assert.True(t, proto.Equal(tablet2, allTablets[key])) // same tablet, different port, should update (previous // one should go away, new one be added) // // if refreshKnownTablets is disabled, this case is *not* - // detected and the tablet remains in the topo using the + // detected and the tablet remains in the healthcheck using the // old key origTablet := tablet.CloneVT() origKey := TabletToMapKey(tablet) tablet.PortMap["vt"] = 456 - if _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { + _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { t.PortMap["vt"] = 456 return nil - }); err != nil { - t.Fatalf("UpdateTabletFields failed: %v", err) - } + }) + require.Nil(t, err, "UpdateTabletFields failed") + tw.loadTablets() allTablets = fhc.GetAllTablets() key = TabletToMapKey(tablet) if refreshKnownTablets { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "ReplaceTablet": 1}) - - if _, ok := allTablets[key]; !ok || len(allTablets) != 2 || !proto.Equal(allTablets[key], tablet) { - t.Errorf("fhc.GetAllTablets() = %+v; want %+v", allTablets, tablet) - } - if _, ok := allTablets[origKey]; ok { - t.Errorf("fhc.GetAllTablets() = %+v; don't want %v", allTablets, origKey) - } + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "ReplaceTablet": 1}) + assert.Len(t, allTablets, 2) + assert.Contains(t, allTablets, key) + assert.True(t, proto.Equal(tablet, allTablets[key])) + assert.NotContains(t, allTablets, origKey) checkChecksum(t, tw, 2762153755) } else { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1}) - - if _, ok := allTablets[origKey]; !ok || len(allTablets) != 2 || !proto.Equal(allTablets[origKey], origTablet) { - t.Errorf("fhc.GetAllTablets() = %+v; want %+v", allTablets, origTablet) - } - if _, ok := allTablets[key]; ok { - t.Errorf("fhc.GetAllTablets() = %+v; don't want %v", allTablets, key) - } + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "ReplaceTablet": 0}) + assert.Len(t, allTablets, 2) + assert.Contains(t, allTablets, origKey) + assert.True(t, proto.Equal(origTablet, allTablets[origKey])) + assert.NotContains(t, allTablets, key) checkChecksum(t, tw, 2762153755) } @@ -248,94 +222,77 @@ func checkWatcher(t *testing.T, refreshKnownTablets bool) { if refreshKnownTablets { origTablet := tablet.CloneVT() origTablet2 := tablet2.CloneVT() - if _, err := ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { + _, err := ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { t.Hostname = tablet.Hostname t.PortMap = tablet.PortMap tablet2 = t return nil - }); err != nil { - t.Fatalf("UpdateTabletFields failed: %v", err) - } - if _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { + }) + require.Nil(t, err, "UpdateTabletFields failed") + _, err = ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { t.Hostname = "host3" tablet = t return nil - }); err != nil { - t.Fatalf("UpdateTabletFields failed: %v", err) - } + }) + require.Nil(t, err, "UpdateTabletFields failed") tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "ReplaceTablet": 2}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "ReplaceTablet": 2}) allTablets = fhc.GetAllTablets() key2 := TabletToMapKey(tablet2) - if _, ok := allTablets[key2]; !ok { - t.Fatalf("tablet was lost because it's reusing an address recently used by another tablet: %v", key2) - } + assert.Contains(t, allTablets, key2, "tablet was lost because it's reusing an address recently used by another tablet: %v", key2) // Change tablets back to avoid altering later tests. - if _, err := ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { + _, err = ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { t.Hostname = origTablet2.Hostname t.PortMap = origTablet2.PortMap tablet2 = t return nil - }); err != nil { - t.Fatalf("UpdateTabletFields failed: %v", err) - } - if _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { + }) + require.Nil(t, err, "UpdateTabletFields failed") + + _, err = ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { t.Hostname = origTablet.Hostname tablet = t return nil - }); err != nil { - t.Fatalf("UpdateTabletFields failed: %v", err) - } + }) + require.Nil(t, err, "UpdateTabletFields failed") + tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "ReplaceTablet": 2}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "ReplaceTablet": 2}) } // Remove the tablet and check that it is detected as being gone. - if err := ts.DeleteTablet(context.Background(), tablet.Alias); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } - if _, err := topo.FixShardReplication(context.Background(), ts, logger, "aa", "keyspace", "shard"); err != nil { - t.Fatalf("FixShardReplication failed: %v", err) - } + require.NoError(t, ts.DeleteTablet(context.Background(), tablet.Alias)) + + _, err = topo.FixShardReplication(context.Background(), ts, logger, "aa", "keyspace", "shard") + require.Nil(t, err, "FixShardReplication failed") tw.loadTablets() - if refreshKnownTablets { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 1, "RemoveTablet": 1}) - } else { - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "RemoveTablet": 1}) - } + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "RemoveTablet": 1}) checkChecksum(t, tw, 789108290) allTablets = fhc.GetAllTablets() + assert.Len(t, allTablets, 1) key = TabletToMapKey(tablet) - if _, ok := allTablets[key]; ok || len(allTablets) != 1 { - t.Errorf("fhc.GetAllTablets() = %+v; don't want %v", allTablets, key) - } + assert.NotContains(t, allTablets, key) + key = TabletToMapKey(tablet2) - if _, ok := allTablets[key]; !ok || len(allTablets) != 1 || !proto.Equal(allTablets[key], tablet2) { - t.Errorf("fhc.GetAllTablets() = %+v; want %+v", allTablets, tablet2) - } + assert.Contains(t, allTablets, key) + assert.True(t, proto.Equal(tablet2, allTablets[key])) // Remove the other and check that it is detected as being gone. - if err := ts.DeleteTablet(context.Background(), tablet2.Alias); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } - if _, err := topo.FixShardReplication(context.Background(), ts, logger, "aa", "keyspace", "shard"); err != nil { - t.Fatalf("FixShardReplication failed: %v", err) - } + require.NoError(t, ts.DeleteTablet(context.Background(), tablet2.Alias)) + _, err = topo.FixShardReplication(context.Background(), ts, logger, "aa", "keyspace", "shard") + require.Nil(t, err, "FixShardReplication failed") tw.loadTablets() checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "RemoveTablet": 1}) checkChecksum(t, tw, 0) allTablets = fhc.GetAllTablets() + assert.Len(t, allTablets, 0) key = TabletToMapKey(tablet) - if _, ok := allTablets[key]; ok || len(allTablets) != 0 { - t.Errorf("fhc.GetAllTablets() = %+v; don't want %v", allTablets, key) - } + assert.NotContains(t, allTablets, key) key = TabletToMapKey(tablet2) - if _, ok := allTablets[key]; ok || len(allTablets) != 0 { - t.Errorf("fhc.GetAllTablets() = %+v; don't want %v", allTablets, key) - } + assert.NotContains(t, allTablets, key) tw.Stop() } @@ -402,19 +359,13 @@ func TestFilterByShard(t *testing.T) { for _, tc := range testcases { fbs, err := NewFilterByShard(tc.filters) - if err != nil { - t.Errorf("cannot create FilterByShard for filters %v: %v", tc.filters, err) - } + require.Nil(t, err, "cannot create FilterByShard for filters %v", tc.filters) tablet := &topodatapb.Tablet{ Keyspace: tc.keyspace, Shard: tc.shard, } - - got := fbs.IsIncluded(tablet) - if got != tc.included { - t.Errorf("isIncluded(%v,%v) for filters %v returned %v but expected %v", tc.keyspace, tc.shard, tc.filters, got, tc.included) - } + require.Equal(t, tc.included, fbs.IsIncluded(tablet)) } } @@ -444,7 +395,7 @@ func TestFilterByKeyspace(t *testing.T) { f := NewFilterByKeyspace(testKeyspacesToWatch) ts := memorytopo.NewServer(ctx, testCell) defer ts.Close() - tw := NewCellTabletsWatcher(context.Background(), ts, hc, f, testCell, 10*time.Minute, true, 5) + tw := NewTopologyWatcher(context.Background(), ts, hc, f, testCell, 10*time.Minute, true, 5) for _, test := range testFilterByKeyspace { // Add a new tablet to the topology. @@ -462,22 +413,21 @@ func TestFilterByKeyspace(t *testing.T) { Shard: testShard, } - got := f.IsIncluded(tablet) - if got != test.expected { - t.Errorf("isIncluded(%v) for keyspace %v returned %v but expected %v", test.keyspace, test.keyspace, got, test.expected) - } + assert.Equal(t, test.expected, f.IsIncluded(tablet)) - if err := ts.CreateTablet(context.Background(), tablet); err != nil { - t.Errorf("CreateTablet failed: %v", err) - } + // Make this fatal because there is no point continuing if CreateTablet fails + require.NoError(t, ts.CreateTablet(context.Background(), tablet)) tw.loadTablets() key := TabletToMapKey(tablet) allTablets := hc.GetAllTablets() - if _, ok := allTablets[key]; ok != test.expected && proto.Equal(allTablets[key], tablet) != test.expected { - t.Errorf("Error adding tablet - got %v; want %v", ok, test.expected) + if test.expected { + assert.Contains(t, allTablets, key) + } else { + assert.NotContains(t, allTablets, key) } + assert.Equal(t, test.expected, proto.Equal(tablet, allTablets[key])) // Replace the tablet we added above tabletReplacement := &topodatapb.Tablet{ @@ -492,35 +442,31 @@ func TestFilterByKeyspace(t *testing.T) { Keyspace: test.keyspace, Shard: testShard, } - got = f.IsIncluded(tabletReplacement) - if got != test.expected { - t.Errorf("isIncluded(%v) for keyspace %v returned %v but expected %v", test.keyspace, test.keyspace, got, test.expected) - } - if err := ts.CreateTablet(context.Background(), tabletReplacement); err != nil { - t.Errorf("CreateTablet failed: %v", err) - } + assert.Equal(t, test.expected, f.IsIncluded(tabletReplacement)) + require.NoError(t, ts.CreateTablet(context.Background(), tabletReplacement)) tw.loadTablets() key = TabletToMapKey(tabletReplacement) allTablets = hc.GetAllTablets() - if _, ok := allTablets[key]; ok != test.expected && proto.Equal(allTablets[key], tabletReplacement) != test.expected { - t.Errorf("Error replacing tablet - got %v; want %v", ok, test.expected) + if test.expected { + assert.Contains(t, allTablets, key) + } else { + assert.NotContains(t, allTablets, key) } + assert.Equal(t, test.expected, proto.Equal(tabletReplacement, allTablets[key])) // Delete the tablet - if err := ts.DeleteTablet(context.Background(), tabletReplacement.Alias); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } + require.NoError(t, ts.DeleteTablet(context.Background(), tabletReplacement.Alias)) } } -// TestFilterByKeypsaceSkipsIgnoredTablets confirms a bug fix for the case when a TopologyWatcher +// TestFilterByKeyspaceSkipsIgnoredTablets confirms a bug fix for the case when a TopologyWatcher // has a FilterByKeyspace TabletFilter configured along with refreshKnownTablets turned off. We want // to ensure that the TopologyWatcher: -// - does not continuosly call GetTablets for tablets that do not satisfy the filter -// - does not add or remove these filtered out tablets from the its healtcheck -func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { +// - does not continuously call GetTablets for tablets that do not satisfy the filter +// - does not add or remove these filtered out tablets from its healthcheck +func TestFilterByKeyspaceSkipsIgnoredTablets(t *testing.T) { ctx := utils.LeakCheckContext(t) ts := memorytopo.NewServer(ctx, "aa") @@ -530,7 +476,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { topologyWatcherOperations.ZeroAll() counts := topologyWatcherOperations.Counts() f := NewFilterByKeyspace(testKeyspacesToWatch) - tw := NewCellTabletsWatcher(context.Background(), ts, fhc, f, "aa", 10*time.Minute, false /*refreshKnownTablets*/, 5) + tw := NewTopologyWatcher(context.Background(), ts, fhc, f, "aa", 10*time.Minute, false /*refreshKnownTablets*/, 5) counts = checkOpCounts(t, counts, map[string]int64{}) checkChecksum(t, tw, 0) @@ -551,7 +497,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { require.NoError(t, ts.CreateTablet(context.Background(), tablet)) tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 1, "AddTablet": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "AddTablet": 1}) checkChecksum(t, tw, 3238442862) // Check tablet is reported by HealthCheck @@ -576,7 +522,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { require.NoError(t, ts.CreateTablet(context.Background(), tablet2)) tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0}) checkChecksum(t, tw, 2762153755) // Check the new tablet is NOT reported by HealthCheck. @@ -588,7 +534,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { // Load the tablets again to show that when refreshKnownTablets is disabled, // only the list is read from the topo and the checksum doesn't change tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0}) checkChecksum(t, tw, 2762153755) // With refreshKnownTablets set to false, changes to the port map for the same tablet alias @@ -600,7 +546,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { require.NoError(t, err) tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0}) checkChecksum(t, tw, 2762153755) allTablets = fhc.GetAllTablets() @@ -616,7 +562,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { require.NoError(t, ts.DeleteTablet(context.Background(), tablet.Alias)) tw.loadTablets() - counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "RemoveTablet": 1}) + counts = checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0, "RemoveTablet": 1}) checkChecksum(t, tw, 789108290) assert.Empty(t, fhc.GetAllTablets()) @@ -624,7 +570,7 @@ func TestFilterByKeypsaceSkipsIgnoredTablets(t *testing.T) { require.NoError(t, ts.DeleteTablet(context.Background(), tablet2.Alias)) tw.loadTablets() - checkOpCounts(t, counts, map[string]int64{"ListTablets": 1}) + checkOpCounts(t, counts, map[string]int64{"ListTablets": 1, "GetTablet": 0}) checkChecksum(t, tw, 0) assert.Empty(t, fhc.GetAllTablets()) diff --git a/go/vt/topo/consultopo/error.go b/go/vt/topo/consultopo/error.go index 42f474e065b..62167a4d295 100644 --- a/go/vt/topo/consultopo/error.go +++ b/go/vt/topo/consultopo/error.go @@ -40,15 +40,16 @@ var ( // are either application-level errors, or context errors. func convertError(err error, nodePath string) error { // Unwrap errors from the Go HTTP client. - if urlErr, ok := err.(*url.Error); ok { + var urlErr *url.Error + if errors.As(err, &urlErr) { err = urlErr.Err } // Convert specific sentinel values. - switch err { - case context.Canceled: + switch { + case errors.Is(err, context.Canceled): return topo.NewError(topo.Interrupted, nodePath) - case context.DeadlineExceeded: + case errors.Is(err, context.DeadlineExceeded): return topo.NewError(topo.Timeout, nodePath) } diff --git a/go/vt/topo/errors.go b/go/vt/topo/errors.go index a645f1aa178..3be4b60b103 100644 --- a/go/vt/topo/errors.go +++ b/go/vt/topo/errors.go @@ -36,6 +36,7 @@ const ( NoUpdateNeeded NoImplementation NoReadOnlyImplementation + ResourceExhausted ) // Error represents a topo error. @@ -68,6 +69,8 @@ func NewError(code ErrorCode, node string) error { message = fmt.Sprintf("no such topology implementation %s", node) case NoReadOnlyImplementation: message = fmt.Sprintf("no read-only topology implementation %s", node) + case ResourceExhausted: + message = fmt.Sprintf("server resource exhausted: %s", node) default: message = fmt.Sprintf("unknown code: %s", node) } diff --git a/go/vt/topo/etcd2topo/error.go b/go/vt/topo/etcd2topo/error.go index e784fecd9b9..5e13d0bdf8d 100644 --- a/go/vt/topo/etcd2topo/error.go +++ b/go/vt/topo/etcd2topo/error.go @@ -45,7 +45,8 @@ func convertError(err error, nodePath string) error { return nil } - if typeErr, ok := err.(rpctypes.EtcdError); ok { + var typeErr rpctypes.EtcdError + if errors.As(err, &typeErr) { switch typeErr.Code() { case codes.NotFound: return topo.NewError(topo.NoNode, nodePath) @@ -61,6 +62,8 @@ func convertError(err error, nodePath string) error { // etcd primary election is failing, so timeout // also sounds reasonable there. return topo.NewError(topo.Timeout, nodePath) + case codes.ResourceExhausted: + return topo.NewError(topo.ResourceExhausted, nodePath) } return err } @@ -74,15 +77,17 @@ func convertError(err error, nodePath string) error { return topo.NewError(topo.Interrupted, nodePath) case codes.DeadlineExceeded: return topo.NewError(topo.Timeout, nodePath) + case codes.ResourceExhausted: + return topo.NewError(topo.ResourceExhausted, nodePath) default: return err } } - switch err { - case context.Canceled: + switch { + case errors.Is(err, context.Canceled): return topo.NewError(topo.Interrupted, nodePath) - case context.DeadlineExceeded: + case errors.Is(err, context.DeadlineExceeded): return topo.NewError(topo.Timeout, nodePath) default: return err diff --git a/go/vt/topo/memorytopo/file.go b/go/vt/topo/memorytopo/file.go index 0007203799f..cc19eb79011 100644 --- a/go/vt/topo/memorytopo/file.go +++ b/go/vt/topo/memorytopo/file.go @@ -187,6 +187,9 @@ func (c *Conn) List(ctx context.Context, filePathPrefix string) ([]topo.KVInfo, if c.factory.err != nil { return nil, c.factory.err } + if c.factory.listErr != nil { + return nil, c.factory.listErr + } dir, file := path.Split(filePathPrefix) // Get the node to list. diff --git a/go/vt/topo/memorytopo/memorytopo.go b/go/vt/topo/memorytopo/memorytopo.go index f24b2f6c89e..ae33bb73edd 100644 --- a/go/vt/topo/memorytopo/memorytopo.go +++ b/go/vt/topo/memorytopo/memorytopo.go @@ -70,6 +70,9 @@ type Factory struct { // err is used for testing purposes to force queries / watches // to return the given error err error + // listErr is used for testing purposed to fake errors from + // calls to List. + listErr error } // HasGlobalReadOnlyCell is part of the topo.Factory interface. @@ -348,3 +351,10 @@ func (f *Factory) recursiveDelete(n *node) { f.recursiveDelete(parent) } } + +func (f *Factory) SetListError(err error) { + f.mu.Lock() + defer f.mu.Unlock() + + f.listErr = err +} diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index 752001438f4..7343db2c0ab 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -666,7 +666,7 @@ func (ts *Server) GetTabletMapForShardByCell(ctx context.Context, keyspace, shar // get the tablets for the cells we were able to reach, forward // ErrPartialResult from FindAllTabletAliasesInShard - result, gerr := ts.GetTabletMap(ctx, aliases) + result, gerr := ts.GetTabletMap(ctx, aliases, nil) if gerr == nil && err != nil { gerr = err } diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index 5254252db1c..5359f607c41 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -24,6 +24,8 @@ import ( "sync" "time" + "golang.org/x/sync/semaphore" + "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/vt/key" @@ -282,10 +284,17 @@ func (ts *Server) GetTabletAliasesByCell(ctx context.Context, cell string) ([]*t return result, nil } +// GetTabletsByCellOptions controls the behavior of +// Server.FindAllShardsInKeyspace. +type GetTabletsByCellOptions struct { + // Concurrency controls the maximum number of concurrent calls to GetTablet. + Concurrency int64 +} + // GetTabletsByCell returns all the tablets in the cell. // It returns ErrNoNode if the cell doesn't exist. // It returns (nil, nil) if the cell exists, but there are no tablets in it. -func (ts *Server) GetTabletsByCell(ctx context.Context, cellAlias string) ([]*TabletInfo, error) { +func (ts *Server) GetTabletsByCell(ctx context.Context, cellAlias string, opt *GetTabletsByCellOptions) ([]*TabletInfo, error) { // If the cell doesn't exist, this will return ErrNoNode. cellConn, err := ts.ConnForCell(ctx, cellAlias) if err != nil { @@ -293,10 +302,12 @@ func (ts *Server) GetTabletsByCell(ctx context.Context, cellAlias string) ([]*Ta } listResults, err := cellConn.List(ctx, TabletsPath) if err != nil || len(listResults) == 0 { - // Currently the ZooKeeper and Memory topo implementations do not support scans + // Currently the ZooKeeper implementation does not support scans // so we fall back to the more costly method of fetching the tablets one by one. - if IsErrType(err, NoImplementation) { - return ts.GetTabletsIndividuallyByCell(ctx, cellAlias) + // In the etcd case, it is possible that the response is too large. We also fall + // back to fetching the tablets one by one in that case. + if IsErrType(err, NoImplementation) || IsErrType(err, ResourceExhausted) { + return ts.GetTabletsIndividuallyByCell(ctx, cellAlias, opt) } if IsErrType(err, NoNode) { return nil, nil @@ -320,7 +331,7 @@ func (ts *Server) GetTabletsByCell(ctx context.Context, cellAlias string) ([]*Ta // directly support the topoConn.List() functionality. // It returns ErrNoNode if the cell doesn't exist. // It returns (nil, nil) if the cell exists, but there are no tablets in it. -func (ts *Server) GetTabletsIndividuallyByCell(ctx context.Context, cell string) ([]*TabletInfo, error) { +func (ts *Server) GetTabletsIndividuallyByCell(ctx context.Context, cell string, opt *GetTabletsByCellOptions) ([]*TabletInfo, error) { // If the cell doesn't exist, this will return ErrNoNode. aliases, err := ts.GetTabletAliasesByCell(ctx, cell) if err != nil { @@ -328,7 +339,7 @@ func (ts *Server) GetTabletsIndividuallyByCell(ctx context.Context, cell string) } sort.Sort(topoproto.TabletAliasList(aliases)) - tabletMap, err := ts.GetTabletMap(ctx, aliases) + tabletMap, err := ts.GetTabletMap(ctx, aliases, opt) if err != nil { // we got another error than topo.ErrNoNode return nil, err @@ -502,41 +513,62 @@ func DeleteTabletReplicationData(ctx context.Context, ts *Server, tablet *topoda } // GetTabletMap tries to read all the tablets in the provided list, -// and returns them all in a map. -// If error is ErrPartialResult, the results in the dictionary are +// and returns them in a map. +// If error is ErrPartialResult, the results in the map are // incomplete, meaning some tablets couldn't be read. // The map is indexed by topoproto.TabletAliasString(tablet alias). -func (ts *Server) GetTabletMap(ctx context.Context, tabletAliases []*topodatapb.TabletAlias) (map[string]*TabletInfo, error) { +func (ts *Server) GetTabletMap(ctx context.Context, tabletAliases []*topodatapb.TabletAlias, opt *GetTabletsByCellOptions) (map[string]*TabletInfo, error) { span, ctx := trace.NewSpan(ctx, "topo.GetTabletMap") span.Annotate("num_tablets", len(tabletAliases)) defer span.Finish() - wg := sync.WaitGroup{} - mutex := sync.Mutex{} + var ( + mu sync.Mutex + wg sync.WaitGroup + tabletMap = make(map[string]*TabletInfo) + returnErr error + // Previously this was always run with unlimited concurrency, so 32 should be fine. + concurrency int64 = 32 + ) - tabletMap := make(map[string]*TabletInfo) - var someError error + if opt != nil && opt.Concurrency > 0 { + concurrency = opt.Concurrency + } + var sem = semaphore.NewWeighted(concurrency) for _, tabletAlias := range tabletAliases { wg.Add(1) go func(tabletAlias *topodatapb.TabletAlias) { defer wg.Done() + if err := sem.Acquire(ctx, 1); err != nil { + // Only happens if context is cancelled. + mu.Lock() + defer mu.Unlock() + log.Warningf("%v: %v", tabletAlias, err) + // We only need to set this on the first error. + if returnErr == nil { + returnErr = NewError(PartialResult, tabletAlias.GetCell()) + } + return + } tabletInfo, err := ts.GetTablet(ctx, tabletAlias) - mutex.Lock() + sem.Release(1) + mu.Lock() + defer mu.Unlock() if err != nil { log.Warningf("%v: %v", tabletAlias, err) // There can be data races removing nodes - ignore them for now. - if !IsErrType(err, NoNode) { - someError = NewError(PartialResult, "") + // We only need to set this on first error. + if returnErr == nil && !IsErrType(err, NoNode) { + returnErr = NewError(PartialResult, tabletAlias.GetCell()) } } else { tabletMap[topoproto.TabletAliasString(tabletAlias)] = tabletInfo } - mutex.Unlock() }(tabletAlias) } wg.Wait() - return tabletMap, someError + return tabletMap, returnErr } // InitTablet creates or updates a tablet. If no parent is specified diff --git a/go/vt/topo/tablet_test.go b/go/vt/topo/tablet_test.go new file mode 100644 index 00000000000..04eea71a8a2 --- /dev/null +++ b/go/vt/topo/tablet_test.go @@ -0,0 +1,118 @@ +/* +Copyright 2023 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 topo_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +// Test various cases of calls to GetTabletsByCell. +// GetTabletsByCell first tries to get all the tablets using List. +// If the response is too large, we will get an error, and fall back to one tablet at a time. +func TestServerGetTabletsByCell(t *testing.T) { + tests := []struct { + name string + tablets int + opt *topo.GetTabletsByCellOptions + listError error + }{ + { + name: "negative concurrency", + tablets: 1, + // Ensure this doesn't panic. + opt: &topo.GetTabletsByCellOptions{Concurrency: -1}, + }, + { + name: "single", + tablets: 1, + // Make sure the defaults apply as expected. + opt: nil, + }, + { + name: "multiple", + // should work with more than 1 tablet + tablets: 32, + opt: &topo.GetTabletsByCellOptions{Concurrency: 8}, + }, + { + name: "multiple with list error", + // should work with more than 1 tablet when List returns an error + tablets: 32, + opt: &topo.GetTabletsByCellOptions{Concurrency: 8}, + listError: topo.NewError(topo.ResourceExhausted, ""), + }, + } + + const cell = "zone1" + const keyspace = "keyspace" + const shard = "shard" + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ts, factory := memorytopo.NewServerAndFactory(ctx, cell) + defer ts.Close() + if tt.listError != nil { + factory.SetListError(tt.listError) + } + + // Create an ephemeral keyspace and generate shard records within + // the keyspace to fetch later. + require.NoError(t, ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{})) + require.NoError(t, ts.CreateShard(ctx, keyspace, shard)) + + tablets := make([]*topo.TabletInfo, tt.tablets) + + for i := 0; i < tt.tablets; i++ { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: cell, + Uid: uint32(i), + }, + Hostname: "host1", + PortMap: map[string]int32{ + "vt": int32(i), + }, + Keyspace: keyspace, + Shard: shard, + } + tInfo := &topo.TabletInfo{Tablet: tablet} + tablets[i] = tInfo + require.NoError(t, ts.CreateTablet(ctx, tablet)) + } + + // Verify that we return a complete list of tablets and that each + // tablet matches what we expect. + out, err := ts.GetTabletsByCell(ctx, cell, tt.opt) + require.NoError(t, err) + require.Len(t, out, tt.tablets) + + for i, tab := range tablets { + require.Equal(t, tab.Tablet, tablets[i].Tablet) + } + }) + } +} diff --git a/go/vt/topo/zk2topo/error.go b/go/vt/topo/zk2topo/error.go index 1ebc3896f40..1149ad60bf3 100644 --- a/go/vt/topo/zk2topo/error.go +++ b/go/vt/topo/zk2topo/error.go @@ -18,6 +18,7 @@ package zk2topo import ( "context" + "errors" "github.com/z-division/go-zookeeper/zk" @@ -26,20 +27,20 @@ import ( // Error codes returned by the zookeeper Go client: func convertError(err error, node string) error { - switch err { - case zk.ErrBadVersion: + switch { + case errors.Is(err, zk.ErrBadVersion): return topo.NewError(topo.BadVersion, node) - case zk.ErrNoNode: + case errors.Is(err, zk.ErrNoNode): return topo.NewError(topo.NoNode, node) - case zk.ErrNodeExists: + case errors.Is(err, zk.ErrNodeExists): return topo.NewError(topo.NodeExists, node) - case zk.ErrNotEmpty: + case errors.Is(err, zk.ErrNotEmpty): return topo.NewError(topo.NodeNotEmpty, node) - case zk.ErrSessionExpired: + case errors.Is(err, zk.ErrSessionExpired): return topo.NewError(topo.Timeout, node) - case context.Canceled: + case errors.Is(err, context.Canceled): return topo.NewError(topo.Interrupted, node) - case context.DeadlineExceeded: + case errors.Is(err, context.DeadlineExceeded): return topo.NewError(topo.Timeout, node) } return err diff --git a/go/vt/topotools/tablet.go b/go/vt/topotools/tablet.go index 8bbca4b8c03..76f9e3d6cec 100644 --- a/go/vt/topotools/tablet.go +++ b/go/vt/topotools/tablet.go @@ -127,7 +127,7 @@ func DoCellsHaveRdonlyTablets(ctx context.Context, ts *topo.Server, cells []stri } for _, cell := range cells { - tablets, err := ts.GetTabletsByCell(ctx, cell) + tablets, err := ts.GetTabletsByCell(ctx, cell, nil) if err != nil { return false, err } diff --git a/go/vt/topotools/utils.go b/go/vt/topotools/utils.go index 6b618383a1e..6d1522e04e7 100644 --- a/go/vt/topotools/utils.go +++ b/go/vt/topotools/utils.go @@ -43,7 +43,7 @@ func GetTabletMapForCell(ctx context.Context, ts *topo.Server, cell string) (map if err != nil { return nil, err } - tabletMap, err := ts.GetTabletMap(ctx, aliases) + tabletMap, err := ts.GetTabletMap(ctx, aliases, nil) if err != nil { // we got another error than topo.ErrNoNode return nil, err @@ -65,7 +65,7 @@ func GetAllTabletsAcrossCells(ctx context.Context, ts *topo.Server) ([]*topo.Tab wg.Add(len(cells)) for i, cell := range cells { go func(i int, cell string) { - results[i], errors[i] = ts.GetTabletsByCell(ctx, cell) + results[i], errors[i] = ts.GetTabletsByCell(ctx, cell, nil) wg.Done() }(i, cell) } diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index feee4e30ed2..de63ba2cdc2 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -1981,7 +1981,7 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable case len(req.TabletAliases) > 0: span.Annotate("tablet_aliases", strings.Join(topoproto.TabletAliasList(req.TabletAliases).ToStringSlice(), ",")) - tabletMap, err = s.ts.GetTabletMap(ctx, req.TabletAliases) + tabletMap, err = s.ts.GetTabletMap(ctx, req.TabletAliases, nil) if err != nil { err = fmt.Errorf("GetTabletMap(%v) failed: %w", req.TabletAliases, err) } @@ -2057,7 +2057,7 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable go func(cell string) { defer wg.Done() - tablets, err := s.ts.GetTabletsByCell(ctx, cell) + tablets, err := s.ts.GetTabletsByCell(ctx, cell, nil) if err != nil { if req.Strict { log.Infof("GetTablets got an error from cell %s: %s. Running in strict mode, so canceling other cell RPCs", cell, err) @@ -4390,7 +4390,7 @@ func (s *VtctldServer) ValidateShard(ctx context.Context, req *vtctldatapb.Valid getTabletMapCtx, getTabletMapCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer getTabletMapCancel() - tabletMap, _ := s.ts.GetTabletMap(getTabletMapCtx, aliases) + tabletMap, _ := s.ts.GetTabletMap(getTabletMapCtx, aliases, nil) var primaryAlias *topodatapb.TabletAlias for _, alias := range aliases { diff --git a/go/vt/vtctl/grpcvtctldserver/topo.go b/go/vt/vtctl/grpcvtctldserver/topo.go index 70fae6613aa..5ec369ca17f 100644 --- a/go/vt/vtctl/grpcvtctldserver/topo.go +++ b/go/vt/vtctl/grpcvtctldserver/topo.go @@ -161,7 +161,7 @@ func deleteShardCell(ctx context.Context, ts *topo.Server, keyspace string, shar // Get all the tablet records for the aliases we've collected. Note that // GetTabletMap ignores ErrNoNode, which is convenient for our purpose; it // means a tablet was deleted but is still referenced. - tabletMap, err := ts.GetTabletMap(ctx, aliases) + tabletMap, err := ts.GetTabletMap(ctx, aliases, nil) if err != nil { return fmt.Errorf("GetTabletMap() failed: %w", err) } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index ec39efa875b..d15e9dc1bbd 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -2705,7 +2705,7 @@ func (s *Server) DeleteShard(ctx context.Context, keyspace, shard string, recurs // GetTabletMap ignores ErrNoNode, and it's good for // our purpose, it means a tablet was deleted but is // still referenced. - tabletMap, err := s.ts.GetTabletMap(ctx, aliases) + tabletMap, err := s.ts.GetTabletMap(ctx, aliases, nil) if err != nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "GetTabletMap() failed: %v", err) } diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go index 4ac2e79d38b..78392a4b078 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go @@ -83,14 +83,6 @@ type ThrottlerInterface interface { ResetConfiguration() } -// TopologyWatcherInterface defines the public interface that is implemented by -// discovery.LegacyTopologyWatcher. It is only used here to allow mocking out -// go/vt/discovery.LegacyTopologyWatcher. -type TopologyWatcherInterface interface { - Start() - Stop() -} - // TxThrottlerName is the name the wrapped go/vt/throttler object will be registered with // go/vt/throttler.GlobalManager. const TxThrottlerName = "TransactionThrottler" diff --git a/go/vt/wrangler/shard.go b/go/vt/wrangler/shard.go index c1c65b0407b..6b74f32031e 100644 --- a/go/vt/wrangler/shard.go +++ b/go/vt/wrangler/shard.go @@ -113,7 +113,7 @@ func (wr *Wrangler) DeleteShard(ctx context.Context, keyspace, shard string, rec // GetTabletMap ignores ErrNoNode, and it's good for // our purpose, it means a tablet was deleted but is // still referenced. - tabletMap, err := wr.ts.GetTabletMap(ctx, aliases) + tabletMap, err := wr.ts.GetTabletMap(ctx, aliases, nil) if err != nil { return fmt.Errorf("GetTabletMap() failed: %v", err) } diff --git a/go/vt/wrangler/split.go b/go/vt/wrangler/split.go index ba67fd8efef..543d50a808d 100644 --- a/go/vt/wrangler/split.go +++ b/go/vt/wrangler/split.go @@ -40,7 +40,7 @@ const ( // on a Shard. func (wr *Wrangler) SetSourceShards(ctx context.Context, keyspace, shard string, sources []*topodatapb.TabletAlias, tables []string) error { // Read the source tablets. - sourceTablets, err := wr.ts.GetTabletMap(ctx, sources) + sourceTablets, err := wr.ts.GetTabletMap(ctx, sources, nil) if err != nil { return err } From 327549e73af888aefcac07275700c200d3b31170 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 13 Dec 2023 03:40:34 +0530 Subject: [PATCH 116/119] Pass on vindex errors with wrap than overriding them (#14737) Co-authored-by: Florent Poinsard --- go/test/endtoend/vtgate/misc_test.go | 56 +++++++++++++++++-- .../vtgate/queries/dml/insert_test.go | 12 ++-- go/vt/vterrors/code.go | 8 ++- .../planbuilder/testdata/dml_cases.json | 12 ++-- .../testdata/unsupported_cases.json | 2 +- go/vt/vtgate/vindexes/consistent_lookup.go | 7 ++- go/vt/vtgate/vindexes/lookup_hash.go | 21 +++---- go/vt/vtgate/vindexes/lookup_hash_test.go | 10 +--- go/vt/vtgate/vindexes/lookup_internal.go | 27 +++++---- go/vt/vtgate/vindexes/lookup_test.go | 8 +-- .../lookup_unicodeloosemd5_hash_test.go | 10 +--- 11 files changed, 107 insertions(+), 66 deletions(-) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index d3eaf8479e0..4d529da5d17 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -23,12 +23,13 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/sqlerror" + "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestInsertOnDuplicateKey(t *testing.T) { @@ -790,8 +791,15 @@ func TestJoinWithMergedRouteWithPredicate(t *testing.T) { } func TestRowCountExceed(t *testing.T) { - conn, closer := start(t) - defer closer() + conn, _ := start(t) + defer func() { + cluster.PanicHandler(t) + // needs special delete logic as it exceeds row count. + for i := 50; i <= 300; i += 50 { + utils.Exec(t, conn, fmt.Sprintf("delete from t1 where id1 < %d", i)) + } + conn.Close() + }() for i := 0; i < 250; i++ { utils.Exec(t, conn, fmt.Sprintf("insert into t1 (id1, id2) values (%d, %d)", i, i+1)) @@ -799,3 +807,41 @@ func TestRowCountExceed(t *testing.T) { utils.AssertContainsError(t, conn, "select id1 from t1 where id1 < 1000", `Row count exceeded 100`) } + +func TestLookupErrorMetric(t *testing.T) { + conn, closer := start(t) + defer closer() + + oldErrCount := getVtgateApiErrorCounts(t) + + utils.Exec(t, conn, `insert into t1 values (1,1)`) + _, err := utils.ExecAllowError(t, conn, `insert into t1 values (2,1)`) + require.ErrorContains(t, err, `(errno 1062) (sqlstate 23000)`) + + newErrCount := getVtgateApiErrorCounts(t) + require.EqualValues(t, oldErrCount+1, newErrCount) +} + +func getVtgateApiErrorCounts(t *testing.T) float64 { + apiErr := getVar(t, "VtgateApiErrorCounts") + if apiErr == nil { + return 0 + } + mapErrors := apiErr.(map[string]interface{}) + val, exists := mapErrors["Execute.ks.primary.ALREADY_EXISTS"] + if exists { + return val.(float64) + } + return 0 +} + +func getVar(t *testing.T, key string) interface{} { + vars, err := clusterInstance.VtgateProcess.GetVars() + require.NoError(t, err) + + val, exists := vars[key] + if !exists { + return nil + } + return val +} diff --git a/go/test/endtoend/vtgate/queries/dml/insert_test.go b/go/test/endtoend/vtgate/queries/dml/insert_test.go index 867b3b46fc8..aa34761ee2b 100644 --- a/go/test/endtoend/vtgate/queries/dml/insert_test.go +++ b/go/test/endtoend/vtgate/queries/dml/insert_test.go @@ -68,11 +68,11 @@ func TestFailureInsertSelect(t *testing.T) { // primary key same mcmp.AssertContainsError("insert into s_tbl(id, num) select id, num*20 from s_tbl where id = 1", `AlreadyExists desc = Duplicate entry '1' for key`) - // lookup key same (does not fail on MySQL as there is no lookup, and we have not put unique contrains on num column) - utils.AssertContainsError(t, mcmp.VtConn, "insert into s_tbl(id, num) select id*20, num from s_tbl where id = 1", `lookup.Create: Code: ALREADY_EXISTS`) + // lookup key same (does not fail on MySQL as there is no lookup, and we have not put unique constraint on num column) + utils.AssertContainsError(t, mcmp.VtConn, "insert into s_tbl(id, num) select id*20, num from s_tbl where id = 1", `(errno 1062) (sqlstate 23000)`) // mismatch column count - mcmp.AssertContainsError("insert into s_tbl(id, num) select 100,200,300", `column count does not match value count at row 1`) - mcmp.AssertContainsError("insert into s_tbl(id, num) select 100", `column count does not match value count at row 1`) + mcmp.AssertContainsError("insert into s_tbl(id, num) select 100,200,300", `column count does not match value count with the row`) + mcmp.AssertContainsError("insert into s_tbl(id, num) select 100", `column count does not match value count with the row`) }) } } @@ -298,7 +298,7 @@ func TestIgnoreInsertSelect(t *testing.T) { mcmp.Exec("insert into order_tbl(region_id, oid, cust_no) values (1,1,100),(1,2,200),(1,3,300)") // inserting same rows, throws error. - mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `lookup.Create: Code: ALREADY_EXISTS`) + mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `(errno 1062) (sqlstate 23000)`) // inserting same rows with ignore qr := mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl") assert.EqualValues(t, 0, qr.RowsAffected) @@ -336,7 +336,7 @@ func TestIgnoreInsertSelectOlapMode(t *testing.T) { mcmp.Exec("insert into order_tbl(region_id, oid, cust_no) values (1,1,100),(1,2,200),(1,3,300)") // inserting same rows, throws error. - mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `lookup.Create: Code: ALREADY_EXISTS`) + mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `(errno 1062) (sqlstate 23000)`) // inserting same rows with ignore qr := mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl") assert.EqualValues(t, 0, qr.RowsAffected) diff --git a/go/vt/vterrors/code.go b/go/vt/vterrors/code.go index e6cd1ca9ba0..5e13e23b54e 100644 --- a/go/vt/vterrors/code.go +++ b/go/vt/vterrors/code.go @@ -31,7 +31,7 @@ var ( VT03003 = errorWithState("VT03003", vtrpcpb.Code_INVALID_ARGUMENT, UnknownTable, "unknown table '%s' in MULTI DELETE", "The specified table in this DELETE statement is unknown.") VT03004 = errorWithState("VT03004", vtrpcpb.Code_INVALID_ARGUMENT, NonUpdateableTable, "the target table %s of the DELETE is not updatable", "You cannot delete something that is not a real MySQL table.") VT03005 = errorWithState("VT03005", vtrpcpb.Code_INVALID_ARGUMENT, WrongGroupField, "cannot group on '%s'", "The planner does not allow grouping on certain field. For instance, aggregation function.") - VT03006 = errorWithState("VT03006", vtrpcpb.Code_INVALID_ARGUMENT, WrongValueCountOnRow, "column count does not match value count at row 1", "The number of columns you want to insert do not match the number of columns of your SELECT query.") + VT03006 = errorWithState("VT03006", vtrpcpb.Code_INVALID_ARGUMENT, WrongValueCountOnRow, "column count does not match value count with the row", "The number of columns you want to insert do not match the number of columns of your SELECT query.") VT03007 = errorWithoutState("VT03007", vtrpcpb.Code_INVALID_ARGUMENT, "keyspace not specified", "You need to add a keyspace qualifier.") VT03008 = errorWithState("VT03008", vtrpcpb.Code_INVALID_ARGUMENT, CantUseOptionHere, "incorrect usage/placement of '%s'", "The given token is not usable in this situation. Please refer to the MySQL documentation to learn more about your token's syntax.") VT03009 = errorWithState("VT03009", vtrpcpb.Code_INVALID_ARGUMENT, WrongValueForVar, "unexpected value type for '%s': %v", "You cannot assign this type to the given variable.") @@ -53,6 +53,9 @@ var ( VT03025 = errorWithState("VT03025", vtrpcpb.Code_INVALID_ARGUMENT, WrongArguments, "Incorrect arguments to %s", "The execute statement have wrong number of arguments") VT03026 = errorWithoutState("VT03024", vtrpcpb.Code_INVALID_ARGUMENT, "'%s' bind variable does not exists", "The query cannot be executed as missing the bind variable.") VT03027 = errorWithState("VT03027", vtrpcpb.Code_INVALID_ARGUMENT, BadNullError, "Column '%s' cannot be null", "The column cannot have null value.") + VT03028 = errorWithState("VT03028", vtrpcpb.Code_INVALID_ARGUMENT, BadNullError, "Column '%s' cannot be null on row %d, col %d", "The column cannot have null value.") + VT03029 = errorWithState("VT03029", vtrpcpb.Code_INVALID_ARGUMENT, WrongValueCountOnRow, "column count does not match value count with the row for vindex '%s'", "The number of columns you want to insert do not match the number of columns of your SELECT query.") + VT03030 = errorWithState("VT03030", vtrpcpb.Code_INVALID_ARGUMENT, WrongValueCountOnRow, "lookup column count does not match value count with the row (columns, count): (%v, %d)", "The number of columns you want to insert do not match the number of columns of your SELECT query.") VT05001 = errorWithState("VT05001", vtrpcpb.Code_NOT_FOUND, DbDropExists, "cannot drop database '%s'; database does not exists", "The given database does not exist; Vitess cannot drop it.") VT05002 = errorWithState("VT05002", vtrpcpb.Code_NOT_FOUND, BadDb, "cannot alter database '%s'; unknown database", "The given database does not exist; Vitess cannot alter it.") @@ -132,6 +135,9 @@ var ( VT03025, VT03026, VT03027, + VT03028, + VT03029, + VT03030, VT05001, VT05002, VT05003, diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index 511ce9fb954..eb257064afd 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -1207,7 +1207,7 @@ { "comment": "insert with mimatched column list", "query": "insert into user(id) values (1, 2)", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert no column list for sharded authoritative table", @@ -3759,17 +3759,17 @@ { "comment": "insert using select with more columns in insert", "query": "insert into music(id, user_id) select 1", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert using select with more columns in select", "query": "insert into music(id, user_id) select id, count(user_id), sum(user_id) from user group by id", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert using select with more columns in select after accounting for star column", "query": "insert into music(id, user_id) select id, *, 2 from user", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert using select with auto-inc column using vitess sequence, sequence column not present", @@ -4893,12 +4893,12 @@ { "comment": "insert row values smaller than number of columns", "query": "insert into user(one, two, three, four) values (1, 2, 3)", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert row values greater than number of columns", "query": "insert into user(one, two, three) values (1, 2, 3, 4)", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "insert on duplicate key update with database qualifier", diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index ba69f459e2d..58e19b0b5c1 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -102,7 +102,7 @@ { "comment": "unsharded insert, col list does not match values", "query": "insert into unsharded_auto(id, val) values(1)", - "plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count with the row" }, { "comment": "sharded upsert can't change vindex", diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go index fb5eb5dfb0a..9173ded96e6 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup.go +++ b/go/vt/vtgate/vindexes/consistent_lookup.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/evalengine" querypb "vitess.io/vitess/go/vt/proto/query" @@ -171,7 +172,7 @@ func (lu *ConsistentLookup) UnknownParams() []string { return lu.unknownParams } -//==================================================================== +// ==================================================================== // ConsistentLookupUnique defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's @@ -271,7 +272,7 @@ func (lu *ConsistentLookupUnique) AutoCommitEnabled() bool { return lu.lkp.Autocommit } -//==================================================================== +// ==================================================================== // clCommon defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's @@ -309,7 +310,7 @@ func (lu *clCommon) SetOwnerInfo(keyspace, table string, cols []sqlparser.Identi lu.keyspace = keyspace lu.ownerTable = sqlparser.String(sqlparser.NewIdentifierCS(table)) if len(cols) != len(lu.lkp.FromColumns) { - return fmt.Errorf("owner table column count does not match vindex %s", lu.name) + return vterrors.VT03029(lu.name) } lu.ownerColumns = make([]string, len(cols)) for i, col := range cols { diff --git a/go/vt/vtgate/vindexes/lookup_hash.go b/go/vt/vtgate/vindexes/lookup_hash.go index 4a4c6f7a6b5..28f38942afa 100644 --- a/go/vt/vtgate/vindexes/lookup_hash.go +++ b/go/vt/vtgate/vindexes/lookup_hash.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/vt/key" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + "vitess.io/vitess/go/vt/vterrors" ) const ( @@ -52,7 +53,7 @@ func init() { Register("lookup_hash_unique", newLookupHashUnique) } -//==================================================================== +// ==================================================================== // LookupHash defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's @@ -205,7 +206,7 @@ func (lh *LookupHash) Verify(ctx context.Context, vcursor VCursor, ids []sqltype values, err := unhashList(ksids) if err != nil { - return nil, fmt.Errorf("lookup.Verify.vunhash: %v", err) + return nil, vterrors.Wrap(err, "lookup.Verify.vunhash") } return lh.lkp.Verify(ctx, vcursor, ids, values) } @@ -214,7 +215,7 @@ func (lh *LookupHash) Verify(ctx context.Context, vcursor VCursor, ids []sqltype func (lh *LookupHash) Create(ctx context.Context, vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte, ignoreMode bool) error { values, err := unhashList(ksids) if err != nil { - return fmt.Errorf("lookup.Create.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Create.vunhash") } return lh.lkp.Create(ctx, vcursor, rowsColValues, values, ignoreMode) } @@ -223,7 +224,7 @@ func (lh *LookupHash) Create(ctx context.Context, vcursor VCursor, rowsColValues func (lh *LookupHash) Update(ctx context.Context, vcursor VCursor, oldValues []sqltypes.Value, ksid []byte, newValues []sqltypes.Value) error { v, err := vunhash(ksid) if err != nil { - return fmt.Errorf("lookup.Update.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Update.vunhash") } return lh.lkp.Update(ctx, vcursor, oldValues, ksid, sqltypes.NewUint64(v), newValues) } @@ -232,7 +233,7 @@ func (lh *LookupHash) Update(ctx context.Context, vcursor VCursor, oldValues []s func (lh *LookupHash) Delete(ctx context.Context, vcursor VCursor, rowsColValues [][]sqltypes.Value, ksid []byte) error { v, err := vunhash(ksid) if err != nil { - return fmt.Errorf("lookup.Delete.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Delete.vunhash") } return lh.lkp.Delete(ctx, vcursor, rowsColValues, sqltypes.NewUint64(v), vtgatepb.CommitOrder_NORMAL) } @@ -260,7 +261,7 @@ func unhashList(ksids [][]byte) ([]sqltypes.Value, error) { return values, nil } -//==================================================================== +// ==================================================================== // LookupHashUnique defines a vindex that uses a lookup table. // The table is expected to define the id column as unique. It's @@ -383,7 +384,7 @@ func (lhu *LookupHashUnique) Verify(ctx context.Context, vcursor VCursor, ids [] values, err := unhashList(ksids) if err != nil { - return nil, fmt.Errorf("lookup.Verify.vunhash: %v", err) + return nil, vterrors.Wrap(err, "lookup.Verify.vunhash") } return lhu.lkp.Verify(ctx, vcursor, ids, values) } @@ -392,7 +393,7 @@ func (lhu *LookupHashUnique) Verify(ctx context.Context, vcursor VCursor, ids [] func (lhu *LookupHashUnique) Create(ctx context.Context, vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte, ignoreMode bool) error { values, err := unhashList(ksids) if err != nil { - return fmt.Errorf("lookup.Create.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Create.vunhash") } return lhu.lkp.Create(ctx, vcursor, rowsColValues, values, ignoreMode) } @@ -401,7 +402,7 @@ func (lhu *LookupHashUnique) Create(ctx context.Context, vcursor VCursor, rowsCo func (lhu *LookupHashUnique) Delete(ctx context.Context, vcursor VCursor, rowsColValues [][]sqltypes.Value, ksid []byte) error { v, err := vunhash(ksid) if err != nil { - return fmt.Errorf("lookup.Delete.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Delete.vunhash") } return lhu.lkp.Delete(ctx, vcursor, rowsColValues, sqltypes.NewUint64(v), vtgatepb.CommitOrder_NORMAL) } @@ -410,7 +411,7 @@ func (lhu *LookupHashUnique) Delete(ctx context.Context, vcursor VCursor, rowsCo func (lhu *LookupHashUnique) Update(ctx context.Context, vcursor VCursor, oldValues []sqltypes.Value, ksid []byte, newValues []sqltypes.Value) error { v, err := vunhash(ksid) if err != nil { - return fmt.Errorf("lookup.Update.vunhash: %v", err) + return vterrors.Wrap(err, "lookup.Update.vunhash") } return lhu.lkp.Update(ctx, vcursor, oldValues, ksid, sqltypes.NewUint64(v), newValues) } diff --git a/go/vt/vtgate/vindexes/lookup_hash_test.go b/go/vt/vtgate/vindexes/lookup_hash_test.go index 69bff9f6f34..fd07f6ab7d8 100644 --- a/go/vt/vtgate/vindexes/lookup_hash_test.go +++ b/go/vt/vtgate/vindexes/lookup_hash_test.go @@ -236,10 +236,7 @@ func TestLookupHashCreate(t *testing.T) { } err = lookuphash.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NULL}}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")}, false /* ignoreMode */) - want := "lookup.Create: input has null values: row: 0, col: 0" - if err == nil || err.Error() != want { - t.Errorf("lookuphash.Create(NULL) err: %v, want %s", err, want) - } + require.ErrorContains(t, err, "VT03028: Column 'fromc' cannot be null on row 0, col 0") vc.queries = nil lookuphash.(*LookupHash).lkp.IgnoreNulls = true @@ -250,10 +247,7 @@ func TestLookupHashCreate(t *testing.T) { } err = lookuphash.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1)}}, [][]byte{[]byte("bogus")}, false /* ignoreMode */) - want = "lookup.Create.vunhash: invalid keyspace id: 626f677573" - if err == nil || err.Error() != want { - t.Errorf("lookuphash.Create(bogus) err: %v, want %s", err, want) - } + require.ErrorContains(t, err, "lookup.Create.vunhash: invalid keyspace id: 626f677573") } func TestLookupHashDelete(t *testing.T) { diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index b793d57c3c8..5e224259d1d 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -24,13 +24,11 @@ import ( "strconv" "strings" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" ) const ( @@ -143,7 +141,7 @@ func (lkp *lookupInternal) Init(lookupQueryParams map[string]string, autocommit, // Lookup performs a lookup for the ids. func (lkp *lookupInternal) Lookup(ctx context.Context, vcursor VCursor, ids []sqltypes.Value, co vtgatepb.CommitOrder) ([]*sqltypes.Result, error) { if vcursor == nil { - return nil, fmt.Errorf("cannot perform lookup: no vcursor provided") + return nil, vterrors.VT13001("cannot perform lookup: no vcursor provided") } results := make([]*sqltypes.Result, 0, len(ids)) if lkp.Autocommit { @@ -159,14 +157,14 @@ func (lkp *lookupInternal) Lookup(ctx context.Context, vcursor VCursor, ids []sq // for integral types, batch query all ids and then map them back to the input order vars, err := sqltypes.BuildBindVariable(ids) if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) + return nil, err } bindVars := map[string]*querypb.BindVariable{ lkp.FromColumns[0]: vars, } result, err := vcursor.Execute(ctx, "VindexLookup", sel, bindVars, false /* rollbackOnError */, co) if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) + return nil, vterrors.Wrap(err, "lookup.Map") } resultMap := make(map[string][][]sqltypes.Value) for _, row := range result.Rows { @@ -183,7 +181,7 @@ func (lkp *lookupInternal) Lookup(ctx context.Context, vcursor VCursor, ids []sq for _, id := range ids { vars, err := sqltypes.BuildBindVariable([]any{id}) if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) + return nil, err } bindVars := map[string]*querypb.BindVariable{ lkp.FromColumns[0]: vars, @@ -191,7 +189,7 @@ func (lkp *lookupInternal) Lookup(ctx context.Context, vcursor VCursor, ids []sq var result *sqltypes.Result result, err = vcursor.Execute(ctx, "VindexLookup", sel, bindVars, false /* rollbackOnError */, co) if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) + return nil, vterrors.Wrap(err, "lookup.Map") } rows := make([][]sqltypes.Value, 0, len(result.Rows)) for _, row := range result.Rows { @@ -223,7 +221,7 @@ func (lkp *lookupInternal) VerifyCustom(ctx context.Context, vcursor VCursor, id } result, err := vcursor.Execute(ctx, "VindexVerify", lkp.ver, bindVars, false /* rollbackOnError */, co) if err != nil { - return nil, fmt.Errorf("lookup.Verify: %v", err) + return nil, vterrors.Wrap(err, "lookup.Verify") } out[i] = (len(result.Rows) != 0) } @@ -290,7 +288,8 @@ nextRow: for j, col := range row { if col.IsNull() { if !lkp.IgnoreNulls { - return fmt.Errorf("lookup.Create: input has null values: row: %d, col: %d", i, j) + cols := strings.Join(lkp.FromColumns, ",") + return vterrors.VT03028(cols, i, j) } continue nextRow } @@ -304,7 +303,7 @@ nextRow: // We only need to check the first row. Number of cols per row // is guaranteed by the engine to be uniform. if len(trimmedRowsCols[0]) != len(lkp.FromColumns) { - return fmt.Errorf("lookup.Create: column vindex count does not match the columns in the lookup: %d vs %v", len(trimmedRowsCols[0]), lkp.FromColumns) + return vterrors.VT03030(lkp.FromColumns, len(trimmedRowsCols[0])) } sort.Sort(&sorter{rowsColValues: trimmedRowsCols, toValues: trimmedToValues}) @@ -348,7 +347,7 @@ nextRow: } if _, err := vcursor.Execute(ctx, "VindexCreate", buf.String(), bindVars, true /* rollbackOnError */, co); err != nil { - return fmt.Errorf("lookup.Create: %v", err) + return vterrors.Wrap(err, "lookup.Create") } return nil } @@ -380,7 +379,7 @@ func (lkp *lookupInternal) Delete(ctx context.Context, vcursor VCursor, rowsColV // We only need to check the first row. Number of cols per row // is guaranteed by the engine to be uniform. if len(rowsColValues[0]) != len(lkp.FromColumns) { - return fmt.Errorf("lookup.Delete: column vindex count does not match the columns in the lookup: %d vs %v", len(rowsColValues[0]), lkp.FromColumns) + return vterrors.VT03030(lkp.FromColumns, len(rowsColValues[0])) } for _, column := range rowsColValues { bindVars := make(map[string]*querypb.BindVariable, len(rowsColValues)) @@ -390,7 +389,7 @@ func (lkp *lookupInternal) Delete(ctx context.Context, vcursor VCursor, rowsColV bindVars[lkp.To] = sqltypes.ValueBindVariable(value) _, err := vcursor.Execute(ctx, "VindexDelete", lkp.del, bindVars, true /* rollbackOnError */, co) if err != nil { - return fmt.Errorf("lookup.Delete: %v", err) + return vterrors.Wrap(err, "lookup.Delete") } } return nil diff --git a/go/vt/vtgate/vindexes/lookup_test.go b/go/vt/vtgate/vindexes/lookup_test.go index a59fcbf1da9..b82ab3d4fec 100644 --- a/go/vt/vtgate/vindexes/lookup_test.go +++ b/go/vt/vtgate/vindexes/lookup_test.go @@ -369,7 +369,7 @@ func TestLookupNonUniqueNew(t *testing.T) { func TestLookupNilVCursor(t *testing.T) { lnu := createLookup(t, "lookup", false /* writeOnly */) _, err := lnu.Map(context.Background(), nil, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) - require.EqualError(t, err, "cannot perform lookup: no vcursor provided") + require.EqualError(t, err, "VT13001: [BUG] cannot perform lookup: no vcursor provided") } func TestLookupNonUniqueMap(t *testing.T) { @@ -620,7 +620,7 @@ func TestLookupNonUniqueCreate(t *testing.T) { // With ignore_nulls off err = lnu.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(2)}, {sqltypes.NULL}}, [][]byte{[]byte("test2"), []byte("test1")}, true /* ignoreMode */) - assert.EqualError(t, err, "lookup.Create: input has null values: row: 1, col: 0") + assert.EqualError(t, err, "VT03028: Column 'fromc' cannot be null on row 1, col 0") // With ignore_nulls on vc.queries = nil @@ -644,7 +644,7 @@ func TestLookupNonUniqueCreate(t *testing.T) { // Test column mismatch. err = lnu.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")}, false /* ignoreMode */) - assert.EqualError(t, err, "lookup.Create: column vindex count does not match the columns in the lookup: 2 vs [fromc]") + assert.EqualError(t, err, "VT03030: lookup column count does not match value count with the row (columns, count): ([fromc], 2)") } func TestLookupNonUniqueCreateAutocommit(t *testing.T) { @@ -710,7 +710,7 @@ func TestLookupNonUniqueDelete(t *testing.T) { // Test column count fail. err = lnu.(Lookup).Delete(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}}, []byte("\x16k@\xb4J\xbaK\xd6")) - assert.EqualError(t, err, "lookup.Delete: column vindex count does not match the columns in the lookup: 2 vs [fromc]") + assert.EqualError(t, err, "VT03030: lookup column count does not match value count with the row (columns, count): ([fromc], 2)") } func TestLookupNonUniqueDeleteAutocommit(t *testing.T) { diff --git a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go index 989458ccc13..c0e4611d684 100644 --- a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go +++ b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go @@ -320,10 +320,7 @@ func TestLookupUnicodeLooseMD5HashCreate(t *testing.T) { // Test column mismatch. err = lnu.(Lookup).Create(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(10), sqltypes.NewInt64(20)}}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")}, false) - want = "lookup.Create: column vindex count does not match the columns in the lookup: 2 vs [fromc]" - if err == nil || err.Error() != want { - t.Errorf("lookupNonUnique(query fail) err: %v, want %s", err, want) - } + require.ErrorContains(t, err, "VT03030: lookup column count does not match value count with the row (columns, count): ([fromc], 2)") } func TestLookupUnicodeLooseMD5HashCreateAutocommit(t *testing.T) { @@ -443,10 +440,7 @@ func TestLookupUnicodeLooseMD5HashDelete(t *testing.T) { // Test column count fail. err = lnu.(Lookup).Delete(context.Background(), vc, [][]sqltypes.Value{{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}}, []byte("\x16k@\xb4J\xbaK\xd6")) - want = "lookup.Delete: column vindex count does not match the columns in the lookup: 2 vs [fromc]" - if err == nil || err.Error() != want { - t.Errorf("lookupNonUnique(query fail) err: %v, want %s", err, want) - } + require.ErrorContains(t, err, "VT03030: lookup column count does not match value count with the row (columns, count): ([fromc], 2)") } func TestLookupUnicodeLooseMD5HashDeleteAutocommit(t *testing.T) { From 764d70c3f6ae02ffe4dfb0c502272ba72e0761c3 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:03:27 +0200 Subject: [PATCH 117/119] Tablet throttler: post 18 refactoring, race condition fixes, unit & race testing, deprecation of HTTP checks (#14181) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/base/http.go | 39 +- .../throttle/base/metric_health.go | 39 +- .../throttle/base/metric_health_test.go | 38 +- .../tabletserver/throttle/base/recent_app.go | 38 +- .../throttle/base/throttle_metric.go | 39 +- .../throttle/base/throttle_metric_app.go | 39 +- go/vt/vttablet/tabletserver/throttle/check.go | 42 +- .../tabletserver/throttle/check_result.go | 39 +- .../tabletserver/throttle/config/config.go | 39 +- .../throttle/config/mysql_config.go | 39 +- .../throttle/config/store_config.go | 39 +- go/vt/vttablet/tabletserver/throttle/mysql.go | 51 +- .../throttle/mysql/instance_key.go | 98 --- .../throttle/mysql/instance_key_test.go | 66 -- .../throttle/mysql/mysql_inventory.go | 63 +- .../throttle/mysql/mysql_throttle_metric.go | 53 +- .../tabletserver/throttle/mysql/probe.go | 65 +- .../tabletserver/throttle/mysql/probe_test.go | 42 +- .../tabletserver/throttle/mysql_test.go | 141 +++-- .../tabletserver/throttle/throttler.go | 581 +++++++++--------- .../throttle/throttler_exclude_race_test.go | 76 +++ .../tabletserver/throttle/throttler_test.go | 175 +++++- .../throttle/throttlerapp/app_test.go | 14 +- 23 files changed, 1271 insertions(+), 584 deletions(-) delete mode 100644 go/vt/vttablet/tabletserver/throttle/mysql/instance_key.go delete mode 100644 go/vt/vttablet/tabletserver/throttle/mysql/instance_key_test.go create mode 100644 go/vt/vttablet/tabletserver/throttle/throttler_exclude_race_test.go diff --git a/go/vt/vttablet/tabletserver/throttle/base/http.go b/go/vt/vttablet/tabletserver/throttle/base/http.go index 6f657766ad1..bbf4662d6cf 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/http.go +++ b/go/vt/vttablet/tabletserver/throttle/base/http.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package base diff --git a/go/vt/vttablet/tabletserver/throttle/base/metric_health.go b/go/vt/vttablet/tabletserver/throttle/base/metric_health.go index e970888bf13..458e8e28264 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/metric_health.go +++ b/go/vt/vttablet/tabletserver/throttle/base/metric_health.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package base diff --git a/go/vt/vttablet/tabletserver/throttle/base/metric_health_test.go b/go/vt/vttablet/tabletserver/throttle/base/metric_health_test.go index d11ecd7b8e5..a1a1ad4e0c0 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/metric_health_test.go +++ b/go/vt/vttablet/tabletserver/throttle/base/metric_health_test.go @@ -1,9 +1,43 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. */ +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ package base import ( diff --git a/go/vt/vttablet/tabletserver/throttle/base/recent_app.go b/go/vt/vttablet/tabletserver/throttle/base/recent_app.go index 2c629fbff25..64527c4cc1c 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/recent_app.go +++ b/go/vt/vttablet/tabletserver/throttle/base/recent_app.go @@ -1,9 +1,43 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. */ +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ package base import ( diff --git a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go index 7070febb3bc..3d4c4f95a2e 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go +++ b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package base diff --git a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_app.go b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_app.go index ce77f7068b6..482f319365f 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_app.go +++ b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_app.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package base diff --git a/go/vt/vttablet/tabletserver/throttle/check.go b/go/vt/vttablet/tabletserver/throttle/check.go index dd209a0c423..9dfbade8af6 100644 --- a/go/vt/vttablet/tabletserver/throttle/check.go +++ b/go/vt/vttablet/tabletserver/throttle/check.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package throttle @@ -11,7 +46,6 @@ import ( "fmt" "net/http" "strings" - "sync/atomic" "time" "vitess.io/vitess/go/stats" @@ -114,7 +148,7 @@ func (check *ThrottlerCheck) Check(ctx context.Context, appName string, storeTyp } checkResult = check.checkAppMetricResult(ctx, appName, storeType, storeName, metricResultFunc, flags) - atomic.StoreInt64(&check.throttler.lastCheckTimeNano, time.Now().UnixNano()) + check.throttler.lastCheckTimeNano.Store(time.Now().UnixNano()) go func(statusCode int) { stats.GetOrNewCounter("ThrottlerCheckAnyTotal", "total number of checks").Add(1) diff --git a/go/vt/vttablet/tabletserver/throttle/check_result.go b/go/vt/vttablet/tabletserver/throttle/check_result.go index 3bc162b623a..41a1b240934 100644 --- a/go/vt/vttablet/tabletserver/throttle/check_result.go +++ b/go/vt/vttablet/tabletserver/throttle/check_result.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package throttle diff --git a/go/vt/vttablet/tabletserver/throttle/config/config.go b/go/vt/vttablet/tabletserver/throttle/config/config.go index b1f3ad61f80..5241d686d10 100644 --- a/go/vt/vttablet/tabletserver/throttle/config/config.go +++ b/go/vt/vttablet/tabletserver/throttle/config/config.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package config diff --git a/go/vt/vttablet/tabletserver/throttle/config/mysql_config.go b/go/vt/vttablet/tabletserver/throttle/config/mysql_config.go index 3e3e82adff4..3aa0607fb28 100644 --- a/go/vt/vttablet/tabletserver/throttle/config/mysql_config.go +++ b/go/vt/vttablet/tabletserver/throttle/config/mysql_config.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package config diff --git a/go/vt/vttablet/tabletserver/throttle/config/store_config.go b/go/vt/vttablet/tabletserver/throttle/config/store_config.go index 9a19025df05..7e5594050d9 100644 --- a/go/vt/vttablet/tabletserver/throttle/config/store_config.go +++ b/go/vt/vttablet/tabletserver/throttle/config/store_config.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package config diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go index 350ad465b73..81a967ddacb 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package throttle @@ -16,9 +51,9 @@ import ( func aggregateMySQLProbes( ctx context.Context, - probes *mysql.Probes, + probes mysql.Probes, clusterName string, - instanceResultsMap mysql.InstanceMetricResultMap, + tabletResultsMap mysql.TabletResultMap, ignoreHostsCount int, IgnoreDialTCPErrors bool, ignoreHostsThreshold float64, @@ -26,13 +61,13 @@ func aggregateMySQLProbes( // probes is known not to change. It can be *replaced*, but not changed. // so it's safe to iterate it probeValues := []float64{} - for _, probe := range *probes { - instanceMetricResult, ok := instanceResultsMap[mysql.GetClusterInstanceKey(clusterName, &probe.Key)] + for _, probe := range probes { + tabletMetricResult, ok := tabletResultsMap[mysql.GetClusterTablet(clusterName, probe.Alias)] if !ok { return base.NoMetricResultYet } - value, err := instanceMetricResult.Get() + value, err := tabletMetricResult.Get() if err != nil { if IgnoreDialTCPErrors && base.IsDialTCPError(err) { continue @@ -42,7 +77,7 @@ func aggregateMySQLProbes( ignoreHostsCount = ignoreHostsCount - 1 continue } - return instanceMetricResult + return tabletMetricResult } // No error diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/instance_key.go b/go/vt/vttablet/tabletserver/throttle/mysql/instance_key.go deleted file mode 100644 index adcd6f422fb..00000000000 --- a/go/vt/vttablet/tabletserver/throttle/mysql/instance_key.go +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright 2015 Shlomi Noach, courtesy Booking.com - See https://github.com/github/freno/blob/master/LICENSE -*/ - -package mysql - -import ( - "fmt" - "strconv" - "strings" -) - -// InstanceKey is an instance indicator, identified by hostname and port -type InstanceKey struct { - Hostname string - Port int -} - -// SelfInstanceKey is a special indicator for "this instance", e.g. denoting the MySQL server associated with local tablet -// The values of this key are immaterial and are intentionally descriptive -var SelfInstanceKey = &InstanceKey{Hostname: "(self)", Port: 1} - -// newRawInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 -// It expects such format and returns with error if input differs in format -func newRawInstanceKey(hostPort string) (*InstanceKey, error) { - tokens := strings.SplitN(hostPort, ":", 2) - if len(tokens) != 2 { - return nil, fmt.Errorf("Cannot parse InstanceKey from %s. Expected format is host:port", hostPort) - } - instanceKey := &InstanceKey{Hostname: tokens[0]} - var err error - if instanceKey.Port, err = strconv.Atoi(tokens[1]); err != nil { - return instanceKey, fmt.Errorf("Invalid port: %s", tokens[1]) - } - - return instanceKey, nil -} - -// ParseInstanceKey will parse an InstanceKey from a string representation such as 127.0.0.1:3306 or some.hostname -// `defaultPort` is used if `hostPort` does not include a port. -func ParseInstanceKey(hostPort string, defaultPort int) (*InstanceKey, error) { - if !strings.Contains(hostPort, ":") { - return &InstanceKey{Hostname: hostPort, Port: defaultPort}, nil - } - return newRawInstanceKey(hostPort) -} - -// Equals tests equality between this key and another key -func (i *InstanceKey) Equals(other *InstanceKey) bool { - if other == nil { - return false - } - return i.Hostname == other.Hostname && i.Port == other.Port -} - -// SmallerThan returns true if this key is dictionary-smaller than another. -// This is used for consistent sorting/ordering; there's nothing magical about it. -func (i *InstanceKey) SmallerThan(other *InstanceKey) bool { - if i.Hostname < other.Hostname { - return true - } - if i.Hostname == other.Hostname && i.Port < other.Port { - return true - } - return false -} - -// IsValid uses simple heuristics to see whether this key represents an actual instance -func (i *InstanceKey) IsValid() bool { - if i.Hostname == "_" { - return false - } - return len(i.Hostname) > 0 && i.Port > 0 -} - -// IsSelf checks if this is the special "self" instance key -func (i *InstanceKey) IsSelf() bool { - if SelfInstanceKey == i { - return true - } - return SelfInstanceKey.Equals(i) -} - -// StringCode returns an official string representation of this key -func (i *InstanceKey) StringCode() string { - return fmt.Sprintf("%s:%d", i.Hostname, i.Port) -} - -// DisplayString returns a user-friendly string representation of this key -func (i *InstanceKey) DisplayString() string { - return i.StringCode() -} - -// String returns a user-friendly string representation of this key -func (i InstanceKey) String() string { - return i.StringCode() -} diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/instance_key_test.go b/go/vt/vttablet/tabletserver/throttle/mysql/instance_key_test.go deleted file mode 100644 index a8d3424c36a..00000000000 --- a/go/vt/vttablet/tabletserver/throttle/mysql/instance_key_test.go +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright 2017 GitHub Inc. - - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE -*/ - -package mysql - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNewRawInstanceKey(t *testing.T) { - { - key, err := newRawInstanceKey("127.0.0.1:3307") - assert.NoError(t, err) - assert.Equal(t, key.Hostname, "127.0.0.1") - assert.Equal(t, key.Port, 3307) - } - { - _, err := newRawInstanceKey("127.0.0.1:abcd") - assert.Error(t, err) - } - { - _, err := newRawInstanceKey("127.0.0.1:") - assert.Error(t, err) - } - { - _, err := newRawInstanceKey("127.0.0.1") - assert.Error(t, err) - } -} - -func TestParseInstanceKey(t *testing.T) { - { - key, err := ParseInstanceKey("127.0.0.1:3307", 3306) - assert.NoError(t, err) - assert.Equal(t, "127.0.0.1", key.Hostname) - assert.Equal(t, 3307, key.Port) - } - { - key, err := ParseInstanceKey("127.0.0.1", 3306) - assert.NoError(t, err) - assert.Equal(t, "127.0.0.1", key.Hostname) - assert.Equal(t, 3306, key.Port) - } -} - -func TestEquals(t *testing.T) { - { - expect := &InstanceKey{Hostname: "127.0.0.1", Port: 3306} - key, err := ParseInstanceKey("127.0.0.1", 3306) - assert.NoError(t, err) - assert.True(t, key.Equals(expect)) - } -} - -func TestStringCode(t *testing.T) { - { - key := &InstanceKey{Hostname: "127.0.0.1", Port: 3306} - stringCode := key.StringCode() - assert.Equal(t, "127.0.0.1:3306", stringCode) - } -} diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go index ace9a2853a7..744bcc99a44 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package mysql @@ -10,35 +45,35 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) -// ClusterInstanceKey combines a cluster name with an instance key -type ClusterInstanceKey struct { +// ClusterTablet combines a cluster name with a tablet alias +type ClusterTablet struct { ClusterName string - Key InstanceKey + Alias string } -// GetClusterInstanceKey creates a ClusterInstanceKey object -func GetClusterInstanceKey(clusterName string, key *InstanceKey) ClusterInstanceKey { - return ClusterInstanceKey{ClusterName: clusterName, Key: *key} +// GetClusterTablet creates a GetClusterTablet object +func GetClusterTablet(clusterName string, alias string) ClusterTablet { + return ClusterTablet{ClusterName: clusterName, Alias: alias} } -// InstanceMetricResultMap maps a cluster-instance to a result -type InstanceMetricResultMap map[ClusterInstanceKey]base.MetricResult +// TabletResultMap maps a cluster-tablet to a result +type TabletResultMap map[ClusterTablet]base.MetricResult // Inventory has the operational data about probes, their metrics, and relevant configuration type Inventory struct { - ClustersProbes map[string](*Probes) + ClustersProbes map[string](Probes) IgnoreHostsCount map[string]int IgnoreHostsThreshold map[string]float64 - InstanceKeyMetrics InstanceMetricResultMap + TabletMetrics TabletResultMap } // NewInventory creates a Inventory func NewInventory() *Inventory { inventory := &Inventory{ - ClustersProbes: make(map[string](*Probes)), + ClustersProbes: make(map[string](Probes)), IgnoreHostsCount: make(map[string]int), IgnoreHostsThreshold: make(map[string]float64), - InstanceKeyMetrics: make(map[ClusterInstanceKey]base.MetricResult), + TabletMetrics: make(map[ClusterTablet]base.MetricResult), } return inventory } diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go index a7e3650f8f3..966c7a93d7f 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package mysql @@ -33,7 +68,7 @@ const ( var mysqlMetricCache = cache.New(cache.NoExpiration, 10*time.Second) func getMySQLMetricCacheKey(probe *Probe) string { - return fmt.Sprintf("%s:%s", probe.Key, probe.MetricQuery) + return fmt.Sprintf("%s:%s", probe.Alias, probe.MetricQuery) } func cacheMySQLThrottleMetric(probe *Probe, mySQLThrottleMetric *MySQLThrottleMetric) *MySQLThrottleMetric { @@ -71,10 +106,10 @@ func GetMetricsQueryType(query string) MetricsQueryType { return MetricsQueryTypeUnknown } -// MySQLThrottleMetric has the probed metric for a mysql instance +// MySQLThrottleMetric has the probed metric for a tablet type MySQLThrottleMetric struct { // nolint:revive ClusterName string - Key InstanceKey + Alias string Value float64 Err error } @@ -84,9 +119,9 @@ func NewMySQLThrottleMetric() *MySQLThrottleMetric { return &MySQLThrottleMetric{Value: 0} } -// GetClusterInstanceKey returns the ClusterInstanceKey part of the metric -func (metric *MySQLThrottleMetric) GetClusterInstanceKey() ClusterInstanceKey { - return GetClusterInstanceKey(metric.ClusterName, &metric.Key) +// GetClusterTablet returns the ClusterTablet part of the metric +func (metric *MySQLThrottleMetric) GetClusterTablet() ClusterTablet { + return GetClusterTablet(metric.ClusterName, metric.Alias) } // Get implements MetricResult @@ -105,7 +140,7 @@ func ReadThrottleMetric(probe *Probe, clusterName string, overrideGetMetricFunc started := time.Now() mySQLThrottleMetric = NewMySQLThrottleMetric() mySQLThrottleMetric.ClusterName = clusterName - mySQLThrottleMetric.Key = probe.Key + mySQLThrottleMetric.Alias = probe.Alias defer func(metric *MySQLThrottleMetric, started time.Time) { go func() { diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/probe.go b/go/vt/vttablet/tabletserver/throttle/mysql/probe.go index 53b835497b4..8c3e069c0d1 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/probe.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/probe.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package mysql @@ -14,45 +49,35 @@ import ( // Probe is the minimal configuration required to connect to a MySQL server type Probe struct { - Key InstanceKey + Alias string MetricQuery string Tablet *topodatapb.Tablet - TabletHost string - TabletPort int CacheMillis int QueryInProgress int64 } -// Probes maps instances to probe(s) -type Probes map[InstanceKey](*Probe) +// Probes maps tablet aliases to probe(s) +type Probes map[string](*Probe) // ClusterProbes has the probes for a specific cluster type ClusterProbes struct { ClusterName string IgnoreHostsCount int IgnoreHostsThreshold float64 - InstanceProbes *Probes + TabletProbes Probes } // NewProbes creates Probes -func NewProbes() *Probes { - return &Probes{} +func NewProbes() Probes { + return Probes{} } // NewProbe creates Probe func NewProbe() *Probe { - config := &Probe{ - Key: InstanceKey{}, - } - return config + return &Probe{} } // String returns a human readable string of this struct func (p *Probe) String() string { - return fmt.Sprintf("%s, tablet=%s:%d", p.Key.DisplayString(), p.TabletHost, p.TabletPort) -} - -// Equals checks if this probe has same instance key as another -func (p *Probe) Equals(other *Probe) bool { - return p.Key.Equals(&other.Key) + return fmt.Sprintf("probe alias=%s", p.Alias) } diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go b/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go index cb63441d419..8f489f39258 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package mysql @@ -14,6 +49,5 @@ import ( func TestNewProbe(t *testing.T) { c := NewProbe() - assert.Equal(t, "", c.Key.Hostname) - assert.Equal(t, 0, c.Key.Port) + assert.Equal(t, "", c.Alias) } diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go index e90f9a69614..15d6feab03f 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql_test.go @@ -1,7 +1,42 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package throttle @@ -17,64 +52,64 @@ import ( ) var ( - key1 = mysql.InstanceKey{Hostname: "10.0.0.1", Port: 3306} - key2 = mysql.InstanceKey{Hostname: "10.0.0.2", Port: 3306} - key3 = mysql.InstanceKey{Hostname: "10.0.0.3", Port: 3306} - key4 = mysql.InstanceKey{Hostname: "10.0.0.4", Port: 3306} - key5 = mysql.InstanceKey{Hostname: "10.0.0.5", Port: 3306} + alias1 = "zone1-0001" + alias2 = "zone1-0002" + alias3 = "zone1-0003" + alias4 = "zone1-0004" + alias5 = "zone1-0005" ) func TestAggregateMySQLProbesNoErrors(t *testing.T) { ctx := context.Background() clusterName := "c0" - key1cluster := mysql.GetClusterInstanceKey(clusterName, &key1) - key2cluster := mysql.GetClusterInstanceKey(clusterName, &key2) - key3cluster := mysql.GetClusterInstanceKey(clusterName, &key3) - key4cluster := mysql.GetClusterInstanceKey(clusterName, &key4) - key5cluster := mysql.GetClusterInstanceKey(clusterName, &key5) - instanceResultsMap := mysql.InstanceMetricResultMap{ + key1cluster := mysql.GetClusterTablet(clusterName, alias1) + key2cluster := mysql.GetClusterTablet(clusterName, alias2) + key3cluster := mysql.GetClusterTablet(clusterName, alias3) + key4cluster := mysql.GetClusterTablet(clusterName, alias4) + key5cluster := mysql.GetClusterTablet(clusterName, alias5) + tabletResultsMap := mysql.TabletResultMap{ key1cluster: base.NewSimpleMetricResult(1.2), key2cluster: base.NewSimpleMetricResult(1.7), key3cluster: base.NewSimpleMetricResult(0.3), key4cluster: base.NewSimpleMetricResult(0.6), key5cluster: base.NewSimpleMetricResult(1.1), } - var probes mysql.Probes = map[mysql.InstanceKey](*mysql.Probe){} - for clusterKey := range instanceResultsMap { - probes[clusterKey.Key] = &mysql.Probe{Key: clusterKey.Key} + var probes mysql.Probes = map[string](*mysql.Probe){} + for clusterKey := range tabletResultsMap { + probes[clusterKey.Alias] = &mysql.Probe{Alias: clusterKey.Alias} } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 0, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 0, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 1, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 2, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 3, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 3, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 4, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 4, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 5, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 5, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) @@ -84,54 +119,54 @@ func TestAggregateMySQLProbesNoErrors(t *testing.T) { func TestAggregateMySQLProbesNoErrorsIgnoreHostsThreshold(t *testing.T) { ctx := context.Background() clusterName := "c0" - key1cluster := mysql.GetClusterInstanceKey(clusterName, &key1) - key2cluster := mysql.GetClusterInstanceKey(clusterName, &key2) - key3cluster := mysql.GetClusterInstanceKey(clusterName, &key3) - key4cluster := mysql.GetClusterInstanceKey(clusterName, &key4) - key5cluster := mysql.GetClusterInstanceKey(clusterName, &key5) - instanceResultsMap := mysql.InstanceMetricResultMap{ + key1cluster := mysql.GetClusterTablet(clusterName, alias1) + key2cluster := mysql.GetClusterTablet(clusterName, alias2) + key3cluster := mysql.GetClusterTablet(clusterName, alias3) + key4cluster := mysql.GetClusterTablet(clusterName, alias4) + key5cluster := mysql.GetClusterTablet(clusterName, alias5) + tableteResultsMap := mysql.TabletResultMap{ key1cluster: base.NewSimpleMetricResult(1.2), key2cluster: base.NewSimpleMetricResult(1.7), key3cluster: base.NewSimpleMetricResult(0.3), key4cluster: base.NewSimpleMetricResult(0.6), key5cluster: base.NewSimpleMetricResult(1.1), } - var probes mysql.Probes = map[mysql.InstanceKey](*mysql.Probe){} - for clusterKey := range instanceResultsMap { - probes[clusterKey.Key] = &mysql.Probe{Key: clusterKey.Key} + var probes mysql.Probes = map[string](*mysql.Probe){} + for clusterKey := range tableteResultsMap { + probes[clusterKey.Alias] = &mysql.Probe{Alias: clusterKey.Alias} } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 0, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 0, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 1, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 1, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 2, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 2, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 3, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 3, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 4, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 4, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 5, false, 1.0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tableteResultsMap, 5, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) @@ -141,56 +176,56 @@ func TestAggregateMySQLProbesNoErrorsIgnoreHostsThreshold(t *testing.T) { func TestAggregateMySQLProbesWithErrors(t *testing.T) { ctx := context.Background() clusterName := "c0" - key1cluster := mysql.GetClusterInstanceKey(clusterName, &key1) - key2cluster := mysql.GetClusterInstanceKey(clusterName, &key2) - key3cluster := mysql.GetClusterInstanceKey(clusterName, &key3) - key4cluster := mysql.GetClusterInstanceKey(clusterName, &key4) - key5cluster := mysql.GetClusterInstanceKey(clusterName, &key5) - instanceResultsMap := mysql.InstanceMetricResultMap{ + key1cluster := mysql.GetClusterTablet(clusterName, alias1) + key2cluster := mysql.GetClusterTablet(clusterName, alias2) + key3cluster := mysql.GetClusterTablet(clusterName, alias3) + key4cluster := mysql.GetClusterTablet(clusterName, alias4) + key5cluster := mysql.GetClusterTablet(clusterName, alias5) + tabletResultsMap := mysql.TabletResultMap{ key1cluster: base.NewSimpleMetricResult(1.2), key2cluster: base.NewSimpleMetricResult(1.7), key3cluster: base.NewSimpleMetricResult(0.3), key4cluster: base.NoSuchMetric, key5cluster: base.NewSimpleMetricResult(1.1), } - var probes mysql.Probes = map[mysql.InstanceKey](*mysql.Probe){} - for clusterKey := range instanceResultsMap { - probes[clusterKey.Key] = &mysql.Probe{Key: clusterKey.Key} + var probes mysql.Probes = map[string](*mysql.Probe){} + for clusterKey := range tabletResultsMap { + probes[clusterKey.Alias] = &mysql.Probe{Alias: clusterKey.Alias} } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 0, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, err, base.ErrNoSuchMetric) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 1, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 2, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } - instanceResultsMap[key1cluster] = base.NoSuchMetric + tabletResultsMap[key1cluster] = base.NoSuchMetric { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 0, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, err, base.ErrNoSuchMetric) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 1, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 1, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, err, base.ErrNoSuchMetric) } { - worstMetric := aggregateMySQLProbes(ctx, &probes, clusterName, instanceResultsMap, 2, false, 0) + worstMetric := aggregateMySQLProbes(ctx, probes, clusterName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 1e03a1dec73..5c5050d10ab 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1,17 +1,50 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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. +*/ + +// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE +/* + MIT License + + Copyright (c) 2017 GitHub + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ package throttle import ( "context" - "encoding/json" "errors" "fmt" - "io" "math" "math/rand" "net/http" @@ -36,6 +69,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" "vitess.io/vitess/go/vt/vttablet/tabletserver/heartbeat" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" @@ -47,15 +81,15 @@ import ( ) const ( - leaderCheckInterval = 5 * time.Second - mysqlCollectInterval = 250 * time.Millisecond - mysqlDormantCollectInterval = 5 * time.Second - mysqlRefreshInterval = 10 * time.Second - mysqlAggregateInterval = 125 * time.Millisecond - - aggregatedMetricsExpiration = 5 * time.Second + leaderCheckInterval = 5 * time.Second + mysqlCollectInterval = 250 * time.Millisecond + mysqlDormantCollectInterval = 5 * time.Second + mysqlRefreshInterval = 10 * time.Second + mysqlAggregateInterval = 125 * time.Millisecond throttledAppsSnapshotInterval = 5 * time.Second - recentAppsExpiration = time.Hour * 24 + + aggregatedMetricsExpiration = 5 * time.Second + recentAppsExpiration = time.Hour * 24 nonDeprioritizedAppMapExpiration = time.Second @@ -118,18 +152,26 @@ type Throttler struct { isLeader atomic.Bool isOpen atomic.Bool - env tabletenv.Env - pool *connpool.Pool - tabletTypeFunc func() topodatapb.TabletType - ts throttlerTopoService - srvTopoServer srvtopo.Server - heartbeatWriter heartbeat.HeartbeatWriter + leaderCheckInterval time.Duration + mysqlCollectInterval time.Duration + mysqlDormantCollectInterval time.Duration + mysqlRefreshInterval time.Duration + mysqlAggregateInterval time.Duration + throttledAppsSnapshotInterval time.Duration + + env tabletenv.Env + pool *connpool.Pool + tabletTypeFunc func() topodatapb.TabletType + ts throttlerTopoService + srvTopoServer srvtopo.Server + heartbeatWriter heartbeat.HeartbeatWriter + overrideTmClient tmclient.TabletManagerClient // recentCheckTickerValue is an ever increasing number, incrementing once per second. - recentCheckTickerValue int64 + recentCheckTickerValue atomic.Int64 // recentCheckValue is set to match or exceed recentCheckTickerValue whenever a "check" was made (other than by the throttler itself). // when recentCheckValue < recentCheckTickerValue that means there hasn't been a recent check. - recentCheckValue int64 + recentCheckValue atomic.Int64 throttleTabletTypesMap map[topodatapb.TabletType]bool @@ -150,14 +192,15 @@ type Throttler struct { recentApps *cache.Cache metricsHealth *cache.Cache - lastCheckTimeNano int64 + lastCheckTimeNano atomic.Int64 + + initMutex sync.Mutex + enableMutex sync.Mutex + cancelOpenContext context.CancelFunc + cancelEnableContext context.CancelFunc + throttledAppsMutex sync.Mutex - initMutex sync.Mutex - enableMutex sync.Mutex - cancelOpenContext context.CancelFunc - cancelEnableContext context.CancelFunc - throttledAppsMutex sync.Mutex - watchSrvKeyspaceOnce sync.Once + readSelfThrottleMetric func(context.Context, *mysql.Probe) *mysql.MySQLThrottleMetric // overwritten by unit test nonLowPriorityAppRequestsThrottled *cache.Cache httpClient *http.Client @@ -212,7 +255,17 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv throttler.initThrottleTabletTypes() throttler.check = NewThrottlerCheck(throttler) + throttler.leaderCheckInterval = leaderCheckInterval + throttler.mysqlCollectInterval = mysqlCollectInterval + throttler.mysqlDormantCollectInterval = mysqlDormantCollectInterval + throttler.mysqlRefreshInterval = mysqlRefreshInterval + throttler.mysqlAggregateInterval = mysqlAggregateInterval + throttler.throttledAppsSnapshotInterval = throttledAppsSnapshotInterval + throttler.StoreMetricsThreshold(defaultThrottleLagThreshold.Seconds()) //default + throttler.readSelfThrottleMetric = func(ctx context.Context, p *mysql.Probe) *mysql.MySQLThrottleMetric { + return throttler.readSelfMySQLThrottleMetric(ctx, p) + } return throttler } @@ -342,9 +395,9 @@ func (throttler *Throttler) applyThrottlerConfig(ctx context.Context, throttlerC throttler.ThrottleApp(appRule.Name, protoutil.TimeFromProto(appRule.ExpiresAt).UTC(), appRule.Ratio, appRule.Exempt) } if throttlerConfig.Enabled { - go throttler.Enable(ctx) + go throttler.Enable() } else { - go throttler.Disable(ctx) + go throttler.Disable() } } @@ -372,18 +425,18 @@ func (throttler *Throttler) IsRunning() bool { // Enable activates the throttler probes; when enabled, the throttler responds to check queries based on // the collected metrics. -func (throttler *Throttler) Enable(ctx context.Context) bool { +func (throttler *Throttler) Enable() bool { throttler.enableMutex.Lock() defer throttler.enableMutex.Unlock() - isEnabled := throttler.isEnabled.Swap(true) - if isEnabled { + if wasEnabled := throttler.isEnabled.Swap(true); wasEnabled { log.Infof("Throttler: already enabled") return false } log.Infof("Throttler: enabling") - ctx, throttler.cancelEnableContext = context.WithCancel(ctx) + var ctx context.Context + ctx, throttler.cancelEnableContext = context.WithCancel(context.Background()) throttler.check.SelfChecks(ctx) throttler.Operate(ctx) @@ -395,12 +448,11 @@ func (throttler *Throttler) Enable(ctx context.Context) bool { // Disable deactivates the probes and associated operations. When disabled, the throttler responds to check // queries with "200 OK" irrespective of lag or any other metrics. -func (throttler *Throttler) Disable(ctx context.Context) bool { +func (throttler *Throttler) Disable() bool { throttler.enableMutex.Lock() defer throttler.enableMutex.Unlock() - isEnabled := throttler.isEnabled.Swap(false) - if !isEnabled { + if wasEnabled := throttler.isEnabled.Swap(false); !wasEnabled { log.Infof("Throttler: already disabled") return false } @@ -415,6 +467,54 @@ func (throttler *Throttler) Disable(ctx context.Context) bool { return true } +// retryReadAndApplyThrottlerConfig() is called by Open(), read throttler config from topo, applies it, and starts watching +// for topo changes. +// But also, we're in an Open() function, which blocks state manager's operation, and affects +// opening of all other components. We thus read the throttler config in the background. +// However, we want to handle a situation where the read errors out. +// So we kick a loop that keeps retrying reading the config, for as long as this throttler is open. +func (throttler *Throttler) retryReadAndApplyThrottlerConfig(ctx context.Context) { + var watchSrvKeyspaceOnce sync.Once + retryInterval := 10 * time.Second + retryTicker := time.NewTicker(retryInterval) + defer retryTicker.Stop() + for { + if !throttler.IsOpen() { + // Throttler is not open so no need to keep retrying. + log.Warningf("Throttler.retryReadAndApplyThrottlerConfig(): throttler no longer seems to be open, exiting") + return + } + + requestCtx, requestCancel := context.WithTimeout(ctx, 5*time.Second) + defer requestCancel() + throttlerConfig, err := throttler.readThrottlerConfig(requestCtx) + if err == nil { + log.Infof("Throttler.retryReadAndApplyThrottlerConfig(): success reading throttler config: %+v", throttlerConfig) + // It's possible that during a retry-sleep, the throttler is closed and opened again, leading + // to two (or more) instances of this goroutine. That's not a big problem; it's fine if all + // attempt to read the throttler config; but we just want to ensure they don't step on each other + // while applying the changes. + throttler.initMutex.Lock() + defer throttler.initMutex.Unlock() + throttler.applyThrottlerConfig(ctx, throttlerConfig) // may issue an Enable + go watchSrvKeyspaceOnce.Do(func() { + // We start watching SrvKeyspace only after we know it's been created. Now is that time! + // We watch using the given ctx, which is cancelled when the throttler is Close()d. + throttler.srvTopoServer.WatchSrvKeyspace(ctx, throttler.cell, throttler.keyspace, throttler.WatchSrvKeyspaceCallback) + }) + return + } + log.Errorf("Throttler.retryReadAndApplyThrottlerConfig(): error reading throttler config. Will retry in %v. Err=%+v", retryInterval, err) + select { + case <-ctx.Done(): + // Throttler is not open so no need to keep retrying. + log.Infof("Throttler.retryReadAndApplyThrottlerConfig(): throttler no longer seems to be open, exiting") + return + case <-retryTicker.C: + } + } +} + // Open opens database pool and initializes the schema func (throttler *Throttler) Open() error { log.Infof("Throttler: started execution of Open. Acquiring initMutex lock") @@ -439,52 +539,7 @@ func (throttler *Throttler) Open() error { throttler.ThrottleApp("always-throttled-app", time.Now().Add(time.Hour*24*365*10), DefaultThrottleRatio, false) - log.Infof("Throttler: throttler-config-via-topo detected") - // We want to read throttler config from topo and apply it. - // But also, we're in an Open() function, which blocks state manager's operation, and affects - // opening of all other components. We thus read the throttler config in the background. - // However, we want to handle a situation where the read errors out. - // So we kick a loop that keeps retrying reading the config, for as long as this throttler is open. - retryReadAndApplyThrottlerConfig := func(ctx context.Context) { - retryInterval := 10 * time.Second - retryTicker := time.NewTicker(retryInterval) - defer retryTicker.Stop() - for { - if !throttler.IsOpen() { - // Throttler is not open so no need to keep retrying. - log.Errorf("Throttler.retryReadAndApplyThrottlerConfig(): throttler no longer seems to be open, exiting") - return - } - - requestCtx, requestCancel := context.WithTimeout(ctx, 5*time.Second) - defer requestCancel() - throttlerConfig, err := throttler.readThrottlerConfig(requestCtx) - if err == nil { - log.Errorf("Throttler.retryReadAndApplyThrottlerConfig(): success reading throttler config: %+v", throttlerConfig) - // It's possible that during a retry-sleep, the throttler is closed and opened again, leading - // to two (or more) instances of this goroutine. That's not a big problem; it's fine if all - // attempt to read the throttler config; but we just want to ensure they don't step on each other - // while applying the changes. - throttler.initMutex.Lock() - defer throttler.initMutex.Unlock() - throttler.applyThrottlerConfig(ctx, throttlerConfig) // may issue an Enable - go throttler.watchSrvKeyspaceOnce.Do(func() { - // We start watching SrvKeyspace only after we know it's been created. Now is that time! - throttler.srvTopoServer.WatchSrvKeyspace(context.Background(), throttler.cell, throttler.keyspace, throttler.WatchSrvKeyspaceCallback) - }) - return - } - log.Errorf("Throttler.retryReadAndApplyThrottlerConfig(): error reading throttler config. Will retry in %v. Err=%+v", retryInterval, err) - select { - case <-ctx.Done(): - // Throttler is not open so no need to keep retrying. - log.Errorf("Throttler.retryReadAndApplyThrottlerConfig(): throttler no longer seems to be open, exiting") - return - case <-retryTicker.C: - } - } - } - go retryReadAndApplyThrottlerConfig(ctx) + go throttler.retryReadAndApplyThrottlerConfig(ctx) return nil } @@ -500,19 +555,24 @@ func (throttler *Throttler) Close() { log.Infof("Throttler: throttler is not open") return } - ctx := context.Background() - throttler.Disable(ctx) + throttler.Disable() throttler.isLeader.Store(false) - log.Infof("Throttler: closing pool") - throttler.pool.Close() - throttler.cancelOpenContext() + // The below " != nil " checks are relevant to unit tests, where perhaps not all + // fields are supplied. + if throttler.pool != nil { + log.Infof("Throttler: closing pool") + throttler.pool.Close() + } + if throttler.cancelOpenContext != nil { + throttler.cancelOpenContext() + } log.Infof("Throttler: finished execution of Close") } func (throttler *Throttler) generateSelfMySQLThrottleMetricFunc(ctx context.Context, probe *mysql.Probe) func() *mysql.MySQLThrottleMetric { f := func() *mysql.MySQLThrottleMetric { - return throttler.readSelfMySQLThrottleMetric(ctx, probe) + return throttler.readSelfThrottleMetric(ctx, probe) } return f } @@ -521,7 +581,7 @@ func (throttler *Throttler) generateSelfMySQLThrottleMetricFunc(ctx context.Cont func (throttler *Throttler) readSelfMySQLThrottleMetric(ctx context.Context, probe *mysql.Probe) *mysql.MySQLThrottleMetric { metric := &mysql.MySQLThrottleMetric{ ClusterName: selfStoreName, - Key: *mysql.SelfInstanceKey, + Alias: "", Value: 0, Err: nil, } @@ -576,7 +636,7 @@ func (throttler *Throttler) ThrottledApps() (result []base.AppThrottle) { // isDormant returns true when the last check was more than dormantPeriod ago func (throttler *Throttler) isDormant() bool { - lastCheckTime := time.Unix(0, atomic.LoadInt64(&throttler.lastCheckTimeNano)) + lastCheckTime := time.Unix(0, throttler.lastCheckTimeNano.Load()) return time.Since(lastCheckTime) > dormantPeriod } @@ -589,118 +649,105 @@ func (throttler *Throttler) Operate(ctx context.Context) { tickers = append(tickers, t) return t } - leaderCheckTicker := addTicker(leaderCheckInterval) - mysqlCollectTicker := addTicker(mysqlCollectInterval) - mysqlDormantCollectTicker := addTicker(mysqlDormantCollectInterval) - mysqlRefreshTicker := addTicker(mysqlRefreshInterval) - mysqlAggregateTicker := addTicker(mysqlAggregateInterval) - throttledAppsTicker := addTicker(throttledAppsSnapshotInterval) + leaderCheckTicker := addTicker(throttler.leaderCheckInterval) + mysqlCollectTicker := addTicker(throttler.mysqlCollectInterval) + mysqlDormantCollectTicker := addTicker(throttler.mysqlDormantCollectInterval) + mysqlRefreshTicker := addTicker(throttler.mysqlRefreshInterval) + mysqlAggregateTicker := addTicker(throttler.mysqlAggregateInterval) + throttledAppsTicker := addTicker(throttler.throttledAppsSnapshotInterval) recentCheckTicker := addTicker(time.Second) - tmClient := tmclient.NewTabletManagerClient() - go func() { defer log.Infof("Throttler: Operate terminated, tickers stopped") - defer tmClient.Close() for _, t := range tickers { defer t.Stop() // since we just started the tickers now, speed up the ticks by forcing an immediate tick go t.TickNow() } + tmClient := throttler.overrideTmClient + if tmClient == nil { + // This is the normal production behavior. + // throttler.overrideTmClient != nil only in unit testing + tmClient = tmclient.NewTabletManagerClient() + defer tmClient.Close() + } + for { select { case <-ctx.Done(): return case <-leaderCheckTicker.C: - { - func() { - throttler.initMutex.Lock() - defer throttler.initMutex.Unlock() - - // sparse - shouldBeLeader := false - if throttler.IsOpen() { - if throttler.tabletTypeFunc() == topodatapb.TabletType_PRIMARY { - shouldBeLeader = true - } - } - - isLeader := throttler.isLeader.Swap(shouldBeLeader) - transitionedIntoLeader := false - if shouldBeLeader && !isLeader { - log.Infof("Throttler: transition into leadership") - transitionedIntoLeader = true - } - if !shouldBeLeader && isLeader { - log.Infof("Throttler: transition out of leadership") - } - - if transitionedIntoLeader { - // transitioned into leadership, let's speed up the next 'refresh' and 'collect' ticks - go mysqlRefreshTicker.TickNow() - go throttler.heartbeatWriter.RequestHeartbeats() - } - }() - } + func() { + throttler.initMutex.Lock() + defer throttler.initMutex.Unlock() + + // sparse + shouldBeLeader := false + if throttler.IsOpen() && throttler.tabletTypeFunc() == topodatapb.TabletType_PRIMARY { + shouldBeLeader = true + } + + isLeader := throttler.isLeader.Swap(shouldBeLeader) + transitionedIntoLeader := false + if shouldBeLeader && !isLeader { + log.Infof("Throttler: transition into leadership") + transitionedIntoLeader = true + } + if !shouldBeLeader && isLeader { + log.Infof("Throttler: transition out of leadership") + } + + if transitionedIntoLeader { + // transitioned into leadership, let's speed up the next 'refresh' and 'collect' ticks + go mysqlRefreshTicker.TickNow() + go throttler.heartbeatWriter.RequestHeartbeats() + } + }() case <-mysqlCollectTicker.C: - { - if throttler.IsOpen() { - // frequent - if !throttler.isDormant() { - throttler.collectMySQLMetrics(ctx, tmClient) - } + if throttler.IsOpen() { + // frequent + if !throttler.isDormant() { + throttler.collectMySQLMetrics(ctx, tmClient) } } case <-mysqlDormantCollectTicker.C: - { - if throttler.IsOpen() { - // infrequent - if throttler.isDormant() { - throttler.collectMySQLMetrics(ctx, tmClient) - } + if throttler.IsOpen() { + // infrequent + if throttler.isDormant() { + throttler.collectMySQLMetrics(ctx, tmClient) } } case metric := <-throttler.mysqlThrottleMetricChan: - { - // incoming MySQL metric, frequent, as result of collectMySQLMetrics() - throttler.mysqlInventory.InstanceKeyMetrics[metric.GetClusterInstanceKey()] = metric - } + // incoming MySQL metric, frequent, as result of collectMySQLMetrics() + throttler.mysqlInventory.TabletMetrics[metric.GetClusterTablet()] = metric case <-mysqlRefreshTicker.C: - { - // sparse - if throttler.IsOpen() { - throttler.refreshMySQLInventory(ctx) - } + // sparse + if throttler.IsOpen() { + throttler.refreshMySQLInventory(ctx) } case probes := <-throttler.mysqlClusterProbesChan: - { - // incoming structural update, sparse, as result of refreshMySQLInventory() - throttler.updateMySQLClusterProbes(ctx, probes) - } + // incoming structural update, sparse, as result of refreshMySQLInventory() + throttler.updateMySQLClusterProbes(ctx, probes) case <-mysqlAggregateTicker.C: - { - if throttler.IsOpen() { - throttler.aggregateMySQLMetrics(ctx) - } + if throttler.IsOpen() { + throttler.aggregateMySQLMetrics(ctx) } case <-throttledAppsTicker.C: - { - if throttler.IsOpen() { - go throttler.expireThrottledApps() - } + if throttler.IsOpen() { + go throttler.expireThrottledApps() } case throttlerConfig := <-throttler.throttlerConfigChan: throttler.applyThrottlerConfig(ctx, throttlerConfig) case <-recentCheckTicker.C: // Increment recentCheckTickerValue by one. - atomic.AddInt64(&throttler.recentCheckTickerValue, 1) + throttler.recentCheckTickerValue.Add(1) } } }() } -func (throttler *Throttler) generateTabletHTTPProbeFunction(ctx context.Context, tmClient tmclient.TabletManagerClient, clusterName string, probe *mysql.Probe) (probeFunc func() *mysql.MySQLThrottleMetric) { +func (throttler *Throttler) generateTabletProbeFunction(ctx context.Context, clusterName string, tmClient tmclient.TabletManagerClient, probe *mysql.Probe) (probeFunc func() *mysql.MySQLThrottleMetric) { return func() *mysql.MySQLThrottleMetric { // Some reasonable timeout, to ensure we release connections even if they're hanging (otherwise grpc-go keeps polling those connections forever) ctx, cancel := context.WithTimeout(ctx, 4*mysqlCollectInterval) @@ -709,55 +756,24 @@ func (throttler *Throttler) generateTabletHTTPProbeFunction(ctx context.Context, // Hit a tablet's `check-self` via HTTP, and convert its CheckResult JSON output into a MySQLThrottleMetric mySQLThrottleMetric := mysql.NewMySQLThrottleMetric() mySQLThrottleMetric.ClusterName = clusterName - mySQLThrottleMetric.Key = probe.Key - - { - req := &tabletmanagerdatapb.CheckThrottlerRequest{} // We leave AppName empty; it will default to VitessName anyway, and we can save some proto space - if resp, gRPCErr := tmClient.CheckThrottler(ctx, probe.Tablet, req); gRPCErr == nil { - mySQLThrottleMetric.Value = resp.Value - if resp.StatusCode == http.StatusInternalServerError { - mySQLThrottleMetric.Err = fmt.Errorf("Status code: %d", resp.StatusCode) - } - if resp.RecentlyChecked { - // We have just probed a tablet, and it reported back that someone just recently "check"ed it. - // We therefore renew the heartbeats lease. - go throttler.heartbeatWriter.RequestHeartbeats() - } - return mySQLThrottleMetric - - // } else { - // In v18 we need to be backwards compatible. If we have a gRPC error it might be because the replica is v17 and - // does not support CheckThrottler() RPC. This is why: - // 1. We fall back to HTTP - // 2. We don't log an error (it would just spam the logs) - // In v19 we will remove all HTTP code, and will *potentially* log an error. - // log.Errorf("error in GRPC call to tablet %v: %v", probe.Tablet.GetAlias(), gRPCErr) - } - } - // Backwards compatibility to v17: if the underlying tablets do not support CheckThrottler gRPC, attempt a HTTP check: - tabletCheckSelfURL := fmt.Sprintf("http://%s:%d/throttler/check-self?app=%s", probe.TabletHost, probe.TabletPort, throttlerapp.VitessName) - resp, err := throttler.httpClient.Get(tabletCheckSelfURL) - if err != nil { - mySQLThrottleMetric.Err = err - return mySQLThrottleMetric - } - defer resp.Body.Close() - b, err := io.ReadAll(resp.Body) - if err != nil { - mySQLThrottleMetric.Err = err + mySQLThrottleMetric.Alias = probe.Alias + + if probe.Tablet == nil { + mySQLThrottleMetric.Err = fmt.Errorf("found nil tablet reference for alias %v, hostname %v", probe.Alias, probe.Tablet.Hostname) return mySQLThrottleMetric } - checkResult := &CheckResult{} - if err := json.Unmarshal(b, checkResult); err != nil { - mySQLThrottleMetric.Err = err + req := &tabletmanagerdatapb.CheckThrottlerRequest{} // We leave AppName empty; it will default to VitessName anyway, and we can save some proto space + resp, gRPCErr := tmClient.CheckThrottler(ctx, probe.Tablet, req) + if gRPCErr != nil { + resp.StatusCode = http.StatusInternalServerError + mySQLThrottleMetric.Err = fmt.Errorf("gRPC error accessing tablet %v. Err=%v", probe.Alias, gRPCErr) return mySQLThrottleMetric } - mySQLThrottleMetric.Value = checkResult.Value - - if checkResult.StatusCode == http.StatusInternalServerError { - mySQLThrottleMetric.Err = fmt.Errorf("Status code: %d", checkResult.StatusCode) + mySQLThrottleMetric.Value = resp.Value + if resp.StatusCode == http.StatusInternalServerError { + mySQLThrottleMetric.Err = fmt.Errorf("Status code: %d", resp.StatusCode) } - if checkResult.RecentlyChecked { + if resp.RecentlyChecked { // We have just probed a tablet, and it reported back that someone just recently "check"ed it. // We therefore renew the heartbeats lease. go throttler.heartbeatWriter.RequestHeartbeats() @@ -770,33 +786,33 @@ func (throttler *Throttler) collectMySQLMetrics(ctx context.Context, tmClient tm // synchronously, get lists of probes for clusterName, probes := range throttler.mysqlInventory.ClustersProbes { clusterName := clusterName - probes := probes - go func() { - // probes is known not to change. It can be *replaced*, but not changed. - // so it's safe to iterate it - for _, probe := range *probes { - probe := probe - go func() { - // Avoid querying the same server twice at the same time. If previous read is still there, - // we avoid re-reading it. - if !atomic.CompareAndSwapInt64(&probe.QueryInProgress, 0, 1) { - return - } - defer atomic.StoreInt64(&probe.QueryInProgress, 0) - - var throttleMetricFunc func() *mysql.MySQLThrottleMetric - if clusterName == selfStoreName { - // Throttler is probing its own tablet's metrics: - throttleMetricFunc = throttler.generateSelfMySQLThrottleMetricFunc(ctx, probe) - } else { - // Throttler probing other tablets: - throttleMetricFunc = throttler.generateTabletHTTPProbeFunction(ctx, tmClient, clusterName, probe) - } - throttleMetrics := mysql.ReadThrottleMetric(probe, clusterName, throttleMetricFunc) - throttler.mysqlThrottleMetricChan <- throttleMetrics - }() - } - }() + // probes is known not to change. It can be *replaced*, but not changed. + // so it's safe to iterate it + for _, probe := range probes { + go func(probe *mysql.Probe) { + // Avoid querying the same server twice at the same time. If previous read is still there, + // we avoid re-reading it. + if !atomic.CompareAndSwapInt64(&probe.QueryInProgress, 0, 1) { + return + } + defer atomic.StoreInt64(&probe.QueryInProgress, 0) + + var throttleMetricFunc func() *mysql.MySQLThrottleMetric + if clusterName == selfStoreName { + // Throttler is probing its own tablet's metrics: + throttleMetricFunc = throttler.generateSelfMySQLThrottleMetricFunc(ctx, probe) + } else { + // Throttler probing other tablets: + throttleMetricFunc = throttler.generateTabletProbeFunction(ctx, clusterName, tmClient, probe) + } + throttleMetrics := mysql.ReadThrottleMetric(probe, clusterName, throttleMetricFunc) + select { + case <-ctx.Done(): + return + case throttler.mysqlThrottleMetricChan <- throttleMetrics: + } + }(probe) + } } return nil } @@ -806,50 +822,64 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // distribute the query/threshold from the throttler down to the cluster settings and from there to the probes metricsQuery := throttler.GetMetricsQuery() metricsThreshold := throttler.MetricsThreshold.Load() - addInstanceKey := func(tablet *topodatapb.Tablet, tabletHost string, tabletPort int, key *mysql.InstanceKey, clusterName string, clusterSettings *config.MySQLClusterConfigurationSettings, probes *mysql.Probes) { + addProbe := func(alias string, tablet *topodatapb.Tablet, clusterName string, clusterSettings *config.MySQLClusterConfigurationSettings, probes mysql.Probes) bool { for _, ignore := range clusterSettings.IgnoreHosts { - if strings.Contains(key.StringCode(), ignore) { - log.Infof("Throttler: instance key ignored: %+v", key) - return + if strings.Contains(alias, ignore) { + log.Infof("Throttler: tablet ignored: %+v", alias) + return false } } - if !key.IsValid() && !key.IsSelf() { - log.Infof("Throttler: read invalid instance key: [%+v] for cluster %+v", key, clusterName) - return + if clusterName != selfStoreName { + if alias == "" { + log.Errorf("Throttler: got empty alias for cluster: %+v", clusterName) + return false + } + if tablet == nil { + log.Errorf("Throttler: got nil tablet for alias: %v in cluster: %+v", alias, clusterName) + return false + } } probe := &mysql.Probe{ - Key: *key, + Alias: alias, Tablet: tablet, - TabletHost: tabletHost, - TabletPort: tabletPort, MetricQuery: clusterSettings.MetricQuery, CacheMillis: clusterSettings.CacheMillis, } - (*probes)[*key] = probe + probes[alias] = probe + return true + } + + attemptWriteProbes := func(clusterProbes *mysql.ClusterProbes) error { + select { + case <-ctx.Done(): + return ctx.Err() + case throttler.mysqlClusterProbesChan <- clusterProbes: + return nil + } } for clusterName, clusterSettings := range config.Settings().Stores.MySQL.Clusters { clusterName := clusterName - clusterSettings := clusterSettings clusterSettings.MetricQuery = metricsQuery clusterSettings.ThrottleThreshold.Store(metricsThreshold) + + clusterSettingsCopy := *clusterSettings // config may dynamically change, but internal structure (config.Settings().Stores.MySQL.Clusters in our case) // is immutable and can only be _replaced_. Hence, it's safe to read in a goroutine: - go func() { - throttler.mysqlClusterThresholds.Set(clusterName, math.Float64frombits(clusterSettings.ThrottleThreshold.Load()), cache.DefaultExpiration) + collect := func() error { + throttler.mysqlClusterThresholds.Set(clusterName, math.Float64frombits(clusterSettingsCopy.ThrottleThreshold.Load()), cache.DefaultExpiration) clusterProbes := &mysql.ClusterProbes{ ClusterName: clusterName, - IgnoreHostsCount: clusterSettings.IgnoreHostsCount, - InstanceProbes: mysql.NewProbes(), + IgnoreHostsCount: clusterSettingsCopy.IgnoreHostsCount, + TabletProbes: mysql.NewProbes(), } if clusterName == selfStoreName { // special case: just looking at this tablet's MySQL server. // We will probe this "cluster" (of one server) is a special way. - addInstanceKey(nil, "", 0, mysql.SelfInstanceKey, clusterName, clusterSettings, clusterProbes.InstanceProbes) - throttler.mysqlClusterProbesChan <- clusterProbes - return + addProbe("", nil, clusterName, &clusterSettingsCopy, clusterProbes.TabletProbes) + return attemptWriteProbes(clusterProbes) } if !throttler.isLeader.Load() { // This tablet may have used to be the primary, but it isn't now. It may have a recollection @@ -858,33 +888,30 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // `clusterProbes` was created above as empty, and identifiable via `clusterName`. This will in turn // be used to overwrite throttler.mysqlInventory.ClustersProbes[clusterProbes.ClusterName] in // updateMySQLClusterProbes(). - throttler.mysqlClusterProbesChan <- clusterProbes + return attemptWriteProbes(clusterProbes) // not the leader (primary tablet)? Then no more work for us. - return } // The primary tablet is also in charge of collecting the shard's metrics - err := func() error { - ctx, cancel := context.WithTimeout(ctx, mysqlRefreshInterval) - defer cancel() + ctx, cancel := context.WithTimeout(ctx, mysqlRefreshInterval) + defer cancel() - tabletAliases, err := throttler.ts.FindAllTabletAliasesInShard(ctx, throttler.keyspace, throttler.shard) + tabletAliases, err := throttler.ts.FindAllTabletAliasesInShard(ctx, throttler.keyspace, throttler.shard) + if err != nil { + return err + } + for _, tabletAlias := range tabletAliases { + tablet, err := throttler.ts.GetTablet(ctx, tabletAlias) if err != nil { return err } - for _, tabletAlias := range tabletAliases { - tablet, err := throttler.ts.GetTablet(ctx, tabletAlias) - if err != nil { - return err - } - if throttler.throttleTabletTypesMap[tablet.Type] { - key := mysql.InstanceKey{Hostname: tablet.MysqlHostname, Port: int(tablet.MysqlPort)} - addInstanceKey(tablet.Tablet, tablet.Hostname, int(tablet.PortMap["vt"]), &key, clusterName, clusterSettings, clusterProbes.InstanceProbes) - } + if throttler.throttleTabletTypesMap[tablet.Type] { + addProbe(topoproto.TabletAliasString(tabletAlias), tablet.Tablet, clusterName, &clusterSettingsCopy, clusterProbes.TabletProbes) } - throttler.mysqlClusterProbesChan <- clusterProbes - return nil - }() - if err != nil { + } + return attemptWriteProbes(clusterProbes) + } + go func() { + if err := collect(); err != nil { log.Errorf("refreshMySQLInventory: %+v", err) } }() @@ -894,7 +921,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // synchronous update of inventory func (throttler *Throttler) updateMySQLClusterProbes(ctx context.Context, clusterProbes *mysql.ClusterProbes) error { - throttler.mysqlInventory.ClustersProbes[clusterProbes.ClusterName] = clusterProbes.InstanceProbes + throttler.mysqlInventory.ClustersProbes[clusterProbes.ClusterName] = clusterProbes.TabletProbes throttler.mysqlInventory.IgnoreHostsCount[clusterProbes.ClusterName] = clusterProbes.IgnoreHostsCount throttler.mysqlInventory.IgnoreHostsThreshold[clusterProbes.ClusterName] = clusterProbes.IgnoreHostsThreshold return nil @@ -906,7 +933,7 @@ func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { metricName := fmt.Sprintf("mysql/%s", clusterName) ignoreHostsCount := throttler.mysqlInventory.IgnoreHostsCount[clusterName] ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold[clusterName] - aggregatedMetric := aggregateMySQLProbes(ctx, probes, clusterName, throttler.mysqlInventory.InstanceKeyMetrics, ignoreHostsCount, config.Settings().Stores.MySQL.IgnoreDialTCPErrors, ignoreHostsThreshold) + aggregatedMetric := aggregateMySQLProbes(ctx, probes, clusterName, throttler.mysqlInventory.TabletMetrics, ignoreHostsCount, config.Settings().Stores.MySQL.IgnoreDialTCPErrors, ignoreHostsThreshold) throttler.aggregatedMetrics.Set(metricName, aggregatedMetric, cache.DefaultExpiration) } return nil @@ -1135,11 +1162,11 @@ func (throttler *Throttler) checkStore(ctx context.Context, appName string, stor // This check was made by someone other than the throttler itself, i.e. this came from online-ddl or vreplication or other. // We mark the fact that someone just made a check. If this is a REPLICA or RDONLY tables, this will be reported back // to the PRIMARY so that it knows it must renew the heartbeat lease. - atomic.StoreInt64(&throttler.recentCheckValue, 1+atomic.LoadInt64(&throttler.recentCheckTickerValue)) + throttler.recentCheckValue.Store(1 + throttler.recentCheckTickerValue.Load()) } checkResult = throttler.check.Check(ctx, appName, "mysql", storeName, remoteAddr, flags) - if atomic.LoadInt64(&throttler.recentCheckValue) >= atomic.LoadInt64(&throttler.recentCheckTickerValue) { + if throttler.recentCheckValue.Load() >= throttler.recentCheckTickerValue.Load() { // This indicates someone, who is not "vitess" ie not internal to the throttling logic, did a _recent_ `check`. // This could be online-ddl, or vreplication or whoever else. // If this tablet is a REPLICA or RDONLY, we want to advertise to the PRIMARY that someone did a recent check, diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_exclude_race_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_exclude_race_test.go new file mode 100644 index 00000000000..903b55b9be8 --- /dev/null +++ b/go/vt/vttablet/tabletserver/throttle/throttler_exclude_race_test.go @@ -0,0 +1,76 @@ +//go:build !race + +/* +Copyright 2023 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 throttle + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestProbesPostDisable runs the throttler for some time, and then investigates the internal throttler maps and values. +// While the throttler is disabled, it is technically safe to iterate those structures. However, `go test -race` disagrees, +// which is why this test is in this *exclude_race* file +func TestProbesPostDisable(t *testing.T) { + throttler := newTestThrottler() + runThrottler(t, throttler, 2*time.Second, nil) + + time.Sleep(time.Second) // throttler's Operate() quits asynchronously. For sake of `go test -race` we allow a graceful wait. + probes := throttler.mysqlInventory.ClustersProbes + assert.NotEmpty(t, probes) + + selfProbes := probes[selfStoreName] + t.Run("self", func(t *testing.T) { + assert.NotEmpty(t, selfProbes) + require.Equal(t, 1, len(selfProbes)) // should always be true once refreshMySQLInventory() runs + probe, ok := selfProbes[""] + assert.True(t, ok) + assert.NotNil(t, probe) + + assert.Equal(t, "", probe.Alias) + assert.Nil(t, probe.Tablet) + assert.Equal(t, "select 1", probe.MetricQuery) + assert.Equal(t, int64(0), probe.QueryInProgress) + }) + + shardProbes := probes[shardStoreName] + t.Run("shard", func(t *testing.T) { + assert.NotEmpty(t, shardProbes) + assert.Equal(t, 2, len(shardProbes)) // see fake FindAllTabletAliasesInShard above + for _, probe := range shardProbes { + require.NotNil(t, probe) + assert.NotEmpty(t, probe.Alias) + assert.NotNil(t, probe.Tablet) + assert.Equal(t, "select 1", probe.MetricQuery) + assert.Equal(t, int64(0), probe.QueryInProgress) + } + }) + + t.Run("metrics", func(t *testing.T) { + assert.Equal(t, 3, len(throttler.mysqlInventory.TabletMetrics)) // 1 self tablet + 2 shard tablets + }) + + t.Run("aggregated", func(t *testing.T) { + assert.Equal(t, 0, throttler.aggregatedMetrics.ItemCount()) // flushed upon Disable() + aggr := throttler.aggregatedMetricsSnapshot() + assert.Equal(t, 0, len(aggr)) + }) +} diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index e1a9c5abc79..b40f3a0a9cb 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -1,7 +1,17 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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 throttle @@ -9,6 +19,7 @@ package throttle import ( "context" "fmt" + "net/http" "sync/atomic" "testing" "time" @@ -18,9 +29,13 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" + "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/config" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" + "vitess.io/vitess/go/vt/vttablet/tmclient" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -28,6 +43,23 @@ const ( waitForProbesTimeout = 30 * time.Second ) +type fakeTMClient struct { + tmclient.TabletManagerClient +} + +func (c *fakeTMClient) Close() { +} + +func (c *fakeTMClient) CheckThrottler(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.CheckThrottlerRequest) (*tabletmanagerdatapb.CheckThrottlerResponse, error) { + resp := &tabletmanagerdatapb.CheckThrottlerResponse{ + StatusCode: http.StatusOK, + Value: 0, + Threshold: 1, + RecentlyChecked: true, + } + return resp, nil +} + type FakeTopoServer struct { } @@ -64,6 +96,65 @@ type FakeHeartbeatWriter struct { func (w FakeHeartbeatWriter) RequestHeartbeats() { } +func newTestThrottler() *Throttler { + metricsQuery := "select 1" + config.Settings().Stores.MySQL.Clusters = map[string]*config.MySQLClusterConfigurationSettings{ + selfStoreName: {}, + shardStoreName: {}, + } + clusters := config.Settings().Stores.MySQL.Clusters + for _, s := range clusters { + s.MetricQuery = metricsQuery + s.ThrottleThreshold = &atomic.Uint64{} + s.ThrottleThreshold.Store(1) + } + env := tabletenv.NewEnv(nil, "TabletServerTest") + throttler := &Throttler{ + mysqlClusterProbesChan: make(chan *mysql.ClusterProbes), + mysqlClusterThresholds: cache.New(cache.NoExpiration, 0), + heartbeatWriter: FakeHeartbeatWriter{}, + ts: &FakeTopoServer{}, + mysqlInventory: mysql.NewInventory(), + pool: connpool.NewPool(env, "ThrottlerPool", tabletenv.ConnPoolConfig{}), + tabletTypeFunc: func() topodatapb.TabletType { return topodatapb.TabletType_PRIMARY }, + overrideTmClient: &fakeTMClient{}, + } + throttler.mysqlThrottleMetricChan = make(chan *mysql.MySQLThrottleMetric) + throttler.mysqlInventoryChan = make(chan *mysql.Inventory, 1) + throttler.mysqlClusterProbesChan = make(chan *mysql.ClusterProbes) + throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) + throttler.mysqlInventory = mysql.NewInventory() + + throttler.throttledApps = cache.New(cache.NoExpiration, 0) + throttler.mysqlClusterThresholds = cache.New(cache.NoExpiration, 0) + throttler.aggregatedMetrics = cache.New(10*aggregatedMetricsExpiration, 0) + throttler.recentApps = cache.New(recentAppsExpiration, 0) + throttler.metricsHealth = cache.New(cache.NoExpiration, 0) + throttler.nonLowPriorityAppRequestsThrottled = cache.New(nonDeprioritizedAppMapExpiration, 0) + throttler.metricsQuery.Store(metricsQuery) + throttler.initThrottleTabletTypes() + throttler.check = NewThrottlerCheck(throttler) + + // High contention & racy itnervals: + throttler.leaderCheckInterval = 10 * time.Millisecond + throttler.mysqlCollectInterval = 10 * time.Millisecond + throttler.mysqlDormantCollectInterval = 10 * time.Millisecond + throttler.mysqlRefreshInterval = 10 * time.Millisecond + throttler.mysqlAggregateInterval = 10 * time.Millisecond + throttler.throttledAppsSnapshotInterval = 10 * time.Millisecond + + throttler.readSelfThrottleMetric = func(ctx context.Context, p *mysql.Probe) *mysql.MySQLThrottleMetric { + return &mysql.MySQLThrottleMetric{ + ClusterName: selfStoreName, + Alias: "", + Value: 1, + Err: nil, + } + } + + return throttler +} + func TestIsAppThrottled(t *testing.T) { throttler := Throttler{ throttledApps: cache.New(cache.NoExpiration, 0), @@ -153,14 +244,14 @@ func TestRefreshMySQLInventory(t *testing.T) { validateClusterProbes := func(t *testing.T, ctx context.Context) { testName := fmt.Sprintf("leader=%t", throttler.isLeader.Load()) t.Run(testName, func(t *testing.T) { - // validateProbesCount expects a number of probes according to cluster name and throttler's leadership status - validateProbesCount := func(t *testing.T, clusterName string, probes *mysql.Probes) { + // validateProbesCount expects number of probes according to cluster name and throttler's leadership status + validateProbesCount := func(t *testing.T, clusterName string, probes mysql.Probes) { if clusterName == selfStoreName { - assert.Equal(t, 1, len(*probes)) + assert.Equal(t, 1, len(probes)) } else if throttler.isLeader.Load() { - assert.NotZero(t, len(*probes)) + assert.NotZero(t, len(probes)) } else { - assert.Empty(t, *probes) + assert.Empty(t, probes) } } t.Run("waiting for probes", func(t *testing.T) { @@ -170,7 +261,7 @@ func TestRefreshMySQLInventory(t *testing.T) { for { select { case probes := <-throttler.mysqlClusterProbesChan: - // Worth noting that in this unit test, the throttler is _closed_. Its own Operate() function does + // Worth noting that in this unit test, the throttler is _closed_ and _disabled_. Its own Operate() function does // not run, and therefore there is none but us to both populate `mysqlClusterProbesChan` as well as // read from it. We do not compete here with any other goroutine. assert.NotNil(t, probes) @@ -178,7 +269,7 @@ func TestRefreshMySQLInventory(t *testing.T) { throttler.updateMySQLClusterProbes(ctx, probes) numClusterProbesResults++ - validateProbesCount(t, probes.ClusterName, probes.InstanceProbes) + validateProbesCount(t, probes.ClusterName, probes.TabletProbes) if numClusterProbesResults == len(clusters) { // Achieved our goal @@ -219,3 +310,69 @@ func TestRefreshMySQLInventory(t *testing.T) { validateClusterProbes(t, ctx) }) } + +// runThrottler opens and enables the throttler, therby making it run the Operate() function, for a given amount of time. +// Optionally, running a given function halfway while the throttler is still open and running. +func runThrottler(t *testing.T, throttler *Throttler, timeout time.Duration, f func(*testing.T)) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + assert.False(t, throttler.IsOpen()) + assert.False(t, throttler.IsEnabled()) + + throttler.isOpen.Swap(true) + defer throttler.isOpen.Swap(false) + assert.True(t, throttler.IsOpen()) + assert.False(t, throttler.IsEnabled()) + + ok := throttler.Enable() + defer throttler.Disable() + assert.True(t, ok) + assert.True(t, throttler.IsEnabled()) + + if f != nil { + time.Sleep(timeout / 2) + f(t) + } + + <-ctx.Done() + assert.Error(t, ctx.Err()) + + throttler.Disable() + assert.False(t, throttler.IsEnabled()) +} + +// TestRace merely lets the throttler run with aggressive intervals for a few seconds, so as to detect race conditions. +// This is relevant to `go test -race` +func TestRace(t *testing.T) { + throttler := newTestThrottler() + runThrottler(t, throttler, 5*time.Second, nil) +} + +// TestProbes enables a throttler for a few seocnds, and afterwards expects to find probes and metrics. +func TestProbesWhileOperating(t *testing.T) { + throttler := newTestThrottler() + + t.Run("aggregated", func(t *testing.T) { + assert.Equal(t, 0, throttler.aggregatedMetrics.ItemCount()) + }) + runThrottler(t, throttler, 5*time.Second, func(t *testing.T) { + t.Run("aggregated", func(t *testing.T) { + assert.Equal(t, 2, throttler.aggregatedMetrics.ItemCount()) // flushed upon Disable() + aggr := throttler.aggregatedMetricsSnapshot() + assert.Equal(t, 2, len(aggr)) // "self" and "shard" clusters + for clusterName, metricResult := range aggr { + val, err := metricResult.Get() + assert.NoError(t, err) + switch clusterName { + case "mysql/self": + assert.Equal(t, float64(1), val) + case "mysql/shard": + assert.Equal(t, float64(0), val) + default: + assert.Failf(t, "unknown clusterName", "%v", clusterName) + } + } + }) + }) +} diff --git a/go/vt/vttablet/tabletserver/throttle/throttlerapp/app_test.go b/go/vt/vttablet/tabletserver/throttle/throttlerapp/app_test.go index bd14624f49b..c468009c793 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttlerapp/app_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttlerapp/app_test.go @@ -1,7 +1,17 @@ /* - Copyright 2017 GitHub Inc. +Copyright 2023 The Vitess Authors. - Licensed under MIT License. See https://github.com/github/freno/blob/master/LICENSE +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 throttlerapp From bebddba7bbdf675d3f01badd59947a37f5cad5d4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:56:46 +0200 Subject: [PATCH 118/119] Online DDL: support migration cut-over backoff and forced cut-over (#14546) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Co-authored-by: Matt Lord --- go/cmd/vtctldclient/command/onlineddl.go | 33 + go/mysql/flavor.go | 1 + go/mysql/flavor_mysql.go | 2 + go/mysql/flavor_test.go | 10 + go/test/endtoend/cluster/vttablet_process.go | 21 +- .../scheduler/onlineddl_scheduler_test.go | 157 + go/test/endtoend/onlineddl/vtgate_util.go | 15 + go/vt/proto/vtctldata/vtctldata.pb.go | 5296 +++--- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 454 + go/vt/proto/vtctlservice/vtctlservice.pb.go | 794 +- .../vtctlservice/vtctlservice_grpc.pb.go | 38 + go/vt/schema/ddl_strategy.go | 49 +- go/vt/schema/ddl_strategy_test.go | 25 +- .../schema/onlineddl/schema_migrations.sql | 2 + go/vt/sqlparser/ast_format.go | 4 + go/vt/sqlparser/ast_format_fast.go | 4 + go/vt/sqlparser/constants.go | 2 + go/vt/sqlparser/keywords.go | 1 + go/vt/sqlparser/parse_test.go | 7 + go/vt/sqlparser/sql.go | 14953 ++++++++-------- go/vt/sqlparser/sql.y | 15 +- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 31 + go/vt/vtctl/grpcvtctldserver/server_test.go | 202 + go/vt/vtctl/localvtctldclient/client_gen.go | 5 + go/vt/vttablet/onlineddl/executor.go | 348 +- go/vt/vttablet/onlineddl/executor_test.go | 107 + go/vt/vttablet/onlineddl/schema.go | 40 +- go/vt/vttablet/tabletserver/query_executor.go | 4 + proto/vtctldata.proto | 10 +- proto/vtctlservice.proto | 2 + web/vtadmin/src/proto/vtadmin.d.ts | 200 + web/vtadmin/src/proto/vtadmin.js | 475 + 33 files changed, 12832 insertions(+), 10484 deletions(-) diff --git a/go/cmd/vtctldclient/command/onlineddl.go b/go/cmd/vtctldclient/command/onlineddl.go index dbe927de2bf..6193de9b2af 100644 --- a/go/cmd/vtctldclient/command/onlineddl.go +++ b/go/cmd/vtctldclient/command/onlineddl.go @@ -102,6 +102,14 @@ var ( Args: cobra.ExactArgs(2), RunE: commandOnlineDDLUnthrottle, } + OnlineDDLForceCutOver = &cobra.Command{ + Use: "force-cutover ", + Short: "Mark a given schema migration, or all pending migrations, for forced cut over.", + Example: "OnlineDDL force-cutover test_keyspace 82fa54ac_e83e_11ea_96b7_f875a4d24e90", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + RunE: commandOnlineDDLForceCutOver, + } OnlineDDLShow = &cobra.Command{ Use: "show", Short: "Display information about online DDL operations.", @@ -184,6 +192,30 @@ func commandOnlineDDLCleanup(cmd *cobra.Command, args []string) error { return nil } +func commandOnlineDDLForceCutOver(cmd *cobra.Command, args []string) error { + keyspace, uuid, err := analyzeOnlineDDLCommandWithUuidOrAllArgument(cmd) + if err != nil { + return err + } + cli.FinishedParsing(cmd) + + resp, err := client.ForceCutOverSchemaMigration(commandCtx, &vtctldatapb.ForceCutOverSchemaMigrationRequest{ + Keyspace: keyspace, + Uuid: uuid, + }) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + func commandOnlineDDLComplete(cmd *cobra.Command, args []string) error { keyspace, uuid, err := analyzeOnlineDDLCommandWithUuidOrAllArgument(cmd) if err != nil { @@ -393,6 +425,7 @@ func init() { OnlineDDL.AddCommand(OnlineDDLRetry) OnlineDDL.AddCommand(OnlineDDLThrottle) OnlineDDL.AddCommand(OnlineDDLUnthrottle) + OnlineDDL.AddCommand(OnlineDDLForceCutOver) OnlineDDLShow.Flags().BoolVar(&onlineDDLShowArgs.JSON, "json", false, "Output JSON instead of human-readable table.") OnlineDDLShow.Flags().StringVar(&onlineDDLShowArgs.OrderStr, "order", "asc", "Sort the results by `id` property of the Schema migration.") diff --git a/go/mysql/flavor.go b/go/mysql/flavor.go index 2c6fb2b867f..245320f7fe3 100644 --- a/go/mysql/flavor.go +++ b/go/mysql/flavor.go @@ -56,6 +56,7 @@ const ( DynamicRedoLogCapacityFlavorCapability // supported in MySQL 8.0.30 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-30.html DisableRedoLogFlavorCapability // supported in MySQL 8.0.21 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html CheckConstraintsCapability // supported in MySQL 8.0.16 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html + PerformanceSchemaDataLocksTableCapability ) const ( diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index a3a449f5490..b9633c93416 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -423,6 +423,8 @@ func (mysqlFlavor80) supportsCapability(serverVersion string, capability FlavorC return ServerVersionAtLeast(serverVersion, 8, 0, 21) case CheckConstraintsCapability: return ServerVersionAtLeast(serverVersion, 8, 0, 16) + case PerformanceSchemaDataLocksTableCapability: + return true, nil default: return false, nil } diff --git a/go/mysql/flavor_test.go b/go/mysql/flavor_test.go index 925504722b7..4804593ff90 100644 --- a/go/mysql/flavor_test.go +++ b/go/mysql/flavor_test.go @@ -170,6 +170,16 @@ func TestGetFlavor(t *testing.T) { capability: CheckConstraintsCapability, isCapable: true, }, + { + version: "5.7.38", + capability: PerformanceSchemaDataLocksTableCapability, + isCapable: false, + }, + { + version: "8.0.20", + capability: PerformanceSchemaDataLocksTableCapability, + isCapable: true, + }, } for _, tc := range testcases { name := fmt.Sprintf("%s %v", tc.version, tc.capability) diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index 96bec7c624b..f92382d5f2d 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -449,11 +449,7 @@ func (vttablet *VttabletProcess) CreateDB(keyspace string) error { // QueryTablet lets you execute a query in this tablet and get the result func (vttablet *VttabletProcess) QueryTablet(query string, keyspace string, useDb bool) (*sqltypes.Result, error) { - if !useDb { - keyspace = "" - } - dbParams := NewConnParams(vttablet.DbPort, vttablet.DbPassword, path.Join(vttablet.Directory, "mysql.sock"), keyspace) - conn, err := vttablet.conn(&dbParams) + conn, err := vttablet.TabletConn(keyspace, useDb) if err != nil { return nil, err } @@ -464,11 +460,7 @@ func (vttablet *VttabletProcess) QueryTablet(query string, keyspace string, useD // QueryTabletMultiple lets you execute multiple queries -- without any // results -- against the tablet. func (vttablet *VttabletProcess) QueryTabletMultiple(queries []string, keyspace string, useDb bool) error { - if !useDb { - keyspace = "" - } - dbParams := NewConnParams(vttablet.DbPort, vttablet.DbPassword, path.Join(vttablet.Directory, "mysql.sock"), keyspace) - conn, err := vttablet.conn(&dbParams) + conn, err := vttablet.TabletConn(keyspace, useDb) if err != nil { return err } @@ -484,6 +476,15 @@ func (vttablet *VttabletProcess) QueryTabletMultiple(queries []string, keyspace return nil } +// TabletConn opens a MySQL connection on this tablet +func (vttablet *VttabletProcess) TabletConn(keyspace string, useDb bool) (*mysql.Conn, error) { + if !useDb { + keyspace = "" + } + dbParams := NewConnParams(vttablet.DbPort, vttablet.DbPassword, path.Join(vttablet.Directory, "mysql.sock"), keyspace) + return vttablet.conn(&dbParams) +} + func (vttablet *VttabletProcess) defaultConn(dbname string) (*mysql.Conn, error) { dbParams := mysql.ConnParams{ Uname: "vt_dba", diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index 575ecb91091..dd3cb1dbb4c 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -200,6 +200,29 @@ func waitForReadyToComplete(t *testing.T, uuid string, expected bool) { } } +func waitForMessage(t *testing.T, uuid string, messageSubstring string) { + ctx, cancel := context.WithTimeout(context.Background(), normalWaitTime) + defer cancel() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + rs := onlineddl.ReadMigrations(t, &vtParams, uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + message := row.AsString("message", "") + if strings.Contains(message, messageSubstring) { + return + } + } + select { + case <-ticker.C: + case <-ctx.Done(): + } + require.NoError(t, ctx.Err()) + } +} + func TestMain(m *testing.M) { defer cluster.PanicHandler(nil) flag.Parse() @@ -366,6 +389,9 @@ func testScheduler(t *testing.T) { alterNonexistent = ` ALTER TABLE nonexistent FORCE ` + populateT1Statement = ` + insert into t1_test values (1, 'new_row') + ` ) testReadTimestamp := func(t *testing.T, uuid string, timestampColumn string) (timestamp string) { @@ -490,6 +516,109 @@ func testScheduler(t *testing.T) { onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) }) }) + + t.Run("Postpone completion ALTER", func(t *testing.T) { + t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy+" --postpone-completion", "vtgate", "", "", true)) // skip wait + + t.Run("wait for t1 running", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + t.Run("check postpone_completion", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + postponeCompletion := row.AsInt64("postpone_completion", 0) + assert.Equal(t, int64(1), postponeCompletion) + } + }) + t.Run("complete", func(t *testing.T) { + onlineddl.CheckCompleteMigration(t, &vtParams, shards, t1uuid, true) + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) + }) + t.Run("check no postpone_completion", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + postponeCompletion := row.AsInt64("postpone_completion", 0) + assert.Equal(t, int64(0), postponeCompletion) + } + }) + }) + + forceCutoverCapable, err := capableOf(mysql.PerformanceSchemaDataLocksTableCapability) // 8.0 + require.NoError(t, err) + if forceCutoverCapable { + t.Run("force_cutover", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), extendedWaitTime*2) + defer cancel() + + t.Run("populate t1_test", func(t *testing.T) { + onlineddl.VtgateExecQuery(t, &vtParams, populateT1Statement, "") + }) + t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy+" --postpone-completion", "vtgate", "", "", true)) // skip wait + + t.Run("wait for t1 running", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + commitTransactionChan := make(chan any) + transactionErrorChan := make(chan error) + t.Run("locking table rows", func(t *testing.T) { + go runInTransaction(t, ctx, shards[0].Vttablets[0], "select * from t1_test for update", commitTransactionChan, transactionErrorChan) + }) + t.Run("check no force_cutover", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + forceCutOver := row.AsInt64("force_cutover", 0) + assert.Equal(t, int64(0), forceCutOver) // disabled + } + }) + t.Run("attempt to complete", func(t *testing.T) { + onlineddl.CheckCompleteMigration(t, &vtParams, shards, t1uuid, true) + }) + t.Run("cut-over fail due to timeout", func(t *testing.T) { + waitForMessage(t, t1uuid, "due to context deadline exceeded") + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusRunning) + }) + t.Run("force_cutover", func(t *testing.T) { + onlineddl.CheckForceMigrationCutOver(t, &vtParams, shards, t1uuid, true) + }) + t.Run("check force_cutover", func(t *testing.T) { + rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + forceCutOver := row.AsInt64("force_cutover", 0) + assert.Equal(t, int64(1), forceCutOver) // enabled + } + }) + t.Run("expect completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) + }) + t.Run("expect transaction failure", func(t *testing.T) { + select { + case commitTransactionChan <- true: //good + case <-ctx.Done(): + assert.Fail(t, ctx.Err().Error()) + } + // Transaction will now attempt to commit. But we expect our "force_cutover" to have terminated + // the transaction's connection. + select { + case err := <-transactionErrorChan: + assert.ErrorContains(t, err, "broken pipe") + case <-ctx.Done(): + assert.Fail(t, ctx.Err().Error()) + } + }) + }) + } t.Run("ALTER both tables non-concurrent", func(t *testing.T) { t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy, "vtgate", "", "", true)) // skip wait t2uuid = testOnlineDDLStatement(t, createParams(trivialAlterT2Statement, ddlStrategy, "vtgate", "", "", true)) // skip wait @@ -2400,3 +2529,31 @@ func getCreateTableStatement(t *testing.T, tablet *cluster.Vttablet, tableName s statement = queryResult.Rows[0][1].ToString() return statement } + +func runInTransaction(t *testing.T, ctx context.Context, tablet *cluster.Vttablet, query string, commitTransactionChan chan any, transactionErrorChan chan error) error { + conn, err := tablet.VttabletProcess.TabletConn(keyspaceName, true) + require.NoError(t, err) + defer conn.Close() + + _, err = conn.ExecuteFetch("begin", 0, false) + require.NoError(t, err) + + _, err = conn.ExecuteFetch(query, 10000, false) + require.NoError(t, err) + + if commitTransactionChan != nil { + // Wait for instruction to commit + select { + case <-commitTransactionChan: + // good + case <-ctx.Done(): + assert.Fail(t, ctx.Err().Error()) + } + } + + _, err = conn.ExecuteFetch("commit", 0, false) + if transactionErrorChan != nil { + transactionErrorChan <- err + } + return err +} diff --git a/go/test/endtoend/onlineddl/vtgate_util.go b/go/test/endtoend/onlineddl/vtgate_util.go index 693523cec48..7d51f3365ba 100644 --- a/go/test/endtoend/onlineddl/vtgate_util.go +++ b/go/test/endtoend/onlineddl/vtgate_util.go @@ -206,6 +206,21 @@ func CheckLaunchAllMigrations(t *testing.T, vtParams *mysql.ConnParams, expectCo } } +// CheckForceMigrationCutOver marks a migration for forced cut-over, and expects success by counting affected rows. +func CheckForceMigrationCutOver(t *testing.T, vtParams *mysql.ConnParams, shards []cluster.Shard, uuid string, expectPossible bool) { + query, err := sqlparser.ParseAndBind("alter vitess_migration %a force_cutover", + sqltypes.StringBindVariable(uuid), + ) + require.NoError(t, err) + r := VtgateExecQuery(t, vtParams, query, "") + + if expectPossible { + assert.Equal(t, len(shards), int(r.RowsAffected)) + } else { + assert.Equal(t, int(0), int(r.RowsAffected)) + } +} + // CheckMigrationStatus verifies that the migration indicated by given UUID has the given expected status func CheckMigrationStatus(t *testing.T, vtParams *mysql.ConnParams, shards []cluster.Shard, uuid string, expectStatuses ...schema.OnlineDDLStatus) bool { query, err := sqlparser.ParseAndBind("show vitess_migrations like %a", diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 6e17040a13b..a74376b5313 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -4266,6 +4266,108 @@ func (x *FindAllShardsInKeyspaceResponse) GetShards() map[string]*Shard { return nil } +type ForceCutOverSchemaMigrationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3" json:"uuid,omitempty"` +} + +func (x *ForceCutOverSchemaMigrationRequest) Reset() { + *x = ForceCutOverSchemaMigrationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ForceCutOverSchemaMigrationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ForceCutOverSchemaMigrationRequest) ProtoMessage() {} + +func (x *ForceCutOverSchemaMigrationRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[57] + 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 ForceCutOverSchemaMigrationRequest.ProtoReflect.Descriptor instead. +func (*ForceCutOverSchemaMigrationRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{57} +} + +func (x *ForceCutOverSchemaMigrationRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *ForceCutOverSchemaMigrationRequest) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +type ForceCutOverSchemaMigrationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RowsAffectedByShard map[string]uint64 `protobuf:"bytes,1,rep,name=rows_affected_by_shard,json=rowsAffectedByShard,proto3" json:"rows_affected_by_shard,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *ForceCutOverSchemaMigrationResponse) Reset() { + *x = ForceCutOverSchemaMigrationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ForceCutOverSchemaMigrationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ForceCutOverSchemaMigrationResponse) ProtoMessage() {} + +func (x *ForceCutOverSchemaMigrationResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[58] + 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 ForceCutOverSchemaMigrationResponse.ProtoReflect.Descriptor instead. +func (*ForceCutOverSchemaMigrationResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{58} +} + +func (x *ForceCutOverSchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { + if x != nil { + return x.RowsAffectedByShard + } + return nil +} + type GetBackupsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4292,7 +4394,7 @@ type GetBackupsRequest struct { func (x *GetBackupsRequest) Reset() { *x = GetBackupsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[57] + mi := &file_vtctldata_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4305,7 +4407,7 @@ func (x *GetBackupsRequest) String() string { func (*GetBackupsRequest) ProtoMessage() {} func (x *GetBackupsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[57] + mi := &file_vtctldata_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4318,7 +4420,7 @@ func (x *GetBackupsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBackupsRequest.ProtoReflect.Descriptor instead. func (*GetBackupsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{57} + return file_vtctldata_proto_rawDescGZIP(), []int{59} } func (x *GetBackupsRequest) GetKeyspace() string { @@ -4367,7 +4469,7 @@ type GetBackupsResponse struct { func (x *GetBackupsResponse) Reset() { *x = GetBackupsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[58] + mi := &file_vtctldata_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4380,7 +4482,7 @@ func (x *GetBackupsResponse) String() string { func (*GetBackupsResponse) ProtoMessage() {} func (x *GetBackupsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[58] + mi := &file_vtctldata_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4393,7 +4495,7 @@ func (x *GetBackupsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBackupsResponse.ProtoReflect.Descriptor instead. func (*GetBackupsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{58} + return file_vtctldata_proto_rawDescGZIP(), []int{60} } func (x *GetBackupsResponse) GetBackups() []*mysqlctl.BackupInfo { @@ -4414,7 +4516,7 @@ type GetCellInfoRequest struct { func (x *GetCellInfoRequest) Reset() { *x = GetCellInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[59] + mi := &file_vtctldata_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4427,7 +4529,7 @@ func (x *GetCellInfoRequest) String() string { func (*GetCellInfoRequest) ProtoMessage() {} func (x *GetCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[59] + mi := &file_vtctldata_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4440,7 +4542,7 @@ func (x *GetCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoRequest.ProtoReflect.Descriptor instead. func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{59} + return file_vtctldata_proto_rawDescGZIP(), []int{61} } func (x *GetCellInfoRequest) GetCell() string { @@ -4461,7 +4563,7 @@ type GetCellInfoResponse struct { func (x *GetCellInfoResponse) Reset() { *x = GetCellInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[60] + mi := &file_vtctldata_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4474,7 +4576,7 @@ func (x *GetCellInfoResponse) String() string { func (*GetCellInfoResponse) ProtoMessage() {} func (x *GetCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[60] + mi := &file_vtctldata_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4487,7 +4589,7 @@ func (x *GetCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoResponse.ProtoReflect.Descriptor instead. func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{60} + return file_vtctldata_proto_rawDescGZIP(), []int{62} } func (x *GetCellInfoResponse) GetCellInfo() *topodata.CellInfo { @@ -4506,7 +4608,7 @@ type GetCellInfoNamesRequest struct { func (x *GetCellInfoNamesRequest) Reset() { *x = GetCellInfoNamesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[61] + mi := &file_vtctldata_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4519,7 +4621,7 @@ func (x *GetCellInfoNamesRequest) String() string { func (*GetCellInfoNamesRequest) ProtoMessage() {} func (x *GetCellInfoNamesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[61] + mi := &file_vtctldata_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4532,7 +4634,7 @@ func (x *GetCellInfoNamesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoNamesRequest.ProtoReflect.Descriptor instead. func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{61} + return file_vtctldata_proto_rawDescGZIP(), []int{63} } type GetCellInfoNamesResponse struct { @@ -4546,7 +4648,7 @@ type GetCellInfoNamesResponse struct { func (x *GetCellInfoNamesResponse) Reset() { *x = GetCellInfoNamesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[62] + mi := &file_vtctldata_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4559,7 +4661,7 @@ func (x *GetCellInfoNamesResponse) String() string { func (*GetCellInfoNamesResponse) ProtoMessage() {} func (x *GetCellInfoNamesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[62] + mi := &file_vtctldata_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4572,7 +4674,7 @@ func (x *GetCellInfoNamesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellInfoNamesResponse.ProtoReflect.Descriptor instead. func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{62} + return file_vtctldata_proto_rawDescGZIP(), []int{64} } func (x *GetCellInfoNamesResponse) GetNames() []string { @@ -4591,7 +4693,7 @@ type GetCellsAliasesRequest struct { func (x *GetCellsAliasesRequest) Reset() { *x = GetCellsAliasesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[63] + mi := &file_vtctldata_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4604,7 +4706,7 @@ func (x *GetCellsAliasesRequest) String() string { func (*GetCellsAliasesRequest) ProtoMessage() {} func (x *GetCellsAliasesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[63] + mi := &file_vtctldata_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4617,7 +4719,7 @@ func (x *GetCellsAliasesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellsAliasesRequest.ProtoReflect.Descriptor instead. func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{63} + return file_vtctldata_proto_rawDescGZIP(), []int{65} } type GetCellsAliasesResponse struct { @@ -4631,7 +4733,7 @@ type GetCellsAliasesResponse struct { func (x *GetCellsAliasesResponse) Reset() { *x = GetCellsAliasesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[64] + mi := &file_vtctldata_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4644,7 +4746,7 @@ func (x *GetCellsAliasesResponse) String() string { func (*GetCellsAliasesResponse) ProtoMessage() {} func (x *GetCellsAliasesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[64] + mi := &file_vtctldata_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4657,7 +4759,7 @@ func (x *GetCellsAliasesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCellsAliasesResponse.ProtoReflect.Descriptor instead. func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{64} + return file_vtctldata_proto_rawDescGZIP(), []int{66} } func (x *GetCellsAliasesResponse) GetAliases() map[string]*topodata.CellsAlias { @@ -4678,7 +4780,7 @@ type GetFullStatusRequest struct { func (x *GetFullStatusRequest) Reset() { *x = GetFullStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[65] + mi := &file_vtctldata_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4691,7 +4793,7 @@ func (x *GetFullStatusRequest) String() string { func (*GetFullStatusRequest) ProtoMessage() {} func (x *GetFullStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[65] + mi := &file_vtctldata_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4704,7 +4806,7 @@ func (x *GetFullStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFullStatusRequest.ProtoReflect.Descriptor instead. func (*GetFullStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{65} + return file_vtctldata_proto_rawDescGZIP(), []int{67} } func (x *GetFullStatusRequest) GetTabletAlias() *topodata.TabletAlias { @@ -4725,7 +4827,7 @@ type GetFullStatusResponse struct { func (x *GetFullStatusResponse) Reset() { *x = GetFullStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[66] + mi := &file_vtctldata_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4738,7 +4840,7 @@ func (x *GetFullStatusResponse) String() string { func (*GetFullStatusResponse) ProtoMessage() {} func (x *GetFullStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[66] + mi := &file_vtctldata_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4751,7 +4853,7 @@ func (x *GetFullStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFullStatusResponse.ProtoReflect.Descriptor instead. func (*GetFullStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{66} + return file_vtctldata_proto_rawDescGZIP(), []int{68} } func (x *GetFullStatusResponse) GetStatus() *replicationdata.FullStatus { @@ -4770,7 +4872,7 @@ type GetKeyspacesRequest struct { func (x *GetKeyspacesRequest) Reset() { *x = GetKeyspacesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[67] + mi := &file_vtctldata_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4783,7 +4885,7 @@ func (x *GetKeyspacesRequest) String() string { func (*GetKeyspacesRequest) ProtoMessage() {} func (x *GetKeyspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[67] + mi := &file_vtctldata_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4796,7 +4898,7 @@ func (x *GetKeyspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspacesRequest.ProtoReflect.Descriptor instead. func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{67} + return file_vtctldata_proto_rawDescGZIP(), []int{69} } type GetKeyspacesResponse struct { @@ -4810,7 +4912,7 @@ type GetKeyspacesResponse struct { func (x *GetKeyspacesResponse) Reset() { *x = GetKeyspacesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[68] + mi := &file_vtctldata_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4823,7 +4925,7 @@ func (x *GetKeyspacesResponse) String() string { func (*GetKeyspacesResponse) ProtoMessage() {} func (x *GetKeyspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[68] + mi := &file_vtctldata_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4836,7 +4938,7 @@ func (x *GetKeyspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspacesResponse.ProtoReflect.Descriptor instead. func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{68} + return file_vtctldata_proto_rawDescGZIP(), []int{70} } func (x *GetKeyspacesResponse) GetKeyspaces() []*Keyspace { @@ -4857,7 +4959,7 @@ type GetKeyspaceRequest struct { func (x *GetKeyspaceRequest) Reset() { *x = GetKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[69] + mi := &file_vtctldata_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4870,7 +4972,7 @@ func (x *GetKeyspaceRequest) String() string { func (*GetKeyspaceRequest) ProtoMessage() {} func (x *GetKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[69] + mi := &file_vtctldata_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4883,7 +4985,7 @@ func (x *GetKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceRequest.ProtoReflect.Descriptor instead. func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{69} + return file_vtctldata_proto_rawDescGZIP(), []int{71} } func (x *GetKeyspaceRequest) GetKeyspace() string { @@ -4904,7 +5006,7 @@ type GetKeyspaceResponse struct { func (x *GetKeyspaceResponse) Reset() { *x = GetKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[70] + mi := &file_vtctldata_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4917,7 +5019,7 @@ func (x *GetKeyspaceResponse) String() string { func (*GetKeyspaceResponse) ProtoMessage() {} func (x *GetKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[70] + mi := &file_vtctldata_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4930,7 +5032,7 @@ func (x *GetKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetKeyspaceResponse.ProtoReflect.Descriptor instead. func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{70} + return file_vtctldata_proto_rawDescGZIP(), []int{72} } func (x *GetKeyspaceResponse) GetKeyspace() *Keyspace { @@ -4951,7 +5053,7 @@ type GetPermissionsRequest struct { func (x *GetPermissionsRequest) Reset() { *x = GetPermissionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[71] + mi := &file_vtctldata_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4964,7 +5066,7 @@ func (x *GetPermissionsRequest) String() string { func (*GetPermissionsRequest) ProtoMessage() {} func (x *GetPermissionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[71] + mi := &file_vtctldata_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4977,7 +5079,7 @@ func (x *GetPermissionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPermissionsRequest.ProtoReflect.Descriptor instead. func (*GetPermissionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{71} + return file_vtctldata_proto_rawDescGZIP(), []int{73} } func (x *GetPermissionsRequest) GetTabletAlias() *topodata.TabletAlias { @@ -4998,7 +5100,7 @@ type GetPermissionsResponse struct { func (x *GetPermissionsResponse) Reset() { *x = GetPermissionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[72] + mi := &file_vtctldata_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5011,7 +5113,7 @@ func (x *GetPermissionsResponse) String() string { func (*GetPermissionsResponse) ProtoMessage() {} func (x *GetPermissionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[72] + mi := &file_vtctldata_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5024,7 +5126,7 @@ func (x *GetPermissionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPermissionsResponse.ProtoReflect.Descriptor instead. func (*GetPermissionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{72} + return file_vtctldata_proto_rawDescGZIP(), []int{74} } func (x *GetPermissionsResponse) GetPermissions() *tabletmanagerdata.Permissions { @@ -5043,7 +5145,7 @@ type GetRoutingRulesRequest struct { func (x *GetRoutingRulesRequest) Reset() { *x = GetRoutingRulesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5056,7 +5158,7 @@ func (x *GetRoutingRulesRequest) String() string { func (*GetRoutingRulesRequest) ProtoMessage() {} func (x *GetRoutingRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5069,7 +5171,7 @@ func (x *GetRoutingRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoutingRulesRequest.ProtoReflect.Descriptor instead. func (*GetRoutingRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{73} + return file_vtctldata_proto_rawDescGZIP(), []int{75} } type GetRoutingRulesResponse struct { @@ -5083,7 +5185,7 @@ type GetRoutingRulesResponse struct { func (x *GetRoutingRulesResponse) Reset() { *x = GetRoutingRulesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5096,7 +5198,7 @@ func (x *GetRoutingRulesResponse) String() string { func (*GetRoutingRulesResponse) ProtoMessage() {} func (x *GetRoutingRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5109,7 +5211,7 @@ func (x *GetRoutingRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoutingRulesResponse.ProtoReflect.Descriptor instead. func (*GetRoutingRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{74} + return file_vtctldata_proto_rawDescGZIP(), []int{76} } func (x *GetRoutingRulesResponse) GetRoutingRules() *vschema.RoutingRules { @@ -5148,7 +5250,7 @@ type GetSchemaRequest struct { func (x *GetSchemaRequest) Reset() { *x = GetSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5161,7 +5263,7 @@ func (x *GetSchemaRequest) String() string { func (*GetSchemaRequest) ProtoMessage() {} func (x *GetSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5174,7 +5276,7 @@ func (x *GetSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaRequest.ProtoReflect.Descriptor instead. func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{75} + return file_vtctldata_proto_rawDescGZIP(), []int{77} } func (x *GetSchemaRequest) GetTabletAlias() *topodata.TabletAlias { @@ -5237,7 +5339,7 @@ type GetSchemaResponse struct { func (x *GetSchemaResponse) Reset() { *x = GetSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5250,7 +5352,7 @@ func (x *GetSchemaResponse) String() string { func (*GetSchemaResponse) ProtoMessage() {} func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5263,7 +5365,7 @@ func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaResponse.ProtoReflect.Descriptor instead. func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{76} + return file_vtctldata_proto_rawDescGZIP(), []int{78} } func (x *GetSchemaResponse) GetSchema() *tabletmanagerdata.SchemaDefinition { @@ -5309,7 +5411,7 @@ type GetSchemaMigrationsRequest struct { func (x *GetSchemaMigrationsRequest) Reset() { *x = GetSchemaMigrationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5322,7 +5424,7 @@ func (x *GetSchemaMigrationsRequest) String() string { func (*GetSchemaMigrationsRequest) ProtoMessage() {} func (x *GetSchemaMigrationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5335,7 +5437,7 @@ func (x *GetSchemaMigrationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaMigrationsRequest.ProtoReflect.Descriptor instead. func (*GetSchemaMigrationsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{77} + return file_vtctldata_proto_rawDescGZIP(), []int{79} } func (x *GetSchemaMigrationsRequest) GetKeyspace() string { @@ -5405,7 +5507,7 @@ type GetSchemaMigrationsResponse struct { func (x *GetSchemaMigrationsResponse) Reset() { *x = GetSchemaMigrationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5418,7 +5520,7 @@ func (x *GetSchemaMigrationsResponse) String() string { func (*GetSchemaMigrationsResponse) ProtoMessage() {} func (x *GetSchemaMigrationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5431,7 +5533,7 @@ func (x *GetSchemaMigrationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaMigrationsResponse.ProtoReflect.Descriptor instead. func (*GetSchemaMigrationsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{78} + return file_vtctldata_proto_rawDescGZIP(), []int{80} } func (x *GetSchemaMigrationsResponse) GetMigrations() []*SchemaMigration { @@ -5453,7 +5555,7 @@ type GetShardRequest struct { func (x *GetShardRequest) Reset() { *x = GetShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5466,7 +5568,7 @@ func (x *GetShardRequest) String() string { func (*GetShardRequest) ProtoMessage() {} func (x *GetShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5479,7 +5581,7 @@ func (x *GetShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRequest.ProtoReflect.Descriptor instead. func (*GetShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{79} + return file_vtctldata_proto_rawDescGZIP(), []int{81} } func (x *GetShardRequest) GetKeyspace() string { @@ -5507,7 +5609,7 @@ type GetShardResponse struct { func (x *GetShardResponse) Reset() { *x = GetShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5520,7 +5622,7 @@ func (x *GetShardResponse) String() string { func (*GetShardResponse) ProtoMessage() {} func (x *GetShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5533,7 +5635,7 @@ func (x *GetShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardResponse.ProtoReflect.Descriptor instead. func (*GetShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{80} + return file_vtctldata_proto_rawDescGZIP(), []int{82} } func (x *GetShardResponse) GetShard() *Shard { @@ -5552,7 +5654,7 @@ type GetShardRoutingRulesRequest struct { func (x *GetShardRoutingRulesRequest) Reset() { *x = GetShardRoutingRulesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5565,7 +5667,7 @@ func (x *GetShardRoutingRulesRequest) String() string { func (*GetShardRoutingRulesRequest) ProtoMessage() {} func (x *GetShardRoutingRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[83] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5578,7 +5680,7 @@ func (x *GetShardRoutingRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRoutingRulesRequest.ProtoReflect.Descriptor instead. func (*GetShardRoutingRulesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{81} + return file_vtctldata_proto_rawDescGZIP(), []int{83} } type GetShardRoutingRulesResponse struct { @@ -5592,7 +5694,7 @@ type GetShardRoutingRulesResponse struct { func (x *GetShardRoutingRulesResponse) Reset() { *x = GetShardRoutingRulesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5605,7 +5707,7 @@ func (x *GetShardRoutingRulesResponse) String() string { func (*GetShardRoutingRulesResponse) ProtoMessage() {} func (x *GetShardRoutingRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[84] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5618,7 +5720,7 @@ func (x *GetShardRoutingRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetShardRoutingRulesResponse.ProtoReflect.Descriptor instead. func (*GetShardRoutingRulesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{82} + return file_vtctldata_proto_rawDescGZIP(), []int{84} } func (x *GetShardRoutingRulesResponse) GetShardRoutingRules() *vschema.ShardRoutingRules { @@ -5639,7 +5741,7 @@ type GetSrvKeyspaceNamesRequest struct { func (x *GetSrvKeyspaceNamesRequest) Reset() { *x = GetSrvKeyspaceNamesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5652,7 +5754,7 @@ func (x *GetSrvKeyspaceNamesRequest) String() string { func (*GetSrvKeyspaceNamesRequest) ProtoMessage() {} func (x *GetSrvKeyspaceNamesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[85] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5665,7 +5767,7 @@ func (x *GetSrvKeyspaceNamesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspaceNamesRequest.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{83} + return file_vtctldata_proto_rawDescGZIP(), []int{85} } func (x *GetSrvKeyspaceNamesRequest) GetCells() []string { @@ -5687,7 +5789,7 @@ type GetSrvKeyspaceNamesResponse struct { func (x *GetSrvKeyspaceNamesResponse) Reset() { *x = GetSrvKeyspaceNamesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5700,7 +5802,7 @@ func (x *GetSrvKeyspaceNamesResponse) String() string { func (*GetSrvKeyspaceNamesResponse) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[86] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5713,7 +5815,7 @@ func (x *GetSrvKeyspaceNamesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspaceNamesResponse.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{84} + return file_vtctldata_proto_rawDescGZIP(), []int{86} } func (x *GetSrvKeyspaceNamesResponse) GetNames() map[string]*GetSrvKeyspaceNamesResponse_NameList { @@ -5737,7 +5839,7 @@ type GetSrvKeyspacesRequest struct { func (x *GetSrvKeyspacesRequest) Reset() { *x = GetSrvKeyspacesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5750,7 +5852,7 @@ func (x *GetSrvKeyspacesRequest) String() string { func (*GetSrvKeyspacesRequest) ProtoMessage() {} func (x *GetSrvKeyspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[87] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5763,7 +5865,7 @@ func (x *GetSrvKeyspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspacesRequest.ProtoReflect.Descriptor instead. func (*GetSrvKeyspacesRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{85} + return file_vtctldata_proto_rawDescGZIP(), []int{87} } func (x *GetSrvKeyspacesRequest) GetKeyspace() string { @@ -5792,7 +5894,7 @@ type GetSrvKeyspacesResponse struct { func (x *GetSrvKeyspacesResponse) Reset() { *x = GetSrvKeyspacesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5805,7 +5907,7 @@ func (x *GetSrvKeyspacesResponse) String() string { func (*GetSrvKeyspacesResponse) ProtoMessage() {} func (x *GetSrvKeyspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[88] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5818,7 +5920,7 @@ func (x *GetSrvKeyspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvKeyspacesResponse.ProtoReflect.Descriptor instead. func (*GetSrvKeyspacesResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{86} + return file_vtctldata_proto_rawDescGZIP(), []int{88} } func (x *GetSrvKeyspacesResponse) GetSrvKeyspaces() map[string]*topodata.SrvKeyspace { @@ -5855,7 +5957,7 @@ type UpdateThrottlerConfigRequest struct { func (x *UpdateThrottlerConfigRequest) Reset() { *x = UpdateThrottlerConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[87] + mi := &file_vtctldata_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5868,7 +5970,7 @@ func (x *UpdateThrottlerConfigRequest) String() string { func (*UpdateThrottlerConfigRequest) ProtoMessage() {} func (x *UpdateThrottlerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[87] + mi := &file_vtctldata_proto_msgTypes[89] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5881,7 +5983,7 @@ func (x *UpdateThrottlerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateThrottlerConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateThrottlerConfigRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{87} + return file_vtctldata_proto_rawDescGZIP(), []int{89} } func (x *UpdateThrottlerConfigRequest) GetKeyspace() string { @@ -5956,7 +6058,7 @@ type UpdateThrottlerConfigResponse struct { func (x *UpdateThrottlerConfigResponse) Reset() { *x = UpdateThrottlerConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5969,7 +6071,7 @@ func (x *UpdateThrottlerConfigResponse) String() string { func (*UpdateThrottlerConfigResponse) ProtoMessage() {} func (x *UpdateThrottlerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[90] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5982,7 +6084,7 @@ func (x *UpdateThrottlerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateThrottlerConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateThrottlerConfigResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{88} + return file_vtctldata_proto_rawDescGZIP(), []int{90} } type GetSrvVSchemaRequest struct { @@ -5996,7 +6098,7 @@ type GetSrvVSchemaRequest struct { func (x *GetSrvVSchemaRequest) Reset() { *x = GetSrvVSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6009,7 +6111,7 @@ func (x *GetSrvVSchemaRequest) String() string { func (*GetSrvVSchemaRequest) ProtoMessage() {} func (x *GetSrvVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[91] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6022,7 +6124,7 @@ func (x *GetSrvVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemaRequest.ProtoReflect.Descriptor instead. func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{89} + return file_vtctldata_proto_rawDescGZIP(), []int{91} } func (x *GetSrvVSchemaRequest) GetCell() string { @@ -6043,7 +6145,7 @@ type GetSrvVSchemaResponse struct { func (x *GetSrvVSchemaResponse) Reset() { *x = GetSrvVSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6056,7 +6158,7 @@ func (x *GetSrvVSchemaResponse) String() string { func (*GetSrvVSchemaResponse) ProtoMessage() {} func (x *GetSrvVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[92] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6069,7 +6171,7 @@ func (x *GetSrvVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemaResponse.ProtoReflect.Descriptor instead. func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{90} + return file_vtctldata_proto_rawDescGZIP(), []int{92} } func (x *GetSrvVSchemaResponse) GetSrvVSchema() *vschema.SrvVSchema { @@ -6090,7 +6192,7 @@ type GetSrvVSchemasRequest struct { func (x *GetSrvVSchemasRequest) Reset() { *x = GetSrvVSchemasRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6103,7 +6205,7 @@ func (x *GetSrvVSchemasRequest) String() string { func (*GetSrvVSchemasRequest) ProtoMessage() {} func (x *GetSrvVSchemasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[93] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6116,7 +6218,7 @@ func (x *GetSrvVSchemasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemasRequest.ProtoReflect.Descriptor instead. func (*GetSrvVSchemasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{91} + return file_vtctldata_proto_rawDescGZIP(), []int{93} } func (x *GetSrvVSchemasRequest) GetCells() []string { @@ -6138,7 +6240,7 @@ type GetSrvVSchemasResponse struct { func (x *GetSrvVSchemasResponse) Reset() { *x = GetSrvVSchemasResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6151,7 +6253,7 @@ func (x *GetSrvVSchemasResponse) String() string { func (*GetSrvVSchemasResponse) ProtoMessage() {} func (x *GetSrvVSchemasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[94] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6164,7 +6266,7 @@ func (x *GetSrvVSchemasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSrvVSchemasResponse.ProtoReflect.Descriptor instead. func (*GetSrvVSchemasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{92} + return file_vtctldata_proto_rawDescGZIP(), []int{94} } func (x *GetSrvVSchemasResponse) GetSrvVSchemas() map[string]*vschema.SrvVSchema { @@ -6185,7 +6287,7 @@ type GetTabletRequest struct { func (x *GetTabletRequest) Reset() { *x = GetTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[93] + mi := &file_vtctldata_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6198,7 +6300,7 @@ func (x *GetTabletRequest) String() string { func (*GetTabletRequest) ProtoMessage() {} func (x *GetTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[93] + mi := &file_vtctldata_proto_msgTypes[95] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6211,7 +6313,7 @@ func (x *GetTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletRequest.ProtoReflect.Descriptor instead. func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{93} + return file_vtctldata_proto_rawDescGZIP(), []int{95} } func (x *GetTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -6232,7 +6334,7 @@ type GetTabletResponse struct { func (x *GetTabletResponse) Reset() { *x = GetTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[94] + mi := &file_vtctldata_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6245,7 +6347,7 @@ func (x *GetTabletResponse) String() string { func (*GetTabletResponse) ProtoMessage() {} func (x *GetTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[94] + mi := &file_vtctldata_proto_msgTypes[96] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6258,7 +6360,7 @@ func (x *GetTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletResponse.ProtoReflect.Descriptor instead. func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{94} + return file_vtctldata_proto_rawDescGZIP(), []int{96} } func (x *GetTabletResponse) GetTablet() *topodata.Tablet { @@ -6300,7 +6402,7 @@ type GetTabletsRequest struct { func (x *GetTabletsRequest) Reset() { *x = GetTabletsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[95] + mi := &file_vtctldata_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6313,7 +6415,7 @@ func (x *GetTabletsRequest) String() string { func (*GetTabletsRequest) ProtoMessage() {} func (x *GetTabletsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[95] + mi := &file_vtctldata_proto_msgTypes[97] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6326,7 +6428,7 @@ func (x *GetTabletsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletsRequest.ProtoReflect.Descriptor instead. func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{95} + return file_vtctldata_proto_rawDescGZIP(), []int{97} } func (x *GetTabletsRequest) GetKeyspace() string { @@ -6382,7 +6484,7 @@ type GetTabletsResponse struct { func (x *GetTabletsResponse) Reset() { *x = GetTabletsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[96] + mi := &file_vtctldata_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6395,7 +6497,7 @@ func (x *GetTabletsResponse) String() string { func (*GetTabletsResponse) ProtoMessage() {} func (x *GetTabletsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[96] + mi := &file_vtctldata_proto_msgTypes[98] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6408,7 +6510,7 @@ func (x *GetTabletsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTabletsResponse.ProtoReflect.Descriptor instead. func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{96} + return file_vtctldata_proto_rawDescGZIP(), []int{98} } func (x *GetTabletsResponse) GetTablets() []*topodata.Tablet { @@ -6429,7 +6531,7 @@ type GetTopologyPathRequest struct { func (x *GetTopologyPathRequest) Reset() { *x = GetTopologyPathRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[97] + mi := &file_vtctldata_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6442,7 +6544,7 @@ func (x *GetTopologyPathRequest) String() string { func (*GetTopologyPathRequest) ProtoMessage() {} func (x *GetTopologyPathRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[97] + mi := &file_vtctldata_proto_msgTypes[99] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6455,7 +6557,7 @@ func (x *GetTopologyPathRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTopologyPathRequest.ProtoReflect.Descriptor instead. func (*GetTopologyPathRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{97} + return file_vtctldata_proto_rawDescGZIP(), []int{99} } func (x *GetTopologyPathRequest) GetPath() string { @@ -6476,7 +6578,7 @@ type GetTopologyPathResponse struct { func (x *GetTopologyPathResponse) Reset() { *x = GetTopologyPathResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[98] + mi := &file_vtctldata_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6489,7 +6591,7 @@ func (x *GetTopologyPathResponse) String() string { func (*GetTopologyPathResponse) ProtoMessage() {} func (x *GetTopologyPathResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[98] + mi := &file_vtctldata_proto_msgTypes[100] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6502,7 +6604,7 @@ func (x *GetTopologyPathResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTopologyPathResponse.ProtoReflect.Descriptor instead. func (*GetTopologyPathResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{98} + return file_vtctldata_proto_rawDescGZIP(), []int{100} } func (x *GetTopologyPathResponse) GetCell() *TopologyCell { @@ -6528,7 +6630,7 @@ type TopologyCell struct { func (x *TopologyCell) Reset() { *x = TopologyCell{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[99] + mi := &file_vtctldata_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6541,7 +6643,7 @@ func (x *TopologyCell) String() string { func (*TopologyCell) ProtoMessage() {} func (x *TopologyCell) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[99] + mi := &file_vtctldata_proto_msgTypes[101] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6554,7 +6656,7 @@ func (x *TopologyCell) ProtoReflect() protoreflect.Message { // Deprecated: Use TopologyCell.ProtoReflect.Descriptor instead. func (*TopologyCell) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{99} + return file_vtctldata_proto_rawDescGZIP(), []int{101} } func (x *TopologyCell) GetName() string { @@ -6596,7 +6698,7 @@ type GetVSchemaRequest struct { func (x *GetVSchemaRequest) Reset() { *x = GetVSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[100] + mi := &file_vtctldata_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6609,7 +6711,7 @@ func (x *GetVSchemaRequest) String() string { func (*GetVSchemaRequest) ProtoMessage() {} func (x *GetVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[100] + mi := &file_vtctldata_proto_msgTypes[102] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6622,7 +6724,7 @@ func (x *GetVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVSchemaRequest.ProtoReflect.Descriptor instead. func (*GetVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{100} + return file_vtctldata_proto_rawDescGZIP(), []int{102} } func (x *GetVSchemaRequest) GetKeyspace() string { @@ -6643,7 +6745,7 @@ type GetVersionRequest struct { func (x *GetVersionRequest) Reset() { *x = GetVersionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[101] + mi := &file_vtctldata_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6656,7 +6758,7 @@ func (x *GetVersionRequest) String() string { func (*GetVersionRequest) ProtoMessage() {} func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[101] + mi := &file_vtctldata_proto_msgTypes[103] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6669,7 +6771,7 @@ func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. func (*GetVersionRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{101} + return file_vtctldata_proto_rawDescGZIP(), []int{103} } func (x *GetVersionRequest) GetTabletAlias() *topodata.TabletAlias { @@ -6690,7 +6792,7 @@ type GetVersionResponse struct { func (x *GetVersionResponse) Reset() { *x = GetVersionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[102] + mi := &file_vtctldata_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6703,7 +6805,7 @@ func (x *GetVersionResponse) String() string { func (*GetVersionResponse) ProtoMessage() {} func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[102] + mi := &file_vtctldata_proto_msgTypes[104] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6716,7 +6818,7 @@ func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. func (*GetVersionResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{102} + return file_vtctldata_proto_rawDescGZIP(), []int{104} } func (x *GetVersionResponse) GetVersion() string { @@ -6737,7 +6839,7 @@ type GetVSchemaResponse struct { func (x *GetVSchemaResponse) Reset() { *x = GetVSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[103] + mi := &file_vtctldata_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6750,7 +6852,7 @@ func (x *GetVSchemaResponse) String() string { func (*GetVSchemaResponse) ProtoMessage() {} func (x *GetVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[103] + mi := &file_vtctldata_proto_msgTypes[105] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6763,7 +6865,7 @@ func (x *GetVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVSchemaResponse.ProtoReflect.Descriptor instead. func (*GetVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{103} + return file_vtctldata_proto_rawDescGZIP(), []int{105} } func (x *GetVSchemaResponse) GetVSchema() *vschema.Keyspace { @@ -6789,7 +6891,7 @@ type GetWorkflowsRequest struct { func (x *GetWorkflowsRequest) Reset() { *x = GetWorkflowsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[104] + mi := &file_vtctldata_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6802,7 +6904,7 @@ func (x *GetWorkflowsRequest) String() string { func (*GetWorkflowsRequest) ProtoMessage() {} func (x *GetWorkflowsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[104] + mi := &file_vtctldata_proto_msgTypes[106] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6815,7 +6917,7 @@ func (x *GetWorkflowsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkflowsRequest.ProtoReflect.Descriptor instead. func (*GetWorkflowsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{104} + return file_vtctldata_proto_rawDescGZIP(), []int{106} } func (x *GetWorkflowsRequest) GetKeyspace() string { @@ -6864,7 +6966,7 @@ type GetWorkflowsResponse struct { func (x *GetWorkflowsResponse) Reset() { *x = GetWorkflowsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[105] + mi := &file_vtctldata_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6877,7 +6979,7 @@ func (x *GetWorkflowsResponse) String() string { func (*GetWorkflowsResponse) ProtoMessage() {} func (x *GetWorkflowsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[105] + mi := &file_vtctldata_proto_msgTypes[107] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6890,7 +6992,7 @@ func (x *GetWorkflowsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkflowsResponse.ProtoReflect.Descriptor instead. func (*GetWorkflowsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{105} + return file_vtctldata_proto_rawDescGZIP(), []int{107} } func (x *GetWorkflowsResponse) GetWorkflows() []*Workflow { @@ -6915,7 +7017,7 @@ type InitShardPrimaryRequest struct { func (x *InitShardPrimaryRequest) Reset() { *x = InitShardPrimaryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[106] + mi := &file_vtctldata_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6928,7 +7030,7 @@ func (x *InitShardPrimaryRequest) String() string { func (*InitShardPrimaryRequest) ProtoMessage() {} func (x *InitShardPrimaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[106] + mi := &file_vtctldata_proto_msgTypes[108] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6941,7 +7043,7 @@ func (x *InitShardPrimaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InitShardPrimaryRequest.ProtoReflect.Descriptor instead. func (*InitShardPrimaryRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{106} + return file_vtctldata_proto_rawDescGZIP(), []int{108} } func (x *InitShardPrimaryRequest) GetKeyspace() string { @@ -6990,7 +7092,7 @@ type InitShardPrimaryResponse struct { func (x *InitShardPrimaryResponse) Reset() { *x = InitShardPrimaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[107] + mi := &file_vtctldata_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7003,7 +7105,7 @@ func (x *InitShardPrimaryResponse) String() string { func (*InitShardPrimaryResponse) ProtoMessage() {} func (x *InitShardPrimaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[107] + mi := &file_vtctldata_proto_msgTypes[109] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7016,7 +7118,7 @@ func (x *InitShardPrimaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InitShardPrimaryResponse.ProtoReflect.Descriptor instead. func (*InitShardPrimaryResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{107} + return file_vtctldata_proto_rawDescGZIP(), []int{109} } func (x *InitShardPrimaryResponse) GetEvents() []*logutil.Event { @@ -7038,7 +7140,7 @@ type LaunchSchemaMigrationRequest struct { func (x *LaunchSchemaMigrationRequest) Reset() { *x = LaunchSchemaMigrationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[108] + mi := &file_vtctldata_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7051,7 +7153,7 @@ func (x *LaunchSchemaMigrationRequest) String() string { func (*LaunchSchemaMigrationRequest) ProtoMessage() {} func (x *LaunchSchemaMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[108] + mi := &file_vtctldata_proto_msgTypes[110] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7064,7 +7166,7 @@ func (x *LaunchSchemaMigrationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LaunchSchemaMigrationRequest.ProtoReflect.Descriptor instead. func (*LaunchSchemaMigrationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{108} + return file_vtctldata_proto_rawDescGZIP(), []int{110} } func (x *LaunchSchemaMigrationRequest) GetKeyspace() string { @@ -7092,7 +7194,7 @@ type LaunchSchemaMigrationResponse struct { func (x *LaunchSchemaMigrationResponse) Reset() { *x = LaunchSchemaMigrationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[109] + mi := &file_vtctldata_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7105,7 +7207,7 @@ func (x *LaunchSchemaMigrationResponse) String() string { func (*LaunchSchemaMigrationResponse) ProtoMessage() {} func (x *LaunchSchemaMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[109] + mi := &file_vtctldata_proto_msgTypes[111] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7118,7 +7220,7 @@ func (x *LaunchSchemaMigrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LaunchSchemaMigrationResponse.ProtoReflect.Descriptor instead. func (*LaunchSchemaMigrationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{109} + return file_vtctldata_proto_rawDescGZIP(), []int{111} } func (x *LaunchSchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { @@ -7145,7 +7247,7 @@ type LookupVindexCreateRequest struct { func (x *LookupVindexCreateRequest) Reset() { *x = LookupVindexCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[110] + mi := &file_vtctldata_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7158,7 +7260,7 @@ func (x *LookupVindexCreateRequest) String() string { func (*LookupVindexCreateRequest) ProtoMessage() {} func (x *LookupVindexCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[110] + mi := &file_vtctldata_proto_msgTypes[112] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7171,7 +7273,7 @@ func (x *LookupVindexCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexCreateRequest.ProtoReflect.Descriptor instead. func (*LookupVindexCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{110} + return file_vtctldata_proto_rawDescGZIP(), []int{112} } func (x *LookupVindexCreateRequest) GetKeyspace() string { @@ -7232,7 +7334,7 @@ type LookupVindexCreateResponse struct { func (x *LookupVindexCreateResponse) Reset() { *x = LookupVindexCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[111] + mi := &file_vtctldata_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7245,7 +7347,7 @@ func (x *LookupVindexCreateResponse) String() string { func (*LookupVindexCreateResponse) ProtoMessage() {} func (x *LookupVindexCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[111] + mi := &file_vtctldata_proto_msgTypes[113] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7258,7 +7360,7 @@ func (x *LookupVindexCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexCreateResponse.ProtoReflect.Descriptor instead. func (*LookupVindexCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{111} + return file_vtctldata_proto_rawDescGZIP(), []int{113} } type LookupVindexExternalizeRequest struct { @@ -7277,7 +7379,7 @@ type LookupVindexExternalizeRequest struct { func (x *LookupVindexExternalizeRequest) Reset() { *x = LookupVindexExternalizeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[112] + mi := &file_vtctldata_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7290,7 +7392,7 @@ func (x *LookupVindexExternalizeRequest) String() string { func (*LookupVindexExternalizeRequest) ProtoMessage() {} func (x *LookupVindexExternalizeRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[112] + mi := &file_vtctldata_proto_msgTypes[114] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7303,7 +7405,7 @@ func (x *LookupVindexExternalizeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexExternalizeRequest.ProtoReflect.Descriptor instead. func (*LookupVindexExternalizeRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{112} + return file_vtctldata_proto_rawDescGZIP(), []int{114} } func (x *LookupVindexExternalizeRequest) GetKeyspace() string { @@ -7339,7 +7441,7 @@ type LookupVindexExternalizeResponse struct { func (x *LookupVindexExternalizeResponse) Reset() { *x = LookupVindexExternalizeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[113] + mi := &file_vtctldata_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7352,7 +7454,7 @@ func (x *LookupVindexExternalizeResponse) String() string { func (*LookupVindexExternalizeResponse) ProtoMessage() {} func (x *LookupVindexExternalizeResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[113] + mi := &file_vtctldata_proto_msgTypes[115] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7365,7 +7467,7 @@ func (x *LookupVindexExternalizeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupVindexExternalizeResponse.ProtoReflect.Descriptor instead. func (*LookupVindexExternalizeResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{113} + return file_vtctldata_proto_rawDescGZIP(), []int{115} } func (x *LookupVindexExternalizeResponse) GetWorkflowDeleted() bool { @@ -7386,7 +7488,7 @@ type MaterializeCreateRequest struct { func (x *MaterializeCreateRequest) Reset() { *x = MaterializeCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[114] + mi := &file_vtctldata_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7399,7 +7501,7 @@ func (x *MaterializeCreateRequest) String() string { func (*MaterializeCreateRequest) ProtoMessage() {} func (x *MaterializeCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[114] + mi := &file_vtctldata_proto_msgTypes[116] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7412,7 +7514,7 @@ func (x *MaterializeCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MaterializeCreateRequest.ProtoReflect.Descriptor instead. func (*MaterializeCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{114} + return file_vtctldata_proto_rawDescGZIP(), []int{116} } func (x *MaterializeCreateRequest) GetSettings() *MaterializeSettings { @@ -7431,7 +7533,7 @@ type MaterializeCreateResponse struct { func (x *MaterializeCreateResponse) Reset() { *x = MaterializeCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[115] + mi := &file_vtctldata_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7444,7 +7546,7 @@ func (x *MaterializeCreateResponse) String() string { func (*MaterializeCreateResponse) ProtoMessage() {} func (x *MaterializeCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[115] + mi := &file_vtctldata_proto_msgTypes[117] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7457,7 +7559,7 @@ func (x *MaterializeCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MaterializeCreateResponse.ProtoReflect.Descriptor instead. func (*MaterializeCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{115} + return file_vtctldata_proto_rawDescGZIP(), []int{117} } type MigrateCreateRequest struct { @@ -7496,7 +7598,7 @@ type MigrateCreateRequest struct { func (x *MigrateCreateRequest) Reset() { *x = MigrateCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[116] + mi := &file_vtctldata_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7509,7 +7611,7 @@ func (x *MigrateCreateRequest) String() string { func (*MigrateCreateRequest) ProtoMessage() {} func (x *MigrateCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[116] + mi := &file_vtctldata_proto_msgTypes[118] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7522,7 +7624,7 @@ func (x *MigrateCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCreateRequest.ProtoReflect.Descriptor instead. func (*MigrateCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{116} + return file_vtctldata_proto_rawDescGZIP(), []int{118} } func (x *MigrateCreateRequest) GetWorkflow() string { @@ -7660,7 +7762,7 @@ type MigrateCompleteRequest struct { func (x *MigrateCompleteRequest) Reset() { *x = MigrateCompleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[117] + mi := &file_vtctldata_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7673,7 +7775,7 @@ func (x *MigrateCompleteRequest) String() string { func (*MigrateCompleteRequest) ProtoMessage() {} func (x *MigrateCompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[117] + mi := &file_vtctldata_proto_msgTypes[119] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7686,7 +7788,7 @@ func (x *MigrateCompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCompleteRequest.ProtoReflect.Descriptor instead. func (*MigrateCompleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{117} + return file_vtctldata_proto_rawDescGZIP(), []int{119} } func (x *MigrateCompleteRequest) GetWorkflow() string { @@ -7743,7 +7845,7 @@ type MigrateCompleteResponse struct { func (x *MigrateCompleteResponse) Reset() { *x = MigrateCompleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[118] + mi := &file_vtctldata_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7756,7 +7858,7 @@ func (x *MigrateCompleteResponse) String() string { func (*MigrateCompleteResponse) ProtoMessage() {} func (x *MigrateCompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[118] + mi := &file_vtctldata_proto_msgTypes[120] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7769,7 +7871,7 @@ func (x *MigrateCompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrateCompleteResponse.ProtoReflect.Descriptor instead. func (*MigrateCompleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{118} + return file_vtctldata_proto_rawDescGZIP(), []int{120} } func (x *MigrateCompleteResponse) GetSummary() string { @@ -7800,7 +7902,7 @@ type MountRegisterRequest struct { func (x *MountRegisterRequest) Reset() { *x = MountRegisterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[119] + mi := &file_vtctldata_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7813,7 +7915,7 @@ func (x *MountRegisterRequest) String() string { func (*MountRegisterRequest) ProtoMessage() {} func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[119] + mi := &file_vtctldata_proto_msgTypes[121] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7826,7 +7928,7 @@ func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterRequest.ProtoReflect.Descriptor instead. func (*MountRegisterRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{119} + return file_vtctldata_proto_rawDescGZIP(), []int{121} } func (x *MountRegisterRequest) GetTopoType() string { @@ -7866,7 +7968,7 @@ type MountRegisterResponse struct { func (x *MountRegisterResponse) Reset() { *x = MountRegisterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[120] + mi := &file_vtctldata_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7879,7 +7981,7 @@ func (x *MountRegisterResponse) String() string { func (*MountRegisterResponse) ProtoMessage() {} func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[120] + mi := &file_vtctldata_proto_msgTypes[122] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7892,7 +7994,7 @@ func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterResponse.ProtoReflect.Descriptor instead. func (*MountRegisterResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{120} + return file_vtctldata_proto_rawDescGZIP(), []int{122} } type MountUnregisterRequest struct { @@ -7906,7 +8008,7 @@ type MountUnregisterRequest struct { func (x *MountUnregisterRequest) Reset() { *x = MountUnregisterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[121] + mi := &file_vtctldata_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7919,7 +8021,7 @@ func (x *MountUnregisterRequest) String() string { func (*MountUnregisterRequest) ProtoMessage() {} func (x *MountUnregisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[121] + mi := &file_vtctldata_proto_msgTypes[123] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7932,7 +8034,7 @@ func (x *MountUnregisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountUnregisterRequest.ProtoReflect.Descriptor instead. func (*MountUnregisterRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{121} + return file_vtctldata_proto_rawDescGZIP(), []int{123} } func (x *MountUnregisterRequest) GetName() string { @@ -7951,7 +8053,7 @@ type MountUnregisterResponse struct { func (x *MountUnregisterResponse) Reset() { *x = MountUnregisterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[122] + mi := &file_vtctldata_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7964,7 +8066,7 @@ func (x *MountUnregisterResponse) String() string { func (*MountUnregisterResponse) ProtoMessage() {} func (x *MountUnregisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[122] + mi := &file_vtctldata_proto_msgTypes[124] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7977,7 +8079,7 @@ func (x *MountUnregisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountUnregisterResponse.ProtoReflect.Descriptor instead. func (*MountUnregisterResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{122} + return file_vtctldata_proto_rawDescGZIP(), []int{124} } type MountShowRequest struct { @@ -7991,7 +8093,7 @@ type MountShowRequest struct { func (x *MountShowRequest) Reset() { *x = MountShowRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[123] + mi := &file_vtctldata_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8004,7 +8106,7 @@ func (x *MountShowRequest) String() string { func (*MountShowRequest) ProtoMessage() {} func (x *MountShowRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[123] + mi := &file_vtctldata_proto_msgTypes[125] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8017,7 +8119,7 @@ func (x *MountShowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountShowRequest.ProtoReflect.Descriptor instead. func (*MountShowRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{123} + return file_vtctldata_proto_rawDescGZIP(), []int{125} } func (x *MountShowRequest) GetName() string { @@ -8041,7 +8143,7 @@ type MountShowResponse struct { func (x *MountShowResponse) Reset() { *x = MountShowResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[124] + mi := &file_vtctldata_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8054,7 +8156,7 @@ func (x *MountShowResponse) String() string { func (*MountShowResponse) ProtoMessage() {} func (x *MountShowResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[124] + mi := &file_vtctldata_proto_msgTypes[126] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8067,7 +8169,7 @@ func (x *MountShowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountShowResponse.ProtoReflect.Descriptor instead. func (*MountShowResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{124} + return file_vtctldata_proto_rawDescGZIP(), []int{126} } func (x *MountShowResponse) GetTopoType() string { @@ -8107,7 +8209,7 @@ type MountListRequest struct { func (x *MountListRequest) Reset() { *x = MountListRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[125] + mi := &file_vtctldata_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8120,7 +8222,7 @@ func (x *MountListRequest) String() string { func (*MountListRequest) ProtoMessage() {} func (x *MountListRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[125] + mi := &file_vtctldata_proto_msgTypes[127] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8133,7 +8235,7 @@ func (x *MountListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListRequest.ProtoReflect.Descriptor instead. func (*MountListRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{125} + return file_vtctldata_proto_rawDescGZIP(), []int{127} } type MountListResponse struct { @@ -8147,7 +8249,7 @@ type MountListResponse struct { func (x *MountListResponse) Reset() { *x = MountListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[126] + mi := &file_vtctldata_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8160,7 +8262,7 @@ func (x *MountListResponse) String() string { func (*MountListResponse) ProtoMessage() {} func (x *MountListResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[126] + mi := &file_vtctldata_proto_msgTypes[128] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8173,7 +8275,7 @@ func (x *MountListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListResponse.ProtoReflect.Descriptor instead. func (*MountListResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{126} + return file_vtctldata_proto_rawDescGZIP(), []int{128} } func (x *MountListResponse) GetNames() []string { @@ -8223,7 +8325,7 @@ type MoveTablesCreateRequest struct { func (x *MoveTablesCreateRequest) Reset() { *x = MoveTablesCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[127] + mi := &file_vtctldata_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8236,7 +8338,7 @@ func (x *MoveTablesCreateRequest) String() string { func (*MoveTablesCreateRequest) ProtoMessage() {} func (x *MoveTablesCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[127] + mi := &file_vtctldata_proto_msgTypes[129] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8249,7 +8351,7 @@ func (x *MoveTablesCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCreateRequest.ProtoReflect.Descriptor instead. func (*MoveTablesCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{127} + return file_vtctldata_proto_rawDescGZIP(), []int{129} } func (x *MoveTablesCreateRequest) GetWorkflow() string { @@ -8397,7 +8499,7 @@ type MoveTablesCreateResponse struct { func (x *MoveTablesCreateResponse) Reset() { *x = MoveTablesCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[128] + mi := &file_vtctldata_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8410,7 +8512,7 @@ func (x *MoveTablesCreateResponse) String() string { func (*MoveTablesCreateResponse) ProtoMessage() {} func (x *MoveTablesCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[128] + mi := &file_vtctldata_proto_msgTypes[130] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8423,7 +8525,7 @@ func (x *MoveTablesCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCreateResponse.ProtoReflect.Descriptor instead. func (*MoveTablesCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{128} + return file_vtctldata_proto_rawDescGZIP(), []int{130} } func (x *MoveTablesCreateResponse) GetSummary() string { @@ -8456,7 +8558,7 @@ type MoveTablesCompleteRequest struct { func (x *MoveTablesCompleteRequest) Reset() { *x = MoveTablesCompleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[129] + mi := &file_vtctldata_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8469,7 +8571,7 @@ func (x *MoveTablesCompleteRequest) String() string { func (*MoveTablesCompleteRequest) ProtoMessage() {} func (x *MoveTablesCompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[129] + mi := &file_vtctldata_proto_msgTypes[131] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8482,7 +8584,7 @@ func (x *MoveTablesCompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCompleteRequest.ProtoReflect.Descriptor instead. func (*MoveTablesCompleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{129} + return file_vtctldata_proto_rawDescGZIP(), []int{131} } func (x *MoveTablesCompleteRequest) GetWorkflow() string { @@ -8539,7 +8641,7 @@ type MoveTablesCompleteResponse struct { func (x *MoveTablesCompleteResponse) Reset() { *x = MoveTablesCompleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[130] + mi := &file_vtctldata_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8552,7 +8654,7 @@ func (x *MoveTablesCompleteResponse) String() string { func (*MoveTablesCompleteResponse) ProtoMessage() {} func (x *MoveTablesCompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[130] + mi := &file_vtctldata_proto_msgTypes[132] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8565,7 +8667,7 @@ func (x *MoveTablesCompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MoveTablesCompleteResponse.ProtoReflect.Descriptor instead. func (*MoveTablesCompleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{130} + return file_vtctldata_proto_rawDescGZIP(), []int{132} } func (x *MoveTablesCompleteResponse) GetSummary() string { @@ -8593,7 +8695,7 @@ type PingTabletRequest struct { func (x *PingTabletRequest) Reset() { *x = PingTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[131] + mi := &file_vtctldata_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8606,7 +8708,7 @@ func (x *PingTabletRequest) String() string { func (*PingTabletRequest) ProtoMessage() {} func (x *PingTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[131] + mi := &file_vtctldata_proto_msgTypes[133] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8619,7 +8721,7 @@ func (x *PingTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingTabletRequest.ProtoReflect.Descriptor instead. func (*PingTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{131} + return file_vtctldata_proto_rawDescGZIP(), []int{133} } func (x *PingTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -8638,7 +8740,7 @@ type PingTabletResponse struct { func (x *PingTabletResponse) Reset() { *x = PingTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[132] + mi := &file_vtctldata_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8651,7 +8753,7 @@ func (x *PingTabletResponse) String() string { func (*PingTabletResponse) ProtoMessage() {} func (x *PingTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[132] + mi := &file_vtctldata_proto_msgTypes[134] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8664,7 +8766,7 @@ func (x *PingTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingTabletResponse.ProtoReflect.Descriptor instead. func (*PingTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{132} + return file_vtctldata_proto_rawDescGZIP(), []int{134} } type PlannedReparentShardRequest struct { @@ -8703,7 +8805,7 @@ type PlannedReparentShardRequest struct { func (x *PlannedReparentShardRequest) Reset() { *x = PlannedReparentShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[133] + mi := &file_vtctldata_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8716,7 +8818,7 @@ func (x *PlannedReparentShardRequest) String() string { func (*PlannedReparentShardRequest) ProtoMessage() {} func (x *PlannedReparentShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[133] + mi := &file_vtctldata_proto_msgTypes[135] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8729,7 +8831,7 @@ func (x *PlannedReparentShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedReparentShardRequest.ProtoReflect.Descriptor instead. func (*PlannedReparentShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{133} + return file_vtctldata_proto_rawDescGZIP(), []int{135} } func (x *PlannedReparentShardRequest) GetKeyspace() string { @@ -8794,7 +8896,7 @@ type PlannedReparentShardResponse struct { func (x *PlannedReparentShardResponse) Reset() { *x = PlannedReparentShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[134] + mi := &file_vtctldata_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8807,7 +8909,7 @@ func (x *PlannedReparentShardResponse) String() string { func (*PlannedReparentShardResponse) ProtoMessage() {} func (x *PlannedReparentShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[134] + mi := &file_vtctldata_proto_msgTypes[136] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8820,7 +8922,7 @@ func (x *PlannedReparentShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedReparentShardResponse.ProtoReflect.Descriptor instead. func (*PlannedReparentShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{134} + return file_vtctldata_proto_rawDescGZIP(), []int{136} } func (x *PlannedReparentShardResponse) GetKeyspace() string { @@ -8866,7 +8968,7 @@ type RebuildKeyspaceGraphRequest struct { func (x *RebuildKeyspaceGraphRequest) Reset() { *x = RebuildKeyspaceGraphRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[135] + mi := &file_vtctldata_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8879,7 +8981,7 @@ func (x *RebuildKeyspaceGraphRequest) String() string { func (*RebuildKeyspaceGraphRequest) ProtoMessage() {} func (x *RebuildKeyspaceGraphRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[135] + mi := &file_vtctldata_proto_msgTypes[137] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8892,7 +8994,7 @@ func (x *RebuildKeyspaceGraphRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildKeyspaceGraphRequest.ProtoReflect.Descriptor instead. func (*RebuildKeyspaceGraphRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{135} + return file_vtctldata_proto_rawDescGZIP(), []int{137} } func (x *RebuildKeyspaceGraphRequest) GetKeyspace() string { @@ -8925,7 +9027,7 @@ type RebuildKeyspaceGraphResponse struct { func (x *RebuildKeyspaceGraphResponse) Reset() { *x = RebuildKeyspaceGraphResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[136] + mi := &file_vtctldata_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8938,7 +9040,7 @@ func (x *RebuildKeyspaceGraphResponse) String() string { func (*RebuildKeyspaceGraphResponse) ProtoMessage() {} func (x *RebuildKeyspaceGraphResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[136] + mi := &file_vtctldata_proto_msgTypes[138] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8951,7 +9053,7 @@ func (x *RebuildKeyspaceGraphResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildKeyspaceGraphResponse.ProtoReflect.Descriptor instead. func (*RebuildKeyspaceGraphResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{136} + return file_vtctldata_proto_rawDescGZIP(), []int{138} } type RebuildVSchemaGraphRequest struct { @@ -8967,7 +9069,7 @@ type RebuildVSchemaGraphRequest struct { func (x *RebuildVSchemaGraphRequest) Reset() { *x = RebuildVSchemaGraphRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[137] + mi := &file_vtctldata_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8980,7 +9082,7 @@ func (x *RebuildVSchemaGraphRequest) String() string { func (*RebuildVSchemaGraphRequest) ProtoMessage() {} func (x *RebuildVSchemaGraphRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[137] + mi := &file_vtctldata_proto_msgTypes[139] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8993,7 +9095,7 @@ func (x *RebuildVSchemaGraphRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildVSchemaGraphRequest.ProtoReflect.Descriptor instead. func (*RebuildVSchemaGraphRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{137} + return file_vtctldata_proto_rawDescGZIP(), []int{139} } func (x *RebuildVSchemaGraphRequest) GetCells() []string { @@ -9012,7 +9114,7 @@ type RebuildVSchemaGraphResponse struct { func (x *RebuildVSchemaGraphResponse) Reset() { *x = RebuildVSchemaGraphResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[138] + mi := &file_vtctldata_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9025,7 +9127,7 @@ func (x *RebuildVSchemaGraphResponse) String() string { func (*RebuildVSchemaGraphResponse) ProtoMessage() {} func (x *RebuildVSchemaGraphResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[138] + mi := &file_vtctldata_proto_msgTypes[140] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9038,7 +9140,7 @@ func (x *RebuildVSchemaGraphResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RebuildVSchemaGraphResponse.ProtoReflect.Descriptor instead. func (*RebuildVSchemaGraphResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{138} + return file_vtctldata_proto_rawDescGZIP(), []int{140} } type RefreshStateRequest struct { @@ -9052,7 +9154,7 @@ type RefreshStateRequest struct { func (x *RefreshStateRequest) Reset() { *x = RefreshStateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[139] + mi := &file_vtctldata_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9065,7 +9167,7 @@ func (x *RefreshStateRequest) String() string { func (*RefreshStateRequest) ProtoMessage() {} func (x *RefreshStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[139] + mi := &file_vtctldata_proto_msgTypes[141] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9078,7 +9180,7 @@ func (x *RefreshStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateRequest.ProtoReflect.Descriptor instead. func (*RefreshStateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{139} + return file_vtctldata_proto_rawDescGZIP(), []int{141} } func (x *RefreshStateRequest) GetTabletAlias() *topodata.TabletAlias { @@ -9097,7 +9199,7 @@ type RefreshStateResponse struct { func (x *RefreshStateResponse) Reset() { *x = RefreshStateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[140] + mi := &file_vtctldata_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9110,7 +9212,7 @@ func (x *RefreshStateResponse) String() string { func (*RefreshStateResponse) ProtoMessage() {} func (x *RefreshStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[140] + mi := &file_vtctldata_proto_msgTypes[142] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9123,7 +9225,7 @@ func (x *RefreshStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateResponse.ProtoReflect.Descriptor instead. func (*RefreshStateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{140} + return file_vtctldata_proto_rawDescGZIP(), []int{142} } type RefreshStateByShardRequest struct { @@ -9139,7 +9241,7 @@ type RefreshStateByShardRequest struct { func (x *RefreshStateByShardRequest) Reset() { *x = RefreshStateByShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[141] + mi := &file_vtctldata_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9152,7 +9254,7 @@ func (x *RefreshStateByShardRequest) String() string { func (*RefreshStateByShardRequest) ProtoMessage() {} func (x *RefreshStateByShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[141] + mi := &file_vtctldata_proto_msgTypes[143] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9165,7 +9267,7 @@ func (x *RefreshStateByShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateByShardRequest.ProtoReflect.Descriptor instead. func (*RefreshStateByShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{141} + return file_vtctldata_proto_rawDescGZIP(), []int{143} } func (x *RefreshStateByShardRequest) GetKeyspace() string { @@ -9202,7 +9304,7 @@ type RefreshStateByShardResponse struct { func (x *RefreshStateByShardResponse) Reset() { *x = RefreshStateByShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[142] + mi := &file_vtctldata_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9215,7 +9317,7 @@ func (x *RefreshStateByShardResponse) String() string { func (*RefreshStateByShardResponse) ProtoMessage() {} func (x *RefreshStateByShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[142] + mi := &file_vtctldata_proto_msgTypes[144] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9228,7 +9330,7 @@ func (x *RefreshStateByShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshStateByShardResponse.ProtoReflect.Descriptor instead. func (*RefreshStateByShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{142} + return file_vtctldata_proto_rawDescGZIP(), []int{144} } func (x *RefreshStateByShardResponse) GetIsPartialRefresh() bool { @@ -9256,7 +9358,7 @@ type ReloadSchemaRequest struct { func (x *ReloadSchemaRequest) Reset() { *x = ReloadSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[143] + mi := &file_vtctldata_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9269,7 +9371,7 @@ func (x *ReloadSchemaRequest) String() string { func (*ReloadSchemaRequest) ProtoMessage() {} func (x *ReloadSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[143] + mi := &file_vtctldata_proto_msgTypes[145] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9282,7 +9384,7 @@ func (x *ReloadSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{143} + return file_vtctldata_proto_rawDescGZIP(), []int{145} } func (x *ReloadSchemaRequest) GetTabletAlias() *topodata.TabletAlias { @@ -9301,7 +9403,7 @@ type ReloadSchemaResponse struct { func (x *ReloadSchemaResponse) Reset() { *x = ReloadSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[144] + mi := &file_vtctldata_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9314,7 +9416,7 @@ func (x *ReloadSchemaResponse) String() string { func (*ReloadSchemaResponse) ProtoMessage() {} func (x *ReloadSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[144] + mi := &file_vtctldata_proto_msgTypes[146] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9327,7 +9429,7 @@ func (x *ReloadSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{144} + return file_vtctldata_proto_rawDescGZIP(), []int{146} } type ReloadSchemaKeyspaceRequest struct { @@ -9347,7 +9449,7 @@ type ReloadSchemaKeyspaceRequest struct { func (x *ReloadSchemaKeyspaceRequest) Reset() { *x = ReloadSchemaKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[145] + mi := &file_vtctldata_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9360,7 +9462,7 @@ func (x *ReloadSchemaKeyspaceRequest) String() string { func (*ReloadSchemaKeyspaceRequest) ProtoMessage() {} func (x *ReloadSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[145] + mi := &file_vtctldata_proto_msgTypes[147] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9373,7 +9475,7 @@ func (x *ReloadSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{145} + return file_vtctldata_proto_rawDescGZIP(), []int{147} } func (x *ReloadSchemaKeyspaceRequest) GetKeyspace() string { @@ -9415,7 +9517,7 @@ type ReloadSchemaKeyspaceResponse struct { func (x *ReloadSchemaKeyspaceResponse) Reset() { *x = ReloadSchemaKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[146] + mi := &file_vtctldata_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9428,7 +9530,7 @@ func (x *ReloadSchemaKeyspaceResponse) String() string { func (*ReloadSchemaKeyspaceResponse) ProtoMessage() {} func (x *ReloadSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[146] + mi := &file_vtctldata_proto_msgTypes[148] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9441,7 +9543,7 @@ func (x *ReloadSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{146} + return file_vtctldata_proto_rawDescGZIP(), []int{148} } func (x *ReloadSchemaKeyspaceResponse) GetEvents() []*logutil.Event { @@ -9467,7 +9569,7 @@ type ReloadSchemaShardRequest struct { func (x *ReloadSchemaShardRequest) Reset() { *x = ReloadSchemaShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[147] + mi := &file_vtctldata_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9480,7 +9582,7 @@ func (x *ReloadSchemaShardRequest) String() string { func (*ReloadSchemaShardRequest) ProtoMessage() {} func (x *ReloadSchemaShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[147] + mi := &file_vtctldata_proto_msgTypes[149] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9493,7 +9595,7 @@ func (x *ReloadSchemaShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaShardRequest.ProtoReflect.Descriptor instead. func (*ReloadSchemaShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{147} + return file_vtctldata_proto_rawDescGZIP(), []int{149} } func (x *ReloadSchemaShardRequest) GetKeyspace() string { @@ -9542,7 +9644,7 @@ type ReloadSchemaShardResponse struct { func (x *ReloadSchemaShardResponse) Reset() { *x = ReloadSchemaShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[148] + mi := &file_vtctldata_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9555,7 +9657,7 @@ func (x *ReloadSchemaShardResponse) String() string { func (*ReloadSchemaShardResponse) ProtoMessage() {} func (x *ReloadSchemaShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[148] + mi := &file_vtctldata_proto_msgTypes[150] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9568,7 +9670,7 @@ func (x *ReloadSchemaShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSchemaShardResponse.ProtoReflect.Descriptor instead. func (*ReloadSchemaShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{148} + return file_vtctldata_proto_rawDescGZIP(), []int{150} } func (x *ReloadSchemaShardResponse) GetEvents() []*logutil.Event { @@ -9591,7 +9693,7 @@ type RemoveBackupRequest struct { func (x *RemoveBackupRequest) Reset() { *x = RemoveBackupRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[149] + mi := &file_vtctldata_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9604,7 +9706,7 @@ func (x *RemoveBackupRequest) String() string { func (*RemoveBackupRequest) ProtoMessage() {} func (x *RemoveBackupRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[149] + mi := &file_vtctldata_proto_msgTypes[151] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9617,7 +9719,7 @@ func (x *RemoveBackupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBackupRequest.ProtoReflect.Descriptor instead. func (*RemoveBackupRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{149} + return file_vtctldata_proto_rawDescGZIP(), []int{151} } func (x *RemoveBackupRequest) GetKeyspace() string { @@ -9650,7 +9752,7 @@ type RemoveBackupResponse struct { func (x *RemoveBackupResponse) Reset() { *x = RemoveBackupResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[150] + mi := &file_vtctldata_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9663,7 +9765,7 @@ func (x *RemoveBackupResponse) String() string { func (*RemoveBackupResponse) ProtoMessage() {} func (x *RemoveBackupResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[150] + mi := &file_vtctldata_proto_msgTypes[152] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9676,7 +9778,7 @@ func (x *RemoveBackupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBackupResponse.ProtoReflect.Descriptor instead. func (*RemoveBackupResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{150} + return file_vtctldata_proto_rawDescGZIP(), []int{152} } type RemoveKeyspaceCellRequest struct { @@ -9698,7 +9800,7 @@ type RemoveKeyspaceCellRequest struct { func (x *RemoveKeyspaceCellRequest) Reset() { *x = RemoveKeyspaceCellRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[151] + mi := &file_vtctldata_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9711,7 +9813,7 @@ func (x *RemoveKeyspaceCellRequest) String() string { func (*RemoveKeyspaceCellRequest) ProtoMessage() {} func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[151] + mi := &file_vtctldata_proto_msgTypes[153] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9724,7 +9826,7 @@ func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellRequest.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{151} + return file_vtctldata_proto_rawDescGZIP(), []int{153} } func (x *RemoveKeyspaceCellRequest) GetKeyspace() string { @@ -9764,7 +9866,7 @@ type RemoveKeyspaceCellResponse struct { func (x *RemoveKeyspaceCellResponse) Reset() { *x = RemoveKeyspaceCellResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[152] + mi := &file_vtctldata_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9777,7 +9879,7 @@ func (x *RemoveKeyspaceCellResponse) String() string { func (*RemoveKeyspaceCellResponse) ProtoMessage() {} func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[152] + mi := &file_vtctldata_proto_msgTypes[154] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9790,7 +9892,7 @@ func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellResponse.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{152} + return file_vtctldata_proto_rawDescGZIP(), []int{154} } type RemoveShardCellRequest struct { @@ -9813,7 +9915,7 @@ type RemoveShardCellRequest struct { func (x *RemoveShardCellRequest) Reset() { *x = RemoveShardCellRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[153] + mi := &file_vtctldata_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9826,7 +9928,7 @@ func (x *RemoveShardCellRequest) String() string { func (*RemoveShardCellRequest) ProtoMessage() {} func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[153] + mi := &file_vtctldata_proto_msgTypes[155] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9839,7 +9941,7 @@ func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellRequest.ProtoReflect.Descriptor instead. func (*RemoveShardCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{153} + return file_vtctldata_proto_rawDescGZIP(), []int{155} } func (x *RemoveShardCellRequest) GetKeyspace() string { @@ -9886,7 +9988,7 @@ type RemoveShardCellResponse struct { func (x *RemoveShardCellResponse) Reset() { *x = RemoveShardCellResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[154] + mi := &file_vtctldata_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9899,7 +10001,7 @@ func (x *RemoveShardCellResponse) String() string { func (*RemoveShardCellResponse) ProtoMessage() {} func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[154] + mi := &file_vtctldata_proto_msgTypes[156] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9912,7 +10014,7 @@ func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellResponse.ProtoReflect.Descriptor instead. func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{154} + return file_vtctldata_proto_rawDescGZIP(), []int{156} } type ReparentTabletRequest struct { @@ -9928,7 +10030,7 @@ type ReparentTabletRequest struct { func (x *ReparentTabletRequest) Reset() { *x = ReparentTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[155] + mi := &file_vtctldata_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9941,7 +10043,7 @@ func (x *ReparentTabletRequest) String() string { func (*ReparentTabletRequest) ProtoMessage() {} func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[155] + mi := &file_vtctldata_proto_msgTypes[157] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9954,7 +10056,7 @@ func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletRequest.ProtoReflect.Descriptor instead. func (*ReparentTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{155} + return file_vtctldata_proto_rawDescGZIP(), []int{157} } func (x *ReparentTabletRequest) GetTablet() *topodata.TabletAlias { @@ -9980,7 +10082,7 @@ type ReparentTabletResponse struct { func (x *ReparentTabletResponse) Reset() { *x = ReparentTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[156] + mi := &file_vtctldata_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9993,7 +10095,7 @@ func (x *ReparentTabletResponse) String() string { func (*ReparentTabletResponse) ProtoMessage() {} func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[156] + mi := &file_vtctldata_proto_msgTypes[158] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10006,7 +10108,7 @@ func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletResponse.ProtoReflect.Descriptor instead. func (*ReparentTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{156} + return file_vtctldata_proto_rawDescGZIP(), []int{158} } func (x *ReparentTabletResponse) GetKeyspace() string { @@ -10058,7 +10160,7 @@ type ReshardCreateRequest struct { func (x *ReshardCreateRequest) Reset() { *x = ReshardCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[157] + mi := &file_vtctldata_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10071,7 +10173,7 @@ func (x *ReshardCreateRequest) String() string { func (*ReshardCreateRequest) ProtoMessage() {} func (x *ReshardCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[157] + mi := &file_vtctldata_proto_msgTypes[159] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10084,7 +10186,7 @@ func (x *ReshardCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReshardCreateRequest.ProtoReflect.Descriptor instead. func (*ReshardCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{157} + return file_vtctldata_proto_rawDescGZIP(), []int{159} } func (x *ReshardCreateRequest) GetWorkflow() string { @@ -10194,7 +10296,7 @@ type RestoreFromBackupRequest struct { func (x *RestoreFromBackupRequest) Reset() { *x = RestoreFromBackupRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[158] + mi := &file_vtctldata_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10207,7 +10309,7 @@ func (x *RestoreFromBackupRequest) String() string { func (*RestoreFromBackupRequest) ProtoMessage() {} func (x *RestoreFromBackupRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[158] + mi := &file_vtctldata_proto_msgTypes[160] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10220,7 +10322,7 @@ func (x *RestoreFromBackupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreFromBackupRequest.ProtoReflect.Descriptor instead. func (*RestoreFromBackupRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{158} + return file_vtctldata_proto_rawDescGZIP(), []int{160} } func (x *RestoreFromBackupRequest) GetTabletAlias() *topodata.TabletAlias { @@ -10273,7 +10375,7 @@ type RestoreFromBackupResponse struct { func (x *RestoreFromBackupResponse) Reset() { *x = RestoreFromBackupResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[159] + mi := &file_vtctldata_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10286,7 +10388,7 @@ func (x *RestoreFromBackupResponse) String() string { func (*RestoreFromBackupResponse) ProtoMessage() {} func (x *RestoreFromBackupResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[159] + mi := &file_vtctldata_proto_msgTypes[161] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10299,7 +10401,7 @@ func (x *RestoreFromBackupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreFromBackupResponse.ProtoReflect.Descriptor instead. func (*RestoreFromBackupResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{159} + return file_vtctldata_proto_rawDescGZIP(), []int{161} } func (x *RestoreFromBackupResponse) GetTabletAlias() *topodata.TabletAlias { @@ -10342,7 +10444,7 @@ type RetrySchemaMigrationRequest struct { func (x *RetrySchemaMigrationRequest) Reset() { *x = RetrySchemaMigrationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[160] + mi := &file_vtctldata_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10355,7 +10457,7 @@ func (x *RetrySchemaMigrationRequest) String() string { func (*RetrySchemaMigrationRequest) ProtoMessage() {} func (x *RetrySchemaMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[160] + mi := &file_vtctldata_proto_msgTypes[162] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10368,7 +10470,7 @@ func (x *RetrySchemaMigrationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RetrySchemaMigrationRequest.ProtoReflect.Descriptor instead. func (*RetrySchemaMigrationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{160} + return file_vtctldata_proto_rawDescGZIP(), []int{162} } func (x *RetrySchemaMigrationRequest) GetKeyspace() string { @@ -10396,7 +10498,7 @@ type RetrySchemaMigrationResponse struct { func (x *RetrySchemaMigrationResponse) Reset() { *x = RetrySchemaMigrationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[161] + mi := &file_vtctldata_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10409,7 +10511,7 @@ func (x *RetrySchemaMigrationResponse) String() string { func (*RetrySchemaMigrationResponse) ProtoMessage() {} func (x *RetrySchemaMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[161] + mi := &file_vtctldata_proto_msgTypes[163] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10422,7 +10524,7 @@ func (x *RetrySchemaMigrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RetrySchemaMigrationResponse.ProtoReflect.Descriptor instead. func (*RetrySchemaMigrationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{161} + return file_vtctldata_proto_rawDescGZIP(), []int{163} } func (x *RetrySchemaMigrationResponse) GetRowsAffectedByShard() map[string]uint64 { @@ -10443,7 +10545,7 @@ type RunHealthCheckRequest struct { func (x *RunHealthCheckRequest) Reset() { *x = RunHealthCheckRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[162] + mi := &file_vtctldata_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10456,7 +10558,7 @@ func (x *RunHealthCheckRequest) String() string { func (*RunHealthCheckRequest) ProtoMessage() {} func (x *RunHealthCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[162] + mi := &file_vtctldata_proto_msgTypes[164] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10469,7 +10571,7 @@ func (x *RunHealthCheckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunHealthCheckRequest.ProtoReflect.Descriptor instead. func (*RunHealthCheckRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{162} + return file_vtctldata_proto_rawDescGZIP(), []int{164} } func (x *RunHealthCheckRequest) GetTabletAlias() *topodata.TabletAlias { @@ -10488,7 +10590,7 @@ type RunHealthCheckResponse struct { func (x *RunHealthCheckResponse) Reset() { *x = RunHealthCheckResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[163] + mi := &file_vtctldata_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10501,7 +10603,7 @@ func (x *RunHealthCheckResponse) String() string { func (*RunHealthCheckResponse) ProtoMessage() {} func (x *RunHealthCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[163] + mi := &file_vtctldata_proto_msgTypes[165] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10514,7 +10616,7 @@ func (x *RunHealthCheckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunHealthCheckResponse.ProtoReflect.Descriptor instead. func (*RunHealthCheckResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{163} + return file_vtctldata_proto_rawDescGZIP(), []int{165} } type SetKeyspaceDurabilityPolicyRequest struct { @@ -10529,7 +10631,7 @@ type SetKeyspaceDurabilityPolicyRequest struct { func (x *SetKeyspaceDurabilityPolicyRequest) Reset() { *x = SetKeyspaceDurabilityPolicyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[164] + mi := &file_vtctldata_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10542,7 +10644,7 @@ func (x *SetKeyspaceDurabilityPolicyRequest) String() string { func (*SetKeyspaceDurabilityPolicyRequest) ProtoMessage() {} func (x *SetKeyspaceDurabilityPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[164] + mi := &file_vtctldata_proto_msgTypes[166] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10555,7 +10657,7 @@ func (x *SetKeyspaceDurabilityPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use SetKeyspaceDurabilityPolicyRequest.ProtoReflect.Descriptor instead. func (*SetKeyspaceDurabilityPolicyRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{164} + return file_vtctldata_proto_rawDescGZIP(), []int{166} } func (x *SetKeyspaceDurabilityPolicyRequest) GetKeyspace() string { @@ -10584,7 +10686,7 @@ type SetKeyspaceDurabilityPolicyResponse struct { func (x *SetKeyspaceDurabilityPolicyResponse) Reset() { *x = SetKeyspaceDurabilityPolicyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[165] + mi := &file_vtctldata_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10597,7 +10699,7 @@ func (x *SetKeyspaceDurabilityPolicyResponse) String() string { func (*SetKeyspaceDurabilityPolicyResponse) ProtoMessage() {} func (x *SetKeyspaceDurabilityPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[165] + mi := &file_vtctldata_proto_msgTypes[167] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10610,7 +10712,7 @@ func (x *SetKeyspaceDurabilityPolicyResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use SetKeyspaceDurabilityPolicyResponse.ProtoReflect.Descriptor instead. func (*SetKeyspaceDurabilityPolicyResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{165} + return file_vtctldata_proto_rawDescGZIP(), []int{167} } func (x *SetKeyspaceDurabilityPolicyResponse) GetKeyspace() *topodata.Keyspace { @@ -10632,7 +10734,7 @@ type SetKeyspaceShardingInfoRequest struct { func (x *SetKeyspaceShardingInfoRequest) Reset() { *x = SetKeyspaceShardingInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[166] + mi := &file_vtctldata_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10645,7 +10747,7 @@ func (x *SetKeyspaceShardingInfoRequest) String() string { func (*SetKeyspaceShardingInfoRequest) ProtoMessage() {} func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[166] + mi := &file_vtctldata_proto_msgTypes[168] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10658,7 +10760,7 @@ func (x *SetKeyspaceShardingInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoRequest.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{166} + return file_vtctldata_proto_rawDescGZIP(), []int{168} } func (x *SetKeyspaceShardingInfoRequest) GetKeyspace() string { @@ -10687,7 +10789,7 @@ type SetKeyspaceShardingInfoResponse struct { func (x *SetKeyspaceShardingInfoResponse) Reset() { *x = SetKeyspaceShardingInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[167] + mi := &file_vtctldata_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10700,7 +10802,7 @@ func (x *SetKeyspaceShardingInfoResponse) String() string { func (*SetKeyspaceShardingInfoResponse) ProtoMessage() {} func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[167] + mi := &file_vtctldata_proto_msgTypes[169] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10713,7 +10815,7 @@ func (x *SetKeyspaceShardingInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetKeyspaceShardingInfoResponse.ProtoReflect.Descriptor instead. func (*SetKeyspaceShardingInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{167} + return file_vtctldata_proto_rawDescGZIP(), []int{169} } func (x *SetKeyspaceShardingInfoResponse) GetKeyspace() *topodata.Keyspace { @@ -10736,7 +10838,7 @@ type SetShardIsPrimaryServingRequest struct { func (x *SetShardIsPrimaryServingRequest) Reset() { *x = SetShardIsPrimaryServingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10749,7 +10851,7 @@ func (x *SetShardIsPrimaryServingRequest) String() string { func (*SetShardIsPrimaryServingRequest) ProtoMessage() {} func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[168] + mi := &file_vtctldata_proto_msgTypes[170] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10762,7 +10864,7 @@ func (x *SetShardIsPrimaryServingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingRequest.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{168} + return file_vtctldata_proto_rawDescGZIP(), []int{170} } func (x *SetShardIsPrimaryServingRequest) GetKeyspace() string { @@ -10798,7 +10900,7 @@ type SetShardIsPrimaryServingResponse struct { func (x *SetShardIsPrimaryServingResponse) Reset() { *x = SetShardIsPrimaryServingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10811,7 +10913,7 @@ func (x *SetShardIsPrimaryServingResponse) String() string { func (*SetShardIsPrimaryServingResponse) ProtoMessage() {} func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[169] + mi := &file_vtctldata_proto_msgTypes[171] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10824,7 +10926,7 @@ func (x *SetShardIsPrimaryServingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardIsPrimaryServingResponse.ProtoReflect.Descriptor instead. func (*SetShardIsPrimaryServingResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{169} + return file_vtctldata_proto_rawDescGZIP(), []int{171} } func (x *SetShardIsPrimaryServingResponse) GetShard() *topodata.Shard { @@ -10865,7 +10967,7 @@ type SetShardTabletControlRequest struct { func (x *SetShardTabletControlRequest) Reset() { *x = SetShardTabletControlRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10878,7 +10980,7 @@ func (x *SetShardTabletControlRequest) String() string { func (*SetShardTabletControlRequest) ProtoMessage() {} func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[170] + mi := &file_vtctldata_proto_msgTypes[172] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10891,7 +10993,7 @@ func (x *SetShardTabletControlRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlRequest.ProtoReflect.Descriptor instead. func (*SetShardTabletControlRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{170} + return file_vtctldata_proto_rawDescGZIP(), []int{172} } func (x *SetShardTabletControlRequest) GetKeyspace() string { @@ -10955,7 +11057,7 @@ type SetShardTabletControlResponse struct { func (x *SetShardTabletControlResponse) Reset() { *x = SetShardTabletControlResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10968,7 +11070,7 @@ func (x *SetShardTabletControlResponse) String() string { func (*SetShardTabletControlResponse) ProtoMessage() {} func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[171] + mi := &file_vtctldata_proto_msgTypes[173] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10981,7 +11083,7 @@ func (x *SetShardTabletControlResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetShardTabletControlResponse.ProtoReflect.Descriptor instead. func (*SetShardTabletControlResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{171} + return file_vtctldata_proto_rawDescGZIP(), []int{173} } func (x *SetShardTabletControlResponse) GetShard() *topodata.Shard { @@ -11003,7 +11105,7 @@ type SetWritableRequest struct { func (x *SetWritableRequest) Reset() { *x = SetWritableRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11016,7 +11118,7 @@ func (x *SetWritableRequest) String() string { func (*SetWritableRequest) ProtoMessage() {} func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[172] + mi := &file_vtctldata_proto_msgTypes[174] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11029,7 +11131,7 @@ func (x *SetWritableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableRequest.ProtoReflect.Descriptor instead. func (*SetWritableRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{172} + return file_vtctldata_proto_rawDescGZIP(), []int{174} } func (x *SetWritableRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11055,7 +11157,7 @@ type SetWritableResponse struct { func (x *SetWritableResponse) Reset() { *x = SetWritableResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11068,7 +11170,7 @@ func (x *SetWritableResponse) String() string { func (*SetWritableResponse) ProtoMessage() {} func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[173] + mi := &file_vtctldata_proto_msgTypes[175] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11081,7 +11183,7 @@ func (x *SetWritableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWritableResponse.ProtoReflect.Descriptor instead. func (*SetWritableResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{173} + return file_vtctldata_proto_rawDescGZIP(), []int{175} } type ShardReplicationAddRequest struct { @@ -11097,7 +11199,7 @@ type ShardReplicationAddRequest struct { func (x *ShardReplicationAddRequest) Reset() { *x = ShardReplicationAddRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11110,7 +11212,7 @@ func (x *ShardReplicationAddRequest) String() string { func (*ShardReplicationAddRequest) ProtoMessage() {} func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[174] + mi := &file_vtctldata_proto_msgTypes[176] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11123,7 +11225,7 @@ func (x *ShardReplicationAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{174} + return file_vtctldata_proto_rawDescGZIP(), []int{176} } func (x *ShardReplicationAddRequest) GetKeyspace() string { @@ -11156,7 +11258,7 @@ type ShardReplicationAddResponse struct { func (x *ShardReplicationAddResponse) Reset() { *x = ShardReplicationAddResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11169,7 +11271,7 @@ func (x *ShardReplicationAddResponse) String() string { func (*ShardReplicationAddResponse) ProtoMessage() {} func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[175] + mi := &file_vtctldata_proto_msgTypes[177] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11182,7 +11284,7 @@ func (x *ShardReplicationAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationAddResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{175} + return file_vtctldata_proto_rawDescGZIP(), []int{177} } type ShardReplicationFixRequest struct { @@ -11198,7 +11300,7 @@ type ShardReplicationFixRequest struct { func (x *ShardReplicationFixRequest) Reset() { *x = ShardReplicationFixRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11211,7 +11313,7 @@ func (x *ShardReplicationFixRequest) String() string { func (*ShardReplicationFixRequest) ProtoMessage() {} func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[176] + mi := &file_vtctldata_proto_msgTypes[178] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11224,7 +11326,7 @@ func (x *ShardReplicationFixRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationFixRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{176} + return file_vtctldata_proto_rawDescGZIP(), []int{178} } func (x *ShardReplicationFixRequest) GetKeyspace() string { @@ -11262,7 +11364,7 @@ type ShardReplicationFixResponse struct { func (x *ShardReplicationFixResponse) Reset() { *x = ShardReplicationFixResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11275,7 +11377,7 @@ func (x *ShardReplicationFixResponse) String() string { func (*ShardReplicationFixResponse) ProtoMessage() {} func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[177] + mi := &file_vtctldata_proto_msgTypes[179] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11288,7 +11390,7 @@ func (x *ShardReplicationFixResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationFixResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationFixResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{177} + return file_vtctldata_proto_rawDescGZIP(), []int{179} } func (x *ShardReplicationFixResponse) GetError() *topodata.ShardReplicationError { @@ -11310,7 +11412,7 @@ type ShardReplicationPositionsRequest struct { func (x *ShardReplicationPositionsRequest) Reset() { *x = ShardReplicationPositionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11323,7 +11425,7 @@ func (x *ShardReplicationPositionsRequest) String() string { func (*ShardReplicationPositionsRequest) ProtoMessage() {} func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[178] + mi := &file_vtctldata_proto_msgTypes[180] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11336,7 +11438,7 @@ func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationPositionsRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{178} + return file_vtctldata_proto_rawDescGZIP(), []int{180} } func (x *ShardReplicationPositionsRequest) GetKeyspace() string { @@ -11369,7 +11471,7 @@ type ShardReplicationPositionsResponse struct { func (x *ShardReplicationPositionsResponse) Reset() { *x = ShardReplicationPositionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11382,7 +11484,7 @@ func (x *ShardReplicationPositionsResponse) String() string { func (*ShardReplicationPositionsResponse) ProtoMessage() {} func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[179] + mi := &file_vtctldata_proto_msgTypes[181] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11395,7 +11497,7 @@ func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ShardReplicationPositionsResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{179} + return file_vtctldata_proto_rawDescGZIP(), []int{181} } func (x *ShardReplicationPositionsResponse) GetReplicationStatuses() map[string]*replicationdata.Status { @@ -11425,7 +11527,7 @@ type ShardReplicationRemoveRequest struct { func (x *ShardReplicationRemoveRequest) Reset() { *x = ShardReplicationRemoveRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11438,7 +11540,7 @@ func (x *ShardReplicationRemoveRequest) String() string { func (*ShardReplicationRemoveRequest) ProtoMessage() {} func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[180] + mi := &file_vtctldata_proto_msgTypes[182] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11451,7 +11553,7 @@ func (x *ShardReplicationRemoveRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{180} + return file_vtctldata_proto_rawDescGZIP(), []int{182} } func (x *ShardReplicationRemoveRequest) GetKeyspace() string { @@ -11484,7 +11586,7 @@ type ShardReplicationRemoveResponse struct { func (x *ShardReplicationRemoveResponse) Reset() { *x = ShardReplicationRemoveResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11497,7 +11599,7 @@ func (x *ShardReplicationRemoveResponse) String() string { func (*ShardReplicationRemoveResponse) ProtoMessage() {} func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[181] + mi := &file_vtctldata_proto_msgTypes[183] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11510,7 +11612,7 @@ func (x *ShardReplicationRemoveResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationRemoveResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationRemoveResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{181} + return file_vtctldata_proto_rawDescGZIP(), []int{183} } type SleepTabletRequest struct { @@ -11525,7 +11627,7 @@ type SleepTabletRequest struct { func (x *SleepTabletRequest) Reset() { *x = SleepTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11538,7 +11640,7 @@ func (x *SleepTabletRequest) String() string { func (*SleepTabletRequest) ProtoMessage() {} func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[182] + mi := &file_vtctldata_proto_msgTypes[184] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11551,7 +11653,7 @@ func (x *SleepTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletRequest.ProtoReflect.Descriptor instead. func (*SleepTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{182} + return file_vtctldata_proto_rawDescGZIP(), []int{184} } func (x *SleepTabletRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11577,7 +11679,7 @@ type SleepTabletResponse struct { func (x *SleepTabletResponse) Reset() { *x = SleepTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11590,7 +11692,7 @@ func (x *SleepTabletResponse) String() string { func (*SleepTabletResponse) ProtoMessage() {} func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[183] + mi := &file_vtctldata_proto_msgTypes[185] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11603,7 +11705,7 @@ func (x *SleepTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SleepTabletResponse.ProtoReflect.Descriptor instead. func (*SleepTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{183} + return file_vtctldata_proto_rawDescGZIP(), []int{185} } type SourceShardAddRequest struct { @@ -11627,7 +11729,7 @@ type SourceShardAddRequest struct { func (x *SourceShardAddRequest) Reset() { *x = SourceShardAddRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[186] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11640,7 +11742,7 @@ func (x *SourceShardAddRequest) String() string { func (*SourceShardAddRequest) ProtoMessage() {} func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[184] + mi := &file_vtctldata_proto_msgTypes[186] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11653,7 +11755,7 @@ func (x *SourceShardAddRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddRequest.ProtoReflect.Descriptor instead. func (*SourceShardAddRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{184} + return file_vtctldata_proto_rawDescGZIP(), []int{186} } func (x *SourceShardAddRequest) GetKeyspace() string { @@ -11717,7 +11819,7 @@ type SourceShardAddResponse struct { func (x *SourceShardAddResponse) Reset() { *x = SourceShardAddResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[187] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11730,7 +11832,7 @@ func (x *SourceShardAddResponse) String() string { func (*SourceShardAddResponse) ProtoMessage() {} func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[185] + mi := &file_vtctldata_proto_msgTypes[187] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11743,7 +11845,7 @@ func (x *SourceShardAddResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardAddResponse.ProtoReflect.Descriptor instead. func (*SourceShardAddResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{185} + return file_vtctldata_proto_rawDescGZIP(), []int{187} } func (x *SourceShardAddResponse) GetShard() *topodata.Shard { @@ -11766,7 +11868,7 @@ type SourceShardDeleteRequest struct { func (x *SourceShardDeleteRequest) Reset() { *x = SourceShardDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[188] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11779,7 +11881,7 @@ func (x *SourceShardDeleteRequest) String() string { func (*SourceShardDeleteRequest) ProtoMessage() {} func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[186] + mi := &file_vtctldata_proto_msgTypes[188] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11792,7 +11894,7 @@ func (x *SourceShardDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteRequest.ProtoReflect.Descriptor instead. func (*SourceShardDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{186} + return file_vtctldata_proto_rawDescGZIP(), []int{188} } func (x *SourceShardDeleteRequest) GetKeyspace() string { @@ -11828,7 +11930,7 @@ type SourceShardDeleteResponse struct { func (x *SourceShardDeleteResponse) Reset() { *x = SourceShardDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[189] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11841,7 +11943,7 @@ func (x *SourceShardDeleteResponse) String() string { func (*SourceShardDeleteResponse) ProtoMessage() {} func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[187] + mi := &file_vtctldata_proto_msgTypes[189] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11854,7 +11956,7 @@ func (x *SourceShardDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SourceShardDeleteResponse.ProtoReflect.Descriptor instead. func (*SourceShardDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{187} + return file_vtctldata_proto_rawDescGZIP(), []int{189} } func (x *SourceShardDeleteResponse) GetShard() *topodata.Shard { @@ -11875,7 +11977,7 @@ type StartReplicationRequest struct { func (x *StartReplicationRequest) Reset() { *x = StartReplicationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[190] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11888,7 +11990,7 @@ func (x *StartReplicationRequest) String() string { func (*StartReplicationRequest) ProtoMessage() {} func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[188] + mi := &file_vtctldata_proto_msgTypes[190] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11901,7 +12003,7 @@ func (x *StartReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationRequest.ProtoReflect.Descriptor instead. func (*StartReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{188} + return file_vtctldata_proto_rawDescGZIP(), []int{190} } func (x *StartReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -11920,7 +12022,7 @@ type StartReplicationResponse struct { func (x *StartReplicationResponse) Reset() { *x = StartReplicationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[191] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11933,7 +12035,7 @@ func (x *StartReplicationResponse) String() string { func (*StartReplicationResponse) ProtoMessage() {} func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[189] + mi := &file_vtctldata_proto_msgTypes[191] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11946,7 +12048,7 @@ func (x *StartReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StartReplicationResponse.ProtoReflect.Descriptor instead. func (*StartReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{189} + return file_vtctldata_proto_rawDescGZIP(), []int{191} } type StopReplicationRequest struct { @@ -11960,7 +12062,7 @@ type StopReplicationRequest struct { func (x *StopReplicationRequest) Reset() { *x = StopReplicationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[192] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11973,7 +12075,7 @@ func (x *StopReplicationRequest) String() string { func (*StopReplicationRequest) ProtoMessage() {} func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[190] + mi := &file_vtctldata_proto_msgTypes[192] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11986,7 +12088,7 @@ func (x *StopReplicationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationRequest.ProtoReflect.Descriptor instead. func (*StopReplicationRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{190} + return file_vtctldata_proto_rawDescGZIP(), []int{192} } func (x *StopReplicationRequest) GetTabletAlias() *topodata.TabletAlias { @@ -12005,7 +12107,7 @@ type StopReplicationResponse struct { func (x *StopReplicationResponse) Reset() { *x = StopReplicationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[193] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12018,7 +12120,7 @@ func (x *StopReplicationResponse) String() string { func (*StopReplicationResponse) ProtoMessage() {} func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[191] + mi := &file_vtctldata_proto_msgTypes[193] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12031,7 +12133,7 @@ func (x *StopReplicationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StopReplicationResponse.ProtoReflect.Descriptor instead. func (*StopReplicationResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{191} + return file_vtctldata_proto_rawDescGZIP(), []int{193} } type TabletExternallyReparentedRequest struct { @@ -12047,7 +12149,7 @@ type TabletExternallyReparentedRequest struct { func (x *TabletExternallyReparentedRequest) Reset() { *x = TabletExternallyReparentedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[194] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12060,7 +12162,7 @@ func (x *TabletExternallyReparentedRequest) String() string { func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[192] + mi := &file_vtctldata_proto_msgTypes[194] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12073,7 +12175,7 @@ func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedRequest.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{192} + return file_vtctldata_proto_rawDescGZIP(), []int{194} } func (x *TabletExternallyReparentedRequest) GetTablet() *topodata.TabletAlias { @@ -12097,7 +12199,7 @@ type TabletExternallyReparentedResponse struct { func (x *TabletExternallyReparentedResponse) Reset() { *x = TabletExternallyReparentedResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[195] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12110,7 +12212,7 @@ func (x *TabletExternallyReparentedResponse) String() string { func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[193] + mi := &file_vtctldata_proto_msgTypes[195] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12123,7 +12225,7 @@ func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedResponse.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{193} + return file_vtctldata_proto_rawDescGZIP(), []int{195} } func (x *TabletExternallyReparentedResponse) GetKeyspace() string { @@ -12166,7 +12268,7 @@ type UpdateCellInfoRequest struct { func (x *UpdateCellInfoRequest) Reset() { *x = UpdateCellInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[196] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12179,7 +12281,7 @@ func (x *UpdateCellInfoRequest) String() string { func (*UpdateCellInfoRequest) ProtoMessage() {} func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[194] + mi := &file_vtctldata_proto_msgTypes[196] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12192,7 +12294,7 @@ func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoRequest.ProtoReflect.Descriptor instead. func (*UpdateCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{194} + return file_vtctldata_proto_rawDescGZIP(), []int{196} } func (x *UpdateCellInfoRequest) GetName() string { @@ -12221,7 +12323,7 @@ type UpdateCellInfoResponse struct { func (x *UpdateCellInfoResponse) Reset() { *x = UpdateCellInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[197] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12234,7 +12336,7 @@ func (x *UpdateCellInfoResponse) String() string { func (*UpdateCellInfoResponse) ProtoMessage() {} func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[195] + mi := &file_vtctldata_proto_msgTypes[197] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12247,7 +12349,7 @@ func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoResponse.ProtoReflect.Descriptor instead. func (*UpdateCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{195} + return file_vtctldata_proto_rawDescGZIP(), []int{197} } func (x *UpdateCellInfoResponse) GetName() string { @@ -12276,7 +12378,7 @@ type UpdateCellsAliasRequest struct { func (x *UpdateCellsAliasRequest) Reset() { *x = UpdateCellsAliasRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[198] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12289,7 +12391,7 @@ func (x *UpdateCellsAliasRequest) String() string { func (*UpdateCellsAliasRequest) ProtoMessage() {} func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[196] + mi := &file_vtctldata_proto_msgTypes[198] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12302,7 +12404,7 @@ func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasRequest.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{196} + return file_vtctldata_proto_rawDescGZIP(), []int{198} } func (x *UpdateCellsAliasRequest) GetName() string { @@ -12331,7 +12433,7 @@ type UpdateCellsAliasResponse struct { func (x *UpdateCellsAliasResponse) Reset() { *x = UpdateCellsAliasResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[199] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12344,7 +12446,7 @@ func (x *UpdateCellsAliasResponse) String() string { func (*UpdateCellsAliasResponse) ProtoMessage() {} func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[197] + mi := &file_vtctldata_proto_msgTypes[199] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12357,7 +12459,7 @@ func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasResponse.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{197} + return file_vtctldata_proto_rawDescGZIP(), []int{199} } func (x *UpdateCellsAliasResponse) GetName() string { @@ -12385,7 +12487,7 @@ type ValidateRequest struct { func (x *ValidateRequest) Reset() { *x = ValidateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[200] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12398,7 +12500,7 @@ func (x *ValidateRequest) String() string { func (*ValidateRequest) ProtoMessage() {} func (x *ValidateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[198] + mi := &file_vtctldata_proto_msgTypes[200] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12411,7 +12513,7 @@ func (x *ValidateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRequest.ProtoReflect.Descriptor instead. func (*ValidateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{198} + return file_vtctldata_proto_rawDescGZIP(), []int{200} } func (x *ValidateRequest) GetPingTablets() bool { @@ -12433,7 +12535,7 @@ type ValidateResponse struct { func (x *ValidateResponse) Reset() { *x = ValidateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[201] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12446,7 +12548,7 @@ func (x *ValidateResponse) String() string { func (*ValidateResponse) ProtoMessage() {} func (x *ValidateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[199] + mi := &file_vtctldata_proto_msgTypes[201] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12459,7 +12561,7 @@ func (x *ValidateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateResponse.ProtoReflect.Descriptor instead. func (*ValidateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{199} + return file_vtctldata_proto_rawDescGZIP(), []int{201} } func (x *ValidateResponse) GetResults() []string { @@ -12488,7 +12590,7 @@ type ValidateKeyspaceRequest struct { func (x *ValidateKeyspaceRequest) Reset() { *x = ValidateKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12501,7 +12603,7 @@ func (x *ValidateKeyspaceRequest) String() string { func (*ValidateKeyspaceRequest) ProtoMessage() {} func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[200] + mi := &file_vtctldata_proto_msgTypes[202] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12514,7 +12616,7 @@ func (x *ValidateKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{200} + return file_vtctldata_proto_rawDescGZIP(), []int{202} } func (x *ValidateKeyspaceRequest) GetKeyspace() string { @@ -12543,7 +12645,7 @@ type ValidateKeyspaceResponse struct { func (x *ValidateKeyspaceResponse) Reset() { *x = ValidateKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[203] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12556,7 +12658,7 @@ func (x *ValidateKeyspaceResponse) String() string { func (*ValidateKeyspaceResponse) ProtoMessage() {} func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[201] + mi := &file_vtctldata_proto_msgTypes[203] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12569,7 +12671,7 @@ func (x *ValidateKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{201} + return file_vtctldata_proto_rawDescGZIP(), []int{203} } func (x *ValidateKeyspaceResponse) GetResults() []string { @@ -12601,7 +12703,7 @@ type ValidateSchemaKeyspaceRequest struct { func (x *ValidateSchemaKeyspaceRequest) Reset() { *x = ValidateSchemaKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12614,7 +12716,7 @@ func (x *ValidateSchemaKeyspaceRequest) String() string { func (*ValidateSchemaKeyspaceRequest) ProtoMessage() {} func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[202] + mi := &file_vtctldata_proto_msgTypes[204] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12627,7 +12729,7 @@ func (x *ValidateSchemaKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{202} + return file_vtctldata_proto_rawDescGZIP(), []int{204} } func (x *ValidateSchemaKeyspaceRequest) GetKeyspace() string { @@ -12677,7 +12779,7 @@ type ValidateSchemaKeyspaceResponse struct { func (x *ValidateSchemaKeyspaceResponse) Reset() { *x = ValidateSchemaKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12690,7 +12792,7 @@ func (x *ValidateSchemaKeyspaceResponse) String() string { func (*ValidateSchemaKeyspaceResponse) ProtoMessage() {} func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[203] + mi := &file_vtctldata_proto_msgTypes[205] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12703,7 +12805,7 @@ func (x *ValidateSchemaKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateSchemaKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateSchemaKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{203} + return file_vtctldata_proto_rawDescGZIP(), []int{205} } func (x *ValidateSchemaKeyspaceResponse) GetResults() []string { @@ -12733,7 +12835,7 @@ type ValidateShardRequest struct { func (x *ValidateShardRequest) Reset() { *x = ValidateShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[206] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12746,7 +12848,7 @@ func (x *ValidateShardRequest) String() string { func (*ValidateShardRequest) ProtoMessage() {} func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[204] + mi := &file_vtctldata_proto_msgTypes[206] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12759,7 +12861,7 @@ func (x *ValidateShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardRequest.ProtoReflect.Descriptor instead. func (*ValidateShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{204} + return file_vtctldata_proto_rawDescGZIP(), []int{206} } func (x *ValidateShardRequest) GetKeyspace() string { @@ -12794,7 +12896,7 @@ type ValidateShardResponse struct { func (x *ValidateShardResponse) Reset() { *x = ValidateShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[207] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12807,7 +12909,7 @@ func (x *ValidateShardResponse) String() string { func (*ValidateShardResponse) ProtoMessage() {} func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[205] + mi := &file_vtctldata_proto_msgTypes[207] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12820,7 +12922,7 @@ func (x *ValidateShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateShardResponse.ProtoReflect.Descriptor instead. func (*ValidateShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{205} + return file_vtctldata_proto_rawDescGZIP(), []int{207} } func (x *ValidateShardResponse) GetResults() []string { @@ -12841,7 +12943,7 @@ type ValidateVersionKeyspaceRequest struct { func (x *ValidateVersionKeyspaceRequest) Reset() { *x = ValidateVersionKeyspaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[208] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12854,7 +12956,7 @@ func (x *ValidateVersionKeyspaceRequest) String() string { func (*ValidateVersionKeyspaceRequest) ProtoMessage() {} func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[206] + mi := &file_vtctldata_proto_msgTypes[208] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12867,7 +12969,7 @@ func (x *ValidateVersionKeyspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{206} + return file_vtctldata_proto_rawDescGZIP(), []int{208} } func (x *ValidateVersionKeyspaceRequest) GetKeyspace() string { @@ -12889,7 +12991,7 @@ type ValidateVersionKeyspaceResponse struct { func (x *ValidateVersionKeyspaceResponse) Reset() { *x = ValidateVersionKeyspaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12902,7 +13004,7 @@ func (x *ValidateVersionKeyspaceResponse) String() string { func (*ValidateVersionKeyspaceResponse) ProtoMessage() {} func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[207] + mi := &file_vtctldata_proto_msgTypes[209] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12915,7 +13017,7 @@ func (x *ValidateVersionKeyspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionKeyspaceResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionKeyspaceResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{207} + return file_vtctldata_proto_rawDescGZIP(), []int{209} } func (x *ValidateVersionKeyspaceResponse) GetResults() []string { @@ -12944,7 +13046,7 @@ type ValidateVersionShardRequest struct { func (x *ValidateVersionShardRequest) Reset() { *x = ValidateVersionShardRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12957,7 +13059,7 @@ func (x *ValidateVersionShardRequest) String() string { func (*ValidateVersionShardRequest) ProtoMessage() {} func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[208] + mi := &file_vtctldata_proto_msgTypes[210] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12970,7 +13072,7 @@ func (x *ValidateVersionShardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardRequest.ProtoReflect.Descriptor instead. func (*ValidateVersionShardRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{208} + return file_vtctldata_proto_rawDescGZIP(), []int{210} } func (x *ValidateVersionShardRequest) GetKeyspace() string { @@ -12998,7 +13100,7 @@ type ValidateVersionShardResponse struct { func (x *ValidateVersionShardResponse) Reset() { *x = ValidateVersionShardResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13011,7 +13113,7 @@ func (x *ValidateVersionShardResponse) String() string { func (*ValidateVersionShardResponse) ProtoMessage() {} func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[209] + mi := &file_vtctldata_proto_msgTypes[211] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13024,7 +13126,7 @@ func (x *ValidateVersionShardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVersionShardResponse.ProtoReflect.Descriptor instead. func (*ValidateVersionShardResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{209} + return file_vtctldata_proto_rawDescGZIP(), []int{211} } func (x *ValidateVersionShardResponse) GetResults() []string { @@ -13048,7 +13150,7 @@ type ValidateVSchemaRequest struct { func (x *ValidateVSchemaRequest) Reset() { *x = ValidateVSchemaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13061,7 +13163,7 @@ func (x *ValidateVSchemaRequest) String() string { func (*ValidateVSchemaRequest) ProtoMessage() {} func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[210] + mi := &file_vtctldata_proto_msgTypes[212] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13074,7 +13176,7 @@ func (x *ValidateVSchemaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaRequest.ProtoReflect.Descriptor instead. func (*ValidateVSchemaRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{210} + return file_vtctldata_proto_rawDescGZIP(), []int{212} } func (x *ValidateVSchemaRequest) GetKeyspace() string { @@ -13117,7 +13219,7 @@ type ValidateVSchemaResponse struct { func (x *ValidateVSchemaResponse) Reset() { *x = ValidateVSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13130,7 +13232,7 @@ func (x *ValidateVSchemaResponse) String() string { func (*ValidateVSchemaResponse) ProtoMessage() {} func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[211] + mi := &file_vtctldata_proto_msgTypes[213] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13143,7 +13245,7 @@ func (x *ValidateVSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateVSchemaResponse.ProtoReflect.Descriptor instead. func (*ValidateVSchemaResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{211} + return file_vtctldata_proto_rawDescGZIP(), []int{213} } func (x *ValidateVSchemaResponse) GetResults() []string { @@ -13189,7 +13291,7 @@ type VDiffCreateRequest struct { func (x *VDiffCreateRequest) Reset() { *x = VDiffCreateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[214] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13202,7 +13304,7 @@ func (x *VDiffCreateRequest) String() string { func (*VDiffCreateRequest) ProtoMessage() {} func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[212] + mi := &file_vtctldata_proto_msgTypes[214] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13215,7 +13317,7 @@ func (x *VDiffCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateRequest.ProtoReflect.Descriptor instead. func (*VDiffCreateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{212} + return file_vtctldata_proto_rawDescGZIP(), []int{214} } func (x *VDiffCreateRequest) GetWorkflow() string { @@ -13364,7 +13466,7 @@ type VDiffCreateResponse struct { func (x *VDiffCreateResponse) Reset() { *x = VDiffCreateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[215] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13377,7 +13479,7 @@ func (x *VDiffCreateResponse) String() string { func (*VDiffCreateResponse) ProtoMessage() {} func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[213] + mi := &file_vtctldata_proto_msgTypes[215] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13390,7 +13492,7 @@ func (x *VDiffCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffCreateResponse.ProtoReflect.Descriptor instead. func (*VDiffCreateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{213} + return file_vtctldata_proto_rawDescGZIP(), []int{215} } func (x *VDiffCreateResponse) GetUUID() string { @@ -13414,7 +13516,7 @@ type VDiffDeleteRequest struct { func (x *VDiffDeleteRequest) Reset() { *x = VDiffDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[216] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13427,7 +13529,7 @@ func (x *VDiffDeleteRequest) String() string { func (*VDiffDeleteRequest) ProtoMessage() {} func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[214] + mi := &file_vtctldata_proto_msgTypes[216] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13440,7 +13542,7 @@ func (x *VDiffDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteRequest.ProtoReflect.Descriptor instead. func (*VDiffDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{214} + return file_vtctldata_proto_rawDescGZIP(), []int{216} } func (x *VDiffDeleteRequest) GetWorkflow() string { @@ -13473,7 +13575,7 @@ type VDiffDeleteResponse struct { func (x *VDiffDeleteResponse) Reset() { *x = VDiffDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[217] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13486,7 +13588,7 @@ func (x *VDiffDeleteResponse) String() string { func (*VDiffDeleteResponse) ProtoMessage() {} func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[215] + mi := &file_vtctldata_proto_msgTypes[217] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13499,7 +13601,7 @@ func (x *VDiffDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffDeleteResponse.ProtoReflect.Descriptor instead. func (*VDiffDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{215} + return file_vtctldata_proto_rawDescGZIP(), []int{217} } type VDiffResumeRequest struct { @@ -13515,7 +13617,7 @@ type VDiffResumeRequest struct { func (x *VDiffResumeRequest) Reset() { *x = VDiffResumeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[218] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13528,7 +13630,7 @@ func (x *VDiffResumeRequest) String() string { func (*VDiffResumeRequest) ProtoMessage() {} func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[216] + mi := &file_vtctldata_proto_msgTypes[218] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13541,7 +13643,7 @@ func (x *VDiffResumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeRequest.ProtoReflect.Descriptor instead. func (*VDiffResumeRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{216} + return file_vtctldata_proto_rawDescGZIP(), []int{218} } func (x *VDiffResumeRequest) GetWorkflow() string { @@ -13574,7 +13676,7 @@ type VDiffResumeResponse struct { func (x *VDiffResumeResponse) Reset() { *x = VDiffResumeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[219] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13587,7 +13689,7 @@ func (x *VDiffResumeResponse) String() string { func (*VDiffResumeResponse) ProtoMessage() {} func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[217] + mi := &file_vtctldata_proto_msgTypes[219] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13600,7 +13702,7 @@ func (x *VDiffResumeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffResumeResponse.ProtoReflect.Descriptor instead. func (*VDiffResumeResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{217} + return file_vtctldata_proto_rawDescGZIP(), []int{219} } type VDiffShowRequest struct { @@ -13617,7 +13719,7 @@ type VDiffShowRequest struct { func (x *VDiffShowRequest) Reset() { *x = VDiffShowRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[220] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13630,7 +13732,7 @@ func (x *VDiffShowRequest) String() string { func (*VDiffShowRequest) ProtoMessage() {} func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[218] + mi := &file_vtctldata_proto_msgTypes[220] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13643,7 +13745,7 @@ func (x *VDiffShowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowRequest.ProtoReflect.Descriptor instead. func (*VDiffShowRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{218} + return file_vtctldata_proto_rawDescGZIP(), []int{220} } func (x *VDiffShowRequest) GetWorkflow() string { @@ -13679,7 +13781,7 @@ type VDiffShowResponse struct { func (x *VDiffShowResponse) Reset() { *x = VDiffShowResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[221] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13692,7 +13794,7 @@ func (x *VDiffShowResponse) String() string { func (*VDiffShowResponse) ProtoMessage() {} func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[219] + mi := &file_vtctldata_proto_msgTypes[221] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13705,7 +13807,7 @@ func (x *VDiffShowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffShowResponse.ProtoReflect.Descriptor instead. func (*VDiffShowResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{219} + return file_vtctldata_proto_rawDescGZIP(), []int{221} } func (x *VDiffShowResponse) GetTabletResponses() map[string]*tabletmanagerdata.VDiffResponse { @@ -13728,7 +13830,7 @@ type VDiffStopRequest struct { func (x *VDiffStopRequest) Reset() { *x = VDiffStopRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[222] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13741,7 +13843,7 @@ func (x *VDiffStopRequest) String() string { func (*VDiffStopRequest) ProtoMessage() {} func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[220] + mi := &file_vtctldata_proto_msgTypes[222] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13754,7 +13856,7 @@ func (x *VDiffStopRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopRequest.ProtoReflect.Descriptor instead. func (*VDiffStopRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{220} + return file_vtctldata_proto_rawDescGZIP(), []int{222} } func (x *VDiffStopRequest) GetWorkflow() string { @@ -13787,7 +13889,7 @@ type VDiffStopResponse struct { func (x *VDiffStopResponse) Reset() { *x = VDiffStopResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[223] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13800,7 +13902,7 @@ func (x *VDiffStopResponse) String() string { func (*VDiffStopResponse) ProtoMessage() {} func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[221] + mi := &file_vtctldata_proto_msgTypes[223] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13813,7 +13915,7 @@ func (x *VDiffStopResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VDiffStopResponse.ProtoReflect.Descriptor instead. func (*VDiffStopResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{221} + return file_vtctldata_proto_rawDescGZIP(), []int{223} } type WorkflowDeleteRequest struct { @@ -13830,7 +13932,7 @@ type WorkflowDeleteRequest struct { func (x *WorkflowDeleteRequest) Reset() { *x = WorkflowDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[224] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13843,7 +13945,7 @@ func (x *WorkflowDeleteRequest) String() string { func (*WorkflowDeleteRequest) ProtoMessage() {} func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[222] + mi := &file_vtctldata_proto_msgTypes[224] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13856,7 +13958,7 @@ func (x *WorkflowDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteRequest.ProtoReflect.Descriptor instead. func (*WorkflowDeleteRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{222} + return file_vtctldata_proto_rawDescGZIP(), []int{224} } func (x *WorkflowDeleteRequest) GetKeyspace() string { @@ -13899,7 +14001,7 @@ type WorkflowDeleteResponse struct { func (x *WorkflowDeleteResponse) Reset() { *x = WorkflowDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[225] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13912,7 +14014,7 @@ func (x *WorkflowDeleteResponse) String() string { func (*WorkflowDeleteResponse) ProtoMessage() {} func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[223] + mi := &file_vtctldata_proto_msgTypes[225] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13925,7 +14027,7 @@ func (x *WorkflowDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowDeleteResponse.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{223} + return file_vtctldata_proto_rawDescGZIP(), []int{225} } func (x *WorkflowDeleteResponse) GetSummary() string { @@ -13954,7 +14056,7 @@ type WorkflowStatusRequest struct { func (x *WorkflowStatusRequest) Reset() { *x = WorkflowStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[226] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13967,7 +14069,7 @@ func (x *WorkflowStatusRequest) String() string { func (*WorkflowStatusRequest) ProtoMessage() {} func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[224] + mi := &file_vtctldata_proto_msgTypes[226] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13980,7 +14082,7 @@ func (x *WorkflowStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusRequest.ProtoReflect.Descriptor instead. func (*WorkflowStatusRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{224} + return file_vtctldata_proto_rawDescGZIP(), []int{226} } func (x *WorkflowStatusRequest) GetKeyspace() string { @@ -14011,7 +14113,7 @@ type WorkflowStatusResponse struct { func (x *WorkflowStatusResponse) Reset() { *x = WorkflowStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[227] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14024,7 +14126,7 @@ func (x *WorkflowStatusResponse) String() string { func (*WorkflowStatusResponse) ProtoMessage() {} func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[225] + mi := &file_vtctldata_proto_msgTypes[227] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14037,7 +14139,7 @@ func (x *WorkflowStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowStatusResponse.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225} + return file_vtctldata_proto_rawDescGZIP(), []int{227} } func (x *WorkflowStatusResponse) GetTableCopyState() map[string]*WorkflowStatusResponse_TableCopyState { @@ -14081,7 +14183,7 @@ type WorkflowSwitchTrafficRequest struct { func (x *WorkflowSwitchTrafficRequest) Reset() { *x = WorkflowSwitchTrafficRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14094,7 +14196,7 @@ func (x *WorkflowSwitchTrafficRequest) String() string { func (*WorkflowSwitchTrafficRequest) ProtoMessage() {} func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[226] + mi := &file_vtctldata_proto_msgTypes[228] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14107,7 +14209,7 @@ func (x *WorkflowSwitchTrafficRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficRequest.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{226} + return file_vtctldata_proto_rawDescGZIP(), []int{228} } func (x *WorkflowSwitchTrafficRequest) GetKeyspace() string { @@ -14194,7 +14296,7 @@ type WorkflowSwitchTrafficResponse struct { func (x *WorkflowSwitchTrafficResponse) Reset() { *x = WorkflowSwitchTrafficResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14207,7 +14309,7 @@ func (x *WorkflowSwitchTrafficResponse) String() string { func (*WorkflowSwitchTrafficResponse) ProtoMessage() {} func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[227] + mi := &file_vtctldata_proto_msgTypes[229] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14220,7 +14322,7 @@ func (x *WorkflowSwitchTrafficResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowSwitchTrafficResponse.ProtoReflect.Descriptor instead. func (*WorkflowSwitchTrafficResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{227} + return file_vtctldata_proto_rawDescGZIP(), []int{229} } func (x *WorkflowSwitchTrafficResponse) GetSummary() string { @@ -14265,7 +14367,7 @@ type WorkflowUpdateRequest struct { func (x *WorkflowUpdateRequest) Reset() { *x = WorkflowUpdateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[230] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14278,7 +14380,7 @@ func (x *WorkflowUpdateRequest) String() string { func (*WorkflowUpdateRequest) ProtoMessage() {} func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[228] + mi := &file_vtctldata_proto_msgTypes[230] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14291,7 +14393,7 @@ func (x *WorkflowUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateRequest.ProtoReflect.Descriptor instead. func (*WorkflowUpdateRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{228} + return file_vtctldata_proto_rawDescGZIP(), []int{230} } func (x *WorkflowUpdateRequest) GetKeyspace() string { @@ -14320,7 +14422,7 @@ type WorkflowUpdateResponse struct { func (x *WorkflowUpdateResponse) Reset() { *x = WorkflowUpdateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[231] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14333,7 +14435,7 @@ func (x *WorkflowUpdateResponse) String() string { func (*WorkflowUpdateResponse) ProtoMessage() {} func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[229] + mi := &file_vtctldata_proto_msgTypes[231] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14346,7 +14448,7 @@ func (x *WorkflowUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkflowUpdateResponse.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{229} + return file_vtctldata_proto_rawDescGZIP(), []int{231} } func (x *WorkflowUpdateResponse) GetSummary() string { @@ -14375,7 +14477,7 @@ type Workflow_ReplicationLocation struct { func (x *Workflow_ReplicationLocation) Reset() { *x = Workflow_ReplicationLocation{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[233] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14388,7 +14490,7 @@ func (x *Workflow_ReplicationLocation) String() string { func (*Workflow_ReplicationLocation) ProtoMessage() {} func (x *Workflow_ReplicationLocation) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[231] + mi := &file_vtctldata_proto_msgTypes[233] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14431,7 +14533,7 @@ type Workflow_ShardStream struct { func (x *Workflow_ShardStream) Reset() { *x = Workflow_ShardStream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[232] + mi := &file_vtctldata_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14444,7 +14546,7 @@ func (x *Workflow_ShardStream) String() string { func (*Workflow_ShardStream) ProtoMessage() {} func (x *Workflow_ShardStream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[232] + mi := &file_vtctldata_proto_msgTypes[234] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14516,7 +14618,7 @@ type Workflow_Stream struct { func (x *Workflow_Stream) Reset() { *x = Workflow_Stream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14529,7 +14631,7 @@ func (x *Workflow_Stream) String() string { func (*Workflow_Stream) ProtoMessage() {} func (x *Workflow_Stream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[233] + mi := &file_vtctldata_proto_msgTypes[235] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14676,7 +14778,7 @@ type Workflow_Stream_CopyState struct { func (x *Workflow_Stream_CopyState) Reset() { *x = Workflow_Stream_CopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[234] + mi := &file_vtctldata_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14689,7 +14791,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[234] + mi := &file_vtctldata_proto_msgTypes[236] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14737,7 +14839,7 @@ type Workflow_Stream_Log struct { func (x *Workflow_Stream_Log) Reset() { *x = Workflow_Stream_Log{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[235] + mi := &file_vtctldata_proto_msgTypes[237] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14750,7 +14852,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[235] + mi := &file_vtctldata_proto_msgTypes[237] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14834,7 +14936,7 @@ type Workflow_Stream_ThrottlerStatus struct { func (x *Workflow_Stream_ThrottlerStatus) Reset() { *x = Workflow_Stream_ThrottlerStatus{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[236] + mi := &file_vtctldata_proto_msgTypes[238] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14847,7 +14949,7 @@ func (x *Workflow_Stream_ThrottlerStatus) String() string { func (*Workflow_Stream_ThrottlerStatus) ProtoMessage() {} func (x *Workflow_Stream_ThrottlerStatus) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[236] + mi := &file_vtctldata_proto_msgTypes[238] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14888,7 +14990,7 @@ type GetSrvKeyspaceNamesResponse_NameList struct { func (x *GetSrvKeyspaceNamesResponse_NameList) Reset() { *x = GetSrvKeyspaceNamesResponse_NameList{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[247] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14901,7 +15003,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) String() string { func (*GetSrvKeyspaceNamesResponse_NameList) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[247] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14914,7 +15016,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Messa // Deprecated: Use GetSrvKeyspaceNamesResponse_NameList.ProtoReflect.Descriptor instead. func (*GetSrvKeyspaceNamesResponse_NameList) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{84, 1} + return file_vtctldata_proto_rawDescGZIP(), []int{86, 1} } func (x *GetSrvKeyspaceNamesResponse_NameList) GetNames() []string { @@ -14937,7 +15039,7 @@ type MoveTablesCreateResponse_TabletInfo struct { func (x *MoveTablesCreateResponse_TabletInfo) Reset() { *x = MoveTablesCreateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[248] + mi := &file_vtctldata_proto_msgTypes[251] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14950,7 +15052,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) String() string { func (*MoveTablesCreateResponse_TabletInfo) ProtoMessage() {} func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[248] + mi := &file_vtctldata_proto_msgTypes[251] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14963,7 +15065,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Messag // Deprecated: Use MoveTablesCreateResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*MoveTablesCreateResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{128, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{130, 0} } func (x *MoveTablesCreateResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -14993,7 +15095,7 @@ type WorkflowDeleteResponse_TabletInfo struct { func (x *WorkflowDeleteResponse_TabletInfo) Reset() { *x = WorkflowDeleteResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[258] + mi := &file_vtctldata_proto_msgTypes[261] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15006,7 +15108,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) String() string { func (*WorkflowDeleteResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[258] + mi := &file_vtctldata_proto_msgTypes[261] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15019,7 +15121,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowDeleteResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowDeleteResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{223, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{225, 0} } func (x *WorkflowDeleteResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -15052,7 +15154,7 @@ type WorkflowStatusResponse_TableCopyState struct { func (x *WorkflowStatusResponse_TableCopyState) Reset() { *x = WorkflowStatusResponse_TableCopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[259] + mi := &file_vtctldata_proto_msgTypes[262] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15065,7 +15167,7 @@ func (x *WorkflowStatusResponse_TableCopyState) String() string { func (*WorkflowStatusResponse_TableCopyState) ProtoMessage() {} func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[259] + mi := &file_vtctldata_proto_msgTypes[262] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15078,7 +15180,7 @@ func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Mess // Deprecated: Use WorkflowStatusResponse_TableCopyState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_TableCopyState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{227, 0} } func (x *WorkflowStatusResponse_TableCopyState) GetRowsCopied() int64 { @@ -15139,7 +15241,7 @@ type WorkflowStatusResponse_ShardStreamState struct { func (x *WorkflowStatusResponse_ShardStreamState) Reset() { *x = WorkflowStatusResponse_ShardStreamState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[263] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15152,7 +15254,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) String() string { func (*WorkflowStatusResponse_ShardStreamState) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[260] + mi := &file_vtctldata_proto_msgTypes[263] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15165,7 +15267,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Me // Deprecated: Use WorkflowStatusResponse_ShardStreamState.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreamState) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225, 1} + return file_vtctldata_proto_rawDescGZIP(), []int{227, 1} } func (x *WorkflowStatusResponse_ShardStreamState) GetId() int32 { @@ -15221,7 +15323,7 @@ type WorkflowStatusResponse_ShardStreams struct { func (x *WorkflowStatusResponse_ShardStreams) Reset() { *x = WorkflowStatusResponse_ShardStreams{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[264] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15234,7 +15336,7 @@ func (x *WorkflowStatusResponse_ShardStreams) String() string { func (*WorkflowStatusResponse_ShardStreams) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[261] + mi := &file_vtctldata_proto_msgTypes[264] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15247,7 +15349,7 @@ func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Messag // Deprecated: Use WorkflowStatusResponse_ShardStreams.ProtoReflect.Descriptor instead. func (*WorkflowStatusResponse_ShardStreams) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{225, 2} + return file_vtctldata_proto_rawDescGZIP(), []int{227, 2} } func (x *WorkflowStatusResponse_ShardStreams) GetStreams() []*WorkflowStatusResponse_ShardStreamState { @@ -15271,7 +15373,7 @@ type WorkflowUpdateResponse_TabletInfo struct { func (x *WorkflowUpdateResponse_TabletInfo) Reset() { *x = WorkflowUpdateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[264] + mi := &file_vtctldata_proto_msgTypes[267] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15284,7 +15386,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) String() string { func (*WorkflowUpdateResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[264] + mi := &file_vtctldata_proto_msgTypes[267] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15297,7 +15399,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message // Deprecated: Use WorkflowUpdateResponse_TabletInfo.ProtoReflect.Descriptor instead. func (*WorkflowUpdateResponse_TabletInfo) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{229, 0} + return file_vtctldata_proto_rawDescGZIP(), []int{231, 0} } func (x *WorkflowUpdateResponse_TabletInfo) GetTablet() *topodata.TabletAlias { @@ -16086,1174 +16188,1099 @@ var file_vtctldata_proto_rawDesc = []byte{ 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, 0x9e, - 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, + 0x61, 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x54, + 0x0a, 0x22, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 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, 0x50, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x46, 0x75, - 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x4c, 0x0a, 0x15, 0x47, 0x65, 0x74, - 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x22, 0xeb, 0x01, 0x0a, 0x23, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, + 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x16, + 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, + 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, + 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, + 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, + 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, + 0x64, 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, 0x04, 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, 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, 0x50, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x4c, 0x0a, + 0x15, 0x47, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x51, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 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, 0x5a, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 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, 0xb0, 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, 0x22, 0x5a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x40, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 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, 0xb0, 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, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 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, 0xb8, 0x02, 0x0a, 0x1a, 0x47, 0x65, 0x74, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 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, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x28, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 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, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x6f, 0x72, 0x64, - 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, - 0x6b, 0x69, 0x70, 0x22, 0x59, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 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, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf3, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, - 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x1a, 0x69, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 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, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2f, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x20, 0x0a, 0x08, 0x4e, - 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf8, 0x02, 0x0a, 0x1c, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 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, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, - 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x65, 0x6c, - 0x66, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, - 0x61, 0x70, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, - 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, - 0x41, 0x70, 0x70, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, - 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 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, 0xe8, 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, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 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, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, - 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, - 0x46, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, - 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x63, 0x65, - 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, - 0x6c, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x66, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, - 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 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, 0x4d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, - 0x2e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0xae, 0x01, 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, + 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, 0x12, 0x2a, + 0x0a, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, + 0x6e, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0xb8, 0x02, 0x0a, + 0x1a, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 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, 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, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x61, 0x6d, - 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x4c, 0x6f, 0x67, 0x73, 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, 0x4e, 0x0a, 0x1c, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x22, 0xdf, 0x01, 0x0a, 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, - 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, - 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, - 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xff, 0x02, 0x0a, 0x19, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 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, 0x1a, 0x0a, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, - 0x29, 0x0a, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x42, 0x0a, 0x1e, 0x63, 0x6f, - 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, - 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x41, 0x66, 0x74, 0x65, - 0x72, 0x43, 0x6f, 0x70, 0x79, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x37, - 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, - 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 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, 0x06, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, + 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x22, 0x59, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4c, 0x0a, 0x1f, - 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x29, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x56, 0x0a, 0x18, 0x4d, 0x61, - 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0xdd, 0x05, 0x0a, 0x14, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, - 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, - 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, - 0x6f, 0x6e, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, - 0x64, 0x64, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, - 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, - 0x6f, 0x70, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, - 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, - 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, - 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, - 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, - 0xe6, 0x01, 0x0a, 0x16, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, - 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, - 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, - 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, - 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, - 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, - 0x15, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, - 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x26, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, - 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, - 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x10, - 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x29, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0xbb, 0x06, 0x0a, 0x17, - 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, - 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, - 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, - 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, - 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, - 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, - 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, - 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, - 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, - 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, - 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, - 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x74, 0x6f, 0x6d, - 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, - 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x70, 0x79, 0x22, 0xd5, 0x01, 0x0a, 0x18, 0x4d, 0x6f, - 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x48, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x6f, - 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x22, 0xe9, 0x01, 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, - 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, - 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, - 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5e, 0x0a, - 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, - 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, - 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x4d, 0x0a, - 0x11, 0x50, 0x69, 0x6e, 0x67, 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, 0x14, 0x0a, 0x12, - 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xd7, 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, 0x12, 0x4c, - 0x0a, 0x19, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 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, + 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, 0x1d, 0x0a, 0x1b, + 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1c, 0x47, + 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x11, 0x73, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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, 0xf3, 0x01, 0x0a, 0x1b, + 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x05, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 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, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 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, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2f, 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, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x20, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 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, 0xf8, 0x02, 0x0a, + 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x74, 0x0a, 0x1b, 0x52, 0x65, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, + 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, + 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x10, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x53, 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x61, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, + 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x74, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x22, 0x1f, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0xe8, 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, 0x12, 0x35, 0x0a, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 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, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, + 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x22, 0x46, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, + 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x66, 0x0a, 0x0c, 0x54, + 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 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, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x22, - 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, + 0x70, 0x61, 0x63, 0x65, 0x22, 0x4d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 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, 0x83, 0x01, 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, 0x12, - 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x15, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 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, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x6f, - 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xa9, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 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, 0x23, 0x0a, 0x0d, - 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, - 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x46, 0x0a, 0x1c, - 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x22, 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 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, 0x5b, 0x0a, 0x13, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x69, 0x61, 0x73, 0x22, 0x2e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 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, 0xae, 0x01, 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, 0x12, 0x1b, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x73, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x8f, 0x04, 0x0a, 0x14, 0x52, - 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, - 0x69, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x15, 0x0a, 0x06, - 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, - 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, - 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, - 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x64, - 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, - 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x82, 0x02, 0x0a, - 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, - 0x75, 0x70, 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, - 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, - 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, - 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x24, 0x0a, 0x05, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, - 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, - 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, - 0x22, 0xdd, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 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, 0x4e, 0x0a, 0x1c, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0xdf, 0x01, 0x0a, 0x1d, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, + 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, - 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, - 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x51, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, - 0x63, 0x6b, 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, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, - 0x22, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, - 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x75, 0x72, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x55, 0x0a, 0x23, - 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, + 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, + 0x46, 0x0a, 0x18, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, + 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xff, 0x02, 0x0a, 0x19, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 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, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, - 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x06, 0x76, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x42, + 0x0a, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x57, 0x69, 0x74, 0x68, 0x4f, 0x77, 0x6e, + 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77, 0x0a, 0x1e, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, + 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, + 0x7a, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x22, 0x49, 0x0a, 0x20, 0x53, 0x65, - 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x8e, 0x02, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x22, 0x4c, 0x0a, 0x1f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x56, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x56, + 0x0a, 0x18, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x05, 0x0a, 0x14, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, + 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x0a, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, + 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, + 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, + 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, + 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, + 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, + 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, + 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, + 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x16, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, + 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5b, 0x0a, 0x17, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, + 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x6f, + 0x75, 0x6e, 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x6f, 0x75, 0x6e, + 0x74, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x70, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x70, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x12, 0x0a, 0x10, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 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, + 0xbb, 0x06, 0x0a, 0x17, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, + 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, + 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x6f, + 0x72, 0x65, 0x69, 0x67, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x64, 0x72, 0x6f, 0x70, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, + 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, + 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6e, 0x6f, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x61, 0x74, 0x6f, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x70, 0x79, 0x22, 0xd5, 0x01, + 0x0a, 0x18, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, + 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0xe9, 0x01, 0x0a, 0x19, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, + 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, + 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, + 0x6e, 0x22, 0x5e, 0x0a, 0x1a, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, + 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x69, 0x6e, 0x67, 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, 0x14, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd7, 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, 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, - 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, - 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, 0x0a, 0x1d, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x18, 0x01, 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, 0x6a, - 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 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, 0x1a, - 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, - 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 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, 0x38, 0x0a, 0x0c, 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, + 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, 0x12, 0x4c, 0x0a, 0x19, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x62, + 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, + 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, 0x74, 0x0a, + 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x47, 0x72, 0x61, 0x70, 0x68, 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, 0x12, 0x23, + 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 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, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x83, 0x01, 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, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, + 0x65, 0x6c, 0x6f, 0x61, 0x64, 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, 0x22, 0x1d, 0x0a, 0x1b, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x1a, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, - 0x69, 0x78, 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, 0x12, 0x0a, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, - 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, - 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x8b, 0x01, 0x0a, 0x1d, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 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, 0x03, 0x20, 0x01, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x16, 0x0a, 0x14, + 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x22, 0x46, 0x0a, 0x1c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 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, 0xbc, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 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, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x43, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x6f, 0x61, + 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, + 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, 0x5b, 0x0a, 0x13, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x12, 0x53, 0x6c, 0x65, 0x65, - 0x70, 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, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf0, 0x01, - 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, + 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, 0x8f, + 0x04, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x68, 0x61, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, + 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x6f, 0x70, 0x79, + 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, + 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x22, 0x82, 0x02, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 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, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, + 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, + 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 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, 0x1a, 0x0a, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x4d, 0x0a, 0x1b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x16, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, + 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x46, 0x0a, 0x18, + 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x79, 0x53, 0x68, + 0x61, 0x72, 0x64, 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, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x51, 0x0a, 0x15, 0x52, 0x75, 0x6e, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 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, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x6d, 0x0a, 0x22, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x44, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, - 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 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, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x41, - 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x61, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x64, 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x22, 0x55, 0x0a, 0x23, 0x53, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x44, + 0x75, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x66, 0x6f, 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, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, + 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x51, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x72, 0x0a, 0x1f, 0x53, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 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, - 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, - 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x53, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, 0x0a, 0x18, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x22, 0x49, + 0x0a, 0x20, 0x53, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x73, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x8e, 0x02, 0x0a, 0x1c, 0x53, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 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, 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, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6e, + 0x69, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x32, + 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x46, 0x0a, 0x1d, 0x53, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x6a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, + 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, 0x1a, 0x0a, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, + 0x0a, 0x13, 0x53, 0x65, 0x74, 0x57, 0x72, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 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, 0x38, 0x0a, 0x0c, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x62, 0x0a, 0x1a, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 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, + 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, + 0x65, 0x6c, 0x6c, 0x22, 0x54, 0x0a, 0x1b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x8b, 0x01, 0x0a, + 0x1d, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 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, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 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, 0x0b, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, - 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x22, 0x34, 0x0a, 0x0f, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 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, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, - 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, - 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd8, 0x01, 0x0a, 0x1d, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x12, + 0x53, 0x6c, 0x65, 0x65, 0x70, 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, 0x12, 0x2c, 0x0a, 0x08, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x6c, + 0x65, 0x65, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xf0, 0x01, 0x0a, 0x15, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x41, 0x64, 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, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 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, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, - 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, - 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, - 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x31, 0x0a, 0x15, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, - 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 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, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x27, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x6b, + 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 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, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x22, 0x3f, 0x0a, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x5e, 0x0a, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x8a, 0x02, - 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x68, 0x0a, 0x10, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4f, 0x0a, 0x1b, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x22, 0x38, 0x0a, 0x1c, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 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, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x19, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 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, 0x53, 0x0a, 0x17, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, + 0x0a, 0x18, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x16, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x19, + 0x0a, 0x17, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, + 0x22, 0x34, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 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, 0x16, 0x0a, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, - 0x61, 0x72, 0x64, 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, - 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x5f, 0x62, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, + 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x1a, 0x69, 0x0a, 0x16, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 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, 0x21, 0x0a, 0x0c, 0x70, + 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xfc, + 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x61, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x37, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, @@ -17262,273 +17289,368 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x06, - 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, - 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, - 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, - 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, - 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x55, 0x0a, 0x1e, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x4b, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, - 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, - 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, - 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, - 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x14, 0x77, 0x61, 0x69, 0x74, - 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x77, 0x61, 0x69, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, - 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, - 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x22, 0x29, 0x0a, 0x13, 0x56, 0x44, - 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, 0x12, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd8, 0x01, + 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 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, 0x25, 0x0a, 0x0e, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, + 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x4e, 0x6f, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x56, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x88, 0x02, 0x0a, 0x1e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, + 0x0a, 0x13, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 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, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, + 0x22, 0x31, 0x0a, 0x15, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x8a, 0x02, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, + 0x68, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4f, + 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 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, 0x22, + 0x38, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x16, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 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, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 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, 0x22, 0xfa, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x10, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x1a, 0x63, 0x0a, 0x13, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xca, 0x06, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x55, 0x0a, 0x1e, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x09, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x5f, 0x6b, + 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x4b, 0x73, + 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, + 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, + 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, + 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x14, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x77, 0x61, + 0x69, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, + 0x6f, 0x77, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x22, 0x29, + 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x55, 0x49, 0x44, 0x22, 0x6b, 0x0a, 0x12, 0x56, 0x44, 0x69, + 0x66, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x56, 0x44, 0x69, 0x66, 0x66, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x0a, + 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x72, 0x67, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x56, - 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x64, - 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, - 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, - 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6b, 0x65, 0x65, - 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x72, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, - 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x4f, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 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, 0x1a, 0x0a, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe6, 0x07, 0x0a, 0x16, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x70, - 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x61, 0x72, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x72, 0x67, 0x22, 0xd7, + 0x01, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 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, 0x36, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x13, 0x0a, 0x11, 0x56, 0x44, 0x69, 0x66, 0x66, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x15, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x0a, 0x09, + 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x65, + 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x07, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, - 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, - 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, - 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x5f, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x6f, 0x77, - 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x70, - 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x69, - 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x54, 0x6f, - 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, - 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x1a, 0xbc, - 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x5c, 0x0a, - 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x4c, 0x0a, - 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x73, 0x0a, 0x13, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, - 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 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, 0x1a, - 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1b, 0x6d, 0x61, 0x78, - 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, - 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x1b, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x1d, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, - 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, 0x5b, 0x0a, 0x0e, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x16, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, - 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, - 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, - 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, - 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, - 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, - 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, - 0x10, 0x02, 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, + 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x4f, 0x0a, 0x15, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe6, 0x07, 0x0a, + 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x43, + 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x33, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x66, 0x66, + 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xe8, 0x01, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, + 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x72, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x6f, + 0x77, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x02, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, + 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x02, 0x52, 0x0f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, + 0x67, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x18, 0x02, 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, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x1a, 0x5c, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x73, 0x12, 0x4c, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, + 0x73, 0x0a, 0x13, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6f, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 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, 0x44, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x03, 0x0a, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 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, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 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, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, + 0x1b, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 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, 0x18, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x3c, + 0x0a, 0x1a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, + 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, + 0x3e, 0x0a, 0x1b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, + 0xa7, 0x01, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x79, 0x52, + 0x75, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 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, + 0x5b, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd1, 0x01, 0x0a, + 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x46, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x55, 0x0a, 0x0a, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, + 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, + 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, + 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, + 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, + 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, + 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 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 ( @@ -17544,7 +17666,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { } var file_vtctldata_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 265) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 268) var file_vtctldata_proto_goTypes = []interface{}{ (MaterializationIntent)(0), // 0: vtctldata.MaterializationIntent (QueryOrdering)(0), // 1: vtctldata.QueryOrdering @@ -17607,459 +17729,463 @@ var file_vtctldata_proto_goTypes = []interface{}{ (*ExecuteHookResponse)(nil), // 58: vtctldata.ExecuteHookResponse (*FindAllShardsInKeyspaceRequest)(nil), // 59: vtctldata.FindAllShardsInKeyspaceRequest (*FindAllShardsInKeyspaceResponse)(nil), // 60: vtctldata.FindAllShardsInKeyspaceResponse - (*GetBackupsRequest)(nil), // 61: vtctldata.GetBackupsRequest - (*GetBackupsResponse)(nil), // 62: vtctldata.GetBackupsResponse - (*GetCellInfoRequest)(nil), // 63: vtctldata.GetCellInfoRequest - (*GetCellInfoResponse)(nil), // 64: vtctldata.GetCellInfoResponse - (*GetCellInfoNamesRequest)(nil), // 65: vtctldata.GetCellInfoNamesRequest - (*GetCellInfoNamesResponse)(nil), // 66: vtctldata.GetCellInfoNamesResponse - (*GetCellsAliasesRequest)(nil), // 67: vtctldata.GetCellsAliasesRequest - (*GetCellsAliasesResponse)(nil), // 68: vtctldata.GetCellsAliasesResponse - (*GetFullStatusRequest)(nil), // 69: vtctldata.GetFullStatusRequest - (*GetFullStatusResponse)(nil), // 70: vtctldata.GetFullStatusResponse - (*GetKeyspacesRequest)(nil), // 71: vtctldata.GetKeyspacesRequest - (*GetKeyspacesResponse)(nil), // 72: vtctldata.GetKeyspacesResponse - (*GetKeyspaceRequest)(nil), // 73: vtctldata.GetKeyspaceRequest - (*GetKeyspaceResponse)(nil), // 74: vtctldata.GetKeyspaceResponse - (*GetPermissionsRequest)(nil), // 75: vtctldata.GetPermissionsRequest - (*GetPermissionsResponse)(nil), // 76: vtctldata.GetPermissionsResponse - (*GetRoutingRulesRequest)(nil), // 77: vtctldata.GetRoutingRulesRequest - (*GetRoutingRulesResponse)(nil), // 78: vtctldata.GetRoutingRulesResponse - (*GetSchemaRequest)(nil), // 79: vtctldata.GetSchemaRequest - (*GetSchemaResponse)(nil), // 80: vtctldata.GetSchemaResponse - (*GetSchemaMigrationsRequest)(nil), // 81: vtctldata.GetSchemaMigrationsRequest - (*GetSchemaMigrationsResponse)(nil), // 82: vtctldata.GetSchemaMigrationsResponse - (*GetShardRequest)(nil), // 83: vtctldata.GetShardRequest - (*GetShardResponse)(nil), // 84: vtctldata.GetShardResponse - (*GetShardRoutingRulesRequest)(nil), // 85: vtctldata.GetShardRoutingRulesRequest - (*GetShardRoutingRulesResponse)(nil), // 86: vtctldata.GetShardRoutingRulesResponse - (*GetSrvKeyspaceNamesRequest)(nil), // 87: vtctldata.GetSrvKeyspaceNamesRequest - (*GetSrvKeyspaceNamesResponse)(nil), // 88: vtctldata.GetSrvKeyspaceNamesResponse - (*GetSrvKeyspacesRequest)(nil), // 89: vtctldata.GetSrvKeyspacesRequest - (*GetSrvKeyspacesResponse)(nil), // 90: vtctldata.GetSrvKeyspacesResponse - (*UpdateThrottlerConfigRequest)(nil), // 91: vtctldata.UpdateThrottlerConfigRequest - (*UpdateThrottlerConfigResponse)(nil), // 92: vtctldata.UpdateThrottlerConfigResponse - (*GetSrvVSchemaRequest)(nil), // 93: vtctldata.GetSrvVSchemaRequest - (*GetSrvVSchemaResponse)(nil), // 94: vtctldata.GetSrvVSchemaResponse - (*GetSrvVSchemasRequest)(nil), // 95: vtctldata.GetSrvVSchemasRequest - (*GetSrvVSchemasResponse)(nil), // 96: vtctldata.GetSrvVSchemasResponse - (*GetTabletRequest)(nil), // 97: vtctldata.GetTabletRequest - (*GetTabletResponse)(nil), // 98: vtctldata.GetTabletResponse - (*GetTabletsRequest)(nil), // 99: vtctldata.GetTabletsRequest - (*GetTabletsResponse)(nil), // 100: vtctldata.GetTabletsResponse - (*GetTopologyPathRequest)(nil), // 101: vtctldata.GetTopologyPathRequest - (*GetTopologyPathResponse)(nil), // 102: vtctldata.GetTopologyPathResponse - (*TopologyCell)(nil), // 103: vtctldata.TopologyCell - (*GetVSchemaRequest)(nil), // 104: vtctldata.GetVSchemaRequest - (*GetVersionRequest)(nil), // 105: vtctldata.GetVersionRequest - (*GetVersionResponse)(nil), // 106: vtctldata.GetVersionResponse - (*GetVSchemaResponse)(nil), // 107: vtctldata.GetVSchemaResponse - (*GetWorkflowsRequest)(nil), // 108: vtctldata.GetWorkflowsRequest - (*GetWorkflowsResponse)(nil), // 109: vtctldata.GetWorkflowsResponse - (*InitShardPrimaryRequest)(nil), // 110: vtctldata.InitShardPrimaryRequest - (*InitShardPrimaryResponse)(nil), // 111: vtctldata.InitShardPrimaryResponse - (*LaunchSchemaMigrationRequest)(nil), // 112: vtctldata.LaunchSchemaMigrationRequest - (*LaunchSchemaMigrationResponse)(nil), // 113: vtctldata.LaunchSchemaMigrationResponse - (*LookupVindexCreateRequest)(nil), // 114: vtctldata.LookupVindexCreateRequest - (*LookupVindexCreateResponse)(nil), // 115: vtctldata.LookupVindexCreateResponse - (*LookupVindexExternalizeRequest)(nil), // 116: vtctldata.LookupVindexExternalizeRequest - (*LookupVindexExternalizeResponse)(nil), // 117: vtctldata.LookupVindexExternalizeResponse - (*MaterializeCreateRequest)(nil), // 118: vtctldata.MaterializeCreateRequest - (*MaterializeCreateResponse)(nil), // 119: vtctldata.MaterializeCreateResponse - (*MigrateCreateRequest)(nil), // 120: vtctldata.MigrateCreateRequest - (*MigrateCompleteRequest)(nil), // 121: vtctldata.MigrateCompleteRequest - (*MigrateCompleteResponse)(nil), // 122: vtctldata.MigrateCompleteResponse - (*MountRegisterRequest)(nil), // 123: vtctldata.MountRegisterRequest - (*MountRegisterResponse)(nil), // 124: vtctldata.MountRegisterResponse - (*MountUnregisterRequest)(nil), // 125: vtctldata.MountUnregisterRequest - (*MountUnregisterResponse)(nil), // 126: vtctldata.MountUnregisterResponse - (*MountShowRequest)(nil), // 127: vtctldata.MountShowRequest - (*MountShowResponse)(nil), // 128: vtctldata.MountShowResponse - (*MountListRequest)(nil), // 129: vtctldata.MountListRequest - (*MountListResponse)(nil), // 130: vtctldata.MountListResponse - (*MoveTablesCreateRequest)(nil), // 131: vtctldata.MoveTablesCreateRequest - (*MoveTablesCreateResponse)(nil), // 132: vtctldata.MoveTablesCreateResponse - (*MoveTablesCompleteRequest)(nil), // 133: vtctldata.MoveTablesCompleteRequest - (*MoveTablesCompleteResponse)(nil), // 134: vtctldata.MoveTablesCompleteResponse - (*PingTabletRequest)(nil), // 135: vtctldata.PingTabletRequest - (*PingTabletResponse)(nil), // 136: vtctldata.PingTabletResponse - (*PlannedReparentShardRequest)(nil), // 137: vtctldata.PlannedReparentShardRequest - (*PlannedReparentShardResponse)(nil), // 138: vtctldata.PlannedReparentShardResponse - (*RebuildKeyspaceGraphRequest)(nil), // 139: vtctldata.RebuildKeyspaceGraphRequest - (*RebuildKeyspaceGraphResponse)(nil), // 140: vtctldata.RebuildKeyspaceGraphResponse - (*RebuildVSchemaGraphRequest)(nil), // 141: vtctldata.RebuildVSchemaGraphRequest - (*RebuildVSchemaGraphResponse)(nil), // 142: vtctldata.RebuildVSchemaGraphResponse - (*RefreshStateRequest)(nil), // 143: vtctldata.RefreshStateRequest - (*RefreshStateResponse)(nil), // 144: vtctldata.RefreshStateResponse - (*RefreshStateByShardRequest)(nil), // 145: vtctldata.RefreshStateByShardRequest - (*RefreshStateByShardResponse)(nil), // 146: vtctldata.RefreshStateByShardResponse - (*ReloadSchemaRequest)(nil), // 147: vtctldata.ReloadSchemaRequest - (*ReloadSchemaResponse)(nil), // 148: vtctldata.ReloadSchemaResponse - (*ReloadSchemaKeyspaceRequest)(nil), // 149: vtctldata.ReloadSchemaKeyspaceRequest - (*ReloadSchemaKeyspaceResponse)(nil), // 150: vtctldata.ReloadSchemaKeyspaceResponse - (*ReloadSchemaShardRequest)(nil), // 151: vtctldata.ReloadSchemaShardRequest - (*ReloadSchemaShardResponse)(nil), // 152: vtctldata.ReloadSchemaShardResponse - (*RemoveBackupRequest)(nil), // 153: vtctldata.RemoveBackupRequest - (*RemoveBackupResponse)(nil), // 154: vtctldata.RemoveBackupResponse - (*RemoveKeyspaceCellRequest)(nil), // 155: vtctldata.RemoveKeyspaceCellRequest - (*RemoveKeyspaceCellResponse)(nil), // 156: vtctldata.RemoveKeyspaceCellResponse - (*RemoveShardCellRequest)(nil), // 157: vtctldata.RemoveShardCellRequest - (*RemoveShardCellResponse)(nil), // 158: vtctldata.RemoveShardCellResponse - (*ReparentTabletRequest)(nil), // 159: vtctldata.ReparentTabletRequest - (*ReparentTabletResponse)(nil), // 160: vtctldata.ReparentTabletResponse - (*ReshardCreateRequest)(nil), // 161: vtctldata.ReshardCreateRequest - (*RestoreFromBackupRequest)(nil), // 162: vtctldata.RestoreFromBackupRequest - (*RestoreFromBackupResponse)(nil), // 163: vtctldata.RestoreFromBackupResponse - (*RetrySchemaMigrationRequest)(nil), // 164: vtctldata.RetrySchemaMigrationRequest - (*RetrySchemaMigrationResponse)(nil), // 165: vtctldata.RetrySchemaMigrationResponse - (*RunHealthCheckRequest)(nil), // 166: vtctldata.RunHealthCheckRequest - (*RunHealthCheckResponse)(nil), // 167: vtctldata.RunHealthCheckResponse - (*SetKeyspaceDurabilityPolicyRequest)(nil), // 168: vtctldata.SetKeyspaceDurabilityPolicyRequest - (*SetKeyspaceDurabilityPolicyResponse)(nil), // 169: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*SetKeyspaceShardingInfoRequest)(nil), // 170: vtctldata.SetKeyspaceShardingInfoRequest - (*SetKeyspaceShardingInfoResponse)(nil), // 171: vtctldata.SetKeyspaceShardingInfoResponse - (*SetShardIsPrimaryServingRequest)(nil), // 172: vtctldata.SetShardIsPrimaryServingRequest - (*SetShardIsPrimaryServingResponse)(nil), // 173: vtctldata.SetShardIsPrimaryServingResponse - (*SetShardTabletControlRequest)(nil), // 174: vtctldata.SetShardTabletControlRequest - (*SetShardTabletControlResponse)(nil), // 175: vtctldata.SetShardTabletControlResponse - (*SetWritableRequest)(nil), // 176: vtctldata.SetWritableRequest - (*SetWritableResponse)(nil), // 177: vtctldata.SetWritableResponse - (*ShardReplicationAddRequest)(nil), // 178: vtctldata.ShardReplicationAddRequest - (*ShardReplicationAddResponse)(nil), // 179: vtctldata.ShardReplicationAddResponse - (*ShardReplicationFixRequest)(nil), // 180: vtctldata.ShardReplicationFixRequest - (*ShardReplicationFixResponse)(nil), // 181: vtctldata.ShardReplicationFixResponse - (*ShardReplicationPositionsRequest)(nil), // 182: vtctldata.ShardReplicationPositionsRequest - (*ShardReplicationPositionsResponse)(nil), // 183: vtctldata.ShardReplicationPositionsResponse - (*ShardReplicationRemoveRequest)(nil), // 184: vtctldata.ShardReplicationRemoveRequest - (*ShardReplicationRemoveResponse)(nil), // 185: vtctldata.ShardReplicationRemoveResponse - (*SleepTabletRequest)(nil), // 186: vtctldata.SleepTabletRequest - (*SleepTabletResponse)(nil), // 187: vtctldata.SleepTabletResponse - (*SourceShardAddRequest)(nil), // 188: vtctldata.SourceShardAddRequest - (*SourceShardAddResponse)(nil), // 189: vtctldata.SourceShardAddResponse - (*SourceShardDeleteRequest)(nil), // 190: vtctldata.SourceShardDeleteRequest - (*SourceShardDeleteResponse)(nil), // 191: vtctldata.SourceShardDeleteResponse - (*StartReplicationRequest)(nil), // 192: vtctldata.StartReplicationRequest - (*StartReplicationResponse)(nil), // 193: vtctldata.StartReplicationResponse - (*StopReplicationRequest)(nil), // 194: vtctldata.StopReplicationRequest - (*StopReplicationResponse)(nil), // 195: vtctldata.StopReplicationResponse - (*TabletExternallyReparentedRequest)(nil), // 196: vtctldata.TabletExternallyReparentedRequest - (*TabletExternallyReparentedResponse)(nil), // 197: vtctldata.TabletExternallyReparentedResponse - (*UpdateCellInfoRequest)(nil), // 198: vtctldata.UpdateCellInfoRequest - (*UpdateCellInfoResponse)(nil), // 199: vtctldata.UpdateCellInfoResponse - (*UpdateCellsAliasRequest)(nil), // 200: vtctldata.UpdateCellsAliasRequest - (*UpdateCellsAliasResponse)(nil), // 201: vtctldata.UpdateCellsAliasResponse - (*ValidateRequest)(nil), // 202: vtctldata.ValidateRequest - (*ValidateResponse)(nil), // 203: vtctldata.ValidateResponse - (*ValidateKeyspaceRequest)(nil), // 204: vtctldata.ValidateKeyspaceRequest - (*ValidateKeyspaceResponse)(nil), // 205: vtctldata.ValidateKeyspaceResponse - (*ValidateSchemaKeyspaceRequest)(nil), // 206: vtctldata.ValidateSchemaKeyspaceRequest - (*ValidateSchemaKeyspaceResponse)(nil), // 207: vtctldata.ValidateSchemaKeyspaceResponse - (*ValidateShardRequest)(nil), // 208: vtctldata.ValidateShardRequest - (*ValidateShardResponse)(nil), // 209: vtctldata.ValidateShardResponse - (*ValidateVersionKeyspaceRequest)(nil), // 210: vtctldata.ValidateVersionKeyspaceRequest - (*ValidateVersionKeyspaceResponse)(nil), // 211: vtctldata.ValidateVersionKeyspaceResponse - (*ValidateVersionShardRequest)(nil), // 212: vtctldata.ValidateVersionShardRequest - (*ValidateVersionShardResponse)(nil), // 213: vtctldata.ValidateVersionShardResponse - (*ValidateVSchemaRequest)(nil), // 214: vtctldata.ValidateVSchemaRequest - (*ValidateVSchemaResponse)(nil), // 215: vtctldata.ValidateVSchemaResponse - (*VDiffCreateRequest)(nil), // 216: vtctldata.VDiffCreateRequest - (*VDiffCreateResponse)(nil), // 217: vtctldata.VDiffCreateResponse - (*VDiffDeleteRequest)(nil), // 218: vtctldata.VDiffDeleteRequest - (*VDiffDeleteResponse)(nil), // 219: vtctldata.VDiffDeleteResponse - (*VDiffResumeRequest)(nil), // 220: vtctldata.VDiffResumeRequest - (*VDiffResumeResponse)(nil), // 221: vtctldata.VDiffResumeResponse - (*VDiffShowRequest)(nil), // 222: vtctldata.VDiffShowRequest - (*VDiffShowResponse)(nil), // 223: vtctldata.VDiffShowResponse - (*VDiffStopRequest)(nil), // 224: vtctldata.VDiffStopRequest - (*VDiffStopResponse)(nil), // 225: vtctldata.VDiffStopResponse - (*WorkflowDeleteRequest)(nil), // 226: vtctldata.WorkflowDeleteRequest - (*WorkflowDeleteResponse)(nil), // 227: vtctldata.WorkflowDeleteResponse - (*WorkflowStatusRequest)(nil), // 228: vtctldata.WorkflowStatusRequest - (*WorkflowStatusResponse)(nil), // 229: vtctldata.WorkflowStatusResponse - (*WorkflowSwitchTrafficRequest)(nil), // 230: vtctldata.WorkflowSwitchTrafficRequest - (*WorkflowSwitchTrafficResponse)(nil), // 231: vtctldata.WorkflowSwitchTrafficResponse - (*WorkflowUpdateRequest)(nil), // 232: vtctldata.WorkflowUpdateRequest - (*WorkflowUpdateResponse)(nil), // 233: vtctldata.WorkflowUpdateResponse - nil, // 234: vtctldata.Workflow.ShardStreamsEntry - (*Workflow_ReplicationLocation)(nil), // 235: vtctldata.Workflow.ReplicationLocation - (*Workflow_ShardStream)(nil), // 236: vtctldata.Workflow.ShardStream - (*Workflow_Stream)(nil), // 237: vtctldata.Workflow.Stream - (*Workflow_Stream_CopyState)(nil), // 238: vtctldata.Workflow.Stream.CopyState - (*Workflow_Stream_Log)(nil), // 239: vtctldata.Workflow.Stream.Log - (*Workflow_Stream_ThrottlerStatus)(nil), // 240: vtctldata.Workflow.Stream.ThrottlerStatus - nil, // 241: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - nil, // 242: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 243: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 244: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 245: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 246: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 247: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 248: vtctldata.GetSrvKeyspaceNamesResponse.NameList - nil, // 249: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 250: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 251: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - (*MoveTablesCreateResponse_TabletInfo)(nil), // 252: vtctldata.MoveTablesCreateResponse.TabletInfo - nil, // 253: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 254: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 255: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - nil, // 256: vtctldata.ValidateResponse.ResultsByKeyspaceEntry - nil, // 257: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - nil, // 258: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - nil, // 259: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - nil, // 260: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - nil, // 261: vtctldata.VDiffShowResponse.TabletResponsesEntry - (*WorkflowDeleteResponse_TabletInfo)(nil), // 262: vtctldata.WorkflowDeleteResponse.TabletInfo - (*WorkflowStatusResponse_TableCopyState)(nil), // 263: vtctldata.WorkflowStatusResponse.TableCopyState - (*WorkflowStatusResponse_ShardStreamState)(nil), // 264: vtctldata.WorkflowStatusResponse.ShardStreamState - (*WorkflowStatusResponse_ShardStreams)(nil), // 265: vtctldata.WorkflowStatusResponse.ShardStreams - nil, // 266: vtctldata.WorkflowStatusResponse.TableCopyStateEntry - nil, // 267: vtctldata.WorkflowStatusResponse.ShardStreamsEntry - (*WorkflowUpdateResponse_TabletInfo)(nil), // 268: vtctldata.WorkflowUpdateResponse.TabletInfo - (*logutil.Event)(nil), // 269: logutil.Event - (tabletmanagerdata.TabletSelectionPreference)(0), // 270: tabletmanagerdata.TabletSelectionPreference - (*topodata.Keyspace)(nil), // 271: topodata.Keyspace - (*vttime.Time)(nil), // 272: vttime.Time - (*topodata.TabletAlias)(nil), // 273: topodata.TabletAlias - (*vttime.Duration)(nil), // 274: vttime.Duration - (*topodata.Shard)(nil), // 275: topodata.Shard - (*topodata.CellInfo)(nil), // 276: topodata.CellInfo - (*vschema.RoutingRules)(nil), // 277: vschema.RoutingRules - (*vschema.ShardRoutingRules)(nil), // 278: vschema.ShardRoutingRules - (*vtrpc.CallerID)(nil), // 279: vtrpc.CallerID - (*vschema.Keyspace)(nil), // 280: vschema.Keyspace - (topodata.TabletType)(0), // 281: topodata.TabletType - (*topodata.Tablet)(nil), // 282: topodata.Tablet - (topodata.KeyspaceType)(0), // 283: topodata.KeyspaceType - (*query.QueryResult)(nil), // 284: query.QueryResult - (*tabletmanagerdata.ExecuteHookRequest)(nil), // 285: tabletmanagerdata.ExecuteHookRequest - (*tabletmanagerdata.ExecuteHookResponse)(nil), // 286: tabletmanagerdata.ExecuteHookResponse - (*mysqlctl.BackupInfo)(nil), // 287: mysqlctl.BackupInfo - (*replicationdata.FullStatus)(nil), // 288: replicationdata.FullStatus - (*tabletmanagerdata.Permissions)(nil), // 289: tabletmanagerdata.Permissions - (*tabletmanagerdata.SchemaDefinition)(nil), // 290: tabletmanagerdata.SchemaDefinition - (*topodata.ThrottledAppRule)(nil), // 291: topodata.ThrottledAppRule - (*vschema.SrvVSchema)(nil), // 292: vschema.SrvVSchema - (*topodata.ShardReplicationError)(nil), // 293: topodata.ShardReplicationError - (*topodata.KeyRange)(nil), // 294: topodata.KeyRange - (*topodata.CellsAlias)(nil), // 295: topodata.CellsAlias - (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 296: tabletmanagerdata.UpdateVReplicationWorkflowRequest - (*topodata.Shard_TabletControl)(nil), // 297: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 298: binlogdata.BinlogSource - (*topodata.SrvKeyspace)(nil), // 299: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 300: replicationdata.Status - (*tabletmanagerdata.VDiffResponse)(nil), // 301: tabletmanagerdata.VDiffResponse + (*ForceCutOverSchemaMigrationRequest)(nil), // 61: vtctldata.ForceCutOverSchemaMigrationRequest + (*ForceCutOverSchemaMigrationResponse)(nil), // 62: vtctldata.ForceCutOverSchemaMigrationResponse + (*GetBackupsRequest)(nil), // 63: vtctldata.GetBackupsRequest + (*GetBackupsResponse)(nil), // 64: vtctldata.GetBackupsResponse + (*GetCellInfoRequest)(nil), // 65: vtctldata.GetCellInfoRequest + (*GetCellInfoResponse)(nil), // 66: vtctldata.GetCellInfoResponse + (*GetCellInfoNamesRequest)(nil), // 67: vtctldata.GetCellInfoNamesRequest + (*GetCellInfoNamesResponse)(nil), // 68: vtctldata.GetCellInfoNamesResponse + (*GetCellsAliasesRequest)(nil), // 69: vtctldata.GetCellsAliasesRequest + (*GetCellsAliasesResponse)(nil), // 70: vtctldata.GetCellsAliasesResponse + (*GetFullStatusRequest)(nil), // 71: vtctldata.GetFullStatusRequest + (*GetFullStatusResponse)(nil), // 72: vtctldata.GetFullStatusResponse + (*GetKeyspacesRequest)(nil), // 73: vtctldata.GetKeyspacesRequest + (*GetKeyspacesResponse)(nil), // 74: vtctldata.GetKeyspacesResponse + (*GetKeyspaceRequest)(nil), // 75: vtctldata.GetKeyspaceRequest + (*GetKeyspaceResponse)(nil), // 76: vtctldata.GetKeyspaceResponse + (*GetPermissionsRequest)(nil), // 77: vtctldata.GetPermissionsRequest + (*GetPermissionsResponse)(nil), // 78: vtctldata.GetPermissionsResponse + (*GetRoutingRulesRequest)(nil), // 79: vtctldata.GetRoutingRulesRequest + (*GetRoutingRulesResponse)(nil), // 80: vtctldata.GetRoutingRulesResponse + (*GetSchemaRequest)(nil), // 81: vtctldata.GetSchemaRequest + (*GetSchemaResponse)(nil), // 82: vtctldata.GetSchemaResponse + (*GetSchemaMigrationsRequest)(nil), // 83: vtctldata.GetSchemaMigrationsRequest + (*GetSchemaMigrationsResponse)(nil), // 84: vtctldata.GetSchemaMigrationsResponse + (*GetShardRequest)(nil), // 85: vtctldata.GetShardRequest + (*GetShardResponse)(nil), // 86: vtctldata.GetShardResponse + (*GetShardRoutingRulesRequest)(nil), // 87: vtctldata.GetShardRoutingRulesRequest + (*GetShardRoutingRulesResponse)(nil), // 88: vtctldata.GetShardRoutingRulesResponse + (*GetSrvKeyspaceNamesRequest)(nil), // 89: vtctldata.GetSrvKeyspaceNamesRequest + (*GetSrvKeyspaceNamesResponse)(nil), // 90: vtctldata.GetSrvKeyspaceNamesResponse + (*GetSrvKeyspacesRequest)(nil), // 91: vtctldata.GetSrvKeyspacesRequest + (*GetSrvKeyspacesResponse)(nil), // 92: vtctldata.GetSrvKeyspacesResponse + (*UpdateThrottlerConfigRequest)(nil), // 93: vtctldata.UpdateThrottlerConfigRequest + (*UpdateThrottlerConfigResponse)(nil), // 94: vtctldata.UpdateThrottlerConfigResponse + (*GetSrvVSchemaRequest)(nil), // 95: vtctldata.GetSrvVSchemaRequest + (*GetSrvVSchemaResponse)(nil), // 96: vtctldata.GetSrvVSchemaResponse + (*GetSrvVSchemasRequest)(nil), // 97: vtctldata.GetSrvVSchemasRequest + (*GetSrvVSchemasResponse)(nil), // 98: vtctldata.GetSrvVSchemasResponse + (*GetTabletRequest)(nil), // 99: vtctldata.GetTabletRequest + (*GetTabletResponse)(nil), // 100: vtctldata.GetTabletResponse + (*GetTabletsRequest)(nil), // 101: vtctldata.GetTabletsRequest + (*GetTabletsResponse)(nil), // 102: vtctldata.GetTabletsResponse + (*GetTopologyPathRequest)(nil), // 103: vtctldata.GetTopologyPathRequest + (*GetTopologyPathResponse)(nil), // 104: vtctldata.GetTopologyPathResponse + (*TopologyCell)(nil), // 105: vtctldata.TopologyCell + (*GetVSchemaRequest)(nil), // 106: vtctldata.GetVSchemaRequest + (*GetVersionRequest)(nil), // 107: vtctldata.GetVersionRequest + (*GetVersionResponse)(nil), // 108: vtctldata.GetVersionResponse + (*GetVSchemaResponse)(nil), // 109: vtctldata.GetVSchemaResponse + (*GetWorkflowsRequest)(nil), // 110: vtctldata.GetWorkflowsRequest + (*GetWorkflowsResponse)(nil), // 111: vtctldata.GetWorkflowsResponse + (*InitShardPrimaryRequest)(nil), // 112: vtctldata.InitShardPrimaryRequest + (*InitShardPrimaryResponse)(nil), // 113: vtctldata.InitShardPrimaryResponse + (*LaunchSchemaMigrationRequest)(nil), // 114: vtctldata.LaunchSchemaMigrationRequest + (*LaunchSchemaMigrationResponse)(nil), // 115: vtctldata.LaunchSchemaMigrationResponse + (*LookupVindexCreateRequest)(nil), // 116: vtctldata.LookupVindexCreateRequest + (*LookupVindexCreateResponse)(nil), // 117: vtctldata.LookupVindexCreateResponse + (*LookupVindexExternalizeRequest)(nil), // 118: vtctldata.LookupVindexExternalizeRequest + (*LookupVindexExternalizeResponse)(nil), // 119: vtctldata.LookupVindexExternalizeResponse + (*MaterializeCreateRequest)(nil), // 120: vtctldata.MaterializeCreateRequest + (*MaterializeCreateResponse)(nil), // 121: vtctldata.MaterializeCreateResponse + (*MigrateCreateRequest)(nil), // 122: vtctldata.MigrateCreateRequest + (*MigrateCompleteRequest)(nil), // 123: vtctldata.MigrateCompleteRequest + (*MigrateCompleteResponse)(nil), // 124: vtctldata.MigrateCompleteResponse + (*MountRegisterRequest)(nil), // 125: vtctldata.MountRegisterRequest + (*MountRegisterResponse)(nil), // 126: vtctldata.MountRegisterResponse + (*MountUnregisterRequest)(nil), // 127: vtctldata.MountUnregisterRequest + (*MountUnregisterResponse)(nil), // 128: vtctldata.MountUnregisterResponse + (*MountShowRequest)(nil), // 129: vtctldata.MountShowRequest + (*MountShowResponse)(nil), // 130: vtctldata.MountShowResponse + (*MountListRequest)(nil), // 131: vtctldata.MountListRequest + (*MountListResponse)(nil), // 132: vtctldata.MountListResponse + (*MoveTablesCreateRequest)(nil), // 133: vtctldata.MoveTablesCreateRequest + (*MoveTablesCreateResponse)(nil), // 134: vtctldata.MoveTablesCreateResponse + (*MoveTablesCompleteRequest)(nil), // 135: vtctldata.MoveTablesCompleteRequest + (*MoveTablesCompleteResponse)(nil), // 136: vtctldata.MoveTablesCompleteResponse + (*PingTabletRequest)(nil), // 137: vtctldata.PingTabletRequest + (*PingTabletResponse)(nil), // 138: vtctldata.PingTabletResponse + (*PlannedReparentShardRequest)(nil), // 139: vtctldata.PlannedReparentShardRequest + (*PlannedReparentShardResponse)(nil), // 140: vtctldata.PlannedReparentShardResponse + (*RebuildKeyspaceGraphRequest)(nil), // 141: vtctldata.RebuildKeyspaceGraphRequest + (*RebuildKeyspaceGraphResponse)(nil), // 142: vtctldata.RebuildKeyspaceGraphResponse + (*RebuildVSchemaGraphRequest)(nil), // 143: vtctldata.RebuildVSchemaGraphRequest + (*RebuildVSchemaGraphResponse)(nil), // 144: vtctldata.RebuildVSchemaGraphResponse + (*RefreshStateRequest)(nil), // 145: vtctldata.RefreshStateRequest + (*RefreshStateResponse)(nil), // 146: vtctldata.RefreshStateResponse + (*RefreshStateByShardRequest)(nil), // 147: vtctldata.RefreshStateByShardRequest + (*RefreshStateByShardResponse)(nil), // 148: vtctldata.RefreshStateByShardResponse + (*ReloadSchemaRequest)(nil), // 149: vtctldata.ReloadSchemaRequest + (*ReloadSchemaResponse)(nil), // 150: vtctldata.ReloadSchemaResponse + (*ReloadSchemaKeyspaceRequest)(nil), // 151: vtctldata.ReloadSchemaKeyspaceRequest + (*ReloadSchemaKeyspaceResponse)(nil), // 152: vtctldata.ReloadSchemaKeyspaceResponse + (*ReloadSchemaShardRequest)(nil), // 153: vtctldata.ReloadSchemaShardRequest + (*ReloadSchemaShardResponse)(nil), // 154: vtctldata.ReloadSchemaShardResponse + (*RemoveBackupRequest)(nil), // 155: vtctldata.RemoveBackupRequest + (*RemoveBackupResponse)(nil), // 156: vtctldata.RemoveBackupResponse + (*RemoveKeyspaceCellRequest)(nil), // 157: vtctldata.RemoveKeyspaceCellRequest + (*RemoveKeyspaceCellResponse)(nil), // 158: vtctldata.RemoveKeyspaceCellResponse + (*RemoveShardCellRequest)(nil), // 159: vtctldata.RemoveShardCellRequest + (*RemoveShardCellResponse)(nil), // 160: vtctldata.RemoveShardCellResponse + (*ReparentTabletRequest)(nil), // 161: vtctldata.ReparentTabletRequest + (*ReparentTabletResponse)(nil), // 162: vtctldata.ReparentTabletResponse + (*ReshardCreateRequest)(nil), // 163: vtctldata.ReshardCreateRequest + (*RestoreFromBackupRequest)(nil), // 164: vtctldata.RestoreFromBackupRequest + (*RestoreFromBackupResponse)(nil), // 165: vtctldata.RestoreFromBackupResponse + (*RetrySchemaMigrationRequest)(nil), // 166: vtctldata.RetrySchemaMigrationRequest + (*RetrySchemaMigrationResponse)(nil), // 167: vtctldata.RetrySchemaMigrationResponse + (*RunHealthCheckRequest)(nil), // 168: vtctldata.RunHealthCheckRequest + (*RunHealthCheckResponse)(nil), // 169: vtctldata.RunHealthCheckResponse + (*SetKeyspaceDurabilityPolicyRequest)(nil), // 170: vtctldata.SetKeyspaceDurabilityPolicyRequest + (*SetKeyspaceDurabilityPolicyResponse)(nil), // 171: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*SetKeyspaceShardingInfoRequest)(nil), // 172: vtctldata.SetKeyspaceShardingInfoRequest + (*SetKeyspaceShardingInfoResponse)(nil), // 173: vtctldata.SetKeyspaceShardingInfoResponse + (*SetShardIsPrimaryServingRequest)(nil), // 174: vtctldata.SetShardIsPrimaryServingRequest + (*SetShardIsPrimaryServingResponse)(nil), // 175: vtctldata.SetShardIsPrimaryServingResponse + (*SetShardTabletControlRequest)(nil), // 176: vtctldata.SetShardTabletControlRequest + (*SetShardTabletControlResponse)(nil), // 177: vtctldata.SetShardTabletControlResponse + (*SetWritableRequest)(nil), // 178: vtctldata.SetWritableRequest + (*SetWritableResponse)(nil), // 179: vtctldata.SetWritableResponse + (*ShardReplicationAddRequest)(nil), // 180: vtctldata.ShardReplicationAddRequest + (*ShardReplicationAddResponse)(nil), // 181: vtctldata.ShardReplicationAddResponse + (*ShardReplicationFixRequest)(nil), // 182: vtctldata.ShardReplicationFixRequest + (*ShardReplicationFixResponse)(nil), // 183: vtctldata.ShardReplicationFixResponse + (*ShardReplicationPositionsRequest)(nil), // 184: vtctldata.ShardReplicationPositionsRequest + (*ShardReplicationPositionsResponse)(nil), // 185: vtctldata.ShardReplicationPositionsResponse + (*ShardReplicationRemoveRequest)(nil), // 186: vtctldata.ShardReplicationRemoveRequest + (*ShardReplicationRemoveResponse)(nil), // 187: vtctldata.ShardReplicationRemoveResponse + (*SleepTabletRequest)(nil), // 188: vtctldata.SleepTabletRequest + (*SleepTabletResponse)(nil), // 189: vtctldata.SleepTabletResponse + (*SourceShardAddRequest)(nil), // 190: vtctldata.SourceShardAddRequest + (*SourceShardAddResponse)(nil), // 191: vtctldata.SourceShardAddResponse + (*SourceShardDeleteRequest)(nil), // 192: vtctldata.SourceShardDeleteRequest + (*SourceShardDeleteResponse)(nil), // 193: vtctldata.SourceShardDeleteResponse + (*StartReplicationRequest)(nil), // 194: vtctldata.StartReplicationRequest + (*StartReplicationResponse)(nil), // 195: vtctldata.StartReplicationResponse + (*StopReplicationRequest)(nil), // 196: vtctldata.StopReplicationRequest + (*StopReplicationResponse)(nil), // 197: vtctldata.StopReplicationResponse + (*TabletExternallyReparentedRequest)(nil), // 198: vtctldata.TabletExternallyReparentedRequest + (*TabletExternallyReparentedResponse)(nil), // 199: vtctldata.TabletExternallyReparentedResponse + (*UpdateCellInfoRequest)(nil), // 200: vtctldata.UpdateCellInfoRequest + (*UpdateCellInfoResponse)(nil), // 201: vtctldata.UpdateCellInfoResponse + (*UpdateCellsAliasRequest)(nil), // 202: vtctldata.UpdateCellsAliasRequest + (*UpdateCellsAliasResponse)(nil), // 203: vtctldata.UpdateCellsAliasResponse + (*ValidateRequest)(nil), // 204: vtctldata.ValidateRequest + (*ValidateResponse)(nil), // 205: vtctldata.ValidateResponse + (*ValidateKeyspaceRequest)(nil), // 206: vtctldata.ValidateKeyspaceRequest + (*ValidateKeyspaceResponse)(nil), // 207: vtctldata.ValidateKeyspaceResponse + (*ValidateSchemaKeyspaceRequest)(nil), // 208: vtctldata.ValidateSchemaKeyspaceRequest + (*ValidateSchemaKeyspaceResponse)(nil), // 209: vtctldata.ValidateSchemaKeyspaceResponse + (*ValidateShardRequest)(nil), // 210: vtctldata.ValidateShardRequest + (*ValidateShardResponse)(nil), // 211: vtctldata.ValidateShardResponse + (*ValidateVersionKeyspaceRequest)(nil), // 212: vtctldata.ValidateVersionKeyspaceRequest + (*ValidateVersionKeyspaceResponse)(nil), // 213: vtctldata.ValidateVersionKeyspaceResponse + (*ValidateVersionShardRequest)(nil), // 214: vtctldata.ValidateVersionShardRequest + (*ValidateVersionShardResponse)(nil), // 215: vtctldata.ValidateVersionShardResponse + (*ValidateVSchemaRequest)(nil), // 216: vtctldata.ValidateVSchemaRequest + (*ValidateVSchemaResponse)(nil), // 217: vtctldata.ValidateVSchemaResponse + (*VDiffCreateRequest)(nil), // 218: vtctldata.VDiffCreateRequest + (*VDiffCreateResponse)(nil), // 219: vtctldata.VDiffCreateResponse + (*VDiffDeleteRequest)(nil), // 220: vtctldata.VDiffDeleteRequest + (*VDiffDeleteResponse)(nil), // 221: vtctldata.VDiffDeleteResponse + (*VDiffResumeRequest)(nil), // 222: vtctldata.VDiffResumeRequest + (*VDiffResumeResponse)(nil), // 223: vtctldata.VDiffResumeResponse + (*VDiffShowRequest)(nil), // 224: vtctldata.VDiffShowRequest + (*VDiffShowResponse)(nil), // 225: vtctldata.VDiffShowResponse + (*VDiffStopRequest)(nil), // 226: vtctldata.VDiffStopRequest + (*VDiffStopResponse)(nil), // 227: vtctldata.VDiffStopResponse + (*WorkflowDeleteRequest)(nil), // 228: vtctldata.WorkflowDeleteRequest + (*WorkflowDeleteResponse)(nil), // 229: vtctldata.WorkflowDeleteResponse + (*WorkflowStatusRequest)(nil), // 230: vtctldata.WorkflowStatusRequest + (*WorkflowStatusResponse)(nil), // 231: vtctldata.WorkflowStatusResponse + (*WorkflowSwitchTrafficRequest)(nil), // 232: vtctldata.WorkflowSwitchTrafficRequest + (*WorkflowSwitchTrafficResponse)(nil), // 233: vtctldata.WorkflowSwitchTrafficResponse + (*WorkflowUpdateRequest)(nil), // 234: vtctldata.WorkflowUpdateRequest + (*WorkflowUpdateResponse)(nil), // 235: vtctldata.WorkflowUpdateResponse + nil, // 236: vtctldata.Workflow.ShardStreamsEntry + (*Workflow_ReplicationLocation)(nil), // 237: vtctldata.Workflow.ReplicationLocation + (*Workflow_ShardStream)(nil), // 238: vtctldata.Workflow.ShardStream + (*Workflow_Stream)(nil), // 239: vtctldata.Workflow.Stream + (*Workflow_Stream_CopyState)(nil), // 240: vtctldata.Workflow.Stream.CopyState + (*Workflow_Stream_Log)(nil), // 241: vtctldata.Workflow.Stream.Log + (*Workflow_Stream_ThrottlerStatus)(nil), // 242: vtctldata.Workflow.Stream.ThrottlerStatus + nil, // 243: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + nil, // 244: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 245: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 246: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 247: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 248: vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 249: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 250: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 251: vtctldata.GetSrvKeyspaceNamesResponse.NameList + nil, // 252: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 253: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 254: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + (*MoveTablesCreateResponse_TabletInfo)(nil), // 255: vtctldata.MoveTablesCreateResponse.TabletInfo + nil, // 256: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 257: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 258: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + nil, // 259: vtctldata.ValidateResponse.ResultsByKeyspaceEntry + nil, // 260: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + nil, // 261: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + nil, // 262: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + nil, // 263: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + nil, // 264: vtctldata.VDiffShowResponse.TabletResponsesEntry + (*WorkflowDeleteResponse_TabletInfo)(nil), // 265: vtctldata.WorkflowDeleteResponse.TabletInfo + (*WorkflowStatusResponse_TableCopyState)(nil), // 266: vtctldata.WorkflowStatusResponse.TableCopyState + (*WorkflowStatusResponse_ShardStreamState)(nil), // 267: vtctldata.WorkflowStatusResponse.ShardStreamState + (*WorkflowStatusResponse_ShardStreams)(nil), // 268: vtctldata.WorkflowStatusResponse.ShardStreams + nil, // 269: vtctldata.WorkflowStatusResponse.TableCopyStateEntry + nil, // 270: vtctldata.WorkflowStatusResponse.ShardStreamsEntry + (*WorkflowUpdateResponse_TabletInfo)(nil), // 271: vtctldata.WorkflowUpdateResponse.TabletInfo + (*logutil.Event)(nil), // 272: logutil.Event + (tabletmanagerdata.TabletSelectionPreference)(0), // 273: tabletmanagerdata.TabletSelectionPreference + (*topodata.Keyspace)(nil), // 274: topodata.Keyspace + (*vttime.Time)(nil), // 275: vttime.Time + (*topodata.TabletAlias)(nil), // 276: topodata.TabletAlias + (*vttime.Duration)(nil), // 277: vttime.Duration + (*topodata.Shard)(nil), // 278: topodata.Shard + (*topodata.CellInfo)(nil), // 279: topodata.CellInfo + (*vschema.RoutingRules)(nil), // 280: vschema.RoutingRules + (*vschema.ShardRoutingRules)(nil), // 281: vschema.ShardRoutingRules + (*vtrpc.CallerID)(nil), // 282: vtrpc.CallerID + (*vschema.Keyspace)(nil), // 283: vschema.Keyspace + (topodata.TabletType)(0), // 284: topodata.TabletType + (*topodata.Tablet)(nil), // 285: topodata.Tablet + (topodata.KeyspaceType)(0), // 286: topodata.KeyspaceType + (*query.QueryResult)(nil), // 287: query.QueryResult + (*tabletmanagerdata.ExecuteHookRequest)(nil), // 288: tabletmanagerdata.ExecuteHookRequest + (*tabletmanagerdata.ExecuteHookResponse)(nil), // 289: tabletmanagerdata.ExecuteHookResponse + (*mysqlctl.BackupInfo)(nil), // 290: mysqlctl.BackupInfo + (*replicationdata.FullStatus)(nil), // 291: replicationdata.FullStatus + (*tabletmanagerdata.Permissions)(nil), // 292: tabletmanagerdata.Permissions + (*tabletmanagerdata.SchemaDefinition)(nil), // 293: tabletmanagerdata.SchemaDefinition + (*topodata.ThrottledAppRule)(nil), // 294: topodata.ThrottledAppRule + (*vschema.SrvVSchema)(nil), // 295: vschema.SrvVSchema + (*topodata.ShardReplicationError)(nil), // 296: topodata.ShardReplicationError + (*topodata.KeyRange)(nil), // 297: topodata.KeyRange + (*topodata.CellsAlias)(nil), // 298: topodata.CellsAlias + (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 299: tabletmanagerdata.UpdateVReplicationWorkflowRequest + (*topodata.Shard_TabletControl)(nil), // 300: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 301: binlogdata.BinlogSource + (*topodata.SrvKeyspace)(nil), // 302: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 303: replicationdata.Status + (*tabletmanagerdata.VDiffResponse)(nil), // 304: tabletmanagerdata.VDiffResponse } var file_vtctldata_proto_depIdxs = []int32{ - 269, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 272, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 6, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings 0, // 2: vtctldata.MaterializeSettings.materialization_intent:type_name -> vtctldata.MaterializationIntent - 270, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 271, // 4: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 273, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 274, // 4: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace 2, // 5: vtctldata.SchemaMigration.strategy:type_name -> vtctldata.SchemaMigration.Strategy - 272, // 6: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time - 272, // 7: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time - 272, // 8: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time - 272, // 9: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time - 272, // 10: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time - 272, // 11: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time - 272, // 12: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time + 275, // 6: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time + 275, // 7: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time + 275, // 8: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time + 275, // 9: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time + 275, // 10: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time + 275, // 11: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time + 275, // 12: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time 3, // 13: vtctldata.SchemaMigration.status:type_name -> vtctldata.SchemaMigration.Status - 273, // 14: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias - 274, // 15: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration - 272, // 16: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time - 272, // 17: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time - 272, // 18: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time - 272, // 19: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time - 275, // 20: vtctldata.Shard.shard:type_name -> topodata.Shard - 235, // 21: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 235, // 22: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 234, // 23: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry - 276, // 24: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 277, // 25: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 278, // 26: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 274, // 27: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration - 279, // 28: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID - 241, // 29: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - 280, // 30: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 280, // 31: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 273, // 32: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 33: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 269, // 34: vtctldata.BackupResponse.event:type_name -> logutil.Event - 242, // 35: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - 273, // 36: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 281, // 37: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 282, // 38: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 282, // 39: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 243, // 40: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - 244, // 41: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - 283, // 42: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 272, // 43: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 276, // 14: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias + 277, // 15: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration + 275, // 16: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time + 275, // 17: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time + 275, // 18: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time + 275, // 19: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time + 278, // 20: vtctldata.Shard.shard:type_name -> topodata.Shard + 237, // 21: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 237, // 22: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 236, // 23: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 279, // 24: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 280, // 25: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 281, // 26: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 277, // 27: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration + 282, // 28: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID + 243, // 29: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + 283, // 30: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 283, // 31: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 276, // 32: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 33: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 272, // 34: vtctldata.BackupResponse.event:type_name -> logutil.Event + 244, // 35: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + 276, // 36: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 284, // 37: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 285, // 38: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 285, // 39: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 245, // 40: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + 246, // 41: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + 286, // 42: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 275, // 43: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time 8, // 44: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace 8, // 45: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace 10, // 46: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard 10, // 47: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 273, // 48: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 273, // 49: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 273, // 50: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 274, // 51: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 273, // 52: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 269, // 53: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 273, // 54: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias - 284, // 55: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 273, // 56: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 284, // 57: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult - 273, // 58: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias - 285, // 59: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest - 286, // 60: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse - 245, // 61: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 287, // 62: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 276, // 63: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 246, // 64: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry - 273, // 65: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 66: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus - 8, // 67: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace - 8, // 68: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 273, // 69: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias - 289, // 70: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 277, // 71: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 273, // 72: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 290, // 73: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition - 3, // 74: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status - 274, // 75: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration - 1, // 76: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering - 9, // 77: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration - 10, // 78: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 278, // 79: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 247, // 80: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - 249, // 81: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 291, // 82: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule - 292, // 83: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 250, // 84: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 273, // 85: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 282, // 86: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 273, // 87: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 281, // 88: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType - 282, // 89: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 103, // 90: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell - 273, // 91: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias - 280, // 92: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 11, // 93: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 273, // 94: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 274, // 95: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 269, // 96: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 251, // 97: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - 280, // 98: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace - 281, // 99: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType - 270, // 100: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 7, // 101: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings - 281, // 102: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType - 270, // 103: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 281, // 104: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType - 270, // 105: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 252, // 106: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo - 273, // 107: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 108: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 273, // 109: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 274, // 110: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 274, // 111: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration - 273, // 112: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 269, // 113: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 273, // 114: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 115: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 269, // 116: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 269, // 117: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 273, // 118: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 273, // 119: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 281, // 120: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 270, // 121: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 273, // 122: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 272, // 123: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 272, // 124: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 273, // 125: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 269, // 126: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 253, // 127: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 273, // 128: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 271, // 129: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 271, // 130: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 275, // 131: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 281, // 132: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 275, // 133: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 273, // 134: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 135: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 293, // 136: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 254, // 137: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 255, // 138: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 273, // 139: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 140: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 274, // 141: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 294, // 142: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 275, // 143: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 275, // 144: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 273, // 145: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 146: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 273, // 147: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 273, // 148: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 273, // 149: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 276, // 150: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 276, // 151: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 295, // 152: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 295, // 153: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 256, // 154: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 257, // 155: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 258, // 156: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 259, // 157: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 260, // 158: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 281, // 159: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 270, // 160: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 274, // 161: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 274, // 162: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 261, // 163: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 262, // 164: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 266, // 165: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 267, // 166: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 281, // 167: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 274, // 168: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 274, // 169: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 296, // 170: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 268, // 171: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 236, // 172: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 237, // 173: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 297, // 174: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 273, // 175: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 298, // 176: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 272, // 177: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 272, // 178: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 238, // 179: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 239, // 180: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 240, // 181: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 272, // 182: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 272, // 183: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 272, // 184: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 10, // 185: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 295, // 186: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 248, // 187: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 299, // 188: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 292, // 189: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 273, // 190: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 300, // 191: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 282, // 192: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 205, // 193: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 209, // 194: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 209, // 195: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 209, // 196: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 209, // 197: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 301, // 198: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 273, // 199: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 273, // 200: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 264, // 201: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 263, // 202: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 265, // 203: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 273, // 204: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 205, // [205:205] is the sub-list for method output_type - 205, // [205:205] is the sub-list for method input_type - 205, // [205:205] is the sub-list for extension type_name - 205, // [205:205] is the sub-list for extension extendee - 0, // [0:205] is the sub-list for field type_name + 276, // 48: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 276, // 49: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 276, // 50: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 277, // 51: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 276, // 52: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 272, // 53: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 276, // 54: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias + 287, // 55: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 276, // 56: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 287, // 57: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult + 276, // 58: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias + 288, // 59: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest + 289, // 60: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse + 247, // 61: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 248, // 62: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + 290, // 63: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 279, // 64: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 249, // 65: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 276, // 66: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 291, // 67: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus + 8, // 68: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace + 8, // 69: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace + 276, // 70: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias + 292, // 71: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions + 280, // 72: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 276, // 73: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 293, // 74: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 3, // 75: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status + 277, // 76: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration + 1, // 77: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering + 9, // 78: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration + 10, // 79: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard + 281, // 80: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 250, // 81: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + 252, // 82: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 294, // 83: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule + 295, // 84: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 253, // 85: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 276, // 86: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 285, // 87: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 276, // 88: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 284, // 89: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType + 285, // 90: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 105, // 91: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell + 276, // 92: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias + 283, // 93: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 11, // 94: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow + 276, // 95: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 277, // 96: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 272, // 97: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 254, // 98: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + 283, // 99: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace + 284, // 100: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType + 273, // 101: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 7, // 102: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings + 284, // 103: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType + 273, // 104: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 284, // 105: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType + 273, // 106: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 255, // 107: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo + 276, // 108: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 109: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 276, // 110: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 277, // 111: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 277, // 112: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 276, // 113: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 272, // 114: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 276, // 115: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 116: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 272, // 117: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 272, // 118: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 276, // 119: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 276, // 120: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 284, // 121: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 273, // 122: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 276, // 123: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 275, // 124: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 275, // 125: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 276, // 126: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 272, // 127: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 256, // 128: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 276, // 129: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 274, // 130: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 274, // 131: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 278, // 132: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 284, // 133: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 278, // 134: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 276, // 135: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 136: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 296, // 137: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 257, // 138: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 258, // 139: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 276, // 140: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 141: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 277, // 142: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 297, // 143: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 278, // 144: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 278, // 145: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 276, // 146: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 147: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 276, // 148: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 276, // 149: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 276, // 150: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 279, // 151: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 279, // 152: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 298, // 153: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 298, // 154: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 259, // 155: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 260, // 156: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 261, // 157: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 262, // 158: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 263, // 159: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 284, // 160: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 273, // 161: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 277, // 162: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 277, // 163: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 264, // 164: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 265, // 165: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 269, // 166: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 270, // 167: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 284, // 168: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 277, // 169: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 277, // 170: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 299, // 171: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 271, // 172: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 238, // 173: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 239, // 174: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 300, // 175: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 276, // 176: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 301, // 177: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 275, // 178: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 275, // 179: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 240, // 180: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 241, // 181: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 242, // 182: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 275, // 183: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 275, // 184: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 275, // 185: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 10, // 186: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 298, // 187: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 251, // 188: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 302, // 189: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 295, // 190: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 276, // 191: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 303, // 192: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 285, // 193: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 207, // 194: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 211, // 195: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 196: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 197: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 211, // 198: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 304, // 199: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 276, // 200: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 276, // 201: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 267, // 202: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 266, // 203: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 268, // 204: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 276, // 205: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 206, // [206:206] is the sub-list for method output_type + 206, // [206:206] is the sub-list for method input_type + 206, // [206:206] is the sub-list for extension type_name + 206, // [206:206] is the sub-list for extension extendee + 0, // [0:206] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -18753,7 +18879,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBackupsRequest); i { + switch v := v.(*ForceCutOverSchemaMigrationRequest); i { case 0: return &v.state case 1: @@ -18765,7 +18891,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetBackupsResponse); i { + switch v := v.(*ForceCutOverSchemaMigrationResponse); i { case 0: return &v.state case 1: @@ -18777,7 +18903,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellInfoRequest); i { + switch v := v.(*GetBackupsRequest); i { case 0: return &v.state case 1: @@ -18789,7 +18915,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellInfoResponse); i { + switch v := v.(*GetBackupsResponse); i { case 0: return &v.state case 1: @@ -18801,7 +18927,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellInfoNamesRequest); i { + switch v := v.(*GetCellInfoRequest); i { case 0: return &v.state case 1: @@ -18813,7 +18939,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellInfoNamesResponse); i { + switch v := v.(*GetCellInfoResponse); i { case 0: return &v.state case 1: @@ -18825,7 +18951,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellsAliasesRequest); i { + switch v := v.(*GetCellInfoNamesRequest); i { case 0: return &v.state case 1: @@ -18837,7 +18963,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCellsAliasesResponse); i { + switch v := v.(*GetCellInfoNamesResponse); i { case 0: return &v.state case 1: @@ -18849,7 +18975,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFullStatusRequest); i { + switch v := v.(*GetCellsAliasesRequest); i { case 0: return &v.state case 1: @@ -18861,7 +18987,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFullStatusResponse); i { + switch v := v.(*GetCellsAliasesResponse); i { case 0: return &v.state case 1: @@ -18873,7 +18999,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetKeyspacesRequest); i { + switch v := v.(*GetFullStatusRequest); i { case 0: return &v.state case 1: @@ -18885,7 +19011,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetKeyspacesResponse); i { + switch v := v.(*GetFullStatusResponse); i { case 0: return &v.state case 1: @@ -18897,7 +19023,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetKeyspaceRequest); i { + switch v := v.(*GetKeyspacesRequest); i { case 0: return &v.state case 1: @@ -18909,7 +19035,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetKeyspaceResponse); i { + switch v := v.(*GetKeyspacesResponse); i { case 0: return &v.state case 1: @@ -18921,7 +19047,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetPermissionsRequest); i { + switch v := v.(*GetKeyspaceRequest); i { case 0: return &v.state case 1: @@ -18933,7 +19059,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetPermissionsResponse); i { + switch v := v.(*GetKeyspaceResponse); i { case 0: return &v.state case 1: @@ -18945,7 +19071,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetRoutingRulesRequest); i { + switch v := v.(*GetPermissionsRequest); i { case 0: return &v.state case 1: @@ -18957,7 +19083,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetRoutingRulesResponse); i { + switch v := v.(*GetPermissionsResponse); i { case 0: return &v.state case 1: @@ -18969,7 +19095,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSchemaRequest); i { + switch v := v.(*GetRoutingRulesRequest); i { case 0: return &v.state case 1: @@ -18981,7 +19107,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSchemaResponse); i { + switch v := v.(*GetRoutingRulesResponse); i { case 0: return &v.state case 1: @@ -18993,7 +19119,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSchemaMigrationsRequest); i { + switch v := v.(*GetSchemaRequest); i { case 0: return &v.state case 1: @@ -19005,7 +19131,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSchemaMigrationsResponse); i { + switch v := v.(*GetSchemaResponse); i { case 0: return &v.state case 1: @@ -19017,7 +19143,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetShardRequest); i { + switch v := v.(*GetSchemaMigrationsRequest); i { case 0: return &v.state case 1: @@ -19029,7 +19155,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetShardResponse); i { + switch v := v.(*GetSchemaMigrationsResponse); i { case 0: return &v.state case 1: @@ -19041,7 +19167,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetShardRoutingRulesRequest); i { + switch v := v.(*GetShardRequest); i { case 0: return &v.state case 1: @@ -19053,7 +19179,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetShardRoutingRulesResponse); i { + switch v := v.(*GetShardResponse); i { case 0: return &v.state case 1: @@ -19065,7 +19191,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvKeyspaceNamesRequest); i { + switch v := v.(*GetShardRoutingRulesRequest); i { case 0: return &v.state case 1: @@ -19077,7 +19203,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvKeyspaceNamesResponse); i { + switch v := v.(*GetShardRoutingRulesResponse); i { case 0: return &v.state case 1: @@ -19089,7 +19215,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvKeyspacesRequest); i { + switch v := v.(*GetSrvKeyspaceNamesRequest); i { case 0: return &v.state case 1: @@ -19101,7 +19227,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvKeyspacesResponse); i { + switch v := v.(*GetSrvKeyspaceNamesResponse); i { case 0: return &v.state case 1: @@ -19113,7 +19239,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateThrottlerConfigRequest); i { + switch v := v.(*GetSrvKeyspacesRequest); i { case 0: return &v.state case 1: @@ -19125,7 +19251,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateThrottlerConfigResponse); i { + switch v := v.(*GetSrvKeyspacesResponse); i { case 0: return &v.state case 1: @@ -19137,7 +19263,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvVSchemaRequest); i { + switch v := v.(*UpdateThrottlerConfigRequest); i { case 0: return &v.state case 1: @@ -19149,7 +19275,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvVSchemaResponse); i { + switch v := v.(*UpdateThrottlerConfigResponse); i { case 0: return &v.state case 1: @@ -19161,7 +19287,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvVSchemasRequest); i { + switch v := v.(*GetSrvVSchemaRequest); i { case 0: return &v.state case 1: @@ -19173,7 +19299,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSrvVSchemasResponse); i { + switch v := v.(*GetSrvVSchemaResponse); i { case 0: return &v.state case 1: @@ -19185,7 +19311,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTabletRequest); i { + switch v := v.(*GetSrvVSchemasRequest); i { case 0: return &v.state case 1: @@ -19197,7 +19323,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTabletResponse); i { + switch v := v.(*GetSrvVSchemasResponse); i { case 0: return &v.state case 1: @@ -19209,7 +19335,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTabletsRequest); i { + switch v := v.(*GetTabletRequest); i { case 0: return &v.state case 1: @@ -19221,7 +19347,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTabletsResponse); i { + switch v := v.(*GetTabletResponse); i { case 0: return &v.state case 1: @@ -19233,7 +19359,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTopologyPathRequest); i { + switch v := v.(*GetTabletsRequest); i { case 0: return &v.state case 1: @@ -19245,7 +19371,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTopologyPathResponse); i { + switch v := v.(*GetTabletsResponse); i { case 0: return &v.state case 1: @@ -19257,7 +19383,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TopologyCell); i { + switch v := v.(*GetTopologyPathRequest); i { case 0: return &v.state case 1: @@ -19269,7 +19395,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVSchemaRequest); i { + switch v := v.(*GetTopologyPathResponse); i { case 0: return &v.state case 1: @@ -19281,7 +19407,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVersionRequest); i { + switch v := v.(*TopologyCell); i { case 0: return &v.state case 1: @@ -19293,7 +19419,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVersionResponse); i { + switch v := v.(*GetVSchemaRequest); i { case 0: return &v.state case 1: @@ -19305,7 +19431,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVSchemaResponse); i { + switch v := v.(*GetVersionRequest); i { case 0: return &v.state case 1: @@ -19317,7 +19443,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetWorkflowsRequest); i { + switch v := v.(*GetVersionResponse); i { case 0: return &v.state case 1: @@ -19329,7 +19455,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetWorkflowsResponse); i { + switch v := v.(*GetVSchemaResponse); i { case 0: return &v.state case 1: @@ -19341,7 +19467,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InitShardPrimaryRequest); i { + switch v := v.(*GetWorkflowsRequest); i { case 0: return &v.state case 1: @@ -19353,6 +19479,30 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkflowsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitShardPrimaryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InitShardPrimaryResponse); i { case 0: return &v.state @@ -19364,7 +19514,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LaunchSchemaMigrationRequest); i { case 0: return &v.state @@ -19376,7 +19526,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LaunchSchemaMigrationResponse); i { case 0: return &v.state @@ -19388,7 +19538,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LookupVindexCreateRequest); i { case 0: return &v.state @@ -19400,7 +19550,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LookupVindexCreateResponse); i { case 0: return &v.state @@ -19412,7 +19562,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LookupVindexExternalizeRequest); i { case 0: return &v.state @@ -19424,7 +19574,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LookupVindexExternalizeResponse); i { case 0: return &v.state @@ -19436,7 +19586,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MaterializeCreateRequest); i { case 0: return &v.state @@ -19448,7 +19598,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MaterializeCreateResponse); i { case 0: return &v.state @@ -19460,7 +19610,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MigrateCreateRequest); i { case 0: return &v.state @@ -19472,7 +19622,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[119].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MigrateCompleteRequest); i { case 0: return &v.state @@ -19484,7 +19634,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[120].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MigrateCompleteResponse); i { case 0: return &v.state @@ -19496,7 +19646,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[119].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountRegisterRequest); i { case 0: return &v.state @@ -19508,7 +19658,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[120].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountRegisterResponse); i { case 0: return &v.state @@ -19520,7 +19670,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountUnregisterRequest); i { case 0: return &v.state @@ -19532,7 +19682,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountUnregisterResponse); i { case 0: return &v.state @@ -19544,7 +19694,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountShowRequest); i { case 0: return &v.state @@ -19556,7 +19706,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountShowResponse); i { case 0: return &v.state @@ -19568,7 +19718,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountListRequest); i { case 0: return &v.state @@ -19580,7 +19730,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MountListResponse); i { case 0: return &v.state @@ -19592,7 +19742,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCreateRequest); i { case 0: return &v.state @@ -19604,7 +19754,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCreateResponse); i { case 0: return &v.state @@ -19616,7 +19766,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCompleteRequest); i { case 0: return &v.state @@ -19628,7 +19778,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[132].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCompleteResponse); i { case 0: return &v.state @@ -19640,7 +19790,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[133].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PingTabletRequest); i { case 0: return &v.state @@ -19652,7 +19802,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[132].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[134].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PingTabletResponse); i { case 0: return &v.state @@ -19664,7 +19814,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[133].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[135].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlannedReparentShardRequest); i { case 0: return &v.state @@ -19676,7 +19826,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[134].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[136].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlannedReparentShardResponse); i { case 0: return &v.state @@ -19688,7 +19838,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[135].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[137].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RebuildKeyspaceGraphRequest); i { case 0: return &v.state @@ -19700,7 +19850,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[136].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[138].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RebuildKeyspaceGraphResponse); i { case 0: return &v.state @@ -19712,7 +19862,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[137].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[139].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RebuildVSchemaGraphRequest); i { case 0: return &v.state @@ -19724,7 +19874,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[138].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[140].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RebuildVSchemaGraphResponse); i { case 0: return &v.state @@ -19736,7 +19886,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[139].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[141].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RefreshStateRequest); i { case 0: return &v.state @@ -19748,7 +19898,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[140].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[142].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RefreshStateResponse); i { case 0: return &v.state @@ -19760,7 +19910,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[141].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[143].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RefreshStateByShardRequest); i { case 0: return &v.state @@ -19772,7 +19922,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[142].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[144].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RefreshStateByShardResponse); i { case 0: return &v.state @@ -19784,7 +19934,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[143].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[145].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaRequest); i { case 0: return &v.state @@ -19796,7 +19946,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[144].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[146].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaResponse); i { case 0: return &v.state @@ -19808,7 +19958,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[145].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[147].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaKeyspaceRequest); i { case 0: return &v.state @@ -19820,7 +19970,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[146].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[148].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaKeyspaceResponse); i { case 0: return &v.state @@ -19832,7 +19982,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[147].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[149].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaShardRequest); i { case 0: return &v.state @@ -19844,7 +19994,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[148].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[150].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReloadSchemaShardResponse); i { case 0: return &v.state @@ -19856,7 +20006,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[149].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[151].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveBackupRequest); i { case 0: return &v.state @@ -19868,7 +20018,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[150].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[152].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveBackupResponse); i { case 0: return &v.state @@ -19880,7 +20030,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[151].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[153].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveKeyspaceCellRequest); i { case 0: return &v.state @@ -19892,7 +20042,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[152].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[154].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveKeyspaceCellResponse); i { case 0: return &v.state @@ -19904,7 +20054,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[153].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[155].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveShardCellRequest); i { case 0: return &v.state @@ -19916,7 +20066,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[154].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[156].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoveShardCellResponse); i { case 0: return &v.state @@ -19928,7 +20078,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[155].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[157].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReparentTabletRequest); i { case 0: return &v.state @@ -19940,7 +20090,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[156].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[158].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReparentTabletResponse); i { case 0: return &v.state @@ -19952,7 +20102,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[157].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[159].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReshardCreateRequest); i { case 0: return &v.state @@ -19964,7 +20114,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[158].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[160].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RestoreFromBackupRequest); i { case 0: return &v.state @@ -19976,7 +20126,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[159].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[161].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RestoreFromBackupResponse); i { case 0: return &v.state @@ -19988,7 +20138,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[160].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[162].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RetrySchemaMigrationRequest); i { case 0: return &v.state @@ -20000,7 +20150,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[161].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[163].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RetrySchemaMigrationResponse); i { case 0: return &v.state @@ -20012,7 +20162,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[162].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[164].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RunHealthCheckRequest); i { case 0: return &v.state @@ -20024,7 +20174,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[163].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[165].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RunHealthCheckResponse); i { case 0: return &v.state @@ -20036,7 +20186,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[164].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[166].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceDurabilityPolicyRequest); i { case 0: return &v.state @@ -20048,7 +20198,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[165].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[167].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceDurabilityPolicyResponse); i { case 0: return &v.state @@ -20060,7 +20210,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[166].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[168].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceShardingInfoRequest); i { case 0: return &v.state @@ -20072,7 +20222,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[167].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[169].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetKeyspaceShardingInfoResponse); i { case 0: return &v.state @@ -20084,7 +20234,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[168].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[170].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardIsPrimaryServingRequest); i { case 0: return &v.state @@ -20096,7 +20246,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[169].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[171].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardIsPrimaryServingResponse); i { case 0: return &v.state @@ -20108,7 +20258,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[170].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[172].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardTabletControlRequest); i { case 0: return &v.state @@ -20120,7 +20270,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[171].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[173].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetShardTabletControlResponse); i { case 0: return &v.state @@ -20132,7 +20282,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[172].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[174].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetWritableRequest); i { case 0: return &v.state @@ -20144,7 +20294,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[173].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[175].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetWritableResponse); i { case 0: return &v.state @@ -20156,7 +20306,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[174].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[176].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationAddRequest); i { case 0: return &v.state @@ -20168,7 +20318,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[175].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[177].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationAddResponse); i { case 0: return &v.state @@ -20180,7 +20330,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[176].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[178].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationFixRequest); i { case 0: return &v.state @@ -20192,7 +20342,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[177].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[179].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationFixResponse); i { case 0: return &v.state @@ -20204,7 +20354,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[178].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[180].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationPositionsRequest); i { case 0: return &v.state @@ -20216,7 +20366,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[179].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[181].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationPositionsResponse); i { case 0: return &v.state @@ -20228,7 +20378,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[180].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationRemoveRequest); i { case 0: return &v.state @@ -20240,7 +20390,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[181].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ShardReplicationRemoveResponse); i { case 0: return &v.state @@ -20252,7 +20402,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[182].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[184].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SleepTabletRequest); i { case 0: return &v.state @@ -20264,7 +20414,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[183].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[185].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SleepTabletResponse); i { case 0: return &v.state @@ -20276,7 +20426,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[184].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[186].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardAddRequest); i { case 0: return &v.state @@ -20288,7 +20438,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[185].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[187].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardAddResponse); i { case 0: return &v.state @@ -20300,7 +20450,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[186].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[188].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardDeleteRequest); i { case 0: return &v.state @@ -20312,7 +20462,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[187].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[189].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SourceShardDeleteResponse); i { case 0: return &v.state @@ -20324,7 +20474,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[188].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[190].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StartReplicationRequest); i { case 0: return &v.state @@ -20336,7 +20486,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[189].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[191].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StartReplicationResponse); i { case 0: return &v.state @@ -20348,7 +20498,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[190].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[192].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopReplicationRequest); i { case 0: return &v.state @@ -20360,7 +20510,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[191].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[193].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StopReplicationResponse); i { case 0: return &v.state @@ -20372,7 +20522,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[192].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[194].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TabletExternallyReparentedRequest); i { case 0: return &v.state @@ -20384,7 +20534,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[193].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[195].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TabletExternallyReparentedResponse); i { case 0: return &v.state @@ -20396,7 +20546,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[194].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[196].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellInfoRequest); i { case 0: return &v.state @@ -20408,7 +20558,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[195].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[197].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellInfoResponse); i { case 0: return &v.state @@ -20420,7 +20570,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[196].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[198].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellsAliasRequest); i { case 0: return &v.state @@ -20432,7 +20582,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[197].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[199].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateCellsAliasResponse); i { case 0: return &v.state @@ -20444,7 +20594,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[198].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[200].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateRequest); i { case 0: return &v.state @@ -20456,7 +20606,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[199].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[201].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateResponse); i { case 0: return &v.state @@ -20468,7 +20618,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[200].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[202].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateKeyspaceRequest); i { case 0: return &v.state @@ -20480,7 +20630,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[201].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[203].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateKeyspaceResponse); i { case 0: return &v.state @@ -20492,7 +20642,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[202].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[204].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateSchemaKeyspaceRequest); i { case 0: return &v.state @@ -20504,7 +20654,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[203].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[205].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateSchemaKeyspaceResponse); i { case 0: return &v.state @@ -20516,7 +20666,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[204].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[206].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateShardRequest); i { case 0: return &v.state @@ -20528,7 +20678,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[205].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[207].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateShardResponse); i { case 0: return &v.state @@ -20540,7 +20690,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[206].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[208].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionKeyspaceRequest); i { case 0: return &v.state @@ -20552,7 +20702,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[207].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[209].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionKeyspaceResponse); i { case 0: return &v.state @@ -20564,7 +20714,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[208].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[210].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionShardRequest); i { case 0: return &v.state @@ -20576,7 +20726,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[209].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[211].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVersionShardResponse); i { case 0: return &v.state @@ -20588,7 +20738,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[210].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[212].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVSchemaRequest); i { case 0: return &v.state @@ -20600,7 +20750,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[211].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[213].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValidateVSchemaResponse); i { case 0: return &v.state @@ -20612,7 +20762,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[212].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[214].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffCreateRequest); i { case 0: return &v.state @@ -20624,7 +20774,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[213].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[215].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffCreateResponse); i { case 0: return &v.state @@ -20636,7 +20786,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[214].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[216].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffDeleteRequest); i { case 0: return &v.state @@ -20648,7 +20798,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[215].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[217].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffDeleteResponse); i { case 0: return &v.state @@ -20660,7 +20810,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[216].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[218].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffResumeRequest); i { case 0: return &v.state @@ -20672,7 +20822,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[217].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[219].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffResumeResponse); i { case 0: return &v.state @@ -20684,7 +20834,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[218].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[220].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffShowRequest); i { case 0: return &v.state @@ -20696,7 +20846,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[219].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[221].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffShowResponse); i { case 0: return &v.state @@ -20708,7 +20858,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[220].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[222].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffStopRequest); i { case 0: return &v.state @@ -20720,7 +20870,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[221].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[223].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VDiffStopResponse); i { case 0: return &v.state @@ -20732,7 +20882,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[222].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[224].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteRequest); i { case 0: return &v.state @@ -20744,7 +20894,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[223].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[225].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteResponse); i { case 0: return &v.state @@ -20756,7 +20906,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[224].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[226].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusRequest); i { case 0: return &v.state @@ -20768,7 +20918,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[225].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[227].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse); i { case 0: return &v.state @@ -20780,7 +20930,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[226].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[228].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowSwitchTrafficRequest); i { case 0: return &v.state @@ -20792,7 +20942,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[227].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[229].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowSwitchTrafficResponse); i { case 0: return &v.state @@ -20804,7 +20954,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[228].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[230].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateRequest); i { case 0: return &v.state @@ -20816,7 +20966,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[229].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[231].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateResponse); i { case 0: return &v.state @@ -20828,7 +20978,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[231].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[233].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_ReplicationLocation); i { case 0: return &v.state @@ -20840,7 +20990,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[232].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[234].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_ShardStream); i { case 0: return &v.state @@ -20852,7 +21002,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[233].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[235].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream); i { case 0: return &v.state @@ -20864,7 +21014,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[234].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[236].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_CopyState); i { case 0: return &v.state @@ -20876,7 +21026,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[235].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[237].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_Log); i { case 0: return &v.state @@ -20888,7 +21038,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[236].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[238].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_ThrottlerStatus); i { case 0: return &v.state @@ -20900,7 +21050,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[244].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[247].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSrvKeyspaceNamesResponse_NameList); i { case 0: return &v.state @@ -20912,7 +21062,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[248].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[251].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCreateResponse_TabletInfo); i { case 0: return &v.state @@ -20924,7 +21074,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[258].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[261].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteResponse_TabletInfo); i { case 0: return &v.state @@ -20936,7 +21086,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[259].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[262].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_TableCopyState); i { case 0: return &v.state @@ -20948,7 +21098,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[260].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[263].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreamState); i { case 0: return &v.state @@ -20960,7 +21110,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[261].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[264].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreams); i { case 0: return &v.state @@ -20972,7 +21122,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[264].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[267].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateResponse_TabletInfo); i { case 0: return &v.state @@ -20991,7 +21141,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 4, - NumMessages: 265, + NumMessages: 268, 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 0b59d6f8f5c..e4978808160 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -1458,6 +1458,48 @@ func (m *FindAllShardsInKeyspaceResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *ForceCutOverSchemaMigrationRequest) CloneVT() *ForceCutOverSchemaMigrationRequest { + if m == nil { + return (*ForceCutOverSchemaMigrationRequest)(nil) + } + r := &ForceCutOverSchemaMigrationRequest{ + Keyspace: m.Keyspace, + Uuid: m.Uuid, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ForceCutOverSchemaMigrationRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *ForceCutOverSchemaMigrationResponse) CloneVT() *ForceCutOverSchemaMigrationResponse { + if m == nil { + return (*ForceCutOverSchemaMigrationResponse)(nil) + } + r := &ForceCutOverSchemaMigrationResponse{} + if rhs := m.RowsAffectedByShard; rhs != nil { + tmpContainer := make(map[string]uint64, len(rhs)) + for k, v := range rhs { + tmpContainer[k] = v + } + r.RowsAffectedByShard = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ForceCutOverSchemaMigrationResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *GetBackupsRequest) CloneVT() *GetBackupsRequest { if m == nil { return (*GetBackupsRequest)(nil) @@ -9435,6 +9477,103 @@ func (m *FindAllShardsInKeyspaceResponse) MarshalToSizedBufferVT(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *ForceCutOverSchemaMigrationRequest) 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 *ForceCutOverSchemaMigrationRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ForceCutOverSchemaMigrationRequest) 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.Uuid) > 0 { + i -= len(m.Uuid) + copy(dAtA[i:], m.Uuid) + i = encodeVarint(dAtA, i, uint64(len(m.Uuid))) + 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 *ForceCutOverSchemaMigrationResponse) 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 *ForceCutOverSchemaMigrationResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ForceCutOverSchemaMigrationResponse) 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.RowsAffectedByShard) > 0 { + for k := range m.RowsAffectedByShard { + v := m.RowsAffectedByShard[k] + baseI := i + i = encodeVarint(dAtA, i, uint64(v)) + i-- + dAtA[i] = 0x10 + 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] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *GetBackupsRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -20767,6 +20906,42 @@ func (m *FindAllShardsInKeyspaceResponse) SizeVT() (n int) { return n } +func (m *ForceCutOverSchemaMigrationRequest) 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.Uuid) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *ForceCutOverSchemaMigrationResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.RowsAffectedByShard) > 0 { + for k, v := range m.RowsAffectedByShard { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + sov(uint64(v)) + n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + } + } + n += len(m.unknownFields) + return n +} + func (m *GetBackupsRequest) SizeVT() (n int) { if m == nil { return 0 @@ -35087,6 +35262,285 @@ func (m *FindAllShardsInKeyspaceResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *ForceCutOverSchemaMigrationRequest) 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: ForceCutOverSchemaMigrationRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ForceCutOverSchemaMigrationRequest: 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 Uuid", 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.Uuid = 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 *ForceCutOverSchemaMigrationResponse) 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: ForceCutOverSchemaMigrationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ForceCutOverSchemaMigrationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RowsAffectedByShard", 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.RowsAffectedByShard == nil { + m.RowsAffectedByShard = make(map[string]uint64) + } + var mapkey string + var mapvalue uint64 + 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 { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + } 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.RowsAffectedByShard[mapkey] = mapvalue + 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 *GetBackupsRequest) 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 fc2221d7074..afaee7e0175 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, 0x93, 0x50, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0x93, 0x51, 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, @@ -197,6 +197,14 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 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, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x1b, 0x46, 0x6f, 0x72, 0x63, + 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x75, 0x74, 0x4f, 0x76, 0x65, 0x72, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x12, 0x1c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, @@ -726,198 +734,200 @@ var file_vtctlservice_proto_goTypes = []interface{}{ (*vtctldata.ExecuteFetchAsDBARequest)(nil), // 23: vtctldata.ExecuteFetchAsDBARequest (*vtctldata.ExecuteHookRequest)(nil), // 24: vtctldata.ExecuteHookRequest (*vtctldata.FindAllShardsInKeyspaceRequest)(nil), // 25: vtctldata.FindAllShardsInKeyspaceRequest - (*vtctldata.GetBackupsRequest)(nil), // 26: vtctldata.GetBackupsRequest - (*vtctldata.GetCellInfoRequest)(nil), // 27: vtctldata.GetCellInfoRequest - (*vtctldata.GetCellInfoNamesRequest)(nil), // 28: vtctldata.GetCellInfoNamesRequest - (*vtctldata.GetCellsAliasesRequest)(nil), // 29: vtctldata.GetCellsAliasesRequest - (*vtctldata.GetFullStatusRequest)(nil), // 30: vtctldata.GetFullStatusRequest - (*vtctldata.GetKeyspaceRequest)(nil), // 31: vtctldata.GetKeyspaceRequest - (*vtctldata.GetKeyspacesRequest)(nil), // 32: vtctldata.GetKeyspacesRequest - (*vtctldata.GetPermissionsRequest)(nil), // 33: vtctldata.GetPermissionsRequest - (*vtctldata.GetRoutingRulesRequest)(nil), // 34: vtctldata.GetRoutingRulesRequest - (*vtctldata.GetSchemaRequest)(nil), // 35: vtctldata.GetSchemaRequest - (*vtctldata.GetSchemaMigrationsRequest)(nil), // 36: vtctldata.GetSchemaMigrationsRequest - (*vtctldata.GetShardRequest)(nil), // 37: vtctldata.GetShardRequest - (*vtctldata.GetShardRoutingRulesRequest)(nil), // 38: vtctldata.GetShardRoutingRulesRequest - (*vtctldata.GetSrvKeyspaceNamesRequest)(nil), // 39: vtctldata.GetSrvKeyspaceNamesRequest - (*vtctldata.GetSrvKeyspacesRequest)(nil), // 40: vtctldata.GetSrvKeyspacesRequest - (*vtctldata.UpdateThrottlerConfigRequest)(nil), // 41: vtctldata.UpdateThrottlerConfigRequest - (*vtctldata.GetSrvVSchemaRequest)(nil), // 42: vtctldata.GetSrvVSchemaRequest - (*vtctldata.GetSrvVSchemasRequest)(nil), // 43: vtctldata.GetSrvVSchemasRequest - (*vtctldata.GetTabletRequest)(nil), // 44: vtctldata.GetTabletRequest - (*vtctldata.GetTabletsRequest)(nil), // 45: vtctldata.GetTabletsRequest - (*vtctldata.GetTopologyPathRequest)(nil), // 46: vtctldata.GetTopologyPathRequest - (*vtctldata.GetVersionRequest)(nil), // 47: vtctldata.GetVersionRequest - (*vtctldata.GetVSchemaRequest)(nil), // 48: vtctldata.GetVSchemaRequest - (*vtctldata.GetWorkflowsRequest)(nil), // 49: vtctldata.GetWorkflowsRequest - (*vtctldata.InitShardPrimaryRequest)(nil), // 50: vtctldata.InitShardPrimaryRequest - (*vtctldata.LaunchSchemaMigrationRequest)(nil), // 51: vtctldata.LaunchSchemaMigrationRequest - (*vtctldata.LookupVindexCreateRequest)(nil), // 52: vtctldata.LookupVindexCreateRequest - (*vtctldata.LookupVindexExternalizeRequest)(nil), // 53: vtctldata.LookupVindexExternalizeRequest - (*vtctldata.MaterializeCreateRequest)(nil), // 54: vtctldata.MaterializeCreateRequest - (*vtctldata.MigrateCreateRequest)(nil), // 55: vtctldata.MigrateCreateRequest - (*vtctldata.MountRegisterRequest)(nil), // 56: vtctldata.MountRegisterRequest - (*vtctldata.MountUnregisterRequest)(nil), // 57: vtctldata.MountUnregisterRequest - (*vtctldata.MountShowRequest)(nil), // 58: vtctldata.MountShowRequest - (*vtctldata.MountListRequest)(nil), // 59: vtctldata.MountListRequest - (*vtctldata.MoveTablesCreateRequest)(nil), // 60: vtctldata.MoveTablesCreateRequest - (*vtctldata.MoveTablesCompleteRequest)(nil), // 61: vtctldata.MoveTablesCompleteRequest - (*vtctldata.PingTabletRequest)(nil), // 62: vtctldata.PingTabletRequest - (*vtctldata.PlannedReparentShardRequest)(nil), // 63: vtctldata.PlannedReparentShardRequest - (*vtctldata.RebuildKeyspaceGraphRequest)(nil), // 64: vtctldata.RebuildKeyspaceGraphRequest - (*vtctldata.RebuildVSchemaGraphRequest)(nil), // 65: vtctldata.RebuildVSchemaGraphRequest - (*vtctldata.RefreshStateRequest)(nil), // 66: vtctldata.RefreshStateRequest - (*vtctldata.RefreshStateByShardRequest)(nil), // 67: vtctldata.RefreshStateByShardRequest - (*vtctldata.ReloadSchemaRequest)(nil), // 68: vtctldata.ReloadSchemaRequest - (*vtctldata.ReloadSchemaKeyspaceRequest)(nil), // 69: vtctldata.ReloadSchemaKeyspaceRequest - (*vtctldata.ReloadSchemaShardRequest)(nil), // 70: vtctldata.ReloadSchemaShardRequest - (*vtctldata.RemoveBackupRequest)(nil), // 71: vtctldata.RemoveBackupRequest - (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 72: vtctldata.RemoveKeyspaceCellRequest - (*vtctldata.RemoveShardCellRequest)(nil), // 73: vtctldata.RemoveShardCellRequest - (*vtctldata.ReparentTabletRequest)(nil), // 74: vtctldata.ReparentTabletRequest - (*vtctldata.ReshardCreateRequest)(nil), // 75: vtctldata.ReshardCreateRequest - (*vtctldata.RestoreFromBackupRequest)(nil), // 76: vtctldata.RestoreFromBackupRequest - (*vtctldata.RetrySchemaMigrationRequest)(nil), // 77: vtctldata.RetrySchemaMigrationRequest - (*vtctldata.RunHealthCheckRequest)(nil), // 78: vtctldata.RunHealthCheckRequest - (*vtctldata.SetKeyspaceDurabilityPolicyRequest)(nil), // 79: vtctldata.SetKeyspaceDurabilityPolicyRequest - (*vtctldata.SetShardIsPrimaryServingRequest)(nil), // 80: vtctldata.SetShardIsPrimaryServingRequest - (*vtctldata.SetShardTabletControlRequest)(nil), // 81: vtctldata.SetShardTabletControlRequest - (*vtctldata.SetWritableRequest)(nil), // 82: vtctldata.SetWritableRequest - (*vtctldata.ShardReplicationAddRequest)(nil), // 83: vtctldata.ShardReplicationAddRequest - (*vtctldata.ShardReplicationFixRequest)(nil), // 84: vtctldata.ShardReplicationFixRequest - (*vtctldata.ShardReplicationPositionsRequest)(nil), // 85: vtctldata.ShardReplicationPositionsRequest - (*vtctldata.ShardReplicationRemoveRequest)(nil), // 86: vtctldata.ShardReplicationRemoveRequest - (*vtctldata.SleepTabletRequest)(nil), // 87: vtctldata.SleepTabletRequest - (*vtctldata.SourceShardAddRequest)(nil), // 88: vtctldata.SourceShardAddRequest - (*vtctldata.SourceShardDeleteRequest)(nil), // 89: vtctldata.SourceShardDeleteRequest - (*vtctldata.StartReplicationRequest)(nil), // 90: vtctldata.StartReplicationRequest - (*vtctldata.StopReplicationRequest)(nil), // 91: vtctldata.StopReplicationRequest - (*vtctldata.TabletExternallyReparentedRequest)(nil), // 92: vtctldata.TabletExternallyReparentedRequest - (*vtctldata.UpdateCellInfoRequest)(nil), // 93: vtctldata.UpdateCellInfoRequest - (*vtctldata.UpdateCellsAliasRequest)(nil), // 94: vtctldata.UpdateCellsAliasRequest - (*vtctldata.ValidateRequest)(nil), // 95: vtctldata.ValidateRequest - (*vtctldata.ValidateKeyspaceRequest)(nil), // 96: vtctldata.ValidateKeyspaceRequest - (*vtctldata.ValidateSchemaKeyspaceRequest)(nil), // 97: vtctldata.ValidateSchemaKeyspaceRequest - (*vtctldata.ValidateShardRequest)(nil), // 98: vtctldata.ValidateShardRequest - (*vtctldata.ValidateVersionKeyspaceRequest)(nil), // 99: vtctldata.ValidateVersionKeyspaceRequest - (*vtctldata.ValidateVersionShardRequest)(nil), // 100: vtctldata.ValidateVersionShardRequest - (*vtctldata.ValidateVSchemaRequest)(nil), // 101: vtctldata.ValidateVSchemaRequest - (*vtctldata.VDiffCreateRequest)(nil), // 102: vtctldata.VDiffCreateRequest - (*vtctldata.VDiffDeleteRequest)(nil), // 103: vtctldata.VDiffDeleteRequest - (*vtctldata.VDiffResumeRequest)(nil), // 104: vtctldata.VDiffResumeRequest - (*vtctldata.VDiffShowRequest)(nil), // 105: vtctldata.VDiffShowRequest - (*vtctldata.VDiffStopRequest)(nil), // 106: vtctldata.VDiffStopRequest - (*vtctldata.WorkflowDeleteRequest)(nil), // 107: vtctldata.WorkflowDeleteRequest - (*vtctldata.WorkflowStatusRequest)(nil), // 108: vtctldata.WorkflowStatusRequest - (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 109: vtctldata.WorkflowSwitchTrafficRequest - (*vtctldata.WorkflowUpdateRequest)(nil), // 110: vtctldata.WorkflowUpdateRequest - (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 111: vtctldata.ExecuteVtctlCommandResponse - (*vtctldata.AddCellInfoResponse)(nil), // 112: vtctldata.AddCellInfoResponse - (*vtctldata.AddCellsAliasResponse)(nil), // 113: vtctldata.AddCellsAliasResponse - (*vtctldata.ApplyRoutingRulesResponse)(nil), // 114: vtctldata.ApplyRoutingRulesResponse - (*vtctldata.ApplySchemaResponse)(nil), // 115: vtctldata.ApplySchemaResponse - (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 116: vtctldata.ApplyShardRoutingRulesResponse - (*vtctldata.ApplyVSchemaResponse)(nil), // 117: vtctldata.ApplyVSchemaResponse - (*vtctldata.BackupResponse)(nil), // 118: vtctldata.BackupResponse - (*vtctldata.CancelSchemaMigrationResponse)(nil), // 119: vtctldata.CancelSchemaMigrationResponse - (*vtctldata.ChangeTabletTypeResponse)(nil), // 120: vtctldata.ChangeTabletTypeResponse - (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 121: vtctldata.CleanupSchemaMigrationResponse - (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 122: vtctldata.CompleteSchemaMigrationResponse - (*vtctldata.CreateKeyspaceResponse)(nil), // 123: vtctldata.CreateKeyspaceResponse - (*vtctldata.CreateShardResponse)(nil), // 124: vtctldata.CreateShardResponse - (*vtctldata.DeleteCellInfoResponse)(nil), // 125: vtctldata.DeleteCellInfoResponse - (*vtctldata.DeleteCellsAliasResponse)(nil), // 126: vtctldata.DeleteCellsAliasResponse - (*vtctldata.DeleteKeyspaceResponse)(nil), // 127: vtctldata.DeleteKeyspaceResponse - (*vtctldata.DeleteShardsResponse)(nil), // 128: vtctldata.DeleteShardsResponse - (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 129: vtctldata.DeleteSrvVSchemaResponse - (*vtctldata.DeleteTabletsResponse)(nil), // 130: vtctldata.DeleteTabletsResponse - (*vtctldata.EmergencyReparentShardResponse)(nil), // 131: vtctldata.EmergencyReparentShardResponse - (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 132: vtctldata.ExecuteFetchAsAppResponse - (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 133: vtctldata.ExecuteFetchAsDBAResponse - (*vtctldata.ExecuteHookResponse)(nil), // 134: vtctldata.ExecuteHookResponse - (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 135: vtctldata.FindAllShardsInKeyspaceResponse - (*vtctldata.GetBackupsResponse)(nil), // 136: vtctldata.GetBackupsResponse - (*vtctldata.GetCellInfoResponse)(nil), // 137: vtctldata.GetCellInfoResponse - (*vtctldata.GetCellInfoNamesResponse)(nil), // 138: vtctldata.GetCellInfoNamesResponse - (*vtctldata.GetCellsAliasesResponse)(nil), // 139: vtctldata.GetCellsAliasesResponse - (*vtctldata.GetFullStatusResponse)(nil), // 140: vtctldata.GetFullStatusResponse - (*vtctldata.GetKeyspaceResponse)(nil), // 141: vtctldata.GetKeyspaceResponse - (*vtctldata.GetKeyspacesResponse)(nil), // 142: vtctldata.GetKeyspacesResponse - (*vtctldata.GetPermissionsResponse)(nil), // 143: vtctldata.GetPermissionsResponse - (*vtctldata.GetRoutingRulesResponse)(nil), // 144: vtctldata.GetRoutingRulesResponse - (*vtctldata.GetSchemaResponse)(nil), // 145: vtctldata.GetSchemaResponse - (*vtctldata.GetSchemaMigrationsResponse)(nil), // 146: vtctldata.GetSchemaMigrationsResponse - (*vtctldata.GetShardResponse)(nil), // 147: vtctldata.GetShardResponse - (*vtctldata.GetShardRoutingRulesResponse)(nil), // 148: vtctldata.GetShardRoutingRulesResponse - (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 149: vtctldata.GetSrvKeyspaceNamesResponse - (*vtctldata.GetSrvKeyspacesResponse)(nil), // 150: vtctldata.GetSrvKeyspacesResponse - (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 151: vtctldata.UpdateThrottlerConfigResponse - (*vtctldata.GetSrvVSchemaResponse)(nil), // 152: vtctldata.GetSrvVSchemaResponse - (*vtctldata.GetSrvVSchemasResponse)(nil), // 153: vtctldata.GetSrvVSchemasResponse - (*vtctldata.GetTabletResponse)(nil), // 154: vtctldata.GetTabletResponse - (*vtctldata.GetTabletsResponse)(nil), // 155: vtctldata.GetTabletsResponse - (*vtctldata.GetTopologyPathResponse)(nil), // 156: vtctldata.GetTopologyPathResponse - (*vtctldata.GetVersionResponse)(nil), // 157: vtctldata.GetVersionResponse - (*vtctldata.GetVSchemaResponse)(nil), // 158: vtctldata.GetVSchemaResponse - (*vtctldata.GetWorkflowsResponse)(nil), // 159: vtctldata.GetWorkflowsResponse - (*vtctldata.InitShardPrimaryResponse)(nil), // 160: vtctldata.InitShardPrimaryResponse - (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 161: vtctldata.LaunchSchemaMigrationResponse - (*vtctldata.LookupVindexCreateResponse)(nil), // 162: vtctldata.LookupVindexCreateResponse - (*vtctldata.LookupVindexExternalizeResponse)(nil), // 163: vtctldata.LookupVindexExternalizeResponse - (*vtctldata.MaterializeCreateResponse)(nil), // 164: vtctldata.MaterializeCreateResponse - (*vtctldata.WorkflowStatusResponse)(nil), // 165: vtctldata.WorkflowStatusResponse - (*vtctldata.MountRegisterResponse)(nil), // 166: vtctldata.MountRegisterResponse - (*vtctldata.MountUnregisterResponse)(nil), // 167: vtctldata.MountUnregisterResponse - (*vtctldata.MountShowResponse)(nil), // 168: vtctldata.MountShowResponse - (*vtctldata.MountListResponse)(nil), // 169: vtctldata.MountListResponse - (*vtctldata.MoveTablesCompleteResponse)(nil), // 170: vtctldata.MoveTablesCompleteResponse - (*vtctldata.PingTabletResponse)(nil), // 171: vtctldata.PingTabletResponse - (*vtctldata.PlannedReparentShardResponse)(nil), // 172: vtctldata.PlannedReparentShardResponse - (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 173: vtctldata.RebuildKeyspaceGraphResponse - (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 174: vtctldata.RebuildVSchemaGraphResponse - (*vtctldata.RefreshStateResponse)(nil), // 175: vtctldata.RefreshStateResponse - (*vtctldata.RefreshStateByShardResponse)(nil), // 176: vtctldata.RefreshStateByShardResponse - (*vtctldata.ReloadSchemaResponse)(nil), // 177: vtctldata.ReloadSchemaResponse - (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 178: vtctldata.ReloadSchemaKeyspaceResponse - (*vtctldata.ReloadSchemaShardResponse)(nil), // 179: vtctldata.ReloadSchemaShardResponse - (*vtctldata.RemoveBackupResponse)(nil), // 180: vtctldata.RemoveBackupResponse - (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 181: vtctldata.RemoveKeyspaceCellResponse - (*vtctldata.RemoveShardCellResponse)(nil), // 182: vtctldata.RemoveShardCellResponse - (*vtctldata.ReparentTabletResponse)(nil), // 183: vtctldata.ReparentTabletResponse - (*vtctldata.RestoreFromBackupResponse)(nil), // 184: vtctldata.RestoreFromBackupResponse - (*vtctldata.RetrySchemaMigrationResponse)(nil), // 185: vtctldata.RetrySchemaMigrationResponse - (*vtctldata.RunHealthCheckResponse)(nil), // 186: vtctldata.RunHealthCheckResponse - (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 187: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 188: vtctldata.SetShardIsPrimaryServingResponse - (*vtctldata.SetShardTabletControlResponse)(nil), // 189: vtctldata.SetShardTabletControlResponse - (*vtctldata.SetWritableResponse)(nil), // 190: vtctldata.SetWritableResponse - (*vtctldata.ShardReplicationAddResponse)(nil), // 191: vtctldata.ShardReplicationAddResponse - (*vtctldata.ShardReplicationFixResponse)(nil), // 192: vtctldata.ShardReplicationFixResponse - (*vtctldata.ShardReplicationPositionsResponse)(nil), // 193: vtctldata.ShardReplicationPositionsResponse - (*vtctldata.ShardReplicationRemoveResponse)(nil), // 194: vtctldata.ShardReplicationRemoveResponse - (*vtctldata.SleepTabletResponse)(nil), // 195: vtctldata.SleepTabletResponse - (*vtctldata.SourceShardAddResponse)(nil), // 196: vtctldata.SourceShardAddResponse - (*vtctldata.SourceShardDeleteResponse)(nil), // 197: vtctldata.SourceShardDeleteResponse - (*vtctldata.StartReplicationResponse)(nil), // 198: vtctldata.StartReplicationResponse - (*vtctldata.StopReplicationResponse)(nil), // 199: vtctldata.StopReplicationResponse - (*vtctldata.TabletExternallyReparentedResponse)(nil), // 200: vtctldata.TabletExternallyReparentedResponse - (*vtctldata.UpdateCellInfoResponse)(nil), // 201: vtctldata.UpdateCellInfoResponse - (*vtctldata.UpdateCellsAliasResponse)(nil), // 202: vtctldata.UpdateCellsAliasResponse - (*vtctldata.ValidateResponse)(nil), // 203: vtctldata.ValidateResponse - (*vtctldata.ValidateKeyspaceResponse)(nil), // 204: vtctldata.ValidateKeyspaceResponse - (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 205: vtctldata.ValidateSchemaKeyspaceResponse - (*vtctldata.ValidateShardResponse)(nil), // 206: vtctldata.ValidateShardResponse - (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 207: vtctldata.ValidateVersionKeyspaceResponse - (*vtctldata.ValidateVersionShardResponse)(nil), // 208: vtctldata.ValidateVersionShardResponse - (*vtctldata.ValidateVSchemaResponse)(nil), // 209: vtctldata.ValidateVSchemaResponse - (*vtctldata.VDiffCreateResponse)(nil), // 210: vtctldata.VDiffCreateResponse - (*vtctldata.VDiffDeleteResponse)(nil), // 211: vtctldata.VDiffDeleteResponse - (*vtctldata.VDiffResumeResponse)(nil), // 212: vtctldata.VDiffResumeResponse - (*vtctldata.VDiffShowResponse)(nil), // 213: vtctldata.VDiffShowResponse - (*vtctldata.VDiffStopResponse)(nil), // 214: vtctldata.VDiffStopResponse - (*vtctldata.WorkflowDeleteResponse)(nil), // 215: vtctldata.WorkflowDeleteResponse - (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 216: vtctldata.WorkflowSwitchTrafficResponse - (*vtctldata.WorkflowUpdateResponse)(nil), // 217: vtctldata.WorkflowUpdateResponse + (*vtctldata.ForceCutOverSchemaMigrationRequest)(nil), // 26: vtctldata.ForceCutOverSchemaMigrationRequest + (*vtctldata.GetBackupsRequest)(nil), // 27: vtctldata.GetBackupsRequest + (*vtctldata.GetCellInfoRequest)(nil), // 28: vtctldata.GetCellInfoRequest + (*vtctldata.GetCellInfoNamesRequest)(nil), // 29: vtctldata.GetCellInfoNamesRequest + (*vtctldata.GetCellsAliasesRequest)(nil), // 30: vtctldata.GetCellsAliasesRequest + (*vtctldata.GetFullStatusRequest)(nil), // 31: vtctldata.GetFullStatusRequest + (*vtctldata.GetKeyspaceRequest)(nil), // 32: vtctldata.GetKeyspaceRequest + (*vtctldata.GetKeyspacesRequest)(nil), // 33: vtctldata.GetKeyspacesRequest + (*vtctldata.GetPermissionsRequest)(nil), // 34: vtctldata.GetPermissionsRequest + (*vtctldata.GetRoutingRulesRequest)(nil), // 35: vtctldata.GetRoutingRulesRequest + (*vtctldata.GetSchemaRequest)(nil), // 36: vtctldata.GetSchemaRequest + (*vtctldata.GetSchemaMigrationsRequest)(nil), // 37: vtctldata.GetSchemaMigrationsRequest + (*vtctldata.GetShardRequest)(nil), // 38: vtctldata.GetShardRequest + (*vtctldata.GetShardRoutingRulesRequest)(nil), // 39: vtctldata.GetShardRoutingRulesRequest + (*vtctldata.GetSrvKeyspaceNamesRequest)(nil), // 40: vtctldata.GetSrvKeyspaceNamesRequest + (*vtctldata.GetSrvKeyspacesRequest)(nil), // 41: vtctldata.GetSrvKeyspacesRequest + (*vtctldata.UpdateThrottlerConfigRequest)(nil), // 42: vtctldata.UpdateThrottlerConfigRequest + (*vtctldata.GetSrvVSchemaRequest)(nil), // 43: vtctldata.GetSrvVSchemaRequest + (*vtctldata.GetSrvVSchemasRequest)(nil), // 44: vtctldata.GetSrvVSchemasRequest + (*vtctldata.GetTabletRequest)(nil), // 45: vtctldata.GetTabletRequest + (*vtctldata.GetTabletsRequest)(nil), // 46: vtctldata.GetTabletsRequest + (*vtctldata.GetTopologyPathRequest)(nil), // 47: vtctldata.GetTopologyPathRequest + (*vtctldata.GetVersionRequest)(nil), // 48: vtctldata.GetVersionRequest + (*vtctldata.GetVSchemaRequest)(nil), // 49: vtctldata.GetVSchemaRequest + (*vtctldata.GetWorkflowsRequest)(nil), // 50: vtctldata.GetWorkflowsRequest + (*vtctldata.InitShardPrimaryRequest)(nil), // 51: vtctldata.InitShardPrimaryRequest + (*vtctldata.LaunchSchemaMigrationRequest)(nil), // 52: vtctldata.LaunchSchemaMigrationRequest + (*vtctldata.LookupVindexCreateRequest)(nil), // 53: vtctldata.LookupVindexCreateRequest + (*vtctldata.LookupVindexExternalizeRequest)(nil), // 54: vtctldata.LookupVindexExternalizeRequest + (*vtctldata.MaterializeCreateRequest)(nil), // 55: vtctldata.MaterializeCreateRequest + (*vtctldata.MigrateCreateRequest)(nil), // 56: vtctldata.MigrateCreateRequest + (*vtctldata.MountRegisterRequest)(nil), // 57: vtctldata.MountRegisterRequest + (*vtctldata.MountUnregisterRequest)(nil), // 58: vtctldata.MountUnregisterRequest + (*vtctldata.MountShowRequest)(nil), // 59: vtctldata.MountShowRequest + (*vtctldata.MountListRequest)(nil), // 60: vtctldata.MountListRequest + (*vtctldata.MoveTablesCreateRequest)(nil), // 61: vtctldata.MoveTablesCreateRequest + (*vtctldata.MoveTablesCompleteRequest)(nil), // 62: vtctldata.MoveTablesCompleteRequest + (*vtctldata.PingTabletRequest)(nil), // 63: vtctldata.PingTabletRequest + (*vtctldata.PlannedReparentShardRequest)(nil), // 64: vtctldata.PlannedReparentShardRequest + (*vtctldata.RebuildKeyspaceGraphRequest)(nil), // 65: vtctldata.RebuildKeyspaceGraphRequest + (*vtctldata.RebuildVSchemaGraphRequest)(nil), // 66: vtctldata.RebuildVSchemaGraphRequest + (*vtctldata.RefreshStateRequest)(nil), // 67: vtctldata.RefreshStateRequest + (*vtctldata.RefreshStateByShardRequest)(nil), // 68: vtctldata.RefreshStateByShardRequest + (*vtctldata.ReloadSchemaRequest)(nil), // 69: vtctldata.ReloadSchemaRequest + (*vtctldata.ReloadSchemaKeyspaceRequest)(nil), // 70: vtctldata.ReloadSchemaKeyspaceRequest + (*vtctldata.ReloadSchemaShardRequest)(nil), // 71: vtctldata.ReloadSchemaShardRequest + (*vtctldata.RemoveBackupRequest)(nil), // 72: vtctldata.RemoveBackupRequest + (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 73: vtctldata.RemoveKeyspaceCellRequest + (*vtctldata.RemoveShardCellRequest)(nil), // 74: vtctldata.RemoveShardCellRequest + (*vtctldata.ReparentTabletRequest)(nil), // 75: vtctldata.ReparentTabletRequest + (*vtctldata.ReshardCreateRequest)(nil), // 76: vtctldata.ReshardCreateRequest + (*vtctldata.RestoreFromBackupRequest)(nil), // 77: vtctldata.RestoreFromBackupRequest + (*vtctldata.RetrySchemaMigrationRequest)(nil), // 78: vtctldata.RetrySchemaMigrationRequest + (*vtctldata.RunHealthCheckRequest)(nil), // 79: vtctldata.RunHealthCheckRequest + (*vtctldata.SetKeyspaceDurabilityPolicyRequest)(nil), // 80: vtctldata.SetKeyspaceDurabilityPolicyRequest + (*vtctldata.SetShardIsPrimaryServingRequest)(nil), // 81: vtctldata.SetShardIsPrimaryServingRequest + (*vtctldata.SetShardTabletControlRequest)(nil), // 82: vtctldata.SetShardTabletControlRequest + (*vtctldata.SetWritableRequest)(nil), // 83: vtctldata.SetWritableRequest + (*vtctldata.ShardReplicationAddRequest)(nil), // 84: vtctldata.ShardReplicationAddRequest + (*vtctldata.ShardReplicationFixRequest)(nil), // 85: vtctldata.ShardReplicationFixRequest + (*vtctldata.ShardReplicationPositionsRequest)(nil), // 86: vtctldata.ShardReplicationPositionsRequest + (*vtctldata.ShardReplicationRemoveRequest)(nil), // 87: vtctldata.ShardReplicationRemoveRequest + (*vtctldata.SleepTabletRequest)(nil), // 88: vtctldata.SleepTabletRequest + (*vtctldata.SourceShardAddRequest)(nil), // 89: vtctldata.SourceShardAddRequest + (*vtctldata.SourceShardDeleteRequest)(nil), // 90: vtctldata.SourceShardDeleteRequest + (*vtctldata.StartReplicationRequest)(nil), // 91: vtctldata.StartReplicationRequest + (*vtctldata.StopReplicationRequest)(nil), // 92: vtctldata.StopReplicationRequest + (*vtctldata.TabletExternallyReparentedRequest)(nil), // 93: vtctldata.TabletExternallyReparentedRequest + (*vtctldata.UpdateCellInfoRequest)(nil), // 94: vtctldata.UpdateCellInfoRequest + (*vtctldata.UpdateCellsAliasRequest)(nil), // 95: vtctldata.UpdateCellsAliasRequest + (*vtctldata.ValidateRequest)(nil), // 96: vtctldata.ValidateRequest + (*vtctldata.ValidateKeyspaceRequest)(nil), // 97: vtctldata.ValidateKeyspaceRequest + (*vtctldata.ValidateSchemaKeyspaceRequest)(nil), // 98: vtctldata.ValidateSchemaKeyspaceRequest + (*vtctldata.ValidateShardRequest)(nil), // 99: vtctldata.ValidateShardRequest + (*vtctldata.ValidateVersionKeyspaceRequest)(nil), // 100: vtctldata.ValidateVersionKeyspaceRequest + (*vtctldata.ValidateVersionShardRequest)(nil), // 101: vtctldata.ValidateVersionShardRequest + (*vtctldata.ValidateVSchemaRequest)(nil), // 102: vtctldata.ValidateVSchemaRequest + (*vtctldata.VDiffCreateRequest)(nil), // 103: vtctldata.VDiffCreateRequest + (*vtctldata.VDiffDeleteRequest)(nil), // 104: vtctldata.VDiffDeleteRequest + (*vtctldata.VDiffResumeRequest)(nil), // 105: vtctldata.VDiffResumeRequest + (*vtctldata.VDiffShowRequest)(nil), // 106: vtctldata.VDiffShowRequest + (*vtctldata.VDiffStopRequest)(nil), // 107: vtctldata.VDiffStopRequest + (*vtctldata.WorkflowDeleteRequest)(nil), // 108: vtctldata.WorkflowDeleteRequest + (*vtctldata.WorkflowStatusRequest)(nil), // 109: vtctldata.WorkflowStatusRequest + (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 110: vtctldata.WorkflowSwitchTrafficRequest + (*vtctldata.WorkflowUpdateRequest)(nil), // 111: vtctldata.WorkflowUpdateRequest + (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 112: vtctldata.ExecuteVtctlCommandResponse + (*vtctldata.AddCellInfoResponse)(nil), // 113: vtctldata.AddCellInfoResponse + (*vtctldata.AddCellsAliasResponse)(nil), // 114: vtctldata.AddCellsAliasResponse + (*vtctldata.ApplyRoutingRulesResponse)(nil), // 115: vtctldata.ApplyRoutingRulesResponse + (*vtctldata.ApplySchemaResponse)(nil), // 116: vtctldata.ApplySchemaResponse + (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 117: vtctldata.ApplyShardRoutingRulesResponse + (*vtctldata.ApplyVSchemaResponse)(nil), // 118: vtctldata.ApplyVSchemaResponse + (*vtctldata.BackupResponse)(nil), // 119: vtctldata.BackupResponse + (*vtctldata.CancelSchemaMigrationResponse)(nil), // 120: vtctldata.CancelSchemaMigrationResponse + (*vtctldata.ChangeTabletTypeResponse)(nil), // 121: vtctldata.ChangeTabletTypeResponse + (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 122: vtctldata.CleanupSchemaMigrationResponse + (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 123: vtctldata.CompleteSchemaMigrationResponse + (*vtctldata.CreateKeyspaceResponse)(nil), // 124: vtctldata.CreateKeyspaceResponse + (*vtctldata.CreateShardResponse)(nil), // 125: vtctldata.CreateShardResponse + (*vtctldata.DeleteCellInfoResponse)(nil), // 126: vtctldata.DeleteCellInfoResponse + (*vtctldata.DeleteCellsAliasResponse)(nil), // 127: vtctldata.DeleteCellsAliasResponse + (*vtctldata.DeleteKeyspaceResponse)(nil), // 128: vtctldata.DeleteKeyspaceResponse + (*vtctldata.DeleteShardsResponse)(nil), // 129: vtctldata.DeleteShardsResponse + (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 130: vtctldata.DeleteSrvVSchemaResponse + (*vtctldata.DeleteTabletsResponse)(nil), // 131: vtctldata.DeleteTabletsResponse + (*vtctldata.EmergencyReparentShardResponse)(nil), // 132: vtctldata.EmergencyReparentShardResponse + (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 133: vtctldata.ExecuteFetchAsAppResponse + (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 134: vtctldata.ExecuteFetchAsDBAResponse + (*vtctldata.ExecuteHookResponse)(nil), // 135: vtctldata.ExecuteHookResponse + (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 136: vtctldata.FindAllShardsInKeyspaceResponse + (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 137: vtctldata.ForceCutOverSchemaMigrationResponse + (*vtctldata.GetBackupsResponse)(nil), // 138: vtctldata.GetBackupsResponse + (*vtctldata.GetCellInfoResponse)(nil), // 139: vtctldata.GetCellInfoResponse + (*vtctldata.GetCellInfoNamesResponse)(nil), // 140: vtctldata.GetCellInfoNamesResponse + (*vtctldata.GetCellsAliasesResponse)(nil), // 141: vtctldata.GetCellsAliasesResponse + (*vtctldata.GetFullStatusResponse)(nil), // 142: vtctldata.GetFullStatusResponse + (*vtctldata.GetKeyspaceResponse)(nil), // 143: vtctldata.GetKeyspaceResponse + (*vtctldata.GetKeyspacesResponse)(nil), // 144: vtctldata.GetKeyspacesResponse + (*vtctldata.GetPermissionsResponse)(nil), // 145: vtctldata.GetPermissionsResponse + (*vtctldata.GetRoutingRulesResponse)(nil), // 146: vtctldata.GetRoutingRulesResponse + (*vtctldata.GetSchemaResponse)(nil), // 147: vtctldata.GetSchemaResponse + (*vtctldata.GetSchemaMigrationsResponse)(nil), // 148: vtctldata.GetSchemaMigrationsResponse + (*vtctldata.GetShardResponse)(nil), // 149: vtctldata.GetShardResponse + (*vtctldata.GetShardRoutingRulesResponse)(nil), // 150: vtctldata.GetShardRoutingRulesResponse + (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 151: vtctldata.GetSrvKeyspaceNamesResponse + (*vtctldata.GetSrvKeyspacesResponse)(nil), // 152: vtctldata.GetSrvKeyspacesResponse + (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 153: vtctldata.UpdateThrottlerConfigResponse + (*vtctldata.GetSrvVSchemaResponse)(nil), // 154: vtctldata.GetSrvVSchemaResponse + (*vtctldata.GetSrvVSchemasResponse)(nil), // 155: vtctldata.GetSrvVSchemasResponse + (*vtctldata.GetTabletResponse)(nil), // 156: vtctldata.GetTabletResponse + (*vtctldata.GetTabletsResponse)(nil), // 157: vtctldata.GetTabletsResponse + (*vtctldata.GetTopologyPathResponse)(nil), // 158: vtctldata.GetTopologyPathResponse + (*vtctldata.GetVersionResponse)(nil), // 159: vtctldata.GetVersionResponse + (*vtctldata.GetVSchemaResponse)(nil), // 160: vtctldata.GetVSchemaResponse + (*vtctldata.GetWorkflowsResponse)(nil), // 161: vtctldata.GetWorkflowsResponse + (*vtctldata.InitShardPrimaryResponse)(nil), // 162: vtctldata.InitShardPrimaryResponse + (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 163: vtctldata.LaunchSchemaMigrationResponse + (*vtctldata.LookupVindexCreateResponse)(nil), // 164: vtctldata.LookupVindexCreateResponse + (*vtctldata.LookupVindexExternalizeResponse)(nil), // 165: vtctldata.LookupVindexExternalizeResponse + (*vtctldata.MaterializeCreateResponse)(nil), // 166: vtctldata.MaterializeCreateResponse + (*vtctldata.WorkflowStatusResponse)(nil), // 167: vtctldata.WorkflowStatusResponse + (*vtctldata.MountRegisterResponse)(nil), // 168: vtctldata.MountRegisterResponse + (*vtctldata.MountUnregisterResponse)(nil), // 169: vtctldata.MountUnregisterResponse + (*vtctldata.MountShowResponse)(nil), // 170: vtctldata.MountShowResponse + (*vtctldata.MountListResponse)(nil), // 171: vtctldata.MountListResponse + (*vtctldata.MoveTablesCompleteResponse)(nil), // 172: vtctldata.MoveTablesCompleteResponse + (*vtctldata.PingTabletResponse)(nil), // 173: vtctldata.PingTabletResponse + (*vtctldata.PlannedReparentShardResponse)(nil), // 174: vtctldata.PlannedReparentShardResponse + (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 175: vtctldata.RebuildKeyspaceGraphResponse + (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 176: vtctldata.RebuildVSchemaGraphResponse + (*vtctldata.RefreshStateResponse)(nil), // 177: vtctldata.RefreshStateResponse + (*vtctldata.RefreshStateByShardResponse)(nil), // 178: vtctldata.RefreshStateByShardResponse + (*vtctldata.ReloadSchemaResponse)(nil), // 179: vtctldata.ReloadSchemaResponse + (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 180: vtctldata.ReloadSchemaKeyspaceResponse + (*vtctldata.ReloadSchemaShardResponse)(nil), // 181: vtctldata.ReloadSchemaShardResponse + (*vtctldata.RemoveBackupResponse)(nil), // 182: vtctldata.RemoveBackupResponse + (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 183: vtctldata.RemoveKeyspaceCellResponse + (*vtctldata.RemoveShardCellResponse)(nil), // 184: vtctldata.RemoveShardCellResponse + (*vtctldata.ReparentTabletResponse)(nil), // 185: vtctldata.ReparentTabletResponse + (*vtctldata.RestoreFromBackupResponse)(nil), // 186: vtctldata.RestoreFromBackupResponse + (*vtctldata.RetrySchemaMigrationResponse)(nil), // 187: vtctldata.RetrySchemaMigrationResponse + (*vtctldata.RunHealthCheckResponse)(nil), // 188: vtctldata.RunHealthCheckResponse + (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 189: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 190: vtctldata.SetShardIsPrimaryServingResponse + (*vtctldata.SetShardTabletControlResponse)(nil), // 191: vtctldata.SetShardTabletControlResponse + (*vtctldata.SetWritableResponse)(nil), // 192: vtctldata.SetWritableResponse + (*vtctldata.ShardReplicationAddResponse)(nil), // 193: vtctldata.ShardReplicationAddResponse + (*vtctldata.ShardReplicationFixResponse)(nil), // 194: vtctldata.ShardReplicationFixResponse + (*vtctldata.ShardReplicationPositionsResponse)(nil), // 195: vtctldata.ShardReplicationPositionsResponse + (*vtctldata.ShardReplicationRemoveResponse)(nil), // 196: vtctldata.ShardReplicationRemoveResponse + (*vtctldata.SleepTabletResponse)(nil), // 197: vtctldata.SleepTabletResponse + (*vtctldata.SourceShardAddResponse)(nil), // 198: vtctldata.SourceShardAddResponse + (*vtctldata.SourceShardDeleteResponse)(nil), // 199: vtctldata.SourceShardDeleteResponse + (*vtctldata.StartReplicationResponse)(nil), // 200: vtctldata.StartReplicationResponse + (*vtctldata.StopReplicationResponse)(nil), // 201: vtctldata.StopReplicationResponse + (*vtctldata.TabletExternallyReparentedResponse)(nil), // 202: vtctldata.TabletExternallyReparentedResponse + (*vtctldata.UpdateCellInfoResponse)(nil), // 203: vtctldata.UpdateCellInfoResponse + (*vtctldata.UpdateCellsAliasResponse)(nil), // 204: vtctldata.UpdateCellsAliasResponse + (*vtctldata.ValidateResponse)(nil), // 205: vtctldata.ValidateResponse + (*vtctldata.ValidateKeyspaceResponse)(nil), // 206: vtctldata.ValidateKeyspaceResponse + (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 207: vtctldata.ValidateSchemaKeyspaceResponse + (*vtctldata.ValidateShardResponse)(nil), // 208: vtctldata.ValidateShardResponse + (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 209: vtctldata.ValidateVersionKeyspaceResponse + (*vtctldata.ValidateVersionShardResponse)(nil), // 210: vtctldata.ValidateVersionShardResponse + (*vtctldata.ValidateVSchemaResponse)(nil), // 211: vtctldata.ValidateVSchemaResponse + (*vtctldata.VDiffCreateResponse)(nil), // 212: vtctldata.VDiffCreateResponse + (*vtctldata.VDiffDeleteResponse)(nil), // 213: vtctldata.VDiffDeleteResponse + (*vtctldata.VDiffResumeResponse)(nil), // 214: vtctldata.VDiffResumeResponse + (*vtctldata.VDiffShowResponse)(nil), // 215: vtctldata.VDiffShowResponse + (*vtctldata.VDiffStopResponse)(nil), // 216: vtctldata.VDiffStopResponse + (*vtctldata.WorkflowDeleteResponse)(nil), // 217: vtctldata.WorkflowDeleteResponse + (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 218: vtctldata.WorkflowSwitchTrafficResponse + (*vtctldata.WorkflowUpdateResponse)(nil), // 219: vtctldata.WorkflowUpdateResponse } var file_vtctlservice_proto_depIdxs = []int32{ 0, // 0: vtctlservice.Vtctl.ExecuteVtctlCommand:input_type -> vtctldata.ExecuteVtctlCommandRequest @@ -946,204 +956,206 @@ var file_vtctlservice_proto_depIdxs = []int32{ 23, // 23: vtctlservice.Vtctld.ExecuteFetchAsDBA:input_type -> vtctldata.ExecuteFetchAsDBARequest 24, // 24: vtctlservice.Vtctld.ExecuteHook:input_type -> vtctldata.ExecuteHookRequest 25, // 25: vtctlservice.Vtctld.FindAllShardsInKeyspace:input_type -> vtctldata.FindAllShardsInKeyspaceRequest - 26, // 26: vtctlservice.Vtctld.GetBackups:input_type -> vtctldata.GetBackupsRequest - 27, // 27: vtctlservice.Vtctld.GetCellInfo:input_type -> vtctldata.GetCellInfoRequest - 28, // 28: vtctlservice.Vtctld.GetCellInfoNames:input_type -> vtctldata.GetCellInfoNamesRequest - 29, // 29: vtctlservice.Vtctld.GetCellsAliases:input_type -> vtctldata.GetCellsAliasesRequest - 30, // 30: vtctlservice.Vtctld.GetFullStatus:input_type -> vtctldata.GetFullStatusRequest - 31, // 31: vtctlservice.Vtctld.GetKeyspace:input_type -> vtctldata.GetKeyspaceRequest - 32, // 32: vtctlservice.Vtctld.GetKeyspaces:input_type -> vtctldata.GetKeyspacesRequest - 33, // 33: vtctlservice.Vtctld.GetPermissions:input_type -> vtctldata.GetPermissionsRequest - 34, // 34: vtctlservice.Vtctld.GetRoutingRules:input_type -> vtctldata.GetRoutingRulesRequest - 35, // 35: vtctlservice.Vtctld.GetSchema:input_type -> vtctldata.GetSchemaRequest - 36, // 36: vtctlservice.Vtctld.GetSchemaMigrations:input_type -> vtctldata.GetSchemaMigrationsRequest - 37, // 37: vtctlservice.Vtctld.GetShard:input_type -> vtctldata.GetShardRequest - 38, // 38: vtctlservice.Vtctld.GetShardRoutingRules:input_type -> vtctldata.GetShardRoutingRulesRequest - 39, // 39: vtctlservice.Vtctld.GetSrvKeyspaceNames:input_type -> vtctldata.GetSrvKeyspaceNamesRequest - 40, // 40: vtctlservice.Vtctld.GetSrvKeyspaces:input_type -> vtctldata.GetSrvKeyspacesRequest - 41, // 41: vtctlservice.Vtctld.UpdateThrottlerConfig:input_type -> vtctldata.UpdateThrottlerConfigRequest - 42, // 42: vtctlservice.Vtctld.GetSrvVSchema:input_type -> vtctldata.GetSrvVSchemaRequest - 43, // 43: vtctlservice.Vtctld.GetSrvVSchemas:input_type -> vtctldata.GetSrvVSchemasRequest - 44, // 44: vtctlservice.Vtctld.GetTablet:input_type -> vtctldata.GetTabletRequest - 45, // 45: vtctlservice.Vtctld.GetTablets:input_type -> vtctldata.GetTabletsRequest - 46, // 46: vtctlservice.Vtctld.GetTopologyPath:input_type -> vtctldata.GetTopologyPathRequest - 47, // 47: vtctlservice.Vtctld.GetVersion:input_type -> vtctldata.GetVersionRequest - 48, // 48: vtctlservice.Vtctld.GetVSchema:input_type -> vtctldata.GetVSchemaRequest - 49, // 49: vtctlservice.Vtctld.GetWorkflows:input_type -> vtctldata.GetWorkflowsRequest - 50, // 50: vtctlservice.Vtctld.InitShardPrimary:input_type -> vtctldata.InitShardPrimaryRequest - 51, // 51: vtctlservice.Vtctld.LaunchSchemaMigration:input_type -> vtctldata.LaunchSchemaMigrationRequest - 52, // 52: vtctlservice.Vtctld.LookupVindexCreate:input_type -> vtctldata.LookupVindexCreateRequest - 53, // 53: vtctlservice.Vtctld.LookupVindexExternalize:input_type -> vtctldata.LookupVindexExternalizeRequest - 54, // 54: vtctlservice.Vtctld.MaterializeCreate:input_type -> vtctldata.MaterializeCreateRequest - 55, // 55: vtctlservice.Vtctld.MigrateCreate:input_type -> vtctldata.MigrateCreateRequest - 56, // 56: vtctlservice.Vtctld.MountRegister:input_type -> vtctldata.MountRegisterRequest - 57, // 57: vtctlservice.Vtctld.MountUnregister:input_type -> vtctldata.MountUnregisterRequest - 58, // 58: vtctlservice.Vtctld.MountShow:input_type -> vtctldata.MountShowRequest - 59, // 59: vtctlservice.Vtctld.MountList:input_type -> vtctldata.MountListRequest - 60, // 60: vtctlservice.Vtctld.MoveTablesCreate:input_type -> vtctldata.MoveTablesCreateRequest - 61, // 61: vtctlservice.Vtctld.MoveTablesComplete:input_type -> vtctldata.MoveTablesCompleteRequest - 62, // 62: vtctlservice.Vtctld.PingTablet:input_type -> vtctldata.PingTabletRequest - 63, // 63: vtctlservice.Vtctld.PlannedReparentShard:input_type -> vtctldata.PlannedReparentShardRequest - 64, // 64: vtctlservice.Vtctld.RebuildKeyspaceGraph:input_type -> vtctldata.RebuildKeyspaceGraphRequest - 65, // 65: vtctlservice.Vtctld.RebuildVSchemaGraph:input_type -> vtctldata.RebuildVSchemaGraphRequest - 66, // 66: vtctlservice.Vtctld.RefreshState:input_type -> vtctldata.RefreshStateRequest - 67, // 67: vtctlservice.Vtctld.RefreshStateByShard:input_type -> vtctldata.RefreshStateByShardRequest - 68, // 68: vtctlservice.Vtctld.ReloadSchema:input_type -> vtctldata.ReloadSchemaRequest - 69, // 69: vtctlservice.Vtctld.ReloadSchemaKeyspace:input_type -> vtctldata.ReloadSchemaKeyspaceRequest - 70, // 70: vtctlservice.Vtctld.ReloadSchemaShard:input_type -> vtctldata.ReloadSchemaShardRequest - 71, // 71: vtctlservice.Vtctld.RemoveBackup:input_type -> vtctldata.RemoveBackupRequest - 72, // 72: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest - 73, // 73: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest - 74, // 74: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest - 75, // 75: vtctlservice.Vtctld.ReshardCreate:input_type -> vtctldata.ReshardCreateRequest - 76, // 76: vtctlservice.Vtctld.RestoreFromBackup:input_type -> vtctldata.RestoreFromBackupRequest - 77, // 77: vtctlservice.Vtctld.RetrySchemaMigration:input_type -> vtctldata.RetrySchemaMigrationRequest - 78, // 78: vtctlservice.Vtctld.RunHealthCheck:input_type -> vtctldata.RunHealthCheckRequest - 79, // 79: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:input_type -> vtctldata.SetKeyspaceDurabilityPolicyRequest - 80, // 80: vtctlservice.Vtctld.SetShardIsPrimaryServing:input_type -> vtctldata.SetShardIsPrimaryServingRequest - 81, // 81: vtctlservice.Vtctld.SetShardTabletControl:input_type -> vtctldata.SetShardTabletControlRequest - 82, // 82: vtctlservice.Vtctld.SetWritable:input_type -> vtctldata.SetWritableRequest - 83, // 83: vtctlservice.Vtctld.ShardReplicationAdd:input_type -> vtctldata.ShardReplicationAddRequest - 84, // 84: vtctlservice.Vtctld.ShardReplicationFix:input_type -> vtctldata.ShardReplicationFixRequest - 85, // 85: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest - 86, // 86: vtctlservice.Vtctld.ShardReplicationRemove:input_type -> vtctldata.ShardReplicationRemoveRequest - 87, // 87: vtctlservice.Vtctld.SleepTablet:input_type -> vtctldata.SleepTabletRequest - 88, // 88: vtctlservice.Vtctld.SourceShardAdd:input_type -> vtctldata.SourceShardAddRequest - 89, // 89: vtctlservice.Vtctld.SourceShardDelete:input_type -> vtctldata.SourceShardDeleteRequest - 90, // 90: vtctlservice.Vtctld.StartReplication:input_type -> vtctldata.StartReplicationRequest - 91, // 91: vtctlservice.Vtctld.StopReplication:input_type -> vtctldata.StopReplicationRequest - 92, // 92: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest - 93, // 93: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest - 94, // 94: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest - 95, // 95: vtctlservice.Vtctld.Validate:input_type -> vtctldata.ValidateRequest - 96, // 96: vtctlservice.Vtctld.ValidateKeyspace:input_type -> vtctldata.ValidateKeyspaceRequest - 97, // 97: vtctlservice.Vtctld.ValidateSchemaKeyspace:input_type -> vtctldata.ValidateSchemaKeyspaceRequest - 98, // 98: vtctlservice.Vtctld.ValidateShard:input_type -> vtctldata.ValidateShardRequest - 99, // 99: vtctlservice.Vtctld.ValidateVersionKeyspace:input_type -> vtctldata.ValidateVersionKeyspaceRequest - 100, // 100: vtctlservice.Vtctld.ValidateVersionShard:input_type -> vtctldata.ValidateVersionShardRequest - 101, // 101: vtctlservice.Vtctld.ValidateVSchema:input_type -> vtctldata.ValidateVSchemaRequest - 102, // 102: vtctlservice.Vtctld.VDiffCreate:input_type -> vtctldata.VDiffCreateRequest - 103, // 103: vtctlservice.Vtctld.VDiffDelete:input_type -> vtctldata.VDiffDeleteRequest - 104, // 104: vtctlservice.Vtctld.VDiffResume:input_type -> vtctldata.VDiffResumeRequest - 105, // 105: vtctlservice.Vtctld.VDiffShow:input_type -> vtctldata.VDiffShowRequest - 106, // 106: vtctlservice.Vtctld.VDiffStop:input_type -> vtctldata.VDiffStopRequest - 107, // 107: vtctlservice.Vtctld.WorkflowDelete:input_type -> vtctldata.WorkflowDeleteRequest - 108, // 108: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest - 109, // 109: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest - 110, // 110: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest - 111, // 111: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse - 112, // 112: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse - 113, // 113: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse - 114, // 114: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse - 115, // 115: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse - 116, // 116: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse - 117, // 117: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse - 118, // 118: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse - 118, // 119: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse - 119, // 120: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse - 120, // 121: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse - 121, // 122: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse - 122, // 123: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse - 123, // 124: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse - 124, // 125: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse - 125, // 126: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse - 126, // 127: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse - 127, // 128: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse - 128, // 129: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse - 129, // 130: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse - 130, // 131: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse - 131, // 132: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse - 132, // 133: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse - 133, // 134: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse - 134, // 135: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse - 135, // 136: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse - 136, // 137: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse - 137, // 138: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse - 138, // 139: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse - 139, // 140: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse - 140, // 141: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse - 141, // 142: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse - 142, // 143: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse - 143, // 144: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse - 144, // 145: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse - 145, // 146: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse - 146, // 147: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse - 147, // 148: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse - 148, // 149: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse - 149, // 150: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse - 150, // 151: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse - 151, // 152: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse - 152, // 153: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse - 153, // 154: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse - 154, // 155: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse - 155, // 156: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse - 156, // 157: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse - 157, // 158: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse - 158, // 159: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse - 159, // 160: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse - 160, // 161: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse - 161, // 162: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse - 162, // 163: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse - 163, // 164: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse - 164, // 165: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse - 165, // 166: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse - 166, // 167: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse - 167, // 168: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse - 168, // 169: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse - 169, // 170: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse - 165, // 171: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse - 170, // 172: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse - 171, // 173: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse - 172, // 174: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse - 173, // 175: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse - 174, // 176: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse - 175, // 177: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse - 176, // 178: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse - 177, // 179: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse - 178, // 180: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse - 179, // 181: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse - 180, // 182: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse - 181, // 183: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse - 182, // 184: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse - 183, // 185: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse - 165, // 186: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse - 184, // 187: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse - 185, // 188: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse - 186, // 189: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse - 187, // 190: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse - 188, // 191: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse - 189, // 192: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse - 190, // 193: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse - 191, // 194: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse - 192, // 195: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse - 193, // 196: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse - 194, // 197: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse - 195, // 198: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse - 196, // 199: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse - 197, // 200: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse - 198, // 201: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse - 199, // 202: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse - 200, // 203: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse - 201, // 204: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse - 202, // 205: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse - 203, // 206: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse - 204, // 207: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse - 205, // 208: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse - 206, // 209: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse - 207, // 210: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse - 208, // 211: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse - 209, // 212: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse - 210, // 213: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse - 211, // 214: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse - 212, // 215: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse - 213, // 216: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse - 214, // 217: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse - 215, // 218: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse - 165, // 219: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse - 216, // 220: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse - 217, // 221: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse - 111, // [111:222] is the sub-list for method output_type - 0, // [0:111] is the sub-list for method input_type + 26, // 26: vtctlservice.Vtctld.ForceCutOverSchemaMigration:input_type -> vtctldata.ForceCutOverSchemaMigrationRequest + 27, // 27: vtctlservice.Vtctld.GetBackups:input_type -> vtctldata.GetBackupsRequest + 28, // 28: vtctlservice.Vtctld.GetCellInfo:input_type -> vtctldata.GetCellInfoRequest + 29, // 29: vtctlservice.Vtctld.GetCellInfoNames:input_type -> vtctldata.GetCellInfoNamesRequest + 30, // 30: vtctlservice.Vtctld.GetCellsAliases:input_type -> vtctldata.GetCellsAliasesRequest + 31, // 31: vtctlservice.Vtctld.GetFullStatus:input_type -> vtctldata.GetFullStatusRequest + 32, // 32: vtctlservice.Vtctld.GetKeyspace:input_type -> vtctldata.GetKeyspaceRequest + 33, // 33: vtctlservice.Vtctld.GetKeyspaces:input_type -> vtctldata.GetKeyspacesRequest + 34, // 34: vtctlservice.Vtctld.GetPermissions:input_type -> vtctldata.GetPermissionsRequest + 35, // 35: vtctlservice.Vtctld.GetRoutingRules:input_type -> vtctldata.GetRoutingRulesRequest + 36, // 36: vtctlservice.Vtctld.GetSchema:input_type -> vtctldata.GetSchemaRequest + 37, // 37: vtctlservice.Vtctld.GetSchemaMigrations:input_type -> vtctldata.GetSchemaMigrationsRequest + 38, // 38: vtctlservice.Vtctld.GetShard:input_type -> vtctldata.GetShardRequest + 39, // 39: vtctlservice.Vtctld.GetShardRoutingRules:input_type -> vtctldata.GetShardRoutingRulesRequest + 40, // 40: vtctlservice.Vtctld.GetSrvKeyspaceNames:input_type -> vtctldata.GetSrvKeyspaceNamesRequest + 41, // 41: vtctlservice.Vtctld.GetSrvKeyspaces:input_type -> vtctldata.GetSrvKeyspacesRequest + 42, // 42: vtctlservice.Vtctld.UpdateThrottlerConfig:input_type -> vtctldata.UpdateThrottlerConfigRequest + 43, // 43: vtctlservice.Vtctld.GetSrvVSchema:input_type -> vtctldata.GetSrvVSchemaRequest + 44, // 44: vtctlservice.Vtctld.GetSrvVSchemas:input_type -> vtctldata.GetSrvVSchemasRequest + 45, // 45: vtctlservice.Vtctld.GetTablet:input_type -> vtctldata.GetTabletRequest + 46, // 46: vtctlservice.Vtctld.GetTablets:input_type -> vtctldata.GetTabletsRequest + 47, // 47: vtctlservice.Vtctld.GetTopologyPath:input_type -> vtctldata.GetTopologyPathRequest + 48, // 48: vtctlservice.Vtctld.GetVersion:input_type -> vtctldata.GetVersionRequest + 49, // 49: vtctlservice.Vtctld.GetVSchema:input_type -> vtctldata.GetVSchemaRequest + 50, // 50: vtctlservice.Vtctld.GetWorkflows:input_type -> vtctldata.GetWorkflowsRequest + 51, // 51: vtctlservice.Vtctld.InitShardPrimary:input_type -> vtctldata.InitShardPrimaryRequest + 52, // 52: vtctlservice.Vtctld.LaunchSchemaMigration:input_type -> vtctldata.LaunchSchemaMigrationRequest + 53, // 53: vtctlservice.Vtctld.LookupVindexCreate:input_type -> vtctldata.LookupVindexCreateRequest + 54, // 54: vtctlservice.Vtctld.LookupVindexExternalize:input_type -> vtctldata.LookupVindexExternalizeRequest + 55, // 55: vtctlservice.Vtctld.MaterializeCreate:input_type -> vtctldata.MaterializeCreateRequest + 56, // 56: vtctlservice.Vtctld.MigrateCreate:input_type -> vtctldata.MigrateCreateRequest + 57, // 57: vtctlservice.Vtctld.MountRegister:input_type -> vtctldata.MountRegisterRequest + 58, // 58: vtctlservice.Vtctld.MountUnregister:input_type -> vtctldata.MountUnregisterRequest + 59, // 59: vtctlservice.Vtctld.MountShow:input_type -> vtctldata.MountShowRequest + 60, // 60: vtctlservice.Vtctld.MountList:input_type -> vtctldata.MountListRequest + 61, // 61: vtctlservice.Vtctld.MoveTablesCreate:input_type -> vtctldata.MoveTablesCreateRequest + 62, // 62: vtctlservice.Vtctld.MoveTablesComplete:input_type -> vtctldata.MoveTablesCompleteRequest + 63, // 63: vtctlservice.Vtctld.PingTablet:input_type -> vtctldata.PingTabletRequest + 64, // 64: vtctlservice.Vtctld.PlannedReparentShard:input_type -> vtctldata.PlannedReparentShardRequest + 65, // 65: vtctlservice.Vtctld.RebuildKeyspaceGraph:input_type -> vtctldata.RebuildKeyspaceGraphRequest + 66, // 66: vtctlservice.Vtctld.RebuildVSchemaGraph:input_type -> vtctldata.RebuildVSchemaGraphRequest + 67, // 67: vtctlservice.Vtctld.RefreshState:input_type -> vtctldata.RefreshStateRequest + 68, // 68: vtctlservice.Vtctld.RefreshStateByShard:input_type -> vtctldata.RefreshStateByShardRequest + 69, // 69: vtctlservice.Vtctld.ReloadSchema:input_type -> vtctldata.ReloadSchemaRequest + 70, // 70: vtctlservice.Vtctld.ReloadSchemaKeyspace:input_type -> vtctldata.ReloadSchemaKeyspaceRequest + 71, // 71: vtctlservice.Vtctld.ReloadSchemaShard:input_type -> vtctldata.ReloadSchemaShardRequest + 72, // 72: vtctlservice.Vtctld.RemoveBackup:input_type -> vtctldata.RemoveBackupRequest + 73, // 73: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest + 74, // 74: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest + 75, // 75: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest + 76, // 76: vtctlservice.Vtctld.ReshardCreate:input_type -> vtctldata.ReshardCreateRequest + 77, // 77: vtctlservice.Vtctld.RestoreFromBackup:input_type -> vtctldata.RestoreFromBackupRequest + 78, // 78: vtctlservice.Vtctld.RetrySchemaMigration:input_type -> vtctldata.RetrySchemaMigrationRequest + 79, // 79: vtctlservice.Vtctld.RunHealthCheck:input_type -> vtctldata.RunHealthCheckRequest + 80, // 80: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:input_type -> vtctldata.SetKeyspaceDurabilityPolicyRequest + 81, // 81: vtctlservice.Vtctld.SetShardIsPrimaryServing:input_type -> vtctldata.SetShardIsPrimaryServingRequest + 82, // 82: vtctlservice.Vtctld.SetShardTabletControl:input_type -> vtctldata.SetShardTabletControlRequest + 83, // 83: vtctlservice.Vtctld.SetWritable:input_type -> vtctldata.SetWritableRequest + 84, // 84: vtctlservice.Vtctld.ShardReplicationAdd:input_type -> vtctldata.ShardReplicationAddRequest + 85, // 85: vtctlservice.Vtctld.ShardReplicationFix:input_type -> vtctldata.ShardReplicationFixRequest + 86, // 86: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest + 87, // 87: vtctlservice.Vtctld.ShardReplicationRemove:input_type -> vtctldata.ShardReplicationRemoveRequest + 88, // 88: vtctlservice.Vtctld.SleepTablet:input_type -> vtctldata.SleepTabletRequest + 89, // 89: vtctlservice.Vtctld.SourceShardAdd:input_type -> vtctldata.SourceShardAddRequest + 90, // 90: vtctlservice.Vtctld.SourceShardDelete:input_type -> vtctldata.SourceShardDeleteRequest + 91, // 91: vtctlservice.Vtctld.StartReplication:input_type -> vtctldata.StartReplicationRequest + 92, // 92: vtctlservice.Vtctld.StopReplication:input_type -> vtctldata.StopReplicationRequest + 93, // 93: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest + 94, // 94: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest + 95, // 95: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest + 96, // 96: vtctlservice.Vtctld.Validate:input_type -> vtctldata.ValidateRequest + 97, // 97: vtctlservice.Vtctld.ValidateKeyspace:input_type -> vtctldata.ValidateKeyspaceRequest + 98, // 98: vtctlservice.Vtctld.ValidateSchemaKeyspace:input_type -> vtctldata.ValidateSchemaKeyspaceRequest + 99, // 99: vtctlservice.Vtctld.ValidateShard:input_type -> vtctldata.ValidateShardRequest + 100, // 100: vtctlservice.Vtctld.ValidateVersionKeyspace:input_type -> vtctldata.ValidateVersionKeyspaceRequest + 101, // 101: vtctlservice.Vtctld.ValidateVersionShard:input_type -> vtctldata.ValidateVersionShardRequest + 102, // 102: vtctlservice.Vtctld.ValidateVSchema:input_type -> vtctldata.ValidateVSchemaRequest + 103, // 103: vtctlservice.Vtctld.VDiffCreate:input_type -> vtctldata.VDiffCreateRequest + 104, // 104: vtctlservice.Vtctld.VDiffDelete:input_type -> vtctldata.VDiffDeleteRequest + 105, // 105: vtctlservice.Vtctld.VDiffResume:input_type -> vtctldata.VDiffResumeRequest + 106, // 106: vtctlservice.Vtctld.VDiffShow:input_type -> vtctldata.VDiffShowRequest + 107, // 107: vtctlservice.Vtctld.VDiffStop:input_type -> vtctldata.VDiffStopRequest + 108, // 108: vtctlservice.Vtctld.WorkflowDelete:input_type -> vtctldata.WorkflowDeleteRequest + 109, // 109: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest + 110, // 110: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest + 111, // 111: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest + 112, // 112: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse + 113, // 113: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse + 114, // 114: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse + 115, // 115: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse + 116, // 116: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse + 117, // 117: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse + 118, // 118: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse + 119, // 119: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse + 119, // 120: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse + 120, // 121: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse + 121, // 122: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse + 122, // 123: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse + 123, // 124: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse + 124, // 125: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse + 125, // 126: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse + 126, // 127: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse + 127, // 128: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse + 128, // 129: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse + 129, // 130: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse + 130, // 131: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse + 131, // 132: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse + 132, // 133: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse + 133, // 134: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse + 134, // 135: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse + 135, // 136: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse + 136, // 137: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse + 137, // 138: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse + 138, // 139: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse + 139, // 140: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse + 140, // 141: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse + 141, // 142: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse + 142, // 143: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse + 143, // 144: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse + 144, // 145: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse + 145, // 146: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse + 146, // 147: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse + 147, // 148: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse + 148, // 149: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse + 149, // 150: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse + 150, // 151: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse + 151, // 152: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse + 152, // 153: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse + 153, // 154: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse + 154, // 155: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse + 155, // 156: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse + 156, // 157: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse + 157, // 158: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse + 158, // 159: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse + 159, // 160: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse + 160, // 161: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse + 161, // 162: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse + 162, // 163: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse + 163, // 164: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse + 164, // 165: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse + 165, // 166: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse + 166, // 167: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse + 167, // 168: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse + 168, // 169: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse + 169, // 170: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse + 170, // 171: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse + 171, // 172: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse + 167, // 173: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse + 172, // 174: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse + 173, // 175: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse + 174, // 176: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse + 175, // 177: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse + 176, // 178: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse + 177, // 179: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse + 178, // 180: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse + 179, // 181: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse + 180, // 182: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse + 181, // 183: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse + 182, // 184: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse + 183, // 185: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse + 184, // 186: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse + 185, // 187: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse + 167, // 188: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse + 186, // 189: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse + 187, // 190: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse + 188, // 191: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse + 189, // 192: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse + 190, // 193: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse + 191, // 194: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse + 192, // 195: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse + 193, // 196: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse + 194, // 197: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse + 195, // 198: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse + 196, // 199: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse + 197, // 200: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse + 198, // 201: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse + 199, // 202: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse + 200, // 203: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse + 201, // 204: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse + 202, // 205: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse + 203, // 206: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse + 204, // 207: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse + 205, // 208: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse + 206, // 209: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse + 207, // 210: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse + 208, // 211: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse + 209, // 212: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse + 210, // 213: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse + 211, // 214: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse + 212, // 215: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse + 213, // 216: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse + 214, // 217: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse + 215, // 218: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse + 216, // 219: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse + 217, // 220: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse + 167, // 221: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse + 218, // 222: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse + 219, // 223: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse + 112, // [112:224] is the sub-list for method output_type + 0, // [0:112] 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 f0a73530047..f7996d22231 100644 --- a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go @@ -208,6 +208,8 @@ type VtctldClient interface { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // ForceCutOverSchemaMigration marks a schema migration for forced cut-over. + ForceCutOverSchemaMigration(ctx context.Context, in *vtctldata.ForceCutOverSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldata.ForceCutOverSchemaMigrationResponse, error) // GetBackups returns all the backups for a shard. GetBackups(ctx context.Context, in *vtctldata.GetBackupsRequest, opts ...grpc.CallOption) (*vtctldata.GetBackupsResponse, error) // GetCellInfo returns the information for a cell. @@ -731,6 +733,15 @@ func (c *vtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldat return out, nil } +func (c *vtctldClient) ForceCutOverSchemaMigration(ctx context.Context, in *vtctldata.ForceCutOverSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldata.ForceCutOverSchemaMigrationResponse, error) { + out := new(vtctldata.ForceCutOverSchemaMigrationResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ForceCutOverSchemaMigration", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetBackups(ctx context.Context, in *vtctldata.GetBackupsRequest, opts ...grpc.CallOption) (*vtctldata.GetBackupsResponse, error) { out := new(vtctldata.GetBackupsResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetBackups", in, out, opts...) @@ -1595,6 +1606,8 @@ type VtctldServer interface { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // ForceCutOverSchemaMigration marks a schema migration for forced cut-over. + ForceCutOverSchemaMigration(context.Context, *vtctldata.ForceCutOverSchemaMigrationRequest) (*vtctldata.ForceCutOverSchemaMigrationResponse, error) // GetBackups returns all the backups for a shard. GetBackups(context.Context, *vtctldata.GetBackupsRequest) (*vtctldata.GetBackupsResponse, error) // GetCellInfo returns the information for a cell. @@ -1919,6 +1932,9 @@ func (UnimplementedVtctldServer) ExecuteHook(context.Context, *vtctldata.Execute func (UnimplementedVtctldServer) FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FindAllShardsInKeyspace not implemented") } +func (UnimplementedVtctldServer) ForceCutOverSchemaMigration(context.Context, *vtctldata.ForceCutOverSchemaMigrationRequest) (*vtctldata.ForceCutOverSchemaMigrationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ForceCutOverSchemaMigration not implemented") +} func (UnimplementedVtctldServer) GetBackups(context.Context, *vtctldata.GetBackupsRequest) (*vtctldata.GetBackupsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetBackups not implemented") } @@ -2643,6 +2659,24 @@ func _Vtctld_FindAllShardsInKeyspace_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _Vtctld_ForceCutOverSchemaMigration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.ForceCutOverSchemaMigrationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).ForceCutOverSchemaMigration(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/ForceCutOverSchemaMigration", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).ForceCutOverSchemaMigration(ctx, req.(*vtctldata.ForceCutOverSchemaMigrationRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetBackups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetBackupsRequest) if err := dec(in); err != nil { @@ -4275,6 +4309,10 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "FindAllShardsInKeyspace", Handler: _Vtctld_FindAllShardsInKeyspace_Handler, }, + { + MethodName: "ForceCutOverSchemaMigration", + Handler: _Vtctld_ForceCutOverSchemaMigration_Handler, + }, { MethodName: "GetBackups", Handler: _Vtctld_GetBackups_Handler, diff --git a/go/vt/schema/ddl_strategy.go b/go/vt/schema/ddl_strategy.go index bc33c8cb3cf..71d434b5e09 100644 --- a/go/vt/schema/ddl_strategy.go +++ b/go/vt/schema/ddl_strategy.go @@ -27,9 +27,10 @@ import ( ) var ( - strategyParserRegexp = regexp.MustCompile(`^([\S]+)\s+(.*)$`) - cutOverThresholdFlagRegexp = regexp.MustCompile(fmt.Sprintf(`^[-]{1,2}%s=(.*?)$`, cutOverThresholdFlag)) - retainArtifactsFlagRegexp = regexp.MustCompile(fmt.Sprintf(`^[-]{1,2}%s=(.*?)$`, retainArtifactsFlag)) + strategyParserRegexp = regexp.MustCompile(`^([\S]+)\s+(.*)$`) + cutOverThresholdFlagRegexp = regexp.MustCompile(fmt.Sprintf(`^[-]{1,2}%s=(.*?)$`, cutOverThresholdFlag)) + forceCutOverAfterFlagRegexp = regexp.MustCompile(fmt.Sprintf(`^[-]{1,2}%s=(.*?)$`, forceCutOverAfterFlag)) + retainArtifactsFlagRegexp = regexp.MustCompile(fmt.Sprintf(`^[-]{1,2}%s=(.*?)$`, retainArtifactsFlag)) ) const ( @@ -45,6 +46,7 @@ const ( preferInstantDDL = "prefer-instant-ddl" fastRangeRotationFlag = "fast-range-rotation" cutOverThresholdFlag = "cut-over-threshold" + forceCutOverAfterFlag = "force-cut-over-after" retainArtifactsFlag = "retain-artifacts" vreplicationTestSuite = "vreplication-test-suite" allowForeignKeysFlag = "unsafe-allow-foreign-keys" @@ -116,6 +118,17 @@ func ParseDDLStrategy(strategyVariable string) (*DDLStrategySetting, error) { if _, err := setting.RetainArtifactsDuration(); err != nil { return nil, err } + cutoverAfter, err := setting.ForceCutOverAfter() + if err != nil { + return nil, err + } + switch setting.Strategy { + case DDLStrategyVitess, DDLStrategyOnline: + default: + if cutoverAfter != 0 { + return nil, fmt.Errorf("--force-cut-over-after is only valid in 'vitess' strategy. Found %v value in '%v' strategy", cutoverAfter, setting.Strategy) + } + } switch setting.Strategy { case DDLStrategyVitess, DDLStrategyOnline, DDLStrategyMySQL, DDLStrategyDirect: @@ -208,6 +221,15 @@ func isCutOverThresholdFlag(opt string) (string, bool) { return submatch[1], true } +// isForceCutOverFlag returns true when given option denotes a `--force-cut-over-after=[...]` flag +func isForceCutOverFlag(opt string) (string, bool) { + submatch := forceCutOverAfterFlagRegexp.FindStringSubmatch(opt) + if len(submatch) == 0 { + return "", false + } + return submatch[1], true +} + // isRetainArtifactsFlag returns true when given option denotes a `--retain-artifacts=[...]` flag func isRetainArtifactsFlag(opt string) (string, bool) { submatch := retainArtifactsFlagRegexp.FindStringSubmatch(opt) @@ -235,6 +257,24 @@ func (setting *DDLStrategySetting) CutOverThreshold() (d time.Duration, err erro return d, err } +// ForceCutOverAfter returns a the duration threshold indicated by --force-cut-over-after +func (setting *DDLStrategySetting) ForceCutOverAfter() (d time.Duration, err error) { + // We do some ugly manual parsing of --cut-over-threshold value + opts, _ := shlex.Split(setting.Options) + for _, opt := range opts { + if val, isCutOver := isForceCutOverFlag(opt); isCutOver { + // value is possibly quoted + if s, err := strconv.Unquote(val); err == nil { + val = s + } + if val != "" { + d, err = time.ParseDuration(val) + } + } + } + return d, err +} + // RetainArtifactsDuration returns a the duration indicated by --retain-artifacts func (setting *DDLStrategySetting) RetainArtifactsDuration() (d time.Duration, err error) { // We do some ugly manual parsing of --retain-artifacts @@ -276,6 +316,9 @@ func (setting *DDLStrategySetting) RuntimeOptions() []string { if _, ok := isCutOverThresholdFlag(opt); ok { continue } + if _, ok := isForceCutOverFlag(opt); ok { + continue + } if _, ok := isRetainArtifactsFlag(opt); ok { continue } diff --git a/go/vt/schema/ddl_strategy_test.go b/go/vt/schema/ddl_strategy_test.go index ba7d029b8b7..ae6c65815cc 100644 --- a/go/vt/schema/ddl_strategy_test.go +++ b/go/vt/schema/ddl_strategy_test.go @@ -198,6 +198,7 @@ func TestParseDDLStrategy(t *testing.T) { allowForeignKeys bool analyzeTable bool cutOverThreshold time.Duration + forceCutOverAfter time.Duration expireArtifacts time.Duration runtimeOptions string expectError string @@ -320,6 +321,25 @@ func TestParseDDLStrategy(t *testing.T) { runtimeOptions: "", cutOverThreshold: 5 * time.Minute, }, + { + strategyVariable: "vitess --force-cut-over-after=3m", + strategy: DDLStrategyVitess, + options: "--force-cut-over-after=3m", + runtimeOptions: "", + forceCutOverAfter: 3 * time.Minute, + }, + { + strategyVariable: "vitess --force-cut-over-after=r3m", + strategy: DDLStrategyVitess, + runtimeOptions: "", + expectError: "time: invalid duration", + }, + { + strategyVariable: "gh-ost --force-cut-over-after=3m", + strategy: DDLStrategyVitess, + runtimeOptions: "", + expectError: "--force-cut-over-after is only valid in 'vitess' strategy", + }, { strategyVariable: "vitess --retain-artifacts=4m", strategy: DDLStrategyVitess, @@ -338,14 +358,12 @@ func TestParseDDLStrategy(t *testing.T) { { strategyVariable: "vitess --alow-concrrnt", // intentional typo strategy: DDLStrategyVitess, - options: "", runtimeOptions: "", expectError: "invalid flags", }, { strategyVariable: "vitess --declarative --max-load=Threads_running=100", strategy: DDLStrategyVitess, - options: "--declarative --max-load=Threads_running=100", runtimeOptions: "--max-load=Threads_running=100", expectError: "invalid flags", }, @@ -372,6 +390,9 @@ func TestParseDDLStrategy(t *testing.T) { cutOverThreshold, err := setting.CutOverThreshold() assert.NoError(t, err) assert.Equal(t, ts.cutOverThreshold, cutOverThreshold) + forceCutOverAfter, err := setting.ForceCutOverAfter() + assert.NoError(t, err) + assert.Equal(t, ts.forceCutOverAfter, forceCutOverAfter) runtimeOptions := strings.Join(setting.RuntimeOptions(), " ") assert.Equal(t, ts.runtimeOptions, runtimeOptions) diff --git a/go/vt/sidecardb/schema/onlineddl/schema_migrations.sql b/go/vt/sidecardb/schema/onlineddl/schema_migrations.sql index 40fdeef2683..2926ec76f28 100644 --- a/go/vt/sidecardb/schema/onlineddl/schema_migrations.sql +++ b/go/vt/sidecardb/schema/onlineddl/schema_migrations.sql @@ -71,6 +71,8 @@ CREATE TABLE IF NOT EXISTS schema_migrations `reviewed_timestamp` timestamp NULL DEFAULT NULL, `ready_to_complete_timestamp` timestamp NULL DEFAULT NULL, `removed_foreign_key_names` text NOT NULL, + `last_cutover_attempt_timestamp` timestamp NULL DEFAULT NULL, + `force_cutover` tinyint unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `uuid_idx` (`migration_uuid`), KEY `keyspace_shard_idx` (`keyspace`(64), `shard`(64)), diff --git a/go/vt/sqlparser/ast_format.go b/go/vt/sqlparser/ast_format.go index 299ca3bed51..863de56bfba 100644 --- a/go/vt/sqlparser/ast_format.go +++ b/go/vt/sqlparser/ast_format.go @@ -289,6 +289,10 @@ func (node *AlterMigration) Format(buf *TrackedBuffer) { alterType = "unthrottle" case UnthrottleAllMigrationType: alterType = "unthrottle all" + case ForceCutOverMigrationType: + alterType = "force_cutover" + case ForceCutOverAllMigrationType: + alterType = "force_cutover all" } buf.astPrintf(node, " %#s", alterType) if node.Expire != "" { diff --git a/go/vt/sqlparser/ast_format_fast.go b/go/vt/sqlparser/ast_format_fast.go index c951636d3f9..6f6f3594c18 100644 --- a/go/vt/sqlparser/ast_format_fast.go +++ b/go/vt/sqlparser/ast_format_fast.go @@ -416,6 +416,10 @@ func (node *AlterMigration) FormatFast(buf *TrackedBuffer) { alterType = "unthrottle" case UnthrottleAllMigrationType: alterType = "unthrottle all" + case ForceCutOverMigrationType: + alterType = "force_cutover" + case ForceCutOverAllMigrationType: + alterType = "force_cutover all" } buf.WriteByte(' ') buf.WriteString(alterType) diff --git a/go/vt/sqlparser/constants.go b/go/vt/sqlparser/constants.go index 56e8d4637b0..42b7cdb4c28 100644 --- a/go/vt/sqlparser/constants.go +++ b/go/vt/sqlparser/constants.go @@ -928,6 +928,8 @@ const ( ThrottleAllMigrationType UnthrottleMigrationType UnthrottleAllMigrationType + ForceCutOverMigrationType + ForceCutOverAllMigrationType ) // ColumnStorage constants diff --git a/go/vt/sqlparser/keywords.go b/go/vt/sqlparser/keywords.go index 6eaa41a0386..968c2da4e7e 100644 --- a/go/vt/sqlparser/keywords.go +++ b/go/vt/sqlparser/keywords.go @@ -285,6 +285,7 @@ var keywords = []keyword{ {"following", FOLLOWING}, {"for", FOR}, {"force", FORCE}, + {"force_cutover", FORCE_CUTOVER}, {"foreign", FOREIGN}, {"format", FORMAT}, {"format_bytes", FORMAT_BYTES}, diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 4fe2cd8f247..d2396cabe17 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -2421,6 +2421,13 @@ var ( input: "alter vitess_migration complete all", }, { input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' cancel", + }, { + input: "alter vitess_migration force_cutover all", + }, { + input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' force_cutover", + }, { + input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' FORCE_CUTOVER", + output: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' force_cutover", }, { input: "alter vitess_migration cancel all", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index aef17b630f1..d2e316fc722 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -324,426 +324,427 @@ const COMPLETE = 57633 const CLEANUP = 57634 const THROTTLE = 57635 const UNTHROTTLE = 57636 -const EXPIRE = 57637 -const RATIO = 57638 -const VITESS_THROTTLER = 57639 -const BEGIN = 57640 -const START = 57641 -const TRANSACTION = 57642 -const COMMIT = 57643 -const ROLLBACK = 57644 -const SAVEPOINT = 57645 -const RELEASE = 57646 -const WORK = 57647 -const CONSISTENT = 57648 -const SNAPSHOT = 57649 -const BIT = 57650 -const TINYINT = 57651 -const SMALLINT = 57652 -const MEDIUMINT = 57653 -const INT = 57654 -const INTEGER = 57655 -const BIGINT = 57656 -const INTNUM = 57657 -const REAL = 57658 -const DOUBLE = 57659 -const FLOAT_TYPE = 57660 -const FLOAT4_TYPE = 57661 -const FLOAT8_TYPE = 57662 -const DECIMAL_TYPE = 57663 -const NUMERIC = 57664 -const TIME = 57665 -const TIMESTAMP = 57666 -const DATETIME = 57667 -const YEAR = 57668 -const CHAR = 57669 -const VARCHAR = 57670 -const BOOL = 57671 -const CHARACTER = 57672 -const VARBINARY = 57673 -const NCHAR = 57674 -const TEXT = 57675 -const TINYTEXT = 57676 -const MEDIUMTEXT = 57677 -const LONGTEXT = 57678 -const BLOB = 57679 -const TINYBLOB = 57680 -const MEDIUMBLOB = 57681 -const LONGBLOB = 57682 -const JSON = 57683 -const JSON_SCHEMA_VALID = 57684 -const JSON_SCHEMA_VALIDATION_REPORT = 57685 -const ENUM = 57686 -const GEOMETRY = 57687 -const POINT = 57688 -const LINESTRING = 57689 -const POLYGON = 57690 -const GEOMCOLLECTION = 57691 -const GEOMETRYCOLLECTION = 57692 -const MULTIPOINT = 57693 -const MULTILINESTRING = 57694 -const MULTIPOLYGON = 57695 -const ASCII = 57696 -const UNICODE = 57697 -const NULLX = 57698 -const AUTO_INCREMENT = 57699 -const APPROXNUM = 57700 -const SIGNED = 57701 -const UNSIGNED = 57702 -const ZEROFILL = 57703 -const PURGE = 57704 -const BEFORE = 57705 -const CODE = 57706 -const COLLATION = 57707 -const COLUMNS = 57708 -const DATABASES = 57709 -const ENGINES = 57710 -const EVENT = 57711 -const EXTENDED = 57712 -const FIELDS = 57713 -const FULL = 57714 -const FUNCTION = 57715 -const GTID_EXECUTED = 57716 -const KEYSPACES = 57717 -const OPEN = 57718 -const PLUGINS = 57719 -const PRIVILEGES = 57720 -const PROCESSLIST = 57721 -const SCHEMAS = 57722 -const TABLES = 57723 -const TRIGGERS = 57724 -const USER = 57725 -const VGTID_EXECUTED = 57726 -const VITESS_KEYSPACES = 57727 -const VITESS_METADATA = 57728 -const VITESS_MIGRATIONS = 57729 -const VITESS_REPLICATION_STATUS = 57730 -const VITESS_SHARDS = 57731 -const VITESS_TABLETS = 57732 -const VITESS_TARGET = 57733 -const VSCHEMA = 57734 -const VITESS_THROTTLED_APPS = 57735 -const NAMES = 57736 -const GLOBAL = 57737 -const SESSION = 57738 -const ISOLATION = 57739 -const LEVEL = 57740 -const READ = 57741 -const WRITE = 57742 -const ONLY = 57743 -const REPEATABLE = 57744 -const COMMITTED = 57745 -const UNCOMMITTED = 57746 -const SERIALIZABLE = 57747 -const ADDDATE = 57748 -const CURRENT_TIMESTAMP = 57749 -const DATABASE = 57750 -const CURRENT_DATE = 57751 -const CURDATE = 57752 -const DATE_ADD = 57753 -const DATE_SUB = 57754 -const NOW = 57755 -const SUBDATE = 57756 -const CURTIME = 57757 -const CURRENT_TIME = 57758 -const LOCALTIME = 57759 -const LOCALTIMESTAMP = 57760 -const CURRENT_USER = 57761 -const UTC_DATE = 57762 -const UTC_TIME = 57763 -const UTC_TIMESTAMP = 57764 -const SYSDATE = 57765 -const DAY = 57766 -const DAY_HOUR = 57767 -const DAY_MICROSECOND = 57768 -const DAY_MINUTE = 57769 -const DAY_SECOND = 57770 -const HOUR = 57771 -const HOUR_MICROSECOND = 57772 -const HOUR_MINUTE = 57773 -const HOUR_SECOND = 57774 -const MICROSECOND = 57775 -const MINUTE = 57776 -const MINUTE_MICROSECOND = 57777 -const MINUTE_SECOND = 57778 -const MONTH = 57779 -const QUARTER = 57780 -const SECOND = 57781 -const SECOND_MICROSECOND = 57782 -const YEAR_MONTH = 57783 -const WEEK = 57784 -const SQL_TSI_DAY = 57785 -const SQL_TSI_WEEK = 57786 -const SQL_TSI_HOUR = 57787 -const SQL_TSI_MINUTE = 57788 -const SQL_TSI_MONTH = 57789 -const SQL_TSI_QUARTER = 57790 -const SQL_TSI_SECOND = 57791 -const SQL_TSI_MICROSECOND = 57792 -const SQL_TSI_YEAR = 57793 -const REPLACE = 57794 -const CONVERT = 57795 -const CAST = 57796 -const SUBSTR = 57797 -const SUBSTRING = 57798 -const SEPARATOR = 57799 -const TIMESTAMPADD = 57800 -const TIMESTAMPDIFF = 57801 -const WEIGHT_STRING = 57802 -const LTRIM = 57803 -const RTRIM = 57804 -const TRIM = 57805 -const JSON_ARRAY = 57806 -const JSON_OBJECT = 57807 -const JSON_QUOTE = 57808 -const JSON_DEPTH = 57809 -const JSON_TYPE = 57810 -const JSON_LENGTH = 57811 -const JSON_VALID = 57812 -const JSON_ARRAY_APPEND = 57813 -const JSON_ARRAY_INSERT = 57814 -const JSON_INSERT = 57815 -const JSON_MERGE = 57816 -const JSON_MERGE_PATCH = 57817 -const JSON_MERGE_PRESERVE = 57818 -const JSON_REMOVE = 57819 -const JSON_REPLACE = 57820 -const JSON_SET = 57821 -const JSON_UNQUOTE = 57822 -const COUNT = 57823 -const AVG = 57824 -const MAX = 57825 -const MIN = 57826 -const SUM = 57827 -const GROUP_CONCAT = 57828 -const BIT_AND = 57829 -const BIT_OR = 57830 -const BIT_XOR = 57831 -const STD = 57832 -const STDDEV = 57833 -const STDDEV_POP = 57834 -const STDDEV_SAMP = 57835 -const VAR_POP = 57836 -const VAR_SAMP = 57837 -const VARIANCE = 57838 -const ANY_VALUE = 57839 -const REGEXP_INSTR = 57840 -const REGEXP_LIKE = 57841 -const REGEXP_REPLACE = 57842 -const REGEXP_SUBSTR = 57843 -const ExtractValue = 57844 -const UpdateXML = 57845 -const GET_LOCK = 57846 -const RELEASE_LOCK = 57847 -const RELEASE_ALL_LOCKS = 57848 -const IS_FREE_LOCK = 57849 -const IS_USED_LOCK = 57850 -const LOCATE = 57851 -const POSITION = 57852 -const ST_GeometryCollectionFromText = 57853 -const ST_GeometryFromText = 57854 -const ST_LineStringFromText = 57855 -const ST_MultiLineStringFromText = 57856 -const ST_MultiPointFromText = 57857 -const ST_MultiPolygonFromText = 57858 -const ST_PointFromText = 57859 -const ST_PolygonFromText = 57860 -const ST_GeometryCollectionFromWKB = 57861 -const ST_GeometryFromWKB = 57862 -const ST_LineStringFromWKB = 57863 -const ST_MultiLineStringFromWKB = 57864 -const ST_MultiPointFromWKB = 57865 -const ST_MultiPolygonFromWKB = 57866 -const ST_PointFromWKB = 57867 -const ST_PolygonFromWKB = 57868 -const ST_AsBinary = 57869 -const ST_AsText = 57870 -const ST_Dimension = 57871 -const ST_Envelope = 57872 -const ST_IsSimple = 57873 -const ST_IsEmpty = 57874 -const ST_GeometryType = 57875 -const ST_X = 57876 -const ST_Y = 57877 -const ST_Latitude = 57878 -const ST_Longitude = 57879 -const ST_EndPoint = 57880 -const ST_IsClosed = 57881 -const ST_Length = 57882 -const ST_NumPoints = 57883 -const ST_StartPoint = 57884 -const ST_PointN = 57885 -const ST_Area = 57886 -const ST_Centroid = 57887 -const ST_ExteriorRing = 57888 -const ST_InteriorRingN = 57889 -const ST_NumInteriorRings = 57890 -const ST_NumGeometries = 57891 -const ST_GeometryN = 57892 -const ST_LongFromGeoHash = 57893 -const ST_PointFromGeoHash = 57894 -const ST_LatFromGeoHash = 57895 -const ST_GeoHash = 57896 -const ST_AsGeoJSON = 57897 -const ST_GeomFromGeoJSON = 57898 -const MATCH = 57899 -const AGAINST = 57900 -const BOOLEAN = 57901 -const LANGUAGE = 57902 -const WITH = 57903 -const QUERY = 57904 -const EXPANSION = 57905 -const WITHOUT = 57906 -const VALIDATION = 57907 -const UNUSED = 57908 -const ARRAY = 57909 -const BYTE = 57910 -const CUME_DIST = 57911 -const DESCRIPTION = 57912 -const DENSE_RANK = 57913 -const EMPTY = 57914 -const EXCEPT = 57915 -const FIRST_VALUE = 57916 -const GROUPING = 57917 -const GROUPS = 57918 -const JSON_TABLE = 57919 -const LAG = 57920 -const LAST_VALUE = 57921 -const LATERAL = 57922 -const LEAD = 57923 -const NTH_VALUE = 57924 -const NTILE = 57925 -const OF = 57926 -const OVER = 57927 -const PERCENT_RANK = 57928 -const RANK = 57929 -const RECURSIVE = 57930 -const ROW_NUMBER = 57931 -const SYSTEM = 57932 -const WINDOW = 57933 -const ACTIVE = 57934 -const ADMIN = 57935 -const AUTOEXTEND_SIZE = 57936 -const BUCKETS = 57937 -const CLONE = 57938 -const COLUMN_FORMAT = 57939 -const COMPONENT = 57940 -const DEFINITION = 57941 -const ENFORCED = 57942 -const ENGINE_ATTRIBUTE = 57943 -const EXCLUDE = 57944 -const FOLLOWING = 57945 -const GET_MASTER_PUBLIC_KEY = 57946 -const HISTOGRAM = 57947 -const HISTORY = 57948 -const INACTIVE = 57949 -const INVISIBLE = 57950 -const LOCKED = 57951 -const MASTER_COMPRESSION_ALGORITHMS = 57952 -const MASTER_PUBLIC_KEY_PATH = 57953 -const MASTER_TLS_CIPHERSUITES = 57954 -const MASTER_ZSTD_COMPRESSION_LEVEL = 57955 -const NESTED = 57956 -const NETWORK_NAMESPACE = 57957 -const NOWAIT = 57958 -const NULLS = 57959 -const OJ = 57960 -const OLD = 57961 -const OPTIONAL = 57962 -const ORDINALITY = 57963 -const ORGANIZATION = 57964 -const OTHERS = 57965 -const PARTIAL = 57966 -const PATH = 57967 -const PERSIST = 57968 -const PERSIST_ONLY = 57969 -const PRECEDING = 57970 -const PRIVILEGE_CHECKS_USER = 57971 -const PROCESS = 57972 -const RANDOM = 57973 -const REFERENCE = 57974 -const REQUIRE_ROW_FORMAT = 57975 -const RESOURCE = 57976 -const RESPECT = 57977 -const RESTART = 57978 -const RETAIN = 57979 -const REUSE = 57980 -const ROLE = 57981 -const SECONDARY = 57982 -const SECONDARY_ENGINE = 57983 -const SECONDARY_ENGINE_ATTRIBUTE = 57984 -const SECONDARY_LOAD = 57985 -const SECONDARY_UNLOAD = 57986 -const SIMPLE = 57987 -const SKIP = 57988 -const SRID = 57989 -const THREAD_PRIORITY = 57990 -const TIES = 57991 -const UNBOUNDED = 57992 -const VCPU = 57993 -const VISIBLE = 57994 -const RETURNING = 57995 -const FORMAT_BYTES = 57996 -const FORMAT_PICO_TIME = 57997 -const PS_CURRENT_THREAD_ID = 57998 -const PS_THREAD_ID = 57999 -const GTID_SUBSET = 58000 -const GTID_SUBTRACT = 58001 -const WAIT_FOR_EXECUTED_GTID_SET = 58002 -const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58003 -const FORMAT = 58004 -const TREE = 58005 -const VITESS = 58006 -const TRADITIONAL = 58007 -const VTEXPLAIN = 58008 -const VEXPLAIN = 58009 -const PLAN = 58010 -const LOCAL = 58011 -const LOW_PRIORITY = 58012 -const NO_WRITE_TO_BINLOG = 58013 -const LOGS = 58014 -const ERROR = 58015 -const GENERAL = 58016 -const HOSTS = 58017 -const OPTIMIZER_COSTS = 58018 -const USER_RESOURCES = 58019 -const SLOW = 58020 -const CHANNEL = 58021 -const RELAY = 58022 -const EXPORT = 58023 -const CURRENT = 58024 -const ROW = 58025 -const ROWS = 58026 -const AVG_ROW_LENGTH = 58027 -const CONNECTION = 58028 -const CHECKSUM = 58029 -const DELAY_KEY_WRITE = 58030 -const ENCRYPTION = 58031 -const ENGINE = 58032 -const INSERT_METHOD = 58033 -const MAX_ROWS = 58034 -const MIN_ROWS = 58035 -const PACK_KEYS = 58036 -const PASSWORD = 58037 -const FIXED = 58038 -const DYNAMIC = 58039 -const COMPRESSED = 58040 -const REDUNDANT = 58041 -const COMPACT = 58042 -const ROW_FORMAT = 58043 -const STATS_AUTO_RECALC = 58044 -const STATS_PERSISTENT = 58045 -const STATS_SAMPLE_PAGES = 58046 -const STORAGE = 58047 -const MEMORY = 58048 -const DISK = 58049 -const PARTITIONS = 58050 -const LINEAR = 58051 -const RANGE = 58052 -const LIST = 58053 -const SUBPARTITION = 58054 -const SUBPARTITIONS = 58055 -const HASH = 58056 +const FORCE_CUTOVER = 57637 +const EXPIRE = 57638 +const RATIO = 57639 +const VITESS_THROTTLER = 57640 +const BEGIN = 57641 +const START = 57642 +const TRANSACTION = 57643 +const COMMIT = 57644 +const ROLLBACK = 57645 +const SAVEPOINT = 57646 +const RELEASE = 57647 +const WORK = 57648 +const CONSISTENT = 57649 +const SNAPSHOT = 57650 +const BIT = 57651 +const TINYINT = 57652 +const SMALLINT = 57653 +const MEDIUMINT = 57654 +const INT = 57655 +const INTEGER = 57656 +const BIGINT = 57657 +const INTNUM = 57658 +const REAL = 57659 +const DOUBLE = 57660 +const FLOAT_TYPE = 57661 +const FLOAT4_TYPE = 57662 +const FLOAT8_TYPE = 57663 +const DECIMAL_TYPE = 57664 +const NUMERIC = 57665 +const TIME = 57666 +const TIMESTAMP = 57667 +const DATETIME = 57668 +const YEAR = 57669 +const CHAR = 57670 +const VARCHAR = 57671 +const BOOL = 57672 +const CHARACTER = 57673 +const VARBINARY = 57674 +const NCHAR = 57675 +const TEXT = 57676 +const TINYTEXT = 57677 +const MEDIUMTEXT = 57678 +const LONGTEXT = 57679 +const BLOB = 57680 +const TINYBLOB = 57681 +const MEDIUMBLOB = 57682 +const LONGBLOB = 57683 +const JSON = 57684 +const JSON_SCHEMA_VALID = 57685 +const JSON_SCHEMA_VALIDATION_REPORT = 57686 +const ENUM = 57687 +const GEOMETRY = 57688 +const POINT = 57689 +const LINESTRING = 57690 +const POLYGON = 57691 +const GEOMCOLLECTION = 57692 +const GEOMETRYCOLLECTION = 57693 +const MULTIPOINT = 57694 +const MULTILINESTRING = 57695 +const MULTIPOLYGON = 57696 +const ASCII = 57697 +const UNICODE = 57698 +const NULLX = 57699 +const AUTO_INCREMENT = 57700 +const APPROXNUM = 57701 +const SIGNED = 57702 +const UNSIGNED = 57703 +const ZEROFILL = 57704 +const PURGE = 57705 +const BEFORE = 57706 +const CODE = 57707 +const COLLATION = 57708 +const COLUMNS = 57709 +const DATABASES = 57710 +const ENGINES = 57711 +const EVENT = 57712 +const EXTENDED = 57713 +const FIELDS = 57714 +const FULL = 57715 +const FUNCTION = 57716 +const GTID_EXECUTED = 57717 +const KEYSPACES = 57718 +const OPEN = 57719 +const PLUGINS = 57720 +const PRIVILEGES = 57721 +const PROCESSLIST = 57722 +const SCHEMAS = 57723 +const TABLES = 57724 +const TRIGGERS = 57725 +const USER = 57726 +const VGTID_EXECUTED = 57727 +const VITESS_KEYSPACES = 57728 +const VITESS_METADATA = 57729 +const VITESS_MIGRATIONS = 57730 +const VITESS_REPLICATION_STATUS = 57731 +const VITESS_SHARDS = 57732 +const VITESS_TABLETS = 57733 +const VITESS_TARGET = 57734 +const VSCHEMA = 57735 +const VITESS_THROTTLED_APPS = 57736 +const NAMES = 57737 +const GLOBAL = 57738 +const SESSION = 57739 +const ISOLATION = 57740 +const LEVEL = 57741 +const READ = 57742 +const WRITE = 57743 +const ONLY = 57744 +const REPEATABLE = 57745 +const COMMITTED = 57746 +const UNCOMMITTED = 57747 +const SERIALIZABLE = 57748 +const ADDDATE = 57749 +const CURRENT_TIMESTAMP = 57750 +const DATABASE = 57751 +const CURRENT_DATE = 57752 +const CURDATE = 57753 +const DATE_ADD = 57754 +const DATE_SUB = 57755 +const NOW = 57756 +const SUBDATE = 57757 +const CURTIME = 57758 +const CURRENT_TIME = 57759 +const LOCALTIME = 57760 +const LOCALTIMESTAMP = 57761 +const CURRENT_USER = 57762 +const UTC_DATE = 57763 +const UTC_TIME = 57764 +const UTC_TIMESTAMP = 57765 +const SYSDATE = 57766 +const DAY = 57767 +const DAY_HOUR = 57768 +const DAY_MICROSECOND = 57769 +const DAY_MINUTE = 57770 +const DAY_SECOND = 57771 +const HOUR = 57772 +const HOUR_MICROSECOND = 57773 +const HOUR_MINUTE = 57774 +const HOUR_SECOND = 57775 +const MICROSECOND = 57776 +const MINUTE = 57777 +const MINUTE_MICROSECOND = 57778 +const MINUTE_SECOND = 57779 +const MONTH = 57780 +const QUARTER = 57781 +const SECOND = 57782 +const SECOND_MICROSECOND = 57783 +const YEAR_MONTH = 57784 +const WEEK = 57785 +const SQL_TSI_DAY = 57786 +const SQL_TSI_WEEK = 57787 +const SQL_TSI_HOUR = 57788 +const SQL_TSI_MINUTE = 57789 +const SQL_TSI_MONTH = 57790 +const SQL_TSI_QUARTER = 57791 +const SQL_TSI_SECOND = 57792 +const SQL_TSI_MICROSECOND = 57793 +const SQL_TSI_YEAR = 57794 +const REPLACE = 57795 +const CONVERT = 57796 +const CAST = 57797 +const SUBSTR = 57798 +const SUBSTRING = 57799 +const SEPARATOR = 57800 +const TIMESTAMPADD = 57801 +const TIMESTAMPDIFF = 57802 +const WEIGHT_STRING = 57803 +const LTRIM = 57804 +const RTRIM = 57805 +const TRIM = 57806 +const JSON_ARRAY = 57807 +const JSON_OBJECT = 57808 +const JSON_QUOTE = 57809 +const JSON_DEPTH = 57810 +const JSON_TYPE = 57811 +const JSON_LENGTH = 57812 +const JSON_VALID = 57813 +const JSON_ARRAY_APPEND = 57814 +const JSON_ARRAY_INSERT = 57815 +const JSON_INSERT = 57816 +const JSON_MERGE = 57817 +const JSON_MERGE_PATCH = 57818 +const JSON_MERGE_PRESERVE = 57819 +const JSON_REMOVE = 57820 +const JSON_REPLACE = 57821 +const JSON_SET = 57822 +const JSON_UNQUOTE = 57823 +const COUNT = 57824 +const AVG = 57825 +const MAX = 57826 +const MIN = 57827 +const SUM = 57828 +const GROUP_CONCAT = 57829 +const BIT_AND = 57830 +const BIT_OR = 57831 +const BIT_XOR = 57832 +const STD = 57833 +const STDDEV = 57834 +const STDDEV_POP = 57835 +const STDDEV_SAMP = 57836 +const VAR_POP = 57837 +const VAR_SAMP = 57838 +const VARIANCE = 57839 +const ANY_VALUE = 57840 +const REGEXP_INSTR = 57841 +const REGEXP_LIKE = 57842 +const REGEXP_REPLACE = 57843 +const REGEXP_SUBSTR = 57844 +const ExtractValue = 57845 +const UpdateXML = 57846 +const GET_LOCK = 57847 +const RELEASE_LOCK = 57848 +const RELEASE_ALL_LOCKS = 57849 +const IS_FREE_LOCK = 57850 +const IS_USED_LOCK = 57851 +const LOCATE = 57852 +const POSITION = 57853 +const ST_GeometryCollectionFromText = 57854 +const ST_GeometryFromText = 57855 +const ST_LineStringFromText = 57856 +const ST_MultiLineStringFromText = 57857 +const ST_MultiPointFromText = 57858 +const ST_MultiPolygonFromText = 57859 +const ST_PointFromText = 57860 +const ST_PolygonFromText = 57861 +const ST_GeometryCollectionFromWKB = 57862 +const ST_GeometryFromWKB = 57863 +const ST_LineStringFromWKB = 57864 +const ST_MultiLineStringFromWKB = 57865 +const ST_MultiPointFromWKB = 57866 +const ST_MultiPolygonFromWKB = 57867 +const ST_PointFromWKB = 57868 +const ST_PolygonFromWKB = 57869 +const ST_AsBinary = 57870 +const ST_AsText = 57871 +const ST_Dimension = 57872 +const ST_Envelope = 57873 +const ST_IsSimple = 57874 +const ST_IsEmpty = 57875 +const ST_GeometryType = 57876 +const ST_X = 57877 +const ST_Y = 57878 +const ST_Latitude = 57879 +const ST_Longitude = 57880 +const ST_EndPoint = 57881 +const ST_IsClosed = 57882 +const ST_Length = 57883 +const ST_NumPoints = 57884 +const ST_StartPoint = 57885 +const ST_PointN = 57886 +const ST_Area = 57887 +const ST_Centroid = 57888 +const ST_ExteriorRing = 57889 +const ST_InteriorRingN = 57890 +const ST_NumInteriorRings = 57891 +const ST_NumGeometries = 57892 +const ST_GeometryN = 57893 +const ST_LongFromGeoHash = 57894 +const ST_PointFromGeoHash = 57895 +const ST_LatFromGeoHash = 57896 +const ST_GeoHash = 57897 +const ST_AsGeoJSON = 57898 +const ST_GeomFromGeoJSON = 57899 +const MATCH = 57900 +const AGAINST = 57901 +const BOOLEAN = 57902 +const LANGUAGE = 57903 +const WITH = 57904 +const QUERY = 57905 +const EXPANSION = 57906 +const WITHOUT = 57907 +const VALIDATION = 57908 +const UNUSED = 57909 +const ARRAY = 57910 +const BYTE = 57911 +const CUME_DIST = 57912 +const DESCRIPTION = 57913 +const DENSE_RANK = 57914 +const EMPTY = 57915 +const EXCEPT = 57916 +const FIRST_VALUE = 57917 +const GROUPING = 57918 +const GROUPS = 57919 +const JSON_TABLE = 57920 +const LAG = 57921 +const LAST_VALUE = 57922 +const LATERAL = 57923 +const LEAD = 57924 +const NTH_VALUE = 57925 +const NTILE = 57926 +const OF = 57927 +const OVER = 57928 +const PERCENT_RANK = 57929 +const RANK = 57930 +const RECURSIVE = 57931 +const ROW_NUMBER = 57932 +const SYSTEM = 57933 +const WINDOW = 57934 +const ACTIVE = 57935 +const ADMIN = 57936 +const AUTOEXTEND_SIZE = 57937 +const BUCKETS = 57938 +const CLONE = 57939 +const COLUMN_FORMAT = 57940 +const COMPONENT = 57941 +const DEFINITION = 57942 +const ENFORCED = 57943 +const ENGINE_ATTRIBUTE = 57944 +const EXCLUDE = 57945 +const FOLLOWING = 57946 +const GET_MASTER_PUBLIC_KEY = 57947 +const HISTOGRAM = 57948 +const HISTORY = 57949 +const INACTIVE = 57950 +const INVISIBLE = 57951 +const LOCKED = 57952 +const MASTER_COMPRESSION_ALGORITHMS = 57953 +const MASTER_PUBLIC_KEY_PATH = 57954 +const MASTER_TLS_CIPHERSUITES = 57955 +const MASTER_ZSTD_COMPRESSION_LEVEL = 57956 +const NESTED = 57957 +const NETWORK_NAMESPACE = 57958 +const NOWAIT = 57959 +const NULLS = 57960 +const OJ = 57961 +const OLD = 57962 +const OPTIONAL = 57963 +const ORDINALITY = 57964 +const ORGANIZATION = 57965 +const OTHERS = 57966 +const PARTIAL = 57967 +const PATH = 57968 +const PERSIST = 57969 +const PERSIST_ONLY = 57970 +const PRECEDING = 57971 +const PRIVILEGE_CHECKS_USER = 57972 +const PROCESS = 57973 +const RANDOM = 57974 +const REFERENCE = 57975 +const REQUIRE_ROW_FORMAT = 57976 +const RESOURCE = 57977 +const RESPECT = 57978 +const RESTART = 57979 +const RETAIN = 57980 +const REUSE = 57981 +const ROLE = 57982 +const SECONDARY = 57983 +const SECONDARY_ENGINE = 57984 +const SECONDARY_ENGINE_ATTRIBUTE = 57985 +const SECONDARY_LOAD = 57986 +const SECONDARY_UNLOAD = 57987 +const SIMPLE = 57988 +const SKIP = 57989 +const SRID = 57990 +const THREAD_PRIORITY = 57991 +const TIES = 57992 +const UNBOUNDED = 57993 +const VCPU = 57994 +const VISIBLE = 57995 +const RETURNING = 57996 +const FORMAT_BYTES = 57997 +const FORMAT_PICO_TIME = 57998 +const PS_CURRENT_THREAD_ID = 57999 +const PS_THREAD_ID = 58000 +const GTID_SUBSET = 58001 +const GTID_SUBTRACT = 58002 +const WAIT_FOR_EXECUTED_GTID_SET = 58003 +const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58004 +const FORMAT = 58005 +const TREE = 58006 +const VITESS = 58007 +const TRADITIONAL = 58008 +const VTEXPLAIN = 58009 +const VEXPLAIN = 58010 +const PLAN = 58011 +const LOCAL = 58012 +const LOW_PRIORITY = 58013 +const NO_WRITE_TO_BINLOG = 58014 +const LOGS = 58015 +const ERROR = 58016 +const GENERAL = 58017 +const HOSTS = 58018 +const OPTIMIZER_COSTS = 58019 +const USER_RESOURCES = 58020 +const SLOW = 58021 +const CHANNEL = 58022 +const RELAY = 58023 +const EXPORT = 58024 +const CURRENT = 58025 +const ROW = 58026 +const ROWS = 58027 +const AVG_ROW_LENGTH = 58028 +const CONNECTION = 58029 +const CHECKSUM = 58030 +const DELAY_KEY_WRITE = 58031 +const ENCRYPTION = 58032 +const ENGINE = 58033 +const INSERT_METHOD = 58034 +const MAX_ROWS = 58035 +const MIN_ROWS = 58036 +const PACK_KEYS = 58037 +const PASSWORD = 58038 +const FIXED = 58039 +const DYNAMIC = 58040 +const COMPRESSED = 58041 +const REDUNDANT = 58042 +const COMPACT = 58043 +const ROW_FORMAT = 58044 +const STATS_AUTO_RECALC = 58045 +const STATS_PERSISTENT = 58046 +const STATS_SAMPLE_PAGES = 58047 +const STORAGE = 58048 +const MEMORY = 58049 +const DISK = 58050 +const PARTITIONS = 58051 +const LINEAR = 58052 +const RANGE = 58053 +const LIST = 58054 +const SUBPARTITION = 58055 +const SUBPARTITIONS = 58056 +const HASH = 58057 var yyToknames = [...]string{ "$end", @@ -1057,6 +1058,7 @@ var yyToknames = [...]string{ "CLEANUP", "THROTTLE", "UNTHROTTLE", + "FORCE_CUTOVER", "EXPIRE", "RATIO", "VITESS_THROTTLER", @@ -1497,29 +1499,29 @@ var yyExca = [...]int{ -2, 40, -1, 52, 1, 159, - 732, 159, + 733, 159, -2, 167, -1, 53, 136, 167, 178, 167, - 347, 167, + 348, 167, -2, 523, -1, 61, - 36, 775, - 241, 775, - 252, 775, - 287, 789, - 288, 789, - -2, 777, + 36, 777, + 241, 777, + 252, 777, + 287, 791, + 288, 791, + -2, 779, -1, 66, - 243, 813, - -2, 811, + 243, 815, + -2, 813, -1, 122, - 240, 1593, + 240, 1595, -2, 133, -1, 124, 1, 160, - 732, 160, + 733, 160, -2, 167, -1, 135, 137, 408, @@ -1528,45 +1530,45 @@ var yyExca = [...]int{ -1, 154, 136, 167, 178, 167, - 347, 167, + 348, 167, -2, 532, -1, 733, 164, 41, -2, 45, -1, 939, - 87, 1610, - -2, 1459, + 87, 1612, + -2, 1461, -1, 940, - 87, 1611, - 223, 1615, - -2, 1460, + 87, 1613, + 223, 1617, + -2, 1462, -1, 941, - 223, 1614, + 223, 1616, -2, 42, -1, 1024, - 60, 887, - -2, 902, + 60, 889, + -2, 904, -1, 1112, 251, 43, 256, 43, -2, 419, -1, 1197, 1, 580, - 732, 580, + 733, 580, -2, 167, -1, 1500, - 223, 1615, - -2, 1460, + 223, 1617, + -2, 1462, -1, 1709, - 60, 888, - -2, 907, + 60, 890, + -2, 909, -1, 1710, - 60, 889, - -2, 908, + 60, 891, + -2, 910, -1, 1765, 136, 167, 178, 167, - 347, 167, + 348, 167, -2, 458, -1, 1846, 137, 408, @@ -1576,164 +1578,164 @@ var yyExca = [...]int{ 251, 44, 256, 44, -2, 420, - -1, 2293, - 223, 1619, - -2, 1613, -1, 2294, - 223, 1615, - -2, 1611, - -1, 2396, + 223, 1621, + -2, 1615, + -1, 2295, + 223, 1617, + -2, 1613, + -1, 2397, 136, 167, 178, 167, - 347, 167, + 348, 167, -2, 459, - -1, 2403, + -1, 2404, 26, 188, -2, 190, - -1, 2857, + -1, 2860, 78, 98, 88, 98, - -2, 966, - -1, 2926, - 707, 698, - -2, 672, - -1, 3134, - 50, 1561, - -2, 1555, - -1, 3949, - 707, 698, - -2, 686, - -1, 4036, - 90, 630, - 95, 630, - 105, 630, - 180, 630, - 181, 630, - 182, 630, - 183, 630, - 184, 630, - 185, 630, - 186, 630, - 187, 630, - 188, 630, - 189, 630, - 190, 630, - 191, 630, - 192, 630, - 193, 630, - 194, 630, - 195, 630, - 196, 630, - 197, 630, - 198, 630, - 199, 630, - 200, 630, - 201, 630, - 202, 630, - 203, 630, - 204, 630, - 205, 630, - 206, 630, - 207, 630, - 208, 630, - 209, 630, - 210, 630, - 211, 630, - 212, 630, - 213, 630, - 214, 630, - 215, 630, - 216, 630, - 217, 630, - 218, 630, - 219, 630, - 220, 630, - 221, 630, - -2, 1982, + -2, 968, + -1, 2929, + 708, 700, + -2, 674, + -1, 3137, + 50, 1563, + -2, 1557, + -1, 3952, + 708, 700, + -2, 688, + -1, 4039, + 90, 632, + 95, 632, + 105, 632, + 180, 632, + 181, 632, + 182, 632, + 183, 632, + 184, 632, + 185, 632, + 186, 632, + 187, 632, + 188, 632, + 189, 632, + 190, 632, + 191, 632, + 192, 632, + 193, 632, + 194, 632, + 195, 632, + 196, 632, + 197, 632, + 198, 632, + 199, 632, + 200, 632, + 201, 632, + 202, 632, + 203, 632, + 204, 632, + 205, 632, + 206, 632, + 207, 632, + 208, 632, + 209, 632, + 210, 632, + 211, 632, + 212, 632, + 213, 632, + 214, 632, + 215, 632, + 216, 632, + 217, 632, + 218, 632, + 219, 632, + 220, 632, + 221, 632, + -2, 1984, } const yyPrivate = 57344 -const yyLast = 55650 +const yyLast = 56327 var yyAct = [...]int{ - 955, 3611, 3612, 87, 3610, 4034, 4111, 3930, 4015, 3286, - 4124, 943, 4078, 1265, 950, 3562, 942, 2087, 4079, 2393, - 1974, 4003, 3914, 3839, 2322, 3186, 3415, 3193, 3235, 2099, - 3244, 3249, 3246, 3245, 3243, 3248, 1768, 1263, 3147, 3912, - 2030, 3247, 2753, 5, 3549, 2324, 3264, 3087, 2467, 737, - 3201, 3263, 3151, 3148, 3649, 3460, 3454, 2990, 2348, 3135, - 904, 764, 908, 2430, 903, 42, 3266, 2364, 1724, 3980, - 1824, 2817, 732, 2891, 3293, 2367, 2972, 2923, 2455, 2435, - 2892, 2498, 3446, 3480, 1074, 2893, 1022, 163, 87, 2381, - 1042, 2842, 1144, 1871, 2823, 1019, 2368, 41, 1711, 2369, - 2809, 2793, 2245, 2122, 2277, 2289, 2083, 1022, 43, 2244, - 3145, 2964, 2476, 2038, 2454, 2356, 1853, 2515, 149, 2437, - 1102, 2884, 1084, 1107, 1757, 2859, 1737, 2371, 1512, 1690, - 2126, 100, 2058, 104, 1439, 731, 2342, 1424, 105, 1970, - 1081, 1078, 1860, 747, 1113, 3150, 2452, 1952, 1021, 1082, - 1025, 1120, 2426, 2427, 1108, 2830, 1110, 1109, 1756, 1059, - 1742, 1061, 2195, 2153, 99, 1031, 3644, 2134, 1041, 1044, - 1496, 3902, 2791, 2349, 107, 742, 1472, 2029, 1253, 1028, - 2290, 1982, 85, 167, 127, 1026, 125, 1819, 132, 905, - 1017, 126, 1845, 133, 1193, 1054, 1027, 93, 741, 734, - 1029, 98, 1261, 4112, 3550, 1239, 106, 1516, 3232, 84, - 2469, 1521, 724, 3965, 2914, 1049, 1053, 2469, 2470, 2471, - 2946, 2945, 2513, 3542, 1016, 1937, 1440, 4061, 2980, 2981, - 3961, 1034, 2319, 2320, 2045, 669, 128, 3505, 2044, 3966, - 2043, 2042, 1149, 1075, 1146, 3960, 134, 2041, 2040, 2013, - 1686, 1209, 666, 2561, 667, 2789, 4055, 1163, 1164, 1165, - 3131, 1168, 1169, 1170, 1171, 1035, 3615, 1174, 1175, 1176, - 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, - 1187, 1188, 1189, 1190, 2, 725, 4082, 735, 1124, 2819, - 1069, 1018, 1068, 1123, 1210, 1020, 3615, 3091, 4102, 1435, - 2502, 3939, 1099, 2916, 1043, 4134, 4077, 95, 128, 1098, - 1157, 1097, 1150, 1153, 1154, 1728, 1096, 1091, 3420, 3254, - 1726, 3254, 3419, 1718, 4117, 727, 4065, 709, 703, 111, - 112, 113, 3251, 116, 1450, 909, 122, 1086, 95, 191, - 95, 1166, 661, 709, 2501, 1729, 3961, 1456, 1015, 4116, - 1727, 4064, 2345, 3614, 722, 723, 4063, 2061, 2344, 2939, - 3915, 95, 2754, 2050, 1010, 1011, 1012, 1013, 3312, 3835, - 1100, 1024, 703, 3834, 1148, 3252, 128, 3252, 1147, 2936, - 4092, 4062, 3845, 3614, 4059, 959, 960, 961, 3555, 1426, - 3574, 3556, 959, 960, 961, 1067, 1071, 907, 3563, 1056, - 1057, 3258, 4004, 3258, 4012, 2495, 1067, 1071, 907, 86, - 3844, 2092, 4039, 86, 3332, 700, 1834, 3183, 3184, 3573, - 1095, 2790, 1202, 1203, 86, 2868, 3182, 2979, 2867, 2388, - 2389, 2869, 2567, 2833, 1440, 4016, 2022, 2023, 2387, 2570, - 703, 2963, 1446, 1090, 2500, 1438, 1092, 1758, 1229, 1759, - 1008, 703, 1217, 4044, 1205, 1007, 3931, 1218, 2834, 1217, - 1234, 1235, 3662, 685, 1218, 1216, 2880, 1215, 3320, 2917, - 1978, 4042, 1230, 1223, 703, 2446, 683, 703, 1093, 3290, - 4048, 4049, 703, 1453, 3318, 1454, 1455, 95, 3025, 3203, - 3204, 95, 2406, 2405, 2559, 3944, 4043, 2021, 2440, 1258, - 2826, 2827, 95, 2321, 2568, 3288, 717, 2025, 721, 1192, - 2965, 4020, 715, 1436, 3294, 3255, 680, 3255, 4020, 1754, - 2352, 1694, 2949, 2924, 1167, 695, 1927, 86, 2516, 2477, - 88, 2529, 2525, 2527, 2528, 2526, 2530, 2531, 4083, 704, - 690, 3886, 1450, 3887, 2537, 1095, 2538, 1087, 2539, 3281, - 693, 1425, 4114, 1953, 1089, 1088, 2162, 3282, 2520, 4084, - 1473, 1246, 2522, 1248, 1236, 1250, 1231, 1224, 1232, 1233, - 1928, 3291, 1929, 1255, 1237, 2562, 2563, 2565, 2564, 2953, - 2954, 1238, 3309, 704, 1474, 1475, 1476, 1477, 1478, 1479, - 1480, 1482, 1481, 1483, 1484, 3544, 1198, 3289, 3202, 2967, - 2519, 1245, 1247, 1093, 3543, 95, 1094, 1979, 1257, 2540, - 3205, 1173, 1172, 2521, 1256, 2518, 3819, 2523, 670, 3540, - 672, 686, 1697, 706, 2480, 705, 676, 3619, 674, 678, - 687, 679, 1060, 673, 2365, 684, 1104, 1142, 675, 688, - 689, 692, 696, 697, 698, 694, 691, 2439, 682, 707, - 1446, 704, 4056, 3026, 2154, 1141, 1103, 1140, 1838, 2156, - 1104, 1139, 704, 2161, 2157, 1138, 3457, 2158, 2159, 2160, - 1137, 1136, 2155, 2163, 2164, 2165, 2166, 2167, 2168, 2169, - 2170, 2171, 1135, 1130, 1143, 704, 1079, 3205, 704, 4135, - 1079, 1116, 4089, 704, 1077, 1079, 1115, 1971, 1152, 2453, - 1262, 2968, 1262, 1262, 1115, 3090, 1055, 1243, 1151, 2506, - 2505, 1244, 2350, 2351, 1967, 1070, 1064, 1062, 1427, 1160, - 3225, 1249, 2948, 1832, 1831, 1830, 1070, 1064, 1062, 4057, - 2934, 1094, 1968, 1828, 3539, 1208, 1445, 1442, 1443, 1444, - 1449, 1451, 1448, 660, 1447, 1755, 1242, 1488, 1489, 3927, - 1022, 1497, 1502, 1503, 1441, 1506, 1508, 1509, 1510, 1511, - 3494, 1514, 1515, 1517, 1517, 2918, 1517, 1517, 1522, 1522, + 955, 3614, 3615, 87, 3613, 4037, 4114, 3933, 943, 3289, + 4127, 4018, 4081, 1265, 950, 3565, 942, 2088, 4082, 4006, + 2394, 3917, 3189, 1263, 3247, 3196, 3418, 3252, 2100, 3842, + 2323, 3238, 3249, 3248, 3246, 3251, 1768, 3250, 3150, 3915, + 2756, 2031, 3552, 1975, 5, 2325, 3090, 3983, 3267, 3204, + 2468, 737, 3266, 3154, 3151, 3652, 3463, 3457, 2993, 2349, + 908, 2820, 2368, 42, 731, 3138, 3148, 764, 1724, 3449, + 1824, 732, 2365, 904, 903, 3269, 2894, 2431, 2975, 3296, + 2926, 3483, 2895, 2456, 2436, 2896, 1022, 163, 87, 2499, + 2382, 1042, 1074, 1019, 1144, 2845, 1871, 2370, 41, 43, + 2812, 2278, 1711, 2796, 2290, 2246, 2123, 1022, 2369, 2826, + 2245, 2967, 2084, 2039, 2477, 2455, 149, 2357, 2516, 1853, + 2438, 1102, 1084, 2887, 1107, 1757, 2862, 1737, 2372, 100, + 2833, 1690, 1512, 2127, 104, 2059, 105, 2343, 1439, 1424, + 1860, 1971, 1081, 747, 2453, 1952, 1021, 3153, 1025, 1078, + 1113, 1110, 1082, 734, 2427, 1108, 1109, 1756, 1059, 1742, + 1120, 1061, 2196, 2154, 2030, 1031, 2291, 1044, 2794, 3647, + 2428, 1041, 107, 3905, 2350, 742, 1496, 1472, 1253, 1983, + 1028, 167, 2135, 85, 1819, 99, 1026, 1027, 127, 905, + 1017, 125, 126, 1845, 132, 133, 1193, 1054, 93, 1029, + 741, 98, 1261, 1516, 106, 1239, 735, 4115, 2470, 2471, + 2472, 1521, 84, 3553, 3235, 3968, 2470, 2917, 1049, 1053, + 2514, 724, 2949, 2948, 3508, 3545, 1016, 4064, 2983, 1034, + 2984, 3963, 3964, 2046, 128, 1937, 669, 2320, 2321, 3618, + 2045, 3969, 1149, 2044, 1075, 2043, 1146, 134, 2042, 2041, + 1686, 2014, 1209, 666, 4058, 667, 2564, 2792, 3134, 1163, + 1164, 1165, 4085, 1168, 1169, 1170, 1171, 4137, 2503, 1174, + 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, + 1185, 1186, 1187, 1188, 1189, 1190, 1035, 1435, 1123, 1018, + 1210, 1069, 1068, 3257, 725, 1456, 1718, 1124, 1020, 2, + 3942, 1728, 2919, 1099, 2822, 1043, 128, 1150, 1153, 1154, + 95, 95, 2502, 1098, 3618, 1086, 1097, 1096, 3094, 1157, + 3257, 4080, 4120, 709, 4105, 727, 3617, 95, 3423, 1726, + 2062, 1729, 3964, 3254, 3422, 4068, 909, 2346, 959, 960, + 961, 4066, 1166, 2345, 111, 112, 113, 4119, 116, 3255, + 1015, 122, 703, 1091, 191, 2942, 3918, 661, 709, 1727, + 4067, 2757, 95, 2051, 3315, 3838, 4065, 3837, 3558, 722, + 723, 3559, 4095, 1148, 128, 3261, 3255, 1147, 3848, 1010, + 1011, 1012, 1013, 1067, 1071, 907, 1024, 4062, 4019, 2939, + 2573, 3577, 1426, 3566, 1100, 4007, 959, 960, 961, 2093, + 4015, 3617, 3261, 703, 2496, 3847, 4042, 1067, 1071, 907, + 3335, 1834, 86, 3185, 1056, 1057, 3186, 3187, 2956, 2957, + 4047, 2871, 2982, 1758, 2870, 1759, 1090, 2872, 703, 1092, + 2793, 1453, 86, 1454, 1455, 2570, 2836, 86, 4045, 2389, + 2390, 1095, 2388, 1202, 1203, 3576, 700, 4051, 4052, 2023, + 2024, 2966, 703, 1229, 1008, 2571, 3206, 3207, 1234, 1235, + 1258, 2837, 1007, 4046, 4023, 1217, 3934, 1230, 1979, 2501, + 1218, 1223, 1217, 2447, 2883, 1205, 3293, 1218, 2407, 2406, + 1440, 3665, 703, 86, 703, 1216, 88, 1215, 3028, 3258, + 95, 3291, 2829, 2830, 685, 703, 2441, 703, 3947, 1093, + 2562, 1436, 2022, 3323, 3321, 717, 2026, 683, 2322, 721, + 95, 1754, 3297, 2163, 4086, 95, 3258, 715, 2968, 1440, + 2927, 3889, 4023, 3890, 3284, 2353, 1167, 1958, 1095, 2478, + 1087, 1694, 3285, 4117, 2952, 4087, 2523, 1089, 1088, 2517, + 2353, 1927, 1953, 1250, 2540, 1192, 2541, 680, 2542, 1232, + 1233, 1255, 1238, 2970, 1425, 1198, 695, 3547, 3546, 2519, + 2543, 95, 1231, 1236, 704, 3205, 1224, 1173, 1473, 3294, + 1257, 690, 1172, 1237, 3822, 3543, 1256, 3208, 2565, 2566, + 2568, 2567, 693, 1133, 3292, 1928, 1093, 1929, 1450, 2481, + 3312, 2524, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, + 1481, 1483, 1484, 1103, 1838, 1131, 1980, 1104, 1122, 3460, + 1060, 2155, 3622, 2366, 2521, 704, 2157, 1104, 1142, 1141, + 2162, 2158, 1697, 1140, 2159, 2160, 2161, 1450, 1094, 2156, + 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 1139, + 704, 1138, 1137, 3208, 1136, 2440, 1135, 1143, 1130, 1487, + 670, 4059, 672, 686, 3029, 706, 2520, 705, 676, 2920, + 674, 678, 687, 679, 704, 673, 4138, 684, 4092, 2522, + 675, 688, 689, 692, 696, 697, 698, 694, 691, 1115, + 682, 707, 2530, 2526, 2528, 2529, 2527, 2531, 2532, 2533, + 3542, 1079, 1079, 1079, 704, 1077, 704, 1446, 1116, 1972, + 1262, 1055, 1262, 1262, 1070, 1064, 1062, 704, 2454, 704, + 2971, 1121, 2507, 1832, 1152, 1094, 1125, 1115, 2351, 2352, + 1115, 1127, 2506, 1968, 1151, 1128, 1126, 3093, 1070, 1064, + 1062, 1427, 1134, 2351, 2352, 2987, 1446, 1160, 1755, 1438, + 3228, 2951, 1961, 1831, 1959, 1960, 1129, 1962, 1963, 1964, + 1022, 1497, 1502, 1503, 1132, 1506, 1508, 1509, 1510, 1511, + 1830, 1514, 1515, 1517, 1517, 2954, 1517, 1517, 1522, 1522, 1522, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, @@ -1746,1035 +1748,1094 @@ var yyAct = [...]int{ 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, - 1644, 1645, 1646, 1494, 3938, 1251, 2915, 1647, 1101, 1649, - 1650, 1651, 1652, 1653, 1418, 1419, 1939, 1938, 1940, 1941, - 1942, 1522, 1522, 1522, 1522, 1522, 1522, 2499, 3503, 3504, - 956, 3572, 708, 703, 3613, 2951, 1660, 1661, 1662, 1663, + 1644, 1645, 1646, 1494, 3941, 1251, 2918, 1647, 3616, 1649, + 1650, 1651, 1652, 1653, 1418, 1419, 3506, 3507, 3461, 1507, + 4021, 1522, 1522, 1522, 1522, 1522, 1522, 1939, 1938, 1940, + 1941, 1942, 1417, 1101, 956, 956, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, - 1498, 1417, 1196, 701, 1445, 1442, 1443, 1444, 1449, 1451, - 1448, 956, 1447, 956, 3613, 1507, 4018, 1687, 702, 3189, - 1434, 1214, 1441, 4018, 3458, 1213, 2352, 1219, 1220, 1221, - 1222, 1518, 2938, 1519, 1520, 2443, 1487, 4047, 94, 1204, - 1523, 1524, 94, 3256, 3257, 3256, 3257, 89, 4017, 1133, - 1063, 1259, 1260, 94, 2569, 4017, 3260, 3310, 3260, 1201, - 1487, 1063, 1131, 1122, 3190, 1717, 1859, 1227, 3099, 2568, - 1693, 2991, 2971, 3403, 2962, 2444, 2937, 2961, 1684, 1022, - 3476, 4046, 2442, 1022, 2497, 1958, 2864, 2829, 3192, 1022, - 1122, 1490, 1491, 1492, 1493, 2794, 2796, 2766, 2095, 1746, - 1648, 1504, 1207, 1122, 2394, 3098, 3187, 1957, 124, 2824, - 668, 1487, 1484, 1685, 3181, 4128, 2445, 1718, 2593, 1240, - 1467, 1038, 2984, 1254, 3203, 3204, 2441, 1159, 2135, 1983, - 3952, 3188, 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, - 1145, 1701, 2136, 3535, 3470, 1705, 2582, 2063, 2517, 119, - 2034, 1021, 1964, 2127, 1760, 2993, 94, 1122, 3011, 1095, - 1191, 2064, 1485, 1486, 2062, 3194, 1121, 1212, 2907, 2127, - 4093, 2602, 1703, 3658, 2494, 1858, 104, 1704, 1456, 1455, - 1685, 105, 1654, 1655, 1656, 1657, 1658, 1659, 1454, 1455, - 3510, 3509, 2484, 1121, 704, 1691, 2593, 3327, 1134, 1115, - 1118, 1119, 1868, 1079, 1867, 1857, 1121, 1112, 1116, 1678, - 2489, 1132, 1115, 1118, 1119, 1122, 1079, 107, 2350, 2351, - 1112, 1116, 120, 2492, 1195, 3003, 3002, 3001, 1111, 1133, - 2995, 4085, 2999, 3202, 2994, 2974, 2992, 1131, 2974, 1122, - 2973, 2997, 3495, 2973, 1033, 3205, 1699, 4136, 4130, 2493, - 2996, 1720, 1835, 1836, 1837, 1851, 3569, 1954, 3570, 1955, - 1121, 3827, 1956, 1718, 2795, 1125, 1115, 1241, 2998, 3000, - 1127, 1702, 1226, 2133, 1128, 1126, 1700, 1984, 3826, 1688, - 2496, 1976, 1922, 1228, 1873, 1844, 1874, 1018, 1876, 1878, - 3982, 1723, 1882, 1884, 1886, 1888, 1890, 1863, 1020, 1904, - 1961, 1197, 1959, 1960, 2489, 1962, 1963, 1456, 1718, 2282, - 1262, 1211, 1751, 1752, 1453, 2132, 1454, 1455, 1121, 1912, - 1913, 1947, 1862, 1125, 1115, 1918, 1919, 1456, 1127, 1194, - 1861, 1861, 1128, 1126, 4137, 3983, 4126, 1945, 1934, 4127, - 1827, 4125, 1121, 2491, 1158, 1094, 3817, 3285, 1155, 1456, - 1473, 3920, 2983, 1129, 1842, 2574, 2575, 2576, 1841, 1840, - 1854, 3191, 1479, 1480, 1482, 1481, 1483, 1484, 1706, 3585, - 2052, 2054, 2055, 1865, 1474, 1475, 1476, 1477, 1478, 1479, - 1480, 1482, 1481, 1483, 1484, 1946, 3584, 190, 1473, 3517, - 3516, 1469, 1718, 1470, 1908, 2053, 3921, 959, 960, 961, - 1900, 1944, 1933, 1903, 1972, 1905, 3506, 1471, 1485, 1486, - 1468, 129, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, - 1481, 1483, 1484, 1456, 172, 3233, 1473, 3221, 2889, 2888, - 2887, 2449, 2882, 4098, 1718, 1948, 1833, 1932, 1931, 1930, - 1920, 128, 1098, 1453, 1097, 1454, 1455, 1914, 2641, 1096, + 1498, 956, 4020, 2500, 89, 4050, 2572, 2885, 3575, 1434, + 1490, 1491, 1492, 1493, 708, 4131, 2921, 1687, 3259, 3260, + 1504, 1213, 3406, 1219, 1220, 1221, 1222, 1518, 4021, 1519, + 1520, 3263, 3192, 3616, 2444, 701, 1214, 1201, 1859, 1063, + 1523, 1524, 94, 2941, 1487, 3259, 3260, 1259, 1260, 4049, + 702, 1445, 1442, 1443, 1444, 1449, 1451, 1448, 3263, 1447, + 4020, 1122, 94, 1063, 2937, 1717, 3313, 94, 1969, 1441, + 1693, 1828, 1208, 660, 2445, 1204, 1684, 3193, 4060, 1022, + 1196, 2443, 2571, 1022, 2498, 3930, 3497, 2940, 1122, 1022, + 1445, 1442, 1443, 1444, 1449, 1451, 1448, 3102, 1447, 3479, + 1246, 3195, 1248, 2965, 2974, 2867, 2964, 1227, 1441, 2797, + 2799, 1488, 1489, 94, 1685, 2446, 2832, 2769, 2120, 3190, + 2096, 1746, 1648, 1207, 3101, 2442, 124, 2827, 1159, 2395, + 2585, 1479, 1480, 1482, 1481, 1483, 1484, 3206, 3207, 1701, + 1245, 1247, 668, 1705, 3191, 1487, 1484, 1858, 2136, 1021, + 3184, 2596, 1467, 1038, 3955, 1254, 1122, 1240, 1984, 1145, + 1212, 3538, 2137, 1718, 1121, 1477, 1478, 1479, 1480, 1482, + 1481, 1483, 1484, 1703, 1957, 1704, 3473, 104, 3197, 105, + 2518, 1685, 1654, 1655, 1656, 1657, 1658, 1659, 2035, 1965, + 1760, 1121, 3014, 2064, 2128, 119, 1691, 1115, 1118, 1119, + 1122, 1079, 2128, 2910, 2605, 1112, 1116, 2065, 1485, 1486, + 2063, 1678, 1454, 1455, 3661, 107, 2112, 2101, 2102, 2103, + 2104, 2114, 2105, 2106, 2107, 2119, 2115, 2108, 2109, 2116, + 2117, 2118, 2110, 2111, 2113, 4096, 4129, 1095, 1191, 4130, + 1122, 4128, 2596, 1456, 1455, 3513, 3205, 1243, 2977, 1699, + 3512, 1244, 2485, 2976, 1835, 1836, 1837, 2994, 3208, 1121, + 1868, 1249, 1867, 1851, 1857, 1115, 1118, 1119, 120, 1079, + 2977, 1702, 1720, 1112, 1116, 2976, 2495, 1700, 2798, 2493, + 2497, 1977, 1922, 1844, 1133, 1018, 1242, 1873, 1688, 1874, + 1723, 1876, 1878, 2134, 1111, 1882, 1884, 1886, 1888, 1890, + 1863, 1020, 1195, 1121, 1211, 1241, 1985, 1904, 1125, 1115, + 1262, 2490, 1226, 1127, 1751, 1752, 2490, 1128, 1126, 1197, + 1862, 1912, 1913, 1228, 1954, 1131, 1955, 1918, 1919, 1956, + 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1458, 1473, 1861, + 1861, 2996, 1827, 1121, 4139, 1158, 4088, 1456, 3498, 1155, + 2494, 2053, 2055, 2056, 3985, 2492, 3923, 1854, 1033, 1841, + 1842, 1840, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, + 1481, 1483, 1484, 1865, 1947, 3194, 2054, 1945, 3572, 1453, + 3573, 1454, 1455, 1706, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1482, 1481, 1483, 1484, 1908, 1456, 1718, 4133, 3986, + 1900, 3924, 2283, 1903, 2133, 1905, 1973, 2602, 1194, 1456, + 3830, 3829, 3006, 3005, 3004, 1934, 2283, 2998, 3820, 3002, + 2280, 2997, 1456, 2995, 1094, 2577, 2578, 2579, 3000, 2282, + 3588, 4140, 1456, 2358, 2359, 3587, 3520, 2999, 1946, 128, + 3519, 1944, 1473, 954, 3509, 1469, 1098, 1470, 3236, 1097, + 1096, 1833, 959, 960, 961, 3001, 3003, 3224, 1456, 2892, + 2891, 1471, 1485, 1486, 1468, 1990, 1474, 1475, 1476, 1477, + 1478, 1479, 1480, 1482, 1481, 1483, 1484, 1262, 1262, 1933, + 2601, 1986, 1987, 1453, 2890, 1454, 1455, 2450, 3288, 2012, + 1948, 87, 3016, 1932, 87, 1991, 1473, 1931, 2986, 1930, + 1920, 709, 1998, 1999, 2000, 1914, 4101, 1718, 1911, 1910, + 1909, 1880, 2011, 1698, 1421, 190, 4099, 1718, 1754, 4089, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, 1483, - 1484, 1911, 190, 1453, 1910, 1454, 1455, 1989, 1460, 1461, - 1462, 1463, 1464, 1465, 1466, 1458, 1909, 1262, 1262, 1456, - 169, 1985, 1986, 170, 1880, 1453, 129, 1454, 1455, 2011, - 1473, 87, 1698, 1421, 87, 1990, 3500, 709, 709, 172, - 1754, 2629, 1997, 1998, 1999, 1473, 189, 2581, 2871, 709, - 4086, 1456, 2010, 3947, 1474, 1475, 1476, 1477, 1478, 1479, - 1480, 1482, 1481, 1483, 1484, 1456, 2465, 2464, 3946, 1474, + 1484, 3950, 1453, 110, 1454, 1455, 1731, 1456, 3949, 129, + 3927, 2120, 4029, 1718, 109, 1453, 108, 1454, 1455, 3503, + 709, 42, 172, 3926, 42, 103, 2874, 709, 1453, 3925, + 1454, 1455, 3825, 2091, 2091, 2089, 2089, 2092, 1453, 2642, + 1454, 1455, 2466, 2465, 1988, 2464, 2463, 2462, 2461, 1452, + 1718, 1992, 1732, 1994, 1995, 1996, 1997, 1456, 110, 3809, + 2001, 2057, 1456, 101, 1453, 2876, 1454, 1455, 3808, 109, + 103, 108, 2013, 2640, 102, 1456, 2818, 4116, 169, 2632, + 3660, 170, 101, 3658, 1718, 3198, 3584, 1456, 1683, 3202, + 1682, 4027, 1718, 102, 4076, 1718, 3201, 2592, 1681, 1684, + 1452, 1718, 1718, 2174, 189, 2818, 4014, 2818, 3993, 2112, + 2101, 2102, 2103, 2104, 2114, 2105, 2106, 2107, 2119, 2115, + 2108, 2109, 2116, 2117, 2118, 2110, 2111, 2113, 2036, 1718, + 3203, 2818, 3989, 3976, 1718, 3199, 3517, 1685, 3502, 1718, + 3200, 85, 2061, 1453, 85, 1454, 1455, 1718, 1718, 2019, + 2020, 3556, 3940, 3943, 2067, 1473, 2069, 2070, 2071, 2072, + 2073, 2074, 2076, 2078, 2079, 2080, 2081, 2082, 2083, 3833, + 1718, 4025, 1718, 2818, 3821, 3556, 1718, 2066, 3298, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, - 2463, 2462, 2873, 1475, 1476, 1477, 1478, 1479, 1480, 1482, - 1481, 1483, 1484, 42, 3924, 169, 42, 3923, 170, 1453, - 1456, 1454, 1455, 2090, 2090, 2088, 2088, 2091, 3013, 1456, - 2282, 2461, 2460, 1456, 2279, 1731, 3922, 1456, 1987, 2815, - 4113, 189, 2589, 2281, 3822, 1991, 3806, 1993, 1994, 1995, - 1996, 3805, 2056, 101, 2000, 4096, 1718, 954, 4073, 1718, - 103, 3195, 3657, 101, 102, 3199, 2012, 1452, 1718, 4026, - 1718, 1473, 3198, 110, 102, 1453, 3655, 1454, 1455, 3581, - 173, 1732, 2815, 4011, 109, 1683, 108, 2815, 3990, 179, - 1682, 1684, 1681, 1456, 2173, 1474, 1475, 1476, 1477, 1478, - 1479, 1480, 1482, 1481, 1483, 1484, 3200, 1453, 3514, 1454, - 1455, 3196, 3499, 4024, 1718, 1718, 3197, 4022, 1718, 1718, - 3940, 1453, 4087, 1454, 1455, 2639, 1685, 2815, 3986, 1718, - 85, 2035, 2060, 85, 3295, 1452, 1718, 3973, 1718, 2018, - 2019, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1482, 1481, - 1483, 1484, 2119, 1456, 1718, 173, 1453, 3292, 1454, 1455, - 3553, 3937, 3853, 1456, 179, 1453, 2065, 1454, 1455, 1453, - 3224, 1454, 1455, 1453, 3223, 1454, 1455, 3899, 1718, 3830, - 1718, 3852, 2293, 2815, 3818, 3553, 1718, 3810, 2094, 2292, - 2066, 2898, 2068, 2069, 2070, 2071, 2072, 2073, 2075, 2077, - 2078, 2079, 2080, 2081, 2082, 2885, 2291, 1498, 1680, 1456, - 2121, 2123, 2550, 164, 2137, 2138, 2139, 2140, 2815, 3551, - 3809, 2278, 110, 2549, 2128, 2489, 1718, 2172, 2151, 1453, - 2511, 1454, 1455, 109, 2510, 108, 2347, 3897, 1718, 3474, - 1718, 3561, 1456, 2327, 103, 2721, 1718, 3894, 1718, 2925, - 2111, 2100, 2101, 2102, 2103, 2113, 2104, 2105, 2106, 2118, - 2114, 2107, 2108, 2115, 2116, 2117, 2109, 2110, 2112, 3214, - 3213, 2903, 2373, 2014, 2187, 1980, 2296, 2297, 1456, 2067, - 2293, 3211, 3212, 3209, 3210, 3209, 3208, 2362, 164, 1453, - 103, 1454, 1455, 3876, 1718, 104, 2280, 2839, 1718, 1453, - 105, 1454, 1455, 1718, 2291, 2568, 2947, 1456, 2403, 1823, - 2928, 2921, 2922, 2815, 2814, 1456, 104, 2811, 2637, 2595, - 1718, 105, 1943, 2185, 2059, 2860, 3445, 1718, 109, 1456, - 2338, 1935, 103, 2196, 2375, 2093, 1718, 2490, 1456, 1925, - 2599, 2838, 1921, 1917, 1084, 1453, 1456, 1454, 1455, 1718, - 2295, 1916, 1915, 2298, 2299, 2860, 1823, 1822, 2412, 2413, - 2414, 2415, 3438, 1718, 2407, 1733, 2408, 2409, 2410, 2411, - 2314, 2398, 1034, 2397, 1766, 1765, 2326, 1084, 1453, 1252, - 1454, 1455, 2418, 2419, 2420, 2421, 2379, 2831, 2861, 2831, - 2595, 2332, 1718, 2333, 2402, 2489, 2839, 1452, 2863, 3435, - 1718, 3146, 2432, 2269, 2270, 2271, 2272, 2273, 2340, 2337, - 2401, 3469, 3469, 2598, 1453, 1452, 1454, 1455, 2861, 2478, - 3471, 2438, 3433, 1718, 2360, 1456, 4074, 3176, 2568, 1456, - 3395, 1718, 3978, 2384, 2385, 2383, 1789, 2568, 3951, 1456, - 2815, 2400, 2839, 1453, 2399, 1454, 1455, 1069, 3424, 1068, - 165, 1453, 3211, 1454, 1455, 2475, 3119, 177, 2316, 2839, - 2448, 3469, 2386, 2595, 2196, 1453, 2721, 1454, 1455, 2626, - 1456, 2625, 2489, 2472, 1453, 2355, 1454, 1455, 1722, 2317, - 2093, 2433, 1453, 2036, 1454, 1455, 2422, 2424, 2425, 2429, - 2020, 1023, 1966, 2447, 2483, 2451, 1753, 2486, 185, 2487, - 2459, 1456, 1106, 1105, 95, 1456, 4052, 3993, 2503, 3393, - 1718, 1456, 3236, 3389, 1718, 3841, 2433, 2482, 1456, 2481, - 1725, 1124, 2485, 3386, 1718, 165, 1123, 3807, 3669, 3534, - 3531, 1861, 177, 3512, 3337, 2507, 3336, 2504, 1825, 2508, - 2509, 166, 171, 168, 174, 175, 176, 178, 180, 181, - 182, 183, 1719, 1721, 3384, 1718, 2431, 184, 186, 187, - 188, 1453, 3283, 1454, 1455, 1453, 3238, 1454, 1455, 95, - 3234, 2573, 2929, 185, 2428, 1453, 2423, 1454, 1455, 2417, - 1456, 2416, 1777, 1950, 2514, 3382, 1718, 1856, 3287, 3380, - 1718, 1852, 1821, 121, 2119, 1508, 3935, 1508, 2894, 2895, - 1196, 3842, 3378, 1718, 3481, 3482, 1453, 3518, 1454, 1455, - 1896, 2446, 2330, 2585, 4108, 4106, 166, 171, 168, 174, - 175, 176, 178, 180, 181, 182, 183, 3522, 2543, 2293, - 4080, 3959, 184, 186, 187, 188, 2292, 1453, 3881, 1454, - 1455, 1453, 1456, 1454, 1455, 3484, 2895, 1453, 1456, 1454, - 1455, 3230, 2016, 2588, 1453, 3487, 1454, 1455, 3519, 3520, - 3521, 1897, 1898, 1899, 3376, 1718, 1790, 3229, 3228, 3146, - 2908, 2544, 2357, 2358, 3523, 3524, 3525, 1456, 2558, 3486, - 2844, 2847, 2848, 2849, 2845, 1456, 2846, 2850, 3165, 1456, - 3164, 2566, 2111, 2100, 2101, 2102, 2103, 2113, 2104, 2105, - 2106, 2118, 2114, 2107, 2108, 2115, 2116, 2117, 2109, 2110, - 2112, 3955, 3168, 1456, 2017, 2577, 1453, 3169, 1454, 1455, - 3166, 3170, 1456, 2848, 2849, 3167, 2060, 3814, 1803, 1806, - 1807, 1808, 1809, 1810, 1811, 1456, 1812, 1813, 1815, 1816, - 1814, 1817, 1818, 1791, 1792, 1793, 1794, 1775, 1776, 1804, - 3843, 1778, 665, 1779, 1780, 1781, 1782, 1783, 1784, 1785, - 1786, 1787, 3536, 1456, 1788, 1795, 1796, 1797, 1798, 3848, - 1799, 1800, 1801, 1802, 2890, 1456, 2601, 2346, 1453, 1730, - 1454, 1455, 2336, 2578, 1453, 2580, 1454, 1455, 3475, 3919, - 1892, 1456, 1036, 1735, 2583, 1456, 2584, 3374, 1718, 1456, - 2552, 2553, 3124, 2586, 1456, 2555, 3372, 1718, 3136, 3138, - 3123, 3648, 2765, 1453, 2556, 1454, 1455, 3139, 3650, 3370, - 1718, 1453, 1456, 1454, 1455, 1453, 726, 1454, 1455, 2635, - 3465, 3639, 1456, 3638, 3462, 1039, 1456, 1893, 1894, 1895, - 3133, 1037, 3461, 1040, 2797, 3207, 1965, 3368, 1718, 1453, - 1006, 1454, 1455, 2878, 2135, 2899, 1162, 1161, 1453, 1734, - 1454, 1455, 1022, 2090, 3303, 2088, 2800, 2894, 2136, 2977, - 1456, 1453, 2579, 1454, 1455, 3366, 1718, 1420, 1456, 3364, - 1718, 3637, 2935, 3362, 1718, 2836, 2837, 129, 3360, 1718, - 3467, 2798, 101, 101, 2373, 2357, 2358, 1022, 2856, 1453, - 103, 1454, 1455, 102, 102, 2608, 3358, 1718, 103, 4122, - 3226, 1453, 2547, 1454, 1455, 1456, 3356, 1718, 2059, 4031, - 3342, 1718, 2623, 3936, 3837, 2835, 2816, 1453, 110, 1454, - 1455, 1453, 3206, 1454, 1455, 1453, 1456, 1454, 1455, 109, - 1453, 108, 1454, 1455, 1456, 2852, 3447, 42, 2341, 1456, - 103, 1047, 1048, 2536, 3325, 1718, 2853, 2812, 1453, 2855, - 1454, 1455, 2786, 1718, 2572, 1691, 2825, 2788, 1453, 2854, - 1454, 1455, 1453, 3122, 1454, 1455, 1456, 2535, 2534, 1805, - 1456, 3121, 3907, 2533, 2801, 2532, 2803, 2881, 2883, 2808, - 110, 1685, 108, 1456, 3906, 3884, 3455, 3656, 3654, 2784, - 1718, 109, 2828, 108, 2874, 2813, 1453, 3653, 1454, 1455, - 1456, 2933, 2858, 3646, 1453, 1456, 1454, 1455, 3532, 1456, - 2759, 1718, 3466, 1456, 3464, 3239, 2862, 2473, 2736, 1718, - 1839, 2865, 1046, 2728, 1718, 2438, 2872, 109, 110, 3645, - 1456, 2831, 2875, 2130, 4110, 4109, 4109, 2944, 2131, 109, - 3623, 1453, 2897, 1454, 1455, 2811, 3027, 2900, 2901, 2886, - 2719, 1718, 2627, 2328, 2717, 1718, 1747, 1739, 114, 115, - 4110, 3925, 1453, 3498, 1454, 1455, 2896, 2704, 1718, 3, - 1453, 97, 1454, 1455, 2191, 1453, 2904, 1454, 1455, 2905, - 1, 2909, 2910, 2911, 2702, 1718, 1456, 1014, 1423, 2700, - 1718, 1456, 2941, 2698, 1718, 1456, 2033, 2696, 1718, 10, - 1422, 1844, 1453, 1456, 1454, 1455, 1453, 1456, 1454, 1455, - 3502, 2930, 2931, 1456, 2694, 1718, 4041, 681, 2318, 1453, - 2920, 1454, 1455, 2987, 2988, 2031, 2940, 1689, 9, 2032, - 1456, 4081, 8, 4037, 4038, 1456, 1453, 1936, 1454, 1455, - 1926, 1453, 3564, 1454, 1455, 1453, 2243, 1454, 1455, 1453, - 3838, 1454, 1455, 1456, 2275, 3242, 2479, 2966, 3004, 3530, - 2436, 1114, 154, 1456, 2985, 2395, 1453, 2969, 1454, 1455, - 2692, 1718, 2396, 4006, 1456, 2690, 1718, 118, 1072, 2688, - 1718, 117, 1117, 1225, 2308, 2474, 3554, 2686, 1718, 2879, - 2404, 2684, 1718, 1456, 1772, 1770, 1771, 2682, 1718, 1456, - 1769, 1719, 2315, 1774, 1773, 2942, 3311, 2628, 3005, 3008, - 1456, 3402, 2024, 716, 2680, 1718, 2851, 710, 192, 2678, - 1718, 1761, 1453, 1740, 1454, 1455, 3416, 1453, 1156, 1454, - 1455, 1453, 671, 1454, 1455, 3215, 2339, 2676, 1718, 1453, - 2512, 1454, 1455, 1453, 677, 1454, 1455, 2674, 1718, 1453, - 1505, 1454, 1455, 2015, 3120, 1456, 3029, 2866, 2672, 1718, - 1456, 1066, 1058, 2329, 2802, 3085, 1453, 2975, 1454, 1455, - 2976, 1453, 1065, 1454, 1455, 3815, 3154, 2670, 1718, 3459, - 3132, 3134, 2818, 2665, 1718, 3137, 3130, 3918, 3647, 1453, - 3991, 1454, 1455, 2876, 3489, 2989, 1736, 3423, 2600, 1453, - 2125, 1454, 1455, 3006, 1495, 2372, 3618, 2051, 739, 3092, - 1453, 738, 1454, 1455, 3103, 736, 3094, 2804, 2832, 1459, - 944, 2792, 2373, 1748, 3020, 2843, 1456, 2841, 2278, 1453, - 2278, 1454, 1455, 2840, 3065, 1453, 2545, 1454, 1455, 2661, - 1718, 2380, 2450, 3483, 3440, 3153, 1453, 87, 1454, 1455, - 2373, 2373, 2373, 2373, 2373, 3007, 1456, 3075, 3076, 3077, - 3078, 3079, 3479, 4033, 2374, 2370, 2810, 895, 894, 748, - 2373, 740, 3093, 2373, 3095, 730, 1456, 3103, 893, 892, - 2986, 3102, 3269, 1456, 2375, 3270, 2950, 3158, 1976, 3284, - 2952, 1453, 3175, 1454, 1455, 2877, 1453, 3127, 1454, 1455, - 3280, 3118, 1437, 2280, 3114, 2280, 1456, 1708, 1085, 1025, - 2659, 1718, 2375, 2375, 2375, 2375, 2375, 3308, 3942, 3125, - 2571, 3128, 3331, 1707, 3949, 3140, 3141, 3250, 3548, 1456, - 2591, 3231, 2375, 2926, 2466, 2375, 69, 3259, 46, 3913, - 2590, 3157, 3979, 887, 1026, 3177, 3159, 3267, 3178, 3162, - 3160, 3161, 3171, 3163, 104, 1027, 3115, 3116, 3117, 105, - 2652, 1718, 1453, 3179, 1454, 1455, 1456, 2650, 1718, 884, - 3620, 3185, 3621, 3622, 3088, 3126, 3089, 1456, 3962, 3963, - 883, 3964, 3216, 2180, 3218, 3067, 1433, 3069, 3217, 1430, - 3436, 4054, 1453, 1456, 1454, 1455, 2026, 3219, 3220, 96, - 36, 35, 34, 3080, 3081, 3082, 3083, 3271, 3268, 3143, - 33, 3272, 1453, 3401, 1454, 1455, 3240, 2438, 3261, 1453, - 32, 1454, 1455, 26, 25, 24, 23, 22, 3278, 29, - 19, 21, 20, 3149, 1456, 18, 3253, 4076, 3149, 1456, - 4121, 123, 1453, 1456, 1454, 1455, 55, 52, 50, 131, - 3397, 3296, 130, 53, 3299, 49, 3298, 1199, 47, 31, - 30, 3334, 17, 16, 15, 1453, 3306, 1454, 1455, 3316, - 14, 13, 3313, 3314, 12, 3315, 3262, 3333, 3317, 11, - 3319, 7, 3321, 2844, 2847, 2848, 2849, 2845, 6, 2846, - 2850, 39, 38, 3481, 3482, 37, 28, 27, 40, 4, - 2913, 2468, 1453, 0, 1454, 1455, 0, 1508, 0, 0, - 2587, 1508, 0, 1453, 2592, 1454, 1455, 0, 3330, 0, - 0, 0, 0, 2782, 3241, 0, 0, 2781, 0, 1453, - 0, 1454, 1455, 0, 0, 0, 0, 2596, 0, 2597, - 3418, 0, 0, 0, 2604, 0, 0, 3422, 2606, 2607, - 0, 0, 0, 0, 0, 0, 0, 2613, 2614, 2615, - 2616, 2617, 2618, 2619, 2620, 2621, 2622, 0, 2624, 0, - 1453, 0, 1454, 1455, 0, 1453, 0, 1454, 1455, 1453, - 3152, 1454, 1455, 0, 0, 0, 0, 2373, 0, 0, - 0, 2630, 2631, 2632, 2633, 2634, 0, 2636, 0, 1456, - 3496, 2638, 0, 0, 3463, 2643, 2644, 728, 2645, 3448, - 3449, 2648, 3456, 2649, 2651, 2653, 2654, 2655, 2656, 2657, - 2658, 2660, 2662, 2663, 2664, 2666, 0, 2668, 2669, 2671, - 2673, 2675, 2677, 2679, 2681, 2683, 2685, 2687, 2689, 2691, - 2693, 2695, 2697, 2699, 2701, 2703, 2705, 2706, 2707, 2375, - 2709, 3488, 2711, 3490, 2713, 2714, 3485, 2716, 2718, 2720, - 3271, 3268, 3491, 2723, 3272, 3451, 3497, 2727, 3468, 1456, - 0, 2732, 2733, 2734, 2735, 0, 0, 3513, 0, 3515, - 3301, 3302, 3307, 2777, 2746, 2747, 2748, 2749, 2750, 2751, - 0, 3453, 2755, 2756, 0, 3558, 3559, 0, 0, 0, - 2758, 0, 3507, 3508, 0, 2764, 3425, 0, 3427, 3428, - 3429, 2767, 2768, 2769, 2770, 2771, 1045, 1456, 0, 1051, - 1051, 957, 2778, 2779, 3478, 2780, 958, 0, 2783, 2785, - 2339, 0, 2787, 1716, 1712, 1453, 2089, 1454, 1455, 0, - 0, 0, 2799, 3492, 3493, 0, 0, 0, 1713, 0, - 0, 1716, 1712, 2776, 0, 3541, 0, 0, 3560, 3545, - 3546, 3547, 0, 0, 0, 0, 1713, 0, 0, 0, - 1456, 0, 0, 2334, 2335, 1715, 0, 1714, 0, 0, - 0, 0, 0, 3576, 0, 3537, 3538, 0, 0, 0, - 1456, 1709, 1710, 1715, 0, 1714, 0, 0, 0, 1456, - 0, 2775, 0, 1456, 0, 1453, 0, 1454, 1455, 1456, - 0, 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, 1453, 2774, 1454, 1455, 3636, 0, 3640, - 3641, 0, 0, 0, 0, 3626, 0, 3627, 3628, 3629, - 1456, 3616, 0, 0, 2773, 0, 0, 1456, 0, 0, - 0, 1456, 3153, 2772, 87, 3642, 3153, 2763, 0, 0, - 0, 0, 0, 2762, 1456, 0, 0, 0, 1456, 0, - 0, 0, 0, 0, 0, 0, 1453, 0, 1454, 1455, - 3580, 0, 1456, 0, 2090, 0, 2088, 3671, 0, 0, - 3643, 0, 0, 3651, 3663, 3652, 1453, 0, 1454, 1455, - 0, 0, 0, 3659, 3661, 1453, 0, 1454, 1455, 1453, - 0, 1454, 1455, 0, 0, 1453, 42, 1454, 1455, 0, - 0, 3821, 0, 0, 2761, 0, 0, 0, 3675, 0, - 0, 2760, 0, 0, 0, 2757, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2752, 0, - 0, 0, 2745, 0, 0, 0, 0, 0, 0, 0, - 0, 3813, 0, 3812, 0, 0, 2744, 0, 0, 0, - 0, 0, 0, 3828, 0, 3811, 1453, 0, 1454, 1455, - 3833, 3840, 3832, 1453, 0, 1454, 1455, 1453, 0, 1454, - 1455, 0, 3878, 3879, 3015, 3016, 3017, 3018, 3019, 0, - 1453, 3665, 1454, 1455, 1453, 0, 1454, 1455, 0, 0, - 2090, 0, 2088, 3882, 3024, 3823, 3824, 3825, 1453, 0, - 1454, 1455, 0, 0, 0, 0, 3672, 3673, 3607, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3149, - 0, 0, 0, 3153, 0, 0, 0, 0, 3885, 3667, - 0, 3816, 3888, 0, 0, 0, 0, 1525, 1526, 1527, - 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, - 1538, 1539, 1540, 1541, 1542, 1543, 1545, 1546, 1547, 1548, - 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, - 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, - 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, - 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, - 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, - 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, - 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, - 1619, 1620, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, - 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1643, 1644, - 1645, 1646, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, - 1668, 1669, 1670, 1671, 1672, 1673, 3929, 3152, 3926, 3883, - 3911, 3152, 3908, 3909, 1456, 3910, 0, 0, 0, 0, - 3943, 0, 1456, 0, 0, 0, 0, 1456, 0, 0, - 0, 1456, 0, 0, 0, 1456, 3928, 0, 87, 0, - 0, 0, 3155, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1456, 0, 0, 0, - 3173, 0, 0, 3932, 1456, 0, 0, 0, 0, 3945, - 1456, 0, 0, 0, 0, 3948, 3820, 0, 3950, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1456, 0, - 0, 0, 0, 0, 0, 0, 0, 3917, 2743, 0, - 42, 0, 0, 0, 0, 0, 2742, 0, 0, 0, - 0, 2741, 0, 0, 0, 2740, 0, 0, 0, 2739, - 0, 0, 0, 0, 0, 0, 0, 1457, 3968, 0, - 0, 3969, 3988, 0, 0, 0, 0, 87, 0, 0, - 2738, 0, 0, 0, 3934, 0, 0, 0, 2737, 0, - 1453, 3977, 1454, 1455, 2731, 0, 0, 1513, 1453, 0, - 1454, 1455, 0, 1453, 3984, 1454, 1455, 1453, 3994, 1454, - 1455, 1453, 2730, 1454, 1455, 4005, 4019, 3992, 3953, 0, - 3997, 4002, 3999, 3998, 3996, 4001, 0, 0, 3305, 3840, - 4008, 4000, 1453, 0, 1454, 1455, 0, 0, 3152, 42, - 1453, 4029, 1454, 1455, 0, 0, 1453, 0, 1454, 1455, - 3322, 3323, 4032, 3324, 4050, 3326, 3328, 4040, 0, 4045, - 0, 4058, 0, 0, 1453, 4060, 1454, 1455, 4019, 3335, - 0, 0, 4071, 0, 3339, 3340, 3341, 3343, 3344, 3345, + 3295, 3227, 2294, 1453, 3226, 1454, 1455, 2901, 1453, 2888, + 1454, 1455, 2292, 1680, 2095, 2553, 2122, 2124, 2068, 1456, + 2552, 1453, 2512, 1454, 1455, 2818, 3554, 1498, 173, 1456, + 2490, 1718, 2293, 1453, 2511, 1454, 1455, 179, 3477, 1718, + 1473, 2348, 2724, 1718, 2129, 2281, 2328, 2173, 2188, 2138, + 2139, 2140, 2141, 1473, 2279, 2584, 1456, 3217, 3216, 3214, + 3215, 3856, 2644, 2152, 1474, 1475, 1476, 1477, 1478, 1479, + 1480, 1482, 1481, 1483, 1484, 3212, 3213, 1474, 1475, 1476, + 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, 3212, 3211, + 2842, 1718, 2374, 2571, 2950, 2297, 2298, 1823, 2931, 1456, + 2294, 2924, 2925, 3902, 1718, 2818, 2817, 2598, 1718, 3855, + 2292, 103, 2863, 3900, 1718, 3813, 104, 2015, 105, 1475, + 1476, 1477, 1478, 1479, 1480, 1482, 1481, 1483, 1484, 2404, + 2363, 2094, 1718, 3812, 1456, 2863, 2814, 104, 1981, 105, + 3897, 1718, 3564, 2186, 1943, 2060, 1935, 1925, 1921, 1456, + 1917, 103, 2376, 2197, 2339, 1453, 2296, 1454, 1455, 2299, + 2300, 1916, 164, 1456, 1084, 1453, 1915, 1454, 1455, 1733, + 1718, 1823, 1822, 2594, 1252, 2864, 1456, 1766, 1765, 2413, + 2414, 2415, 2416, 2593, 2408, 2866, 2409, 2410, 2411, 2412, + 1034, 1456, 1453, 2398, 1454, 1455, 2327, 1084, 2864, 2399, + 2928, 3149, 2419, 2420, 2421, 2422, 2380, 2834, 2571, 2598, + 1456, 2315, 3472, 2491, 2333, 2338, 2334, 2834, 3879, 1718, + 3179, 2906, 109, 2270, 2271, 2272, 2273, 2274, 2341, 2403, + 2571, 2402, 3472, 3448, 1718, 1453, 2433, 1454, 1455, 1452, + 3474, 2479, 3981, 2361, 3954, 2841, 2439, 3441, 1718, 1456, + 2818, 2842, 2385, 2386, 3427, 2384, 3214, 3122, 1456, 2387, + 3438, 1718, 2401, 2400, 2598, 2724, 2629, 2628, 1069, 1068, + 1453, 2490, 1454, 1455, 2490, 3436, 1718, 2473, 2317, 2842, + 2356, 1722, 2449, 2476, 2197, 1453, 1456, 1454, 1455, 3472, + 1456, 1452, 2318, 2094, 3398, 1718, 2037, 1456, 2021, 1453, + 2842, 1454, 1455, 1967, 1753, 1456, 1023, 1106, 1105, 2434, + 95, 2430, 1453, 2452, 1454, 1455, 2448, 2484, 2460, 1456, + 2487, 4055, 2488, 2423, 2425, 2426, 1456, 1453, 3996, 1454, + 1455, 3844, 3239, 3396, 1718, 1456, 2504, 1735, 1725, 2483, + 2486, 1123, 3392, 1718, 2434, 2482, 1453, 1456, 1454, 1455, + 1124, 3810, 3672, 3537, 3534, 3515, 190, 3340, 3339, 2505, + 1861, 2508, 3521, 1825, 2432, 2509, 2510, 3286, 3241, 2897, + 3389, 1718, 1719, 1721, 3387, 1718, 3237, 2932, 2429, 1456, + 129, 3385, 1718, 1456, 95, 1453, 2424, 1454, 1455, 3383, + 1718, 2418, 2576, 172, 1453, 2417, 1454, 1455, 1456, 165, + 1950, 1856, 3290, 1734, 2515, 1852, 177, 1821, 121, 2898, + 3381, 1718, 3845, 3522, 3523, 3524, 1508, 2898, 1508, 3379, + 1718, 1196, 1453, 2447, 1454, 1455, 1453, 1456, 1454, 1455, + 2331, 3377, 1718, 1453, 2588, 1454, 1455, 3484, 3485, 1456, + 4111, 1453, 2017, 1454, 1455, 1456, 4109, 185, 4083, 169, + 2294, 2546, 170, 3962, 3884, 1453, 1456, 1454, 1455, 3487, + 2591, 3233, 1453, 3851, 1454, 1455, 1456, 3375, 1718, 3232, + 1456, 1453, 3231, 1454, 1455, 189, 3149, 1456, 2911, 3525, + 2293, 2547, 3492, 1453, 3490, 1454, 1455, 3489, 3168, 1456, + 166, 171, 168, 174, 175, 176, 178, 180, 181, 182, + 183, 2561, 1456, 3167, 2018, 665, 184, 186, 187, 188, + 1730, 3373, 1718, 3958, 1456, 1453, 2569, 1454, 1455, 1453, + 3846, 1454, 1455, 3371, 1718, 1456, 3526, 3527, 3528, 3369, + 1718, 2347, 2337, 3330, 1453, 1456, 1454, 1455, 3478, 2580, + 3367, 1718, 2847, 2850, 2851, 2852, 2848, 2061, 2849, 2853, + 3365, 1718, 1456, 3127, 3363, 1718, 3922, 3126, 2581, 1456, + 2583, 3361, 1718, 1453, 1456, 1454, 1455, 3139, 3141, 2586, + 3651, 2587, 1456, 3359, 1718, 1453, 3142, 1454, 1455, 726, + 3171, 1453, 3468, 1454, 1455, 3172, 3345, 1718, 3653, 173, + 1036, 1456, 1453, 3136, 1454, 1455, 3169, 1966, 179, 1718, + 2604, 3170, 1453, 1006, 1454, 1455, 1453, 3210, 1454, 1455, + 1718, 2881, 2582, 1453, 2902, 1454, 1455, 2555, 2556, 3328, + 1718, 1456, 2558, 3306, 2589, 1453, 3465, 1454, 1455, 1456, + 1162, 2559, 1892, 2768, 3464, 1456, 2789, 1718, 1453, 1037, + 1454, 1455, 1161, 2787, 1718, 2897, 2980, 1456, 2762, 1718, + 1453, 1039, 1454, 1455, 2638, 1420, 2739, 1718, 2136, 1040, + 1456, 1453, 2938, 1454, 1455, 2800, 3173, 1456, 2851, 2852, + 129, 1453, 2137, 1454, 1455, 2731, 1718, 3470, 1456, 1893, + 1894, 1895, 101, 1022, 2091, 101, 2089, 2803, 1453, 103, + 1454, 1455, 1456, 102, 103, 1453, 102, 1454, 1455, 3642, + 1453, 3641, 1454, 1455, 1456, 3443, 2839, 2840, 1453, 4034, + 1454, 1455, 2801, 2722, 1718, 2374, 1456, 4125, 1022, 2859, + 4090, 2358, 2359, 164, 3229, 2550, 2611, 1453, 3939, 1454, + 1455, 2720, 1718, 3840, 2804, 1456, 2806, 3209, 3125, 2855, + 2060, 2342, 110, 2626, 2707, 1718, 3124, 2838, 2819, 3640, + 1456, 2705, 1718, 109, 1456, 108, 2539, 1453, 3450, 1454, + 1455, 1456, 2703, 1718, 103, 1453, 42, 1454, 1455, 2538, + 1896, 1453, 2537, 1454, 1455, 2856, 3439, 2857, 2858, 1047, + 1048, 1456, 2815, 1453, 2536, 1454, 1455, 1691, 2701, 1718, + 2791, 2535, 2534, 1456, 2575, 108, 1453, 109, 1454, 1455, + 2699, 1718, 2828, 1453, 3910, 1454, 1455, 3909, 2811, 2884, + 2886, 1456, 3887, 1685, 1453, 3659, 1454, 1455, 3657, 2697, + 1718, 1897, 1898, 1899, 2831, 2877, 2816, 3458, 1453, 3656, + 1454, 1455, 2936, 2861, 2695, 1718, 3649, 1456, 2693, 1718, + 1453, 1456, 1454, 1455, 3535, 2691, 1718, 3469, 2865, 1456, + 3467, 3242, 1453, 2868, 1454, 1455, 2474, 3648, 2875, 1456, + 1839, 2439, 1046, 2131, 2878, 2689, 1718, 2834, 2132, 2947, + 4112, 1453, 110, 1454, 1455, 2900, 110, 2687, 1718, 1456, + 2903, 2904, 2889, 109, 1456, 108, 1453, 109, 1454, 1455, + 1453, 3626, 1454, 1455, 2814, 2685, 1718, 1453, 2899, 1454, + 1455, 4113, 4112, 3, 2192, 3030, 2630, 2329, 1747, 2907, + 1456, 2908, 1739, 2912, 2913, 2914, 4113, 1453, 3928, 1454, + 1455, 2683, 1718, 114, 115, 3404, 2944, 3501, 97, 1453, + 1844, 1454, 1455, 2681, 1718, 2034, 2032, 1, 10, 9, + 1456, 1014, 1423, 2679, 1718, 2933, 2934, 1453, 2033, 1454, + 1455, 8, 2923, 1456, 1422, 2990, 2991, 3505, 1456, 2943, + 165, 4044, 681, 2677, 1718, 2319, 1456, 177, 2675, 1718, + 1689, 4084, 4040, 1453, 4041, 1454, 1455, 1453, 1456, 1454, + 1455, 1936, 1926, 3567, 2276, 1453, 1456, 1454, 1455, 2969, + 1456, 2244, 3007, 3841, 3400, 1453, 2988, 1454, 1455, 1456, + 2972, 3245, 2480, 1456, 3533, 2437, 1114, 154, 185, 2396, + 2397, 4009, 118, 1072, 2309, 1453, 117, 1454, 1455, 1117, + 1453, 1225, 1454, 1455, 2673, 1718, 2475, 3557, 2882, 2405, + 1456, 1719, 2316, 1772, 1770, 1771, 2945, 2668, 1718, 1769, + 1774, 1773, 2664, 1718, 3314, 3011, 1453, 3008, 1454, 1455, + 3337, 166, 171, 168, 174, 175, 176, 178, 180, 181, + 182, 183, 2662, 1718, 2631, 3405, 2340, 184, 186, 187, + 188, 3938, 1456, 2025, 2655, 1718, 1453, 716, 1454, 1455, + 1456, 2854, 2992, 2653, 1718, 710, 1456, 192, 3817, 1453, + 3009, 1454, 1455, 1761, 1453, 3032, 1454, 1455, 3088, 1740, + 2978, 3419, 1453, 2979, 1454, 1455, 1156, 671, 3218, 2513, + 677, 1505, 2016, 3123, 1453, 3539, 1454, 1455, 2869, 1716, + 1712, 1456, 1453, 1066, 1454, 1455, 1453, 1058, 1454, 1455, + 2330, 2805, 2989, 3106, 1713, 1453, 1065, 1454, 1455, 1453, + 3095, 1454, 1455, 3818, 3157, 3462, 3135, 3137, 3097, 2821, + 3140, 3133, 3921, 3650, 3994, 2374, 3336, 3023, 2879, 2335, + 2336, 1715, 1736, 1714, 3333, 2281, 1453, 2281, 1454, 1455, + 3068, 2893, 2451, 3426, 2279, 2603, 2279, 1456, 3156, 2126, + 87, 1495, 2373, 2374, 2374, 2374, 2374, 2374, 3010, 3621, + 2052, 3078, 3079, 3080, 3081, 3082, 3106, 739, 738, 736, + 2807, 2835, 3096, 2374, 3098, 2785, 2374, 1459, 1453, 944, + 1454, 1455, 1456, 3105, 2795, 2376, 1453, 3130, 1454, 1455, + 3161, 1977, 1453, 1456, 1454, 1455, 1748, 2846, 2844, 2843, + 2548, 3178, 2381, 3486, 3482, 4036, 2375, 3121, 1456, 3117, + 1025, 2371, 1456, 2376, 2376, 2376, 2376, 2376, 2813, 895, + 894, 748, 3128, 740, 730, 893, 1456, 1453, 3131, 1454, + 1455, 2784, 892, 2376, 3272, 3180, 2376, 3273, 3181, 2953, + 3262, 3287, 2955, 3143, 3144, 2880, 3283, 3160, 1026, 1027, + 3270, 3163, 3164, 3129, 3166, 1456, 1437, 1708, 104, 3174, + 105, 3162, 1085, 3311, 3165, 1456, 2780, 3182, 3118, 3119, + 3120, 3945, 2574, 3334, 3188, 1707, 3952, 2779, 3253, 3551, + 3234, 2929, 1456, 1453, 2467, 1454, 1455, 1456, 3070, 3221, + 3072, 3220, 2778, 3219, 69, 1456, 2777, 46, 3916, 3982, + 887, 884, 3222, 3223, 3623, 3624, 3083, 3084, 3085, 3086, + 2776, 3625, 3091, 1716, 1712, 3146, 1456, 3271, 1453, 3092, + 1454, 1455, 3965, 3274, 3275, 2439, 3264, 3243, 1713, 1453, + 3966, 1454, 1455, 883, 3281, 1456, 3152, 3967, 2181, 2775, + 1456, 3152, 1433, 1430, 1453, 4057, 1454, 1455, 1453, 2766, + 1454, 1455, 2027, 1709, 1710, 1715, 96, 1714, 36, 3299, + 3302, 3301, 1453, 35, 1454, 1455, 2765, 34, 3309, 33, + 32, 2764, 1456, 26, 25, 3316, 3317, 24, 3318, 2763, + 3265, 3320, 23, 3322, 22, 3324, 3319, 29, 19, 21, + 20, 1453, 18, 1454, 1455, 3256, 4079, 4124, 123, 55, + 2760, 1453, 52, 1454, 1455, 50, 4077, 131, 130, 53, + 1508, 2590, 49, 1199, 1508, 2595, 1789, 47, 1453, 2755, + 1454, 1455, 31, 1453, 2748, 1454, 1455, 3244, 30, 17, + 16, 1453, 15, 1454, 1455, 14, 13, 12, 2599, 11, + 2600, 3421, 7, 6, 39, 2607, 38, 37, 3425, 2609, + 2610, 28, 1453, 27, 1454, 1455, 2747, 40, 2616, 2617, + 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 4, 2627, + 2916, 1453, 2469, 1454, 1455, 0, 1453, 0, 1454, 1455, + 0, 0, 0, 0, 3155, 0, 0, 0, 0, 0, + 2374, 0, 2633, 2634, 2635, 2636, 2637, 3454, 2639, 3451, + 3452, 0, 2641, 3499, 3310, 3459, 2646, 2647, 1453, 2648, + 1454, 1455, 2651, 3466, 2652, 2654, 2656, 2657, 2658, 2659, + 2660, 2661, 2663, 2665, 2666, 2667, 2669, 3471, 2671, 2672, + 2674, 2676, 2678, 2680, 2682, 2684, 2686, 2688, 2690, 2692, + 2694, 2696, 2698, 2700, 2702, 2704, 2706, 2708, 2709, 2710, + 2376, 2712, 3494, 2714, 3491, 2716, 2717, 3488, 2719, 2721, + 2723, 3493, 1777, 3428, 2726, 3430, 3431, 3432, 2730, 3456, + 3271, 0, 2735, 2736, 2737, 2738, 3274, 3275, 3500, 3304, + 3305, 3516, 0, 3518, 0, 2749, 2750, 2751, 2752, 2753, + 2754, 0, 0, 2758, 2759, 3561, 3562, 0, 0, 0, + 0, 2761, 3481, 0, 0, 0, 2767, 3510, 3511, 0, + 0, 0, 2770, 2771, 2772, 2773, 2774, 0, 0, 1456, + 0, 3495, 3496, 2781, 2782, 0, 2783, 0, 0, 2786, + 2788, 2340, 0, 2790, 2847, 2850, 2851, 2852, 2848, 0, + 2849, 2853, 0, 2802, 3484, 3485, 1790, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1456, + 3544, 3563, 0, 0, 3548, 3549, 3550, 0, 0, 0, + 0, 0, 1456, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3579, 0, 3540, + 3541, 0, 0, 0, 1456, 0, 0, 0, 0, 0, + 0, 0, 0, 2746, 1456, 0, 0, 0, 0, 1803, + 1806, 1807, 1808, 1809, 1810, 1811, 0, 1812, 1813, 1815, + 1816, 1814, 1817, 1818, 1791, 1792, 1793, 1794, 1775, 1776, + 1804, 1456, 1778, 0, 1779, 1780, 1781, 1782, 1783, 1784, + 1785, 1786, 1787, 2745, 0, 1788, 1795, 1796, 1797, 1798, + 1456, 1799, 1800, 1801, 1802, 1453, 2744, 1454, 1455, 0, + 3639, 0, 3643, 3644, 0, 1456, 0, 3629, 0, 3630, + 3631, 3632, 0, 1456, 0, 3619, 0, 0, 2743, 0, + 1456, 0, 0, 0, 1456, 3156, 0, 87, 2742, 3156, + 0, 0, 0, 0, 3645, 1453, 0, 1454, 1455, 0, + 0, 1456, 0, 0, 0, 0, 0, 0, 1453, 0, + 1454, 1455, 0, 0, 0, 2741, 3583, 2091, 1456, 2089, + 3674, 0, 0, 0, 3646, 0, 1456, 3654, 3666, 3655, + 1453, 0, 1454, 1455, 2740, 0, 0, 3662, 3664, 0, + 1453, 0, 1454, 1455, 0, 0, 0, 42, 0, 2734, + 0, 0, 0, 0, 3824, 0, 0, 2733, 0, 0, + 0, 0, 0, 3678, 2732, 0, 0, 1453, 2729, 1454, + 1455, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2728, 1453, 0, 1454, 1455, + 0, 0, 0, 0, 0, 0, 3816, 3815, 0, 0, + 3843, 1453, 2727, 1454, 1455, 0, 3831, 0, 3814, 1453, + 2725, 1454, 1455, 0, 3835, 3836, 1453, 0, 1454, 1455, + 1453, 0, 1454, 1455, 0, 3881, 3882, 3018, 3019, 3020, + 3021, 3022, 0, 0, 3675, 3676, 3668, 1453, 0, 1454, + 1455, 0, 0, 2091, 0, 2089, 3885, 3027, 0, 0, + 3826, 3827, 3828, 0, 1453, 0, 1454, 1455, 0, 0, + 1805, 3610, 1453, 0, 1454, 1455, 0, 0, 0, 0, + 0, 0, 3152, 0, 0, 0, 3156, 0, 0, 0, + 3888, 0, 3670, 0, 3891, 3819, 0, 0, 0, 0, + 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, + 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1545, + 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, + 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, + 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, + 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, + 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, + 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, + 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, + 1616, 1617, 1618, 1619, 1620, 1622, 1623, 1624, 1625, 1626, + 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, + 1637, 1643, 1644, 1645, 1646, 1660, 1661, 1662, 1663, 1664, + 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 728, + 3932, 3155, 3886, 3929, 3913, 3155, 3914, 3911, 3912, 1456, + 0, 0, 0, 3946, 1456, 0, 0, 0, 0, 0, + 1456, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 87, 3931, 0, 0, 3158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1456, 0, 0, + 0, 0, 0, 3176, 0, 0, 3935, 0, 1456, 0, + 0, 0, 3948, 0, 0, 0, 3951, 0, 0, 0, + 3823, 0, 3953, 0, 0, 0, 0, 1456, 0, 0, + 0, 1456, 0, 0, 0, 0, 0, 0, 0, 0, + 3920, 42, 0, 2718, 0, 0, 0, 0, 2715, 0, + 0, 0, 0, 0, 2713, 0, 0, 0, 1045, 0, + 0, 1051, 1051, 0, 0, 0, 0, 0, 0, 3971, + 0, 0, 3972, 0, 0, 3991, 0, 0, 0, 0, + 87, 2711, 0, 0, 0, 0, 0, 0, 3937, 0, + 0, 0, 2670, 0, 3980, 1453, 0, 1454, 1455, 0, + 1453, 0, 1454, 1455, 0, 0, 1453, 3987, 1454, 1455, + 0, 2650, 0, 0, 3997, 2649, 4022, 4000, 3843, 4011, + 4005, 3995, 3956, 0, 4008, 4002, 4001, 3999, 4004, 0, + 4003, 3308, 0, 1453, 0, 1454, 1455, 0, 0, 0, + 42, 0, 3155, 4032, 1453, 0, 1454, 1455, 0, 0, + 0, 0, 0, 3325, 3326, 4053, 3327, 4043, 3329, 3331, + 4048, 4035, 0, 1453, 4061, 1454, 1455, 1453, 4022, 1454, + 1455, 4063, 3338, 0, 0, 4074, 0, 3342, 3343, 3344, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, - 3357, 3359, 3361, 3363, 3365, 3367, 3369, 3371, 3373, 3375, - 3377, 3379, 3381, 3383, 3385, 3387, 3388, 3390, 3391, 3392, - 3394, 1976, 4075, 3396, 4091, 3398, 3399, 3400, 4090, 4101, - 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, - 3414, 2090, 4107, 2088, 4104, 4103, 4094, 4105, 4100, 3421, - 4070, 3989, 4115, 3426, 1456, 4019, 0, 3430, 3431, 1456, - 3432, 3434, 4123, 3437, 3439, 3149, 3441, 3442, 3443, 3444, - 4131, 4129, 0, 1456, 3450, 0, 0, 3957, 1456, 0, - 0, 0, 0, 0, 0, 3967, 0, 1456, 0, 0, - 4140, 4141, 3879, 4139, 0, 0, 0, 1456, 0, 2090, - 0, 2088, 4138, 1456, 0, 3941, 0, 1456, 0, 3472, - 3473, 0, 1456, 3477, 0, 0, 1456, 0, 0, 0, - 1456, 0, 0, 0, 1789, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1456, 2729, 4088, - 0, 0, 0, 2726, 1456, 0, 0, 0, 0, 0, - 1456, 0, 0, 0, 0, 0, 0, 2725, 0, 0, - 0, 0, 2724, 0, 0, 0, 0, 0, 0, 0, - 4066, 2722, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2715, 0, 0, 0, 0, 0, 2712, 0, 0, - 1453, 2710, 1454, 1455, 1738, 1453, 2708, 1454, 1455, 0, - 2667, 1456, 0, 0, 2647, 957, 1456, 2282, 0, 1453, - 958, 1454, 1455, 0, 1453, 0, 1454, 1455, 0, 3552, - 2089, 2646, 0, 1453, 0, 1454, 1455, 0, 2642, 0, - 0, 0, 1826, 1453, 2640, 1454, 1455, 0, 0, 1453, - 0, 1454, 1455, 1453, 0, 1454, 1455, 0, 1453, 0, - 1454, 1455, 1453, 0, 1454, 1455, 1453, 0, 1454, 1455, - 0, 0, 0, 0, 3571, 0, 0, 3575, 0, 0, - 1777, 0, 0, 1453, 0, 1454, 1455, 0, 0, 0, - 1453, 0, 1454, 1455, 0, 2605, 1453, 0, 1454, 1455, - 2594, 0, 0, 940, 3586, 964, 965, 966, 967, 968, + 3356, 3357, 3358, 3360, 3362, 3364, 3366, 3368, 3370, 3372, + 3374, 3376, 3378, 3380, 3382, 3384, 3386, 3388, 3390, 3391, + 3393, 3394, 3395, 3397, 1977, 4078, 3399, 4094, 3401, 3402, + 3403, 4073, 4104, 3407, 3408, 3409, 3410, 3411, 3412, 3413, + 3414, 3415, 3416, 3417, 2091, 4110, 2089, 4107, 4097, 4106, + 4108, 4103, 3424, 1456, 4093, 4022, 3429, 3992, 4118, 0, + 3433, 3434, 0, 3435, 3437, 4126, 3440, 3442, 3152, 3444, + 3445, 3446, 3447, 4134, 4132, 1456, 0, 3453, 0, 1456, + 3960, 0, 190, 0, 0, 1456, 0, 0, 3970, 0, + 0, 0, 0, 4143, 4144, 3882, 4142, 0, 0, 0, + 0, 0, 2091, 0, 2089, 4141, 129, 0, 151, 3944, + 0, 0, 3475, 3476, 0, 0, 3480, 0, 0, 172, + 0, 0, 0, 0, 0, 0, 0, 4069, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2645, 0, 0, + 0, 0, 0, 4091, 0, 0, 0, 0, 0, 0, + 162, 0, 0, 0, 0, 0, 150, 0, 0, 2643, + 0, 0, 0, 2608, 0, 0, 0, 0, 0, 2597, + 0, 0, 0, 0, 0, 169, 0, 0, 170, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1453, + 0, 1454, 1455, 0, 0, 0, 0, 138, 139, 161, + 160, 189, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1453, 0, 1454, 1455, 1453, 0, 1454, 1455, 0, + 0, 1453, 3555, 1454, 1455, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2922, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 129, 0, 151, 0, 3574, 0, 0, + 3578, 0, 0, 0, 0, 0, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3589, 0, 0, + 0, 0, 155, 136, 158, 143, 135, 162, 156, 157, + 0, 0, 0, 150, 0, 173, 0, 0, 0, 0, + 0, 0, 0, 0, 179, 144, 0, 0, 0, 0, + 0, 0, 169, 0, 0, 170, 0, 0, 0, 147, + 145, 140, 141, 142, 146, 0, 0, 0, 0, 0, + 0, 137, 0, 0, 1847, 1848, 161, 160, 189, 0, + 148, 3612, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3620, 0, 0, 0, 0, 0, + 0, 0, 3627, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 44, 45, 88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, + 0, 0, 0, 48, 76, 77, 0, 74, 78, 164, + 0, 0, 0, 0, 0, 0, 75, 0, 0, 155, + 1849, 158, 0, 1846, 0, 156, 157, 0, 0, 0, + 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, + 0, 179, 0, 0, 0, 62, 0, 0, 0, 1457, + 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3832, 0, 0, + 0, 0, 0, 0, 0, 0, 3839, 0, 0, 1513, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3849, 3850, 0, 3852, + 0, 3853, 3854, 83, 0, 159, 3857, 3858, 3859, 3860, + 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, + 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 0, 3880, + 3883, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3892, 3893, 3894, 3895, 3896, + 3898, 3899, 3901, 3903, 3904, 3906, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3936, 0, 0, 0, 51, 54, 57, + 56, 59, 0, 73, 0, 957, 82, 79, 0, 0, + 958, 0, 0, 152, 0, 0, 153, 0, 0, 0, + 2090, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 61, 91, 90, 0, 0, 71, 72, 58, 0, 0, + 0, 0, 0, 80, 81, 0, 165, 0, 0, 0, + 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, + 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 63, 64, 0, 65, + 66, 67, 68, 0, 185, 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, 1453, 0, 1454, - 1455, 0, 1453, 0, 1454, 1455, 0, 0, 0, 195, - 0, 0, 195, 0, 1790, 0, 714, 0, 3609, 0, - 1981, 720, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3617, 195, 0, 0, 0, 0, 0, 0, 3624, - 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 999, 1000, 1001, 1002, 1003, 1004, 1005, 166, 171, 168, + 174, 175, 176, 178, 180, 181, 182, 183, 0, 0, + 60, 0, 0, 184, 186, 187, 188, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1738, 0, 0, 0, + 152, 0, 0, 153, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3961, 0, 0, + 0, 0, 0, 165, 1826, 0, 0, 0, 0, 0, + 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3977, 0, 0, 0, 0, 0, 3978, 3979, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 89, 0, 0, 0, 0, 0, 0, 0, 0, 3990, + 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 940, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4016, 4017, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4024, + 4026, 4028, 0, 0, 166, 171, 168, 174, 175, 176, + 178, 180, 181, 182, 183, 0, 0, 0, 0, 0, + 184, 186, 187, 188, 4056, 0, 0, 0, 0, 195, + 0, 0, 195, 0, 0, 0, 714, 0, 0, 0, + 0, 720, 1982, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 94, + 0, 0, 4075, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 957, 0, 2283, 0, + 0, 958, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2090, 0, 720, 195, 720, 4098, 4100, 4102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 195, 720, 1803, 1806, 1807, 1808, - 1809, 1810, 1811, 0, 1812, 1813, 1815, 1816, 1814, 1817, - 1818, 1791, 1792, 1793, 1794, 1775, 1776, 1804, 0, 1778, - 0, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, - 0, 0, 1788, 1795, 1796, 1797, 1798, 0, 1799, 1800, - 1801, 1802, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4135, 4136, 0, + 0, 1692, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 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, 0, 0, + 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3829, 0, 0, 0, 0, 0, - 0, 0, 0, 3836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3846, 3847, 0, 3849, 0, 3850, 3851, - 0, 0, 0, 3854, 3855, 3856, 3857, 3858, 3859, 3860, - 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, - 3871, 3872, 3873, 3874, 3875, 0, 3877, 3880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3889, 3890, 3891, 3892, 3893, 3895, 3896, 3898, - 3900, 3901, 3903, 0, 0, 0, 0, 0, 0, 0, - 2046, 2047, 2048, 2049, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2057, 0, 0, 0, 0, + 0, 0, 1080, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2047, 2048, 2049, 2050, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2096, 2097, 0, 0, 0, 0, 2120, 1051, 1051, 2124, - 0, 0, 0, 2129, 0, 0, 0, 1805, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2141, 2142, - 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 0, 2152, - 0, 0, 0, 2174, 2175, 2176, 2177, 2178, 2179, 2181, - 0, 2186, 0, 2188, 2189, 2190, 0, 2192, 2193, 2194, - 0, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, - 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, - 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, - 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, - 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2246, 2247, 2248, - 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, - 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, - 0, 0, 0, 0, 0, 2274, 0, 2276, 0, 2283, - 2284, 2285, 2286, 2287, 2288, 1051, 0, 1051, 1051, 1051, - 1051, 1051, 0, 0, 0, 0, 0, 0, 2300, 2301, - 2302, 2303, 2304, 2305, 2306, 2307, 0, 2309, 2310, 2311, - 2312, 2313, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1051, 0, 3974, 0, - 0, 0, 0, 0, 3975, 3976, 0, 0, 190, 0, + 0, 0, 2097, 2098, 0, 0, 0, 0, 2121, 1051, + 1051, 2125, 0, 0, 0, 2130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2353, 2354, 0, 0, 3987, 0, 0, 0, - 0, 0, 129, 0, 151, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 0, 0, 2392, 0, - 0, 0, 4013, 4014, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4021, 4023, 4025, 0, - 0, 0, 0, 0, 0, 0, 162, 0, 1692, 0, - 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, - 0, 4053, 0, 0, 195, 0, 195, 0, 0, 0, - 0, 169, 0, 0, 170, 0, 0, 0, 0, 2434, + 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, + 0, 2153, 0, 0, 0, 2175, 2176, 2177, 2178, 2179, + 2180, 2182, 0, 2187, 0, 2189, 2190, 2191, 0, 2193, + 2194, 2195, 0, 2198, 2199, 2200, 2201, 2202, 2203, 2204, + 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, + 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, + 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, + 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2247, + 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, + 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, + 2268, 2269, 0, 0, 0, 0, 0, 2275, 0, 2277, + 0, 2284, 2285, 2286, 2287, 2288, 2289, 1051, 0, 1051, + 1051, 1051, 1051, 1051, 0, 0, 0, 0, 0, 0, + 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 0, 2310, + 2311, 2312, 2313, 2314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 139, 161, 160, 189, 0, 4072, - 0, 0, 0, 720, 0, 720, 720, 663, 0, 0, - 0, 0, 0, 190, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2919, 720, 195, 1009, 0, 0, - 0, 0, 0, 4095, 4097, 4099, 0, 129, 0, 151, + 0, 0, 0, 0, 1789, 0, 0, 0, 0, 0, + 0, 190, 0, 0, 0, 0, 0, 0, 1051, 0, + 0, 0, 1843, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 129, 0, 151, 0, 0, + 0, 0, 0, 0, 2354, 2355, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 172, 0, 0, 0, 1500, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4120, 0, 0, 1080, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 162, 0, 0, 4132, 4133, 0, 150, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 155, 136, - 158, 143, 135, 0, 156, 157, 169, 0, 0, 170, - 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, - 179, 144, 0, 0, 0, 0, 0, 0, 1847, 1848, - 161, 160, 189, 0, 0, 147, 145, 140, 141, 142, - 146, 0, 0, 0, 0, 0, 0, 137, 0, 0, - 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, + 2393, 0, 0, 0, 0, 0, 0, 0, 0, 162, + 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 0, 0, 170, 0, 0, + 0, 0, 0, 0, 195, 0, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1847, 1848, 161, 160, + 189, 2435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1777, 0, 0, 720, 0, 720, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 155, 1849, 158, 0, 1846, 0, 156, - 157, 0, 0, 0, 164, 0, 173, 0, 0, 0, - 0, 0, 0, 0, 1500, 179, 0, 0, 0, 0, + 0, 155, 1849, 158, 1790, 1846, 0, 156, 157, 0, + 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, + 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2603, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2609, 2610, 2611, 2612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 0, 720, 720, 0, 0, 0, + 0, 0, 1200, 0, 1206, 0, 0, 1803, 1806, 1807, + 1808, 1809, 1810, 1811, 0, 1812, 1813, 1815, 1816, 1814, + 1817, 1818, 1791, 1792, 1793, 1794, 1775, 1776, 1804, 0, + 1778, 0, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, + 1787, 0, 0, 1788, 1795, 1796, 1797, 1798, 0, 1799, + 1800, 1801, 1802, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 1513, 0, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 720, 0, 0, 0, 0, 0, 0, 195, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2606, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2612, 2613, + 2614, 2615, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 720, 720, 0, 0, 0, + 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 1513, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 720, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1805, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, 0, 0, - 0, 0, 0, 720, 720, 0, 720, 0, 720, 720, - 0, 720, 720, 720, 720, 720, 720, 0, 152, 0, - 0, 153, 0, 0, 1500, 0, 0, 1500, 720, 1500, + 0, 0, 152, 720, 720, 153, 720, 0, 720, 720, + 0, 720, 720, 720, 720, 720, 720, 0, 0, 0, + 0, 0, 0, 0, 1500, 0, 0, 1500, 720, 1500, + 195, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, - 195, 165, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 720, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 195, 195, 1738, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 195, 185, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 195, 195, 185, 0, 0, 1738, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 195, 1750, 0, 0, 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 720, 0, 0, 0, 0, 0, 0, + 195, 195, 195, 720, 0, 1767, 166, 171, 168, 174, + 175, 176, 178, 180, 181, 182, 183, 0, 0, 0, + 0, 0, 184, 186, 187, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 166, 171, 168, 174, 175, 176, 178, 180, - 181, 182, 183, 152, 0, 0, 153, 0, 184, 186, - 187, 188, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1200, - 0, 1206, 0, 0, 0, 0, 165, 0, 0, 0, - 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, - 0, 1429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 166, 171, 168, - 174, 175, 176, 178, 180, 181, 182, 183, 0, 0, - 720, 720, 0, 184, 186, 187, 188, 0, 0, 0, - 0, 2982, 0, 720, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1951, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1978, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1989, 0, 0, 0, + 0, 0, 0, 1993, 0, 0, 0, 0, 0, 0, + 720, 720, 0, 0, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 0, 0, 720, 0, 0, 2985, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1051, 0, 0, 3009, 3010, 0, 0, - 3012, 0, 0, 3014, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3021, 3022, 3023, 0, 0, 0, 0, - 0, 720, 0, 0, 0, 3028, 0, 0, 3030, 3031, - 3032, 1500, 0, 0, 3033, 3034, 0, 0, 3035, 0, - 3036, 0, 0, 0, 0, 0, 0, 3037, 1500, 3038, - 0, 0, 0, 3039, 0, 3040, 0, 0, 3041, 0, - 3042, 0, 3043, 0, 3044, 0, 3045, 0, 3046, 0, - 3047, 0, 3048, 0, 3049, 0, 3050, 0, 3051, 0, - 3052, 0, 3053, 0, 3054, 0, 3055, 0, 3056, 0, - 3057, 0, 3058, 0, 0, 0, 3059, 0, 3060, 0, - 3061, 0, 0, 3062, 0, 3063, 0, 3064, 0, 2246, - 3066, 0, 0, 3068, 0, 0, 3070, 3071, 3072, 3073, - 0, 0, 0, 0, 3074, 2246, 2246, 2246, 2246, 2246, - 0, 0, 0, 0, 0, 0, 0, 0, 939, 0, - 3084, 0, 0, 0, 0, 0, 0, 0, 3097, 0, - 0, 3101, 0, 1051, 0, 0, 0, 0, 0, 0, - 3104, 3105, 3106, 3107, 3108, 3109, 0, 0, 0, 3110, - 3111, 0, 3112, 0, 3113, 0, 0, 0, 0, 0, - 0, 0, 2294, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 699, 0, 0, 0, 0, 0, 719, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3144, - 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 720, 0, 1750, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3174, 0, 0, 0, 0, 0, - 0, 0, 1767, 0, 0, 0, 195, 0, 719, 720, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1051, 0, + 0, 3012, 3013, 0, 0, 3015, 0, 0, 3017, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3024, 3025, + 3026, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 3031, 1500, 0, 3033, 3034, 3035, 0, 0, 0, 3036, + 3037, 0, 0, 3038, 0, 3039, 0, 0, 1500, 0, + 0, 0, 3040, 0, 3041, 0, 0, 0, 3042, 0, + 3043, 0, 0, 3044, 0, 3045, 0, 3046, 0, 3047, + 0, 3048, 0, 3049, 0, 3050, 0, 3051, 0, 3052, + 0, 3053, 0, 3054, 0, 3055, 0, 3056, 0, 3057, + 0, 3058, 0, 3059, 0, 3060, 0, 3061, 0, 0, + 0, 3062, 0, 3063, 0, 3064, 0, 0, 3065, 0, + 3066, 0, 3067, 0, 2247, 3069, 0, 0, 3071, 0, + 0, 3073, 3074, 3075, 3076, 0, 0, 0, 0, 3077, + 2247, 2247, 2247, 2247, 2247, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3087, 0, 0, 0, 0, + 2040, 0, 0, 3100, 0, 0, 3104, 0, 1051, 0, + 0, 0, 0, 0, 0, 3107, 3108, 3109, 3110, 3111, + 3112, 0, 0, 0, 3113, 3114, 0, 3115, 0, 3116, + 0, 0, 2295, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3147, 0, 195, 0, 0, 0, + 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3177, + 0, 0, 0, 0, 0, 0, 195, 0, 0, 720, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 720, 0, 0, - 2294, 195, 0, 195, 0, 195, 195, 0, 0, 0, + 2295, 195, 0, 195, 0, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 720, 0, 0, 0, 0, 3237, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 720, 0, 0, 1977, 0, 0, - 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3329, 0, 1988, 0, 0, 0, 0, 0, 0, - 1992, 0, 0, 0, 0, 3338, 0, 0, 0, 0, - 0, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 0, 0, - 86, 44, 45, 88, 0, 0, 0, 720, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 939, 0, + 0, 0, 0, 0, 0, 0, 3332, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3341, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 720, 0, 0, 0, 720, 720, 0, 0, - 92, 0, 0, 0, 48, 76, 77, 0, 74, 78, - 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, + 0, 2360, 0, 0, 0, 0, 0, 0, 0, 2364, + 699, 2367, 0, 0, 2040, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 62, 0, 0, 0, - 195, 195, 0, 0, 195, 0, 195, 0, 95, 0, - 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 195, 195, 0, 0, 195, 0, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 195, 719, 0, + 719, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 0, 83, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 190, 0, 0, 0, 0, 0, 0, 2039, 0, 0, - 0, 1843, 3533, 0, 0, 0, 0, 1500, 0, 2294, - 0, 0, 0, 0, 129, 0, 151, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 172, 51, 54, - 57, 56, 59, 0, 73, 3557, 0, 82, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, - 0, 61, 91, 90, 150, 0, 71, 72, 58, 0, - 0, 0, 0, 0, 80, 81, 0, 0, 0, 0, - 0, 0, 0, 169, 0, 0, 170, 0, 0, 0, - 0, 0, 0, 3577, 0, 3578, 0, 0, 3579, 0, - 0, 3582, 3583, 0, 0, 1847, 1848, 161, 160, 189, - 3587, 0, 0, 0, 0, 0, 63, 64, 0, 65, - 66, 67, 68, 0, 3588, 0, 3589, 0, 3590, 0, - 3591, 0, 3592, 0, 3593, 0, 3594, 0, 3595, 0, - 3596, 0, 3597, 0, 3598, 0, 3599, 0, 3600, 0, - 3601, 0, 3602, 0, 3603, 0, 0, 3604, 0, 0, - 0, 3605, 0, 3606, 0, 0, 0, 0, 0, 3608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3625, 0, 0, 0, 0, 0, 0, 0, - 0, 3630, 0, 3631, 3632, 0, 3633, 0, 3634, 0, - 155, 1849, 158, 3635, 1846, 0, 156, 157, 719, 1416, - 719, 719, 0, 173, 0, 0, 0, 0, 0, 0, - 0, 195, 179, 0, 0, 0, 0, 0, 3660, 195, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 3668, - 720, 0, 3670, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 3674, 0, 0, 0, 0, 1499, - 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3808, 0, 0, 0, 0, 0, 0, 195, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 2359, 0, - 0, 0, 0, 0, 0, 0, 2363, 0, 2366, 0, - 0, 2039, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3536, 1500, 0, + 2295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3560, 0, 2040, 0, 0, 0, 0, 0, 0, 2525, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2544, + 2545, 0, 0, 2549, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2554, 0, 0, 0, 0, + 0, 0, 2557, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3580, 0, + 3581, 0, 0, 3582, 0, 0, 3585, 3586, 2560, 0, + 0, 0, 0, 0, 0, 3590, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3591, + 0, 3592, 0, 3593, 0, 3594, 0, 3595, 0, 3596, + 0, 3597, 0, 3598, 0, 3599, 0, 3600, 0, 3601, + 0, 3602, 0, 3603, 0, 3604, 0, 3605, 0, 3606, + 0, 0, 3607, 0, 0, 0, 3608, 0, 3609, 0, + 0, 0, 0, 0, 3611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, - 720, 0, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 0, 94, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, - 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 0, 0, 0, 897, 0, 0, - 0, 0, 0, 3916, 0, 0, 0, 0, 0, 1500, + 0, 0, 0, 0, 0, 0, 0, 3628, 0, 0, + 0, 0, 0, 0, 0, 0, 3633, 0, 3634, 3635, + 0, 3636, 0, 3637, 0, 0, 0, 0, 3638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 195, 195, 195, 195, 195, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 195, 0, 0, 3663, 0, 0, 0, 0, 0, 0, + 0, 720, 0, 0, 3671, 0, 0, 3673, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 3677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 159, 0, 0, 0, 0, 195, 195, 0, - 0, 0, 0, 193, 0, 0, 664, 0, 0, 1499, + 0, 0, 0, 0, 0, 3811, 0, 0, 195, 0, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 70, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1032, 0, 0, 720, 0, 0, 0, 2039, - 0, 0, 0, 0, 0, 0, 2524, 0, 0, 1052, - 1052, 0, 0, 0, 0, 2541, 2542, 0, 664, 2546, - 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2551, 0, 0, 0, 0, 0, 0, 2554, 0, - 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, - 152, 0, 0, 153, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 2557, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, - 0, 0, 0, 165, 0, 0, 1820, 0, 0, 0, - 177, 0, 0, 0, 0, 0, 1829, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3956, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, - 0, 1855, 0, 0, 0, 0, 0, 0, 0, 1864, - 0, 185, 1499, 1866, 0, 0, 1869, 1870, 719, 719, - 0, 719, 0, 719, 719, 0, 719, 719, 719, 719, - 719, 719, 3970, 0, 0, 3971, 0, 3972, 720, 1499, - 1901, 1902, 1499, 719, 1499, 0, 1907, 0, 0, 0, - 720, 0, 0, 0, 166, 171, 168, 174, 175, 176, - 178, 180, 181, 182, 183, 0, 0, 0, 0, 0, - 184, 186, 187, 188, 0, 0, 0, 0, 719, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1969, 0, 0, 719, 195, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 0, 0, 0, 1500, 0, 0, - 720, 720, 1500, 195, 195, 195, 195, 195, 0, 0, - 0, 4051, 0, 0, 0, 195, 0, 0, 719, 0, - 0, 195, 0, 195, 0, 0, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4067, 0, 4068, 0, 4069, 0, 0, 0, 95, 0, - 0, 957, 0, 0, 0, 945, 958, 959, 960, 961, - 946, 0, 0, 947, 948, 0, 949, 0, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 954, 962, 963, 0, 0, 720, 0, 0, 1500, 0, - 0, 0, 0, 720, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 4118, 0, 4119, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3273, - 3274, 0, 195, 0, 0, 195, 0, 0, 0, 0, - 0, 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, 0, 0, 719, 719, 2857, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 897, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 720, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 193, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 0, 3919, 0, + 1500, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 195, 195, 195, 195, 195, 195, 0, + 0, 0, 0, 0, 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 195, 195, 0, 1052, 1052, 0, 0, 0, 0, 0, + 0, 2860, 664, 0, 0, 0, 0, 0, 719, 1416, + 719, 719, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3275, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, - 0, 2906, 0, 0, 0, 0, 1499, 0, 0, 0, - 0, 0, 0, 0, 0, 2098, 0, 0, 0, 0, - 0, 0, 0, 1499, 195, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 896, 3276, 3277, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, - 664, 0, 0, 0, 0, 0, 0, 2955, 2956, 2957, - 2958, 2959, 2960, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2039, 2970, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 718, 195, - 0, 0, 0, 0, 0, 0, 0, 2978, 0, 0, - 664, 0, 0, 0, 0, 910, 0, 0, 0, 195, - 0, 914, 195, 195, 195, 911, 912, 0, 0, 0, - 913, 915, 720, 720, 0, 0, 0, 0, 1501, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, - 1076, 0, 1083, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2909, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 720, 720, 720, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 719, 0, 0, 0, 0, + 0, 2958, 2959, 2960, 2961, 2962, 2963, 0, 0, 0, + 0, 3959, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2040, 2973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2981, 0, 0, 0, 3973, 0, 0, + 3974, 720, 3975, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 1499, + 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, + 1500, 0, 0, 720, 720, 1500, 195, 195, 195, 195, + 195, 0, 0, 0, 0, 0, 4054, 0, 195, 0, + 0, 0, 0, 0, 195, 0, 195, 0, 0, 195, + 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 719, 0, 0, 0, 4070, 0, 4071, 0, 4072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 0, 1500, 0, 0, 0, 719, 720, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 1820, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 1829, 0, 0, 4121, + 0, 4122, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 195, 719, + 0, 1855, 0, 0, 0, 0, 0, 0, 0, 1864, + 0, 0, 1499, 1866, 0, 0, 1869, 1870, 719, 719, + 0, 719, 0, 719, 719, 0, 719, 719, 719, 719, + 719, 719, 0, 0, 0, 0, 0, 0, 0, 1499, + 1901, 1902, 1499, 719, 1499, 0, 1907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 2456, - 2457, 2458, 0, 0, 0, 0, 0, 0, 1501, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 0, 719, - 0, 0, 0, 0, 0, 719, 1864, 0, 0, 1864, - 0, 1864, 0, 1500, 0, 0, 0, 2488, 720, 0, - 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 719, 0, 0, - 0, 719, 719, 0, 0, 0, 0, 0, 1032, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 664, 0, 720, 0, 0, 3227, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, - 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3265, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3279, 0, 0, + 0, 1970, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3297, 0, 0, - 3300, 1501, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, - 720, 0, 0, 0, 720, 720, 0, 0, 1501, 0, - 0, 1501, 0, 1501, 664, 0, 0, 0, 0, 0, + 0, 0, 720, 3230, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 0, 664, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 3268, + 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 3282, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 896, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3300, 0, 0, 3303, 0, 0, 0, + 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 720, 1923, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, + 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1499, 0, 719, 1975, 664, 0, 0, 0, + 0, 718, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 2001, 2002, - 664, 664, 664, 664, 664, 664, 664, 0, 0, 0, + 0, 0, 195, 0, 0, 195, 195, 195, 0, 0, + 0, 0, 0, 0, 0, 720, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3452, + 0, 0, 0, 1076, 0, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 719, 0, 0, 0, + 0, 0, 0, 0, 720, 720, 720, 720, 719, 0, + 0, 0, 0, 0, 0, 3455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1499, 0, 0, 0, + 0, 0, 0, 0, 0, 2099, 0, 0, 0, 0, + 0, 0, 0, 1499, 0, 0, 0, 0, 0, 0, + 3514, 0, 1501, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3529, 0, 0, 3530, 3531, 3532, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1264, 0, 1264, 1264, 0, 720, 195, 0, 0, 0, - 0, 0, 0, 0, 3511, 0, 0, 0, 0, 0, - 0, 0, 1428, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3526, 0, 0, 3527, 3528, 3529, + 0, 0, 1032, 0, 0, 0, 1500, 0, 0, 0, + 0, 720, 0, 720, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1500, - 0, 720, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 2294, 0, 719, 0, + 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 720, 0, 0, + 0, 0, 0, 0, 0, 1501, 719, 0, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, + 0, 0, 1501, 0, 719, 1501, 0, 1501, 664, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 719, 0, 0, 1923, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 720, 0, 0, 0, 720, 720, 1976, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 720, 0, 0, 0, + 0, 0, 2002, 2003, 664, 664, 664, 664, 664, 664, + 664, 0, 719, 0, 0, 0, 0, 0, 0, 2457, + 2458, 2459, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 0, 0, 0, 0, 719, 1864, 0, 0, 1864, + 0, 1864, 0, 0, 0, 0, 0, 2489, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 719, 0, 0, + 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 720, 0, 0, 1501, 0, 0, 0, 0, - 0, 0, 0, 2870, 0, 0, 0, 1052, 1052, 0, - 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 720, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 720, 0, 720, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 719, - 0, 0, 0, 1864, 1864, 0, 0, 0, 719, 0, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1264, 0, 1264, 1264, 0, 720, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1499, 2943, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1052, 1975, 1052, 1052, 1052, - 1052, 1052, 1695, 1696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1500, 0, 720, 0, 0, 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1052, 1052, 0, 0, 0, 1501, 0, 720, 2295, + 0, 0, 0, 1499, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1923, 0, 1744, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 1052, 1762, 0, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, - 0, 0, 0, 0, 1975, 664, 0, 664, 719, 664, - 2382, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1872, 1872, 0, 1872, 0, 1872, 1872, 0, 1881, 1872, - 1872, 1872, 1872, 1872, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1076, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3957, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 720, 0, + 720, 0, 0, 0, 0, 0, 0, 0, 0, 1052, + 1976, 1052, 1052, 1052, 1052, 1052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1949, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, + 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 1052, 0, 0, 0, 0, 1695, 1696, 0, 0, 0, + 0, 0, 0, 0, 1032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, - 0, 0, 1499, 0, 0, 719, 719, 1499, 664, 0, - 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 664, 664, 0, 0, 664, 0, - 2548, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 664, 0, 0, 0, 0, 0, 0, 664, 0, 0, - 0, 3954, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3222, 0, - 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 664, 0, 0, 0, 0, 0, 0, 1976, 664, + 0, 664, 0, 664, 2383, 1744, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 1762, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 0, 0, 1499, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1264, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2027, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2873, 0, 0, 0, 0, 0, + 0, 0, 0, 1872, 1872, 0, 1872, 0, 1872, 1872, + 0, 1881, 1872, 1872, 1872, 1872, 1872, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3304, 1501, 0, 1975, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1949, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 1974, + 719, 0, 0, 0, 1864, 1864, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2084, 0, + 0, 0, 0, 0, 0, 1499, 2946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 664, 1264, 0, 0, 0, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, + 664, 0, 0, 664, 0, 2551, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, + 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 957, 0, 0, 0, 945, 958, + 959, 960, 961, 946, 0, 0, 947, 948, 0, 949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 0, 954, 962, 963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1501, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1264, 1264, 3276, 3277, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2028, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, + 0, 2085, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 719, 0, 0, 0, 1499, 0, 0, 719, 719, + 1499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3279, 3280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 0, 1923, 0, + 0, 3225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1264, + 0, 0, 1264, 719, 0, 0, 1499, 0, 0, 0, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 910, + 0, 664, 0, 0, 0, 914, 0, 0, 0, 911, + 912, 0, 0, 0, 913, 915, 0, 0, 0, 0, + 0, 2332, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3307, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, - 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2331, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 719, 0, + 0, 0, 0, 0, 0, 0, 0, 1744, 0, 0, + 1264, 0, 0, 0, 0, 664, 0, 0, 0, 0, + 0, 0, 2915, 0, 0, 0, 0, 0, 0, 0, + 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2343, 0, 0, 0, - 0, 664, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 1744, 0, 0, 1264, 0, 0, - 0, 0, 0, 0, 0, 0, 719, 719, 719, 719, - 0, 0, 0, 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1501, 0, + 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, + 0, 664, 664, 664, 664, 664, 664, 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 664, 664, + 0, 0, 0, 0, 1076, 0, 0, 0, 0, 0, + 1083, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 664, 0, 0, 0, 0, 0, 0, 2912, 0, 0, - 0, 0, 0, 0, 1083, 0, 0, 0, 0, 0, + 1052, 0, 0, 0, 0, 0, 0, 1076, 0, 0, + 0, 0, 2085, 0, 0, 0, 2085, 2085, 0, 0, + 0, 0, 0, 0, 0, 0, 3504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1076, 0, 0, 0, 0, 0, 1083, 0, 0, - 0, 0, 0, 1501, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 664, 664, 664, - 664, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 664, 664, 0, 1076, 0, 0, 0, 0, 2084, - 0, 0, 0, 2084, 2084, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1499, 0, - 0, 0, 0, 719, 0, 719, 0, 0, 0, 0, - 0, 0, 0, 1052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, - 0, 0, 0, 0, 0, 2560, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, + 719, 719, 719, 0, 0, 0, 0, 0, 0, 2563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1264, 0, 0, 0, - 0, 0, 0, 0, 0, 719, 0, 0, 0, 719, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1052, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 1052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, + 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1501, 0, + 0, 0, 0, 1501, 664, 664, 664, 664, 664, 0, + 0, 0, 0, 0, 0, 0, 3175, 0, 0, 0, + 0, 0, 1923, 0, 664, 0, 0, 664, 3183, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1501, 0, 0, 0, 0, 1501, 664, 664, 664, - 664, 664, 0, 0, 0, 0, 0, 0, 0, 3172, - 0, 0, 0, 0, 0, 1923, 0, 664, 0, 0, - 664, 3180, 1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1499, 0, 0, 0, 0, 719, 0, 719, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1501, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, + 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, 0, - 0, 0, 1501, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, - 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 664, 0, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 2805, 0, 0, + 0, 0, 0, 664, 0, 0, 664, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1499, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2808, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2823, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 719, 0, + 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 719, 0, 0, 0, 0, 2902, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 719, 0, 0, + 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2343, 0, 0, 0, 664, 0, - 0, 2927, 0, 0, 0, 0, 0, 0, 0, 0, - 2932, 0, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, - 719, 0, 719, 0, 0, 0, 0, 0, 0, 0, + 0, 2905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2344, 0, + 0, 664, 0, 0, 0, 2930, 0, 0, 0, 0, + 0, 0, 0, 0, 2935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 664, 0, 0, 664, 664, 664, 0, - 0, 0, 2084, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 0, 0, 664, 664, 664, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3696, - 3698, 3697, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3699, 3701, + 3700, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2085, 719, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1499, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3086, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1264, 0, 0, + 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, + 0, 3089, 719, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1264, 1501, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 719, 1872, 719, 0, 0, 0, 0, 0, 0, 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, 1923, 0, - 0, 0, 0, 0, 0, 0, 3129, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1501, 0, 0, - 1264, 0, 0, 0, 0, 0, 0, 3156, 1872, 0, + 0, 0, 3132, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1264, 0, 0, 0, + 0, 0, 0, 3159, 1872, 0, 0, 0, 0, 0, + 0, 0, 1923, 0, 0, 3705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3702, 0, 0, 0, 0, + 3713, 3714, 0, 0, 3789, 3788, 3787, 0, 0, 3785, + 3786, 3784, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3710, 3711, 0, 0, 3786, 3785, 3784, 0, 0, 3782, - 3783, 3781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1076, 0, 0, 0, 0, 0, 0, 0, - 2343, 0, 0, 0, 3787, 910, 0, 765, 766, 3788, - 3789, 914, 3790, 768, 769, 911, 912, 0, 763, 767, + 0, 0, 0, 0, 0, 0, 0, 0, 1076, 0, + 0, 0, 0, 0, 3790, 910, 2344, 765, 766, 3791, + 3792, 914, 3793, 768, 769, 911, 912, 0, 763, 767, 913, 915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3693, 3694, 3695, 3699, - 3700, 3701, 3712, 3759, 3760, 3768, 3770, 866, 3769, 3771, - 3772, 3773, 3776, 3777, 3778, 3779, 3774, 3775, 3780, 3676, - 3680, 3677, 3678, 3679, 3691, 3681, 3682, 3683, 3684, 3685, - 3686, 3687, 3688, 3689, 3690, 3692, 3791, 3792, 3793, 3794, - 3795, 3796, 3705, 3709, 3708, 3706, 3707, 3703, 3704, 3731, - 3730, 3732, 3733, 3734, 3735, 3736, 3737, 3739, 3738, 3740, - 3741, 3742, 3743, 3744, 3745, 3713, 3714, 3717, 3718, 3716, - 3715, 3719, 3728, 3729, 3720, 3721, 3722, 3723, 3724, 3725, - 3727, 3726, 3746, 3747, 3748, 3749, 3750, 3752, 3751, 3755, - 3756, 3754, 3753, 3758, 3757, 0, 3417, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 916, 0, 917, + 0, 0, 0, 0, 0, 0, 3696, 3697, 3698, 3702, + 3703, 3704, 3715, 3762, 3763, 3771, 3773, 866, 3772, 3774, + 3775, 3776, 3779, 3780, 3781, 3782, 3777, 3778, 3783, 3679, + 3683, 3680, 3681, 3682, 3694, 3684, 3685, 3686, 3687, 3688, + 3689, 3690, 3691, 3692, 3693, 3695, 3794, 3795, 3796, 3797, + 3798, 3799, 3708, 3712, 3711, 3709, 3710, 3706, 3707, 3734, + 3733, 3735, 3736, 3737, 3738, 3739, 3740, 3742, 3741, 3743, + 3744, 3745, 3746, 3747, 3748, 3716, 3717, 3720, 3721, 3719, + 3718, 3722, 3731, 3732, 3723, 3724, 3725, 3726, 3727, 3728, + 3730, 3729, 3749, 3750, 3751, 3752, 3753, 3755, 3754, 3758, + 3759, 3757, 3756, 3761, 3760, 0, 0, 0, 0, 0, + 0, 0, 3420, 0, 0, 0, 0, 916, 0, 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1923, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1501, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2344, 2344, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2343, - 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1923, 0, 3568, 3569, 3570, 3571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1501, 0, 0, 0, 0, 3565, 3566, - 3567, 3568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4007, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3664, 0, 3666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3667, 0, 3669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3831, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3904, 0, 0, - 0, 3904, 3904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3907, 0, 0, 0, 3907, 3907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2785,197 +2846,54 @@ 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, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3981, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1264, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4027, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4035, + 0, 0, 3984, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1264, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4030, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 392, 3417, 0, 4035, 1399, 1385, 520, 0, 1327, - 1402, 1296, 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, - 1312, 1267, 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, - 1387, 1346, 1401, 362, 266, 1276, 1301, 425, 1317, 203, - 1366, 481, 251, 373, 370, 575, 281, 272, 268, 249, - 315, 381, 423, 510, 417, 1408, 366, 1352, 0, 491, - 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, - 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 4009, 941, 0, - 0, 0, 0, 4010, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, - 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, - 264, 319, 271, 263, 572, 1409, 1390, 1273, 1339, 1397, - 1334, 0, 0, 228, 1400, 1333, 0, 1363, 0, 1415, - 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, 0, - 0, 0, 0, 0, 0, 0, 1330, 1341, 1375, 1379, - 1324, 0, 0, 0, 0, 0, 0, 0, 0, 1302, - 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3984, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1328, - 0, 0, 0, 0, 1283, 0, 1303, 1376, 0, 1266, - 296, 1277, 397, 256, 0, 448, 1383, 1394, 1325, 616, - 1396, 1323, 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, - 197, 224, 0, 1314, 407, 456, 468, 1388, 1299, 1308, - 252, 1306, 466, 421, 594, 232, 283, 453, 427, 464, - 435, 286, 1349, 1368, 465, 368, 577, 445, 591, 617, - 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, - 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, - 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, - 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, - 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, - 639, 227, 610, 219, 1278, 609, 403, 576, 587, 390, - 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, - 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, - 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, - 236, 1294, 278, 282, 290, 293, 301, 302, 311, 363, - 414, 441, 437, 446, 1384, 571, 592, 604, 615, 621, - 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, - 489, 331, 369, 1373, 1414, 420, 467, 239, 596, 490, - 199, 1288, 1293, 1286, 0, 253, 254, 1355, 567, 1289, - 1287, 1344, 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, - 502, 503, 504, 505, 0, 507, 1377, 1282, 0, 1291, - 1292, 1386, 583, 584, 659, 380, 480, 593, 333, 345, - 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, - 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, - 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, - 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, - 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, - 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, - 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, - 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, - 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, - 531, 1348, 196, 220, 364, 1410, 449, 287, 637, 606, - 601, 205, 222, 1285, 261, 1297, 1305, 0, 1311, 1319, - 1320, 1332, 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, - 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, - 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, - 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, - 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, - 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, - 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, - 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, - 632, 614, 433, 374, 1347, 1353, 377, 280, 303, 318, - 1362, 605, 496, 226, 461, 289, 250, 1380, 1382, 210, - 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, - 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, - 391, 265, 428, 1343, 1371, 372, 568, 569, 314, 392, - 0, 0, 0, 1399, 1385, 520, 0, 1327, 1402, 1296, - 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, - 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, - 1401, 362, 266, 1276, 1301, 425, 1317, 203, 1366, 481, - 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 1408, 366, 1352, 0, 491, 396, 0, - 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, - 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, 319, - 271, 263, 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, - 0, 228, 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, - 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, 0, - 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, 0, - 0, 0, 0, 0, 0, 3181, 0, 1302, 0, 1350, - 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1328, 0, 0, - 0, 0, 1283, 0, 1303, 1376, 0, 1266, 296, 1277, - 397, 256, 0, 448, 1383, 1394, 1325, 616, 1396, 1323, - 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, 197, 224, - 0, 1314, 407, 456, 468, 1388, 1299, 1308, 252, 1306, - 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, - 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, - 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 1278, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 1294, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 1384, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 1373, 1414, 420, 467, 239, 596, 490, 199, 1288, - 1293, 1286, 0, 253, 254, 1355, 567, 1289, 1287, 1344, - 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 1377, 1282, 0, 1291, 1292, 1386, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 1348, - 196, 220, 364, 1410, 449, 287, 637, 606, 601, 205, - 222, 1285, 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, - 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, - 1374, 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 1347, 1353, 377, 280, 303, 318, 1362, 605, - 496, 226, 461, 289, 250, 1380, 1382, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 1343, 1371, 372, 568, 569, 314, 392, 0, 0, - 0, 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, - 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, - 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, - 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, - 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, - 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, - 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, - 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, - 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, - 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, - 0, 0, 0, 3142, 0, 1302, 0, 1350, 0, 0, - 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 392, 3420, 0, + 4038, 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, + 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, + 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, + 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, + 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, + 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 4012, 941, 0, 0, 0, 0, 4013, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, + 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, + 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, + 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, + 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, + 0, 0, 0, 0, 0, 1302, 0, 1350, 0, 0, + 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2988,7 +2906,80 @@ var yyAct = [...]int{ 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, + 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, + 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, + 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, + 219, 1278, 609, 403, 576, 587, 390, 379, 218, 585, + 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, + 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, + 493, 599, 640, 447, 211, 233, 234, 236, 1294, 278, + 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, + 446, 1384, 571, 592, 604, 615, 621, 622, 624, 625, + 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, + 1373, 1414, 420, 467, 239, 596, 490, 199, 1288, 1293, + 1286, 0, 253, 254, 1355, 567, 1289, 1287, 1344, 1345, + 1290, 1405, 1406, 1407, 1392, 641, 642, 643, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, + 505, 0, 507, 1377, 1282, 0, 1291, 1292, 1386, 583, + 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, + 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, + 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, + 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, + 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, + 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, + 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, + 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, + 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, + 555, 536, 547, 558, 542, 530, 523, 531, 1348, 196, + 220, 364, 1410, 449, 287, 637, 606, 601, 205, 222, + 1285, 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, 1335, + 1336, 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, 1374, + 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, 242, + 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, + 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, + 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, + 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, + 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, + 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, + 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, + 374, 1347, 1353, 377, 280, 303, 318, 1362, 605, 496, + 226, 461, 289, 250, 1380, 1382, 210, 245, 229, 258, + 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, + 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, + 1343, 1371, 372, 568, 569, 314, 392, 0, 0, 0, + 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, 1318, + 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, 1307, + 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, 266, + 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 1408, 366, 1352, 0, 491, 396, 0, 0, 0, 1331, + 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, 1361, + 1404, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, 572, + 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, 1400, + 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, 1275, + 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, 0, + 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, 0, + 0, 0, 3184, 0, 1302, 0, 1350, 0, 0, 0, + 1280, 1272, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1328, 0, 0, 0, 0, 1283, + 0, 1303, 1376, 0, 1266, 296, 1277, 397, 256, 0, + 448, 1383, 1394, 1325, 616, 1396, 1323, 1322, 1370, 1281, + 1389, 1316, 361, 1279, 328, 197, 224, 0, 1314, 407, + 456, 468, 1388, 1299, 1308, 252, 1306, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 1349, 1368, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, @@ -3039,7 +3030,7 @@ var yyAct = [...]int{ 366, 1352, 0, 491, 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, - 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, 572, 1409, @@ -3047,7 +3038,7 @@ var yyAct = [...]int{ 0, 1363, 0, 1415, 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, 0, 0, - 0, 2361, 0, 1302, 0, 1350, 0, 0, 0, 1280, + 0, 3145, 0, 1302, 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3061,7 +3052,80 @@ var yyAct = [...]int{ 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 1278, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 1294, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 1384, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 1373, 1414, + 420, 467, 239, 596, 490, 199, 1288, 1293, 1286, 0, + 253, 254, 1355, 567, 1289, 1287, 1344, 1345, 1290, 1405, + 1406, 1407, 1392, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 1377, 1282, 0, 1291, 1292, 1386, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 1348, 196, 220, 364, + 1410, 449, 287, 637, 606, 601, 205, 222, 1285, 261, + 1297, 1305, 0, 1311, 1319, 1320, 1332, 1335, 1336, 1337, + 1338, 1356, 1357, 1359, 1367, 1369, 1372, 1374, 1381, 1393, + 1413, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 1347, + 1353, 377, 280, 303, 318, 1362, 605, 496, 226, 461, + 289, 250, 1380, 1382, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 1343, 1371, + 372, 568, 569, 314, 392, 0, 0, 0, 1399, 1385, + 520, 0, 1327, 1402, 1296, 1315, 1412, 1318, 1321, 1364, + 1274, 1342, 411, 1312, 1267, 1300, 1269, 1307, 1270, 1298, + 1329, 269, 1295, 1387, 1346, 1401, 362, 266, 1276, 1301, + 425, 1317, 203, 1366, 481, 251, 373, 370, 575, 281, + 272, 268, 249, 315, 381, 423, 510, 417, 1408, 366, + 1352, 0, 491, 396, 0, 0, 0, 1331, 1391, 1340, + 1378, 1326, 1365, 1284, 1351, 1403, 1313, 1361, 1404, 321, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 941, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 355, 336, 337, 339, 341, 346, 353, 359, 1309, 1358, + 1398, 1310, 1360, 264, 319, 271, 263, 572, 1409, 1390, + 1273, 1339, 1397, 1334, 0, 0, 228, 1400, 1333, 0, + 1363, 0, 1415, 1268, 1354, 0, 1271, 1275, 1411, 1395, + 1304, 274, 0, 0, 0, 0, 0, 0, 0, 1330, + 1341, 1375, 1379, 1324, 0, 0, 0, 0, 0, 0, + 2362, 0, 1302, 0, 1350, 0, 0, 0, 1280, 1272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1328, 0, 0, 0, 0, 1283, 0, 1303, + 1376, 0, 1266, 296, 1277, 397, 256, 0, 448, 1383, + 1394, 1325, 616, 1396, 1323, 1322, 1370, 1281, 1389, 1316, + 361, 1279, 328, 197, 224, 0, 1314, 407, 456, 468, + 1388, 1299, 1308, 252, 1306, 466, 421, 594, 232, 283, + 453, 427, 464, 435, 286, 1349, 1368, 465, 368, 577, + 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, + 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, + 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, + 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 1278, 609, @@ -3134,7 +3198,80 @@ var yyAct = [...]int{ 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, - 600, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 1278, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 1294, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 1384, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 1373, 1414, 420, 467, + 239, 596, 490, 199, 1288, 1293, 1286, 0, 253, 254, + 1355, 567, 1289, 1287, 1344, 1345, 1290, 1405, 1406, 1407, + 1392, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 1377, + 1282, 0, 1291, 1292, 1386, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 1348, 196, 220, 364, 1410, 449, + 287, 637, 606, 601, 205, 222, 1285, 261, 1297, 1305, + 0, 1311, 1319, 1320, 1332, 1335, 1336, 1337, 1338, 1356, + 1357, 1359, 1367, 1369, 1372, 1374, 1381, 1393, 1413, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 1347, 1353, 377, + 280, 303, 318, 1362, 605, 496, 226, 461, 289, 250, + 1380, 1382, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 1343, 1371, 372, 568, + 569, 314, 392, 0, 0, 0, 1399, 1385, 520, 0, + 1327, 1402, 1296, 1315, 1412, 1318, 1321, 1364, 1274, 1342, + 411, 1312, 1267, 1300, 1269, 1307, 1270, 1298, 1329, 269, + 1295, 1387, 1346, 1401, 362, 266, 1276, 1301, 425, 1317, + 203, 1366, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 1408, 366, 1352, 0, + 491, 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, + 1365, 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, + 1360, 264, 319, 271, 263, 572, 1409, 1390, 1273, 1339, + 1397, 1334, 0, 0, 228, 1400, 1333, 0, 1363, 0, + 1415, 1268, 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, + 0, 0, 0, 0, 0, 0, 0, 1330, 1341, 1375, + 1379, 1324, 0, 0, 0, 0, 0, 0, 0, 0, + 1302, 0, 1350, 0, 0, 0, 1280, 1272, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1328, 0, 0, 0, 0, 1283, 0, 1303, 1376, 0, + 1266, 296, 1277, 397, 256, 0, 448, 1383, 1394, 1325, + 616, 1396, 1323, 1322, 1370, 1281, 1389, 1316, 361, 1279, + 328, 197, 224, 0, 1314, 407, 456, 468, 1388, 1299, + 1308, 252, 1306, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 1349, 1368, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 1278, 609, 403, 576, @@ -3184,7 +3321,7 @@ var yyAct = [...]int{ 315, 381, 423, 510, 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, - 408, 492, 285, 0, 0, 0, 0, 0, 194, 0, + 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, @@ -3206,7 +3343,80 @@ var yyAct = [...]int{ 435, 286, 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, - 365, 623, 223, 474, 367, 241, 230, 579, 600, 288, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 0, + 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, + 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, + 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, + 255, 639, 227, 610, 219, 1278, 609, 403, 576, 587, + 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, + 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, + 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, + 234, 236, 1294, 278, 282, 290, 293, 301, 302, 311, + 363, 414, 441, 437, 446, 1384, 571, 592, 604, 615, + 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, + 309, 489, 331, 369, 1373, 1414, 420, 467, 239, 596, + 490, 199, 1288, 1293, 1286, 0, 253, 254, 1355, 567, + 1289, 1287, 1344, 1345, 1290, 1405, 1406, 1407, 1392, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, + 501, 502, 503, 504, 505, 0, 507, 1377, 1282, 0, + 1291, 1292, 1386, 583, 584, 659, 380, 480, 593, 333, + 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, + 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, + 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, + 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, + 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, + 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, + 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, + 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, + 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, + 523, 531, 1348, 196, 220, 364, 1410, 449, 287, 637, + 606, 601, 205, 222, 1285, 261, 1297, 1305, 0, 1311, + 1319, 1320, 1332, 1335, 1336, 1337, 1338, 1356, 1357, 1359, + 1367, 1369, 1372, 1374, 1381, 1393, 1413, 198, 200, 208, + 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, + 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, + 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, + 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, + 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, + 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, + 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, + 588, 632, 614, 433, 374, 1347, 1353, 377, 280, 303, + 318, 1362, 605, 496, 226, 461, 289, 250, 1380, 1382, + 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, + 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, + 515, 391, 265, 428, 1343, 1371, 372, 568, 569, 314, + 392, 0, 0, 0, 1399, 1385, 520, 0, 1327, 1402, + 1296, 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, 1312, + 1267, 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, 1387, + 1346, 1401, 362, 266, 1276, 1301, 425, 1317, 203, 1366, + 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, + 381, 423, 510, 417, 1408, 366, 1352, 0, 491, 396, + 0, 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, + 1351, 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, + 492, 285, 0, 0, 0, 0, 0, 941, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, + 341, 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, + 319, 271, 263, 572, 1409, 1390, 1273, 1339, 1397, 1334, + 0, 0, 228, 1400, 1333, 0, 1363, 0, 1415, 1268, + 1354, 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, + 0, 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, + 0, 0, 0, 0, 0, 0, 0, 0, 1302, 0, + 1350, 0, 0, 0, 1280, 1272, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1328, 0, + 0, 0, 0, 1283, 0, 1303, 1376, 0, 1266, 296, + 1277, 397, 256, 0, 448, 1383, 1394, 1325, 616, 1396, + 1323, 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, 197, + 224, 0, 1314, 407, 456, 468, 1388, 1299, 1308, 252, + 1306, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 1349, 1368, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, @@ -3249,327 +3459,37 @@ var yyAct = [...]int{ 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, 1343, 1371, 372, 568, 569, 314, 392, - 0, 0, 0, 1399, 1385, 520, 0, 1327, 1402, 1296, - 1315, 1412, 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, - 1300, 1269, 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, - 1401, 362, 266, 1276, 1301, 425, 1317, 203, 1366, 481, + 0, 0, 0, 0, 0, 520, 0, 761, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, - 423, 510, 417, 1408, 366, 1352, 0, 491, 396, 0, - 0, 0, 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, - 1403, 1313, 1361, 1404, 321, 247, 323, 202, 408, 492, - 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, - 346, 353, 359, 1309, 1358, 1398, 1310, 1360, 264, 319, - 271, 263, 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, - 0, 228, 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, - 0, 1271, 1275, 1411, 1395, 1304, 274, 0, 0, 0, - 0, 0, 0, 0, 1330, 1341, 1375, 1379, 1324, 0, - 0, 0, 0, 0, 0, 0, 0, 1302, 0, 1350, - 0, 0, 0, 1280, 1272, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1328, 0, 0, - 0, 0, 1283, 0, 1303, 1376, 0, 1266, 296, 1277, - 397, 256, 0, 448, 1383, 1394, 1325, 616, 1396, 1323, - 1322, 1370, 1281, 1389, 1316, 361, 1279, 328, 197, 224, - 0, 1314, 407, 456, 468, 1388, 1299, 1308, 252, 1306, + 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 95, 0, 0, 957, 941, 733, 907, 945, + 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, + 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, + 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, + 271, 263, 572, 0, 0, 2183, 2184, 2185, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, + 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, + 0, 745, 0, 0, 753, 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, 755, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, + 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, - 1349, 1368, 465, 368, 577, 445, 591, 617, 618, 262, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, - 223, 474, 367, 241, 230, 579, 600, 288, 451, 630, - 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, - 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, - 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, - 610, 219, 1278, 609, 403, 576, 587, 390, 379, 218, - 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, - 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, - 0, 493, 599, 640, 447, 211, 233, 234, 236, 1294, - 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, - 437, 446, 1384, 571, 592, 604, 615, 621, 622, 624, - 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, - 369, 1373, 1414, 420, 467, 239, 596, 490, 199, 1288, - 1293, 1286, 0, 253, 254, 1355, 567, 1289, 1287, 1344, - 1345, 1290, 1405, 1406, 1407, 1392, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, - 504, 505, 0, 507, 1377, 1282, 0, 1291, 1292, 1386, - 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, - 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, - 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, - 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, - 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, - 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, - 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, - 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, - 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, - 556, 555, 536, 547, 558, 542, 530, 523, 531, 1348, - 196, 220, 364, 1410, 449, 287, 637, 606, 601, 205, - 222, 1285, 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, - 1335, 1336, 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, - 1374, 1381, 1393, 1413, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, - 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, - 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, - 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, - 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, - 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, - 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, - 433, 374, 1347, 1353, 377, 280, 303, 318, 1362, 605, - 496, 226, 461, 289, 250, 1380, 1382, 210, 245, 229, - 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, - 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, - 428, 1343, 1371, 372, 568, 569, 314, 392, 0, 0, - 0, 1399, 1385, 520, 0, 1327, 1402, 1296, 1315, 1412, - 1318, 1321, 1364, 1274, 1342, 411, 1312, 1267, 1300, 1269, - 1307, 1270, 1298, 1329, 269, 1295, 1387, 1346, 1401, 362, - 266, 1276, 1301, 425, 1317, 203, 1366, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 1408, 366, 1352, 0, 491, 396, 0, 0, 0, - 1331, 1391, 1340, 1378, 1326, 1365, 1284, 1351, 1403, 1313, - 1361, 1404, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 0, 941, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 1309, 1358, 1398, 1310, 1360, 264, 319, 271, 263, - 572, 1409, 1390, 1273, 1339, 1397, 1334, 0, 0, 228, - 1400, 1333, 0, 1363, 0, 1415, 1268, 1354, 0, 1271, - 1275, 1411, 1395, 1304, 274, 0, 0, 0, 0, 0, - 0, 0, 1330, 1341, 1375, 1379, 1324, 0, 0, 0, - 0, 0, 0, 0, 0, 1302, 0, 1350, 0, 0, - 0, 1280, 1272, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1328, 0, 0, 0, 0, - 1283, 0, 1303, 1376, 0, 1266, 296, 1277, 397, 256, - 0, 448, 1383, 1394, 1325, 616, 1396, 1323, 1322, 1370, - 1281, 1389, 1316, 361, 1279, 328, 197, 224, 0, 1314, - 407, 456, 468, 1388, 1299, 1308, 252, 1306, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 1349, 1368, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, - 1278, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, - 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 1294, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 1384, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 1373, - 1414, 420, 467, 239, 596, 490, 199, 1288, 1293, 1286, - 0, 253, 254, 1355, 567, 1289, 1287, 1344, 1345, 1290, - 1405, 1406, 1407, 1392, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 1377, 1282, 0, 1291, 1292, 1386, 583, 584, - 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, - 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, - 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, - 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, - 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, - 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, - 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, - 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, - 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, - 536, 547, 558, 542, 530, 523, 531, 1348, 196, 220, - 364, 1410, 449, 287, 637, 606, 601, 205, 222, 1285, - 261, 1297, 1305, 0, 1311, 1319, 1320, 1332, 1335, 1336, - 1337, 1338, 1356, 1357, 1359, 1367, 1369, 1372, 1374, 1381, - 1393, 1413, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, - 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, - 1347, 1353, 377, 280, 303, 318, 1362, 605, 496, 226, - 461, 289, 250, 1380, 1382, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 1343, - 1371, 372, 568, 569, 314, 392, 0, 0, 0, 0, - 0, 520, 0, 761, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, - 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, - 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, - 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, - 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, - 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, - 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, - 0, 2182, 2183, 2184, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, - 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, - 753, 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, 755, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 805, 806, 279, 305, 882, 881, 880, 304, 306, 878, - 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 888, 910, 899, 765, 766, 889, - 890, 914, 891, 768, 769, 911, 912, 762, 763, 767, - 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 902, 752, 751, 0, 758, 0, 787, 788, 790, 794, - 795, 796, 807, 854, 855, 863, 865, 866, 864, 867, - 868, 869, 872, 873, 874, 875, 870, 871, 876, 770, - 774, 771, 772, 773, 785, 775, 776, 777, 778, 779, - 780, 781, 782, 783, 784, 786, 925, 926, 927, 928, - 929, 930, 800, 804, 803, 801, 802, 798, 799, 826, - 825, 827, 828, 829, 830, 831, 832, 834, 833, 835, - 836, 837, 838, 839, 840, 808, 809, 812, 813, 811, - 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, - 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, - 851, 849, 848, 853, 852, 750, 196, 220, 364, 0, - 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, - 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, - 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 931, 932, 933, 934, 935, 936, 937, 938, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, - 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, - 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, - 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, - 2390, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, - 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, - 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, - 862, 789, 954, 962, 963, 2391, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, - 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, - 0, 0, 753, 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, 755, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, - 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, - 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, - 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, - 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, - 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, - 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, - 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, - 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, - 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, - 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, - 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, - 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, - 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, - 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, - 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, - 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, - 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, - 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, - 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, - 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, - 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, - 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, - 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, - 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, - 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, - 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, - 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, - 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, - 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, - 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, - 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, - 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, - 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, - 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, - 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, - 240, 479, 511, 512, 513, 515, 391, 265, 428, 0, - 392, 372, 568, 569, 314, 86, 520, 0, 761, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, - 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, - 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, - 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, - 901, 0, 745, 0, 0, 753, 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, 755, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, - 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, @@ -3596,7 +3516,7 @@ var yyAct = [...]int{ 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, - 750, 196, 220, 364, 94, 449, 287, 637, 606, 601, + 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, @@ -3618,12 +3538,12 @@ var yyAct = [...]int{ 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 0, 0, 0, 0, 0, 2391, 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 2392, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3638,125 +3558,53 @@ var yyAct = [...]int{ 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 3995, 0, 465, 368, 577, 445, 591, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, - 255, 639, 797, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 805, 806, 279, - 305, 882, 881, 880, 304, 306, 878, 879, 877, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 888, 910, 899, 765, 766, 889, 890, 914, 891, - 768, 769, 911, 912, 762, 763, 767, 913, 915, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 902, 752, 751, - 0, 758, 0, 787, 788, 790, 794, 795, 796, 807, - 854, 855, 863, 865, 866, 864, 867, 868, 869, 872, - 873, 874, 875, 870, 871, 876, 770, 774, 771, 772, - 773, 785, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 786, 925, 926, 927, 928, 929, 930, 800, - 804, 803, 801, 802, 798, 799, 826, 825, 827, 828, - 829, 830, 831, 832, 834, 833, 835, 836, 837, 838, - 839, 840, 808, 809, 812, 813, 811, 810, 814, 823, - 824, 815, 816, 817, 818, 819, 820, 822, 821, 841, - 842, 843, 844, 845, 847, 846, 850, 851, 849, 848, - 853, 852, 750, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 916, 261, 917, 0, 0, 921, - 0, 0, 0, 923, 922, 0, 924, 886, 885, 0, - 0, 918, 919, 0, 920, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 931, - 932, 933, 934, 935, 936, 937, 938, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 956, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, - 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 760, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, - 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 95, 0, 1718, - 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, - 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, - 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, - 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, - 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, - 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, 755, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, - 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 951, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, - 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, - 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, - 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, - 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, - 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, - 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, - 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, - 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, - 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, - 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, - 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, - 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, - 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, - 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, - 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, - 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, + 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, + 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, + 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, + 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, + 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, + 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, + 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, + 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, + 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, + 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, + 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, + 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, + 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, + 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, + 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 0, 392, 372, 568, 569, + 314, 86, 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, @@ -3772,7 +3620,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 743, 744, 1050, 0, 0, 0, 901, 0, 745, 0, + 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, @@ -3786,7 +3634,224 @@ var yyAct = [...]int{ 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 805, 806, 279, 305, 882, 881, 880, 304, + 306, 878, 879, 877, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 888, 910, 899, 765, + 766, 889, 890, 914, 891, 768, 769, 911, 912, 762, + 763, 767, 913, 915, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 902, 752, 751, 0, 758, 0, 787, 788, + 790, 794, 795, 796, 807, 854, 855, 863, 865, 866, + 864, 867, 868, 869, 872, 873, 874, 875, 870, 871, + 876, 770, 774, 771, 772, 773, 785, 775, 776, 777, + 778, 779, 780, 781, 782, 783, 784, 786, 925, 926, + 927, 928, 929, 930, 800, 804, 803, 801, 802, 798, + 799, 826, 825, 827, 828, 829, 830, 831, 832, 834, + 833, 835, 836, 837, 838, 839, 840, 808, 809, 812, + 813, 811, 810, 814, 823, 824, 815, 816, 817, 818, + 819, 820, 822, 821, 841, 842, 843, 844, 845, 847, + 846, 850, 851, 849, 848, 853, 852, 750, 196, 220, + 364, 94, 449, 287, 637, 606, 601, 205, 222, 916, + 261, 917, 0, 0, 921, 0, 0, 0, 923, 922, + 0, 924, 886, 885, 0, 0, 918, 919, 0, 920, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 931, 932, 933, 934, 935, 936, + 937, 938, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 760, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 95, 0, 0, 957, 941, 733, 907, 945, + 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, + 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, + 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 729, + 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, + 0, 745, 0, 0, 753, 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, 755, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, + 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 951, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 3998, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, + 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, + 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, + 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, + 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, + 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, + 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, + 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, + 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, + 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, + 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, + 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, + 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, + 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, + 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, + 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, + 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, + 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, + 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, + 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, + 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, + 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, + 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, + 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, + 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, + 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, + 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, + 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, + 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, + 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, + 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, + 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, + 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, + 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, + 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, + 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, + 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 95, 0, 1718, 957, 941, + 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, + 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, + 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, + 0, 0, 901, 0, 745, 0, 0, 753, 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, + 755, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, + 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, + 953, 255, 639, 797, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 805, 806, + 279, 305, 882, 881, 880, 304, 306, 878, 879, 877, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 888, 910, 899, 765, 766, 889, 890, 914, + 891, 768, 769, 911, 912, 762, 763, 767, 913, 915, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 902, 752, + 751, 0, 758, 0, 787, 788, 790, 794, 795, 796, + 807, 854, 855, 863, 865, 866, 864, 867, 868, 869, + 872, 873, 874, 875, 870, 871, 876, 770, 774, 771, + 772, 773, 785, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 786, 925, 926, 927, 928, 929, 930, + 800, 804, 803, 801, 802, 798, 799, 826, 825, 827, + 828, 829, 830, 831, 832, 834, 833, 835, 836, 837, + 838, 839, 840, 808, 809, 812, 813, 811, 810, 814, + 823, 824, 815, 816, 817, 818, 819, 820, 822, 821, + 841, 842, 843, 844, 845, 847, 846, 850, 851, 849, + 848, 853, 852, 750, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 916, 261, 917, 0, 0, + 921, 0, 0, 0, 923, 922, 0, 924, 886, 885, + 0, 0, 918, 919, 0, 920, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 931, 932, 933, 934, 935, 936, 937, 938, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 956, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 761, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 749, 0, + 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 760, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, + 0, 957, 941, 733, 907, 945, 958, 959, 960, 961, + 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, + 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, + 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 729, 746, 0, 759, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, + 744, 1050, 0, 0, 0, 901, 0, 745, 0, 0, + 753, 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, 755, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 951, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, @@ -3858,151 +3923,79 @@ var yyAct = [...]int{ 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 805, 806, 279, 305, 882, 881, 880, - 304, 306, 878, 879, 877, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 888, 910, 899, - 765, 766, 889, 890, 914, 891, 768, 769, 911, 912, - 762, 763, 767, 913, 915, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 902, 752, 751, 0, 758, 0, 787, - 788, 790, 794, 795, 796, 807, 854, 855, 863, 865, - 866, 864, 867, 868, 869, 872, 873, 874, 875, 870, - 871, 876, 770, 774, 771, 772, 773, 785, 775, 776, - 777, 778, 779, 780, 781, 782, 783, 784, 786, 925, - 926, 927, 928, 929, 930, 800, 804, 803, 801, 802, - 798, 799, 826, 825, 827, 828, 829, 830, 831, 832, - 834, 833, 835, 836, 837, 838, 839, 840, 808, 809, - 812, 813, 811, 810, 814, 823, 824, 815, 816, 817, - 818, 819, 820, 822, 821, 841, 842, 843, 844, 845, - 847, 846, 850, 851, 849, 848, 853, 852, 750, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 916, 261, 917, 0, 0, 921, 0, 0, 0, 923, - 922, 0, 924, 886, 885, 0, 0, 918, 919, 0, - 920, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 931, 932, 933, 934, 935, - 936, 937, 938, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 95, 0, 0, 957, 941, 733, 907, - 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, - 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, - 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, - 901, 0, 745, 0, 0, 753, 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, 3100, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, - 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, - 797, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 805, 806, 279, 305, 882, - 881, 880, 304, 306, 878, 879, 877, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 888, - 910, 899, 765, 766, 889, 890, 914, 891, 768, 769, - 911, 912, 762, 763, 767, 913, 915, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 902, 752, 751, 0, 758, - 0, 787, 788, 790, 794, 795, 796, 807, 854, 855, - 863, 865, 866, 864, 867, 868, 869, 872, 873, 874, - 875, 870, 871, 876, 770, 774, 771, 772, 773, 785, - 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - 786, 925, 926, 927, 928, 929, 930, 800, 804, 803, - 801, 802, 798, 799, 826, 825, 827, 828, 829, 830, - 831, 832, 834, 833, 835, 836, 837, 838, 839, 840, - 808, 809, 812, 813, 811, 810, 814, 823, 824, 815, - 816, 817, 818, 819, 820, 822, 821, 841, 842, 843, - 844, 845, 847, 846, 850, 851, 849, 848, 853, 852, - 750, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 916, 261, 917, 0, 0, 921, 0, 0, - 0, 923, 922, 0, 924, 886, 885, 0, 0, 918, - 919, 0, 920, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 931, 932, 933, - 934, 935, 936, 937, 938, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 956, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 749, 0, 0, 0, 269, - 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 760, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 95, 0, 0, 957, 941, - 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, - 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, - 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, - 0, 0, 901, 0, 745, 0, 0, 753, 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, - 3096, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, - 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 951, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 805, 806, 279, 305, 882, 881, + 880, 304, 306, 878, 879, 877, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 888, 910, + 899, 765, 766, 889, 890, 914, 891, 768, 769, 911, + 912, 762, 763, 767, 913, 915, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 902, 752, 751, 0, 758, 0, + 787, 788, 790, 794, 795, 796, 807, 854, 855, 863, + 865, 866, 864, 867, 868, 869, 872, 873, 874, 875, + 870, 871, 876, 770, 774, 771, 772, 773, 785, 775, + 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, + 925, 926, 927, 928, 929, 930, 800, 804, 803, 801, + 802, 798, 799, 826, 825, 827, 828, 829, 830, 831, + 832, 834, 833, 835, 836, 837, 838, 839, 840, 808, + 809, 812, 813, 811, 810, 814, 823, 824, 815, 816, + 817, 818, 819, 820, 822, 821, 841, 842, 843, 844, + 845, 847, 846, 850, 851, 849, 848, 853, 852, 750, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 916, 261, 917, 0, 0, 921, 0, 0, 0, + 923, 922, 0, 924, 886, 885, 0, 0, 918, 919, + 0, 920, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 931, 932, 933, 934, + 935, 936, 937, 938, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 956, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 761, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 749, 0, 0, 0, 269, 754, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 760, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 95, 0, 0, 957, 941, 733, + 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, + 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, + 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, + 0, 901, 0, 745, 0, 0, 753, 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, 3103, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, + 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 951, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, @@ -4053,12 +4046,12 @@ var yyAct = [...]int{ 0, 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, 0, - 957, 941, 1071, 907, 945, 958, 959, 960, 961, 946, + 957, 941, 733, 907, 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 746, 0, 759, 0, 0, + 0, 0, 0, 0, 729, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, 0, 753, @@ -4066,7 +4059,7 @@ var yyAct = [...]int{ 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, 755, 0, 0, 0, 0, 0, 0, 0, + 1004, 1005, 3099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, @@ -4075,151 +4068,79 @@ var yyAct = [...]int{ 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, - 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, - 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, - 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, - 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, - 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, - 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, - 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, - 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, - 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, - 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, - 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, - 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, - 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, - 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, - 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, - 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 749, - 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 760, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 95, - 0, 0, 957, 941, 1071, 907, 945, 958, 959, 960, - 961, 946, 0, 237, 947, 948, 244, 949, 0, 906, - 791, 793, 792, 856, 857, 858, 859, 860, 861, 862, - 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 746, 0, 759, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 743, 744, 0, 0, 0, 0, 901, 0, 745, 0, - 0, 753, 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, 2076, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 900, 0, 0, 616, 0, 0, 898, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 951, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 952, 953, 255, 639, 797, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 805, 806, 279, 305, 882, 881, 880, 304, 306, - 878, 879, 877, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 888, 910, 899, 765, 766, - 889, 890, 914, 891, 768, 769, 911, 912, 762, 763, - 767, 913, 915, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 902, 752, 751, 0, 758, 0, 787, 788, 790, - 794, 795, 796, 807, 854, 855, 863, 865, 866, 864, - 867, 868, 869, 872, 873, 874, 875, 870, 871, 876, - 770, 774, 771, 772, 773, 785, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 786, 925, 926, 927, - 928, 929, 930, 800, 804, 803, 801, 802, 798, 799, - 826, 825, 827, 828, 829, 830, 831, 832, 834, 833, - 835, 836, 837, 838, 839, 840, 808, 809, 812, 813, - 811, 810, 814, 823, 824, 815, 816, 817, 818, 819, - 820, 822, 821, 841, 842, 843, 844, 845, 847, 846, - 850, 851, 849, 848, 853, 852, 750, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 916, 261, - 917, 0, 0, 921, 0, 0, 0, 923, 922, 0, - 924, 886, 885, 0, 0, 918, 919, 0, 920, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 931, 932, 933, 934, 935, 936, 937, - 938, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 760, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 957, 941, 1071, 907, 945, 958, - 959, 960, 961, 946, 0, 237, 947, 948, 244, 949, - 0, 906, 791, 793, 792, 856, 857, 858, 859, 860, - 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 746, - 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, + 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 952, 953, 255, 639, 797, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 805, 806, 279, 305, 882, 881, 880, 304, 306, 878, + 879, 877, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 888, 910, 899, 765, 766, 889, + 890, 914, 891, 768, 769, 911, 912, 762, 763, 767, + 913, 915, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 902, 752, 751, 0, 758, 0, 787, 788, 790, 794, + 795, 796, 807, 854, 855, 863, 865, 866, 864, 867, + 868, 869, 872, 873, 874, 875, 870, 871, 876, 770, + 774, 771, 772, 773, 785, 775, 776, 777, 778, 779, + 780, 781, 782, 783, 784, 786, 925, 926, 927, 928, + 929, 930, 800, 804, 803, 801, 802, 798, 799, 826, + 825, 827, 828, 829, 830, 831, 832, 834, 833, 835, + 836, 837, 838, 839, 840, 808, 809, 812, 813, 811, + 810, 814, 823, 824, 815, 816, 817, 818, 819, 820, + 822, 821, 841, 842, 843, 844, 845, 847, 846, 850, + 851, 849, 848, 853, 852, 750, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 916, 261, 917, + 0, 0, 921, 0, 0, 0, 923, 922, 0, 924, + 886, 885, 0, 0, 918, 919, 0, 920, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 931, 932, 933, 934, 935, 936, 937, 938, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 760, 366, 0, 0, 491, 396, 0, 0, 0, + 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 95, 0, 0, 957, 941, 1071, 907, 945, 958, 959, + 960, 961, 946, 0, 237, 947, 948, 244, 949, 0, + 906, 791, 793, 792, 856, 857, 858, 859, 860, 861, + 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 746, 0, + 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 743, 744, 0, 0, 0, 0, 901, 0, - 745, 0, 0, 753, 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, 2074, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 900, 0, 0, 616, 0, 0, 898, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 951, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 0, 743, 744, 0, 0, 0, 0, 901, 0, 745, + 0, 0, 753, 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, 755, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 900, 0, 0, 616, 0, 0, 898, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 951, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, 639, 797, 610, @@ -4261,37 +4182,254 @@ var yyAct = [...]int{ 226, 461, 289, 250, 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, + 392, 0, 372, 568, 569, 314, 520, 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, + 0, 0, 0, 749, 0, 0, 0, 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 381, 423, 510, 417, 760, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 756, 757, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, + 492, 285, 0, 95, 0, 0, 957, 941, 1071, 907, + 945, 958, 959, 960, 961, 946, 0, 237, 947, 948, + 244, 949, 0, 906, 791, 793, 792, 856, 857, 858, + 859, 860, 861, 862, 789, 954, 962, 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 1122, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, + 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 746, 0, 759, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 743, 744, 0, 0, 0, 0, + 901, 0, 745, 0, 0, 753, 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, 2077, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, + 0, 397, 256, 0, 448, 900, 0, 0, 616, 0, + 0, 898, 0, 0, 0, 0, 361, 0, 328, 197, + 224, 0, 0, 407, 456, 468, 0, 0, 0, 951, + 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, + 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, + 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, + 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 952, 953, 255, + 639, 797, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 805, 806, 279, 305, + 882, 881, 880, 304, 306, 878, 879, 877, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 888, 910, 899, 765, 766, 889, 890, 914, 891, 768, + 769, 911, 912, 762, 763, 767, 913, 915, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 902, 752, 751, 0, + 758, 0, 787, 788, 790, 794, 795, 796, 807, 854, + 855, 863, 865, 866, 864, 867, 868, 869, 872, 873, + 874, 875, 870, 871, 876, 770, 774, 771, 772, 773, + 785, 775, 776, 777, 778, 779, 780, 781, 782, 783, + 784, 786, 925, 926, 927, 928, 929, 930, 800, 804, + 803, 801, 802, 798, 799, 826, 825, 827, 828, 829, + 830, 831, 832, 834, 833, 835, 836, 837, 838, 839, + 840, 808, 809, 812, 813, 811, 810, 814, 823, 824, + 815, 816, 817, 818, 819, 820, 822, 821, 841, 842, + 843, 844, 845, 847, 846, 850, 851, 849, 848, 853, + 852, 750, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 916, 261, 917, 0, 0, 921, 0, + 0, 0, 923, 922, 0, 924, 886, 885, 0, 0, + 918, 919, 0, 920, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 931, 932, + 933, 934, 935, 936, 937, 938, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 956, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 761, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 749, 0, 0, 0, + 269, 754, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 760, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 756, 757, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 957, + 941, 1071, 907, 945, 958, 959, 960, 961, 946, 0, + 237, 947, 948, 244, 949, 0, 906, 791, 793, 792, + 856, 857, 858, 859, 860, 861, 862, 789, 954, 962, + 963, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 746, 0, 759, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 743, 744, 0, + 0, 0, 0, 901, 0, 745, 0, 0, 753, 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, 2075, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 900, 0, + 0, 616, 0, 0, 898, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 951, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 952, 953, 255, 639, 797, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 805, + 806, 279, 305, 882, 881, 880, 304, 306, 878, 879, + 877, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 888, 910, 899, 765, 766, 889, 890, + 914, 891, 768, 769, 911, 912, 762, 763, 767, 913, + 915, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 902, + 752, 751, 0, 758, 0, 787, 788, 790, 794, 795, + 796, 807, 854, 855, 863, 865, 866, 864, 867, 868, + 869, 872, 873, 874, 875, 870, 871, 876, 770, 774, + 771, 772, 773, 785, 775, 776, 777, 778, 779, 780, + 781, 782, 783, 784, 786, 925, 926, 927, 928, 929, + 930, 800, 804, 803, 801, 802, 798, 799, 826, 825, + 827, 828, 829, 830, 831, 832, 834, 833, 835, 836, + 837, 838, 839, 840, 808, 809, 812, 813, 811, 810, + 814, 823, 824, 815, 816, 817, 818, 819, 820, 822, + 821, 841, 842, 843, 844, 845, 847, 846, 850, 851, + 849, 848, 853, 852, 750, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 916, 261, 917, 0, + 0, 921, 0, 0, 0, 923, 922, 0, 924, 886, + 885, 0, 0, 918, 919, 0, 920, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 931, 932, 933, 934, 935, 936, 937, 938, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 956, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 1122, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 1121, 616, 0, - 0, 0, 0, 0, 1118, 1119, 361, 1079, 328, 197, - 224, 1112, 1116, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 1121, 616, 0, 0, 0, 0, 0, + 1118, 1119, 361, 1079, 328, 197, 224, 1112, 1116, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 1680, 941, 0, 0, 1677, + 0, 0, 0, 0, 1675, 0, 237, 1676, 1674, 244, + 1679, 0, 906, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, @@ -4333,182 +4471,110 @@ var yyAct = [...]int{ 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 1680, 941, - 0, 0, 1677, 0, 0, 0, 0, 1675, 0, 237, - 1676, 1674, 244, 1679, 0, 906, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 0, 392, 372, 568, 569, 314, - 86, 520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, - 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, - 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, - 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 247, 323, 202, 408, 492, 285, 0, 95, 0, - 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, - 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, - 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 265, 428, 0, 392, 372, 568, 569, 314, 86, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, - 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, - 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, - 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, - 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, - 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, - 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, - 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, - 230, 579, 600, 288, 451, 630, 212, 509, 589, 238, - 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, - 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, - 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, - 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, - 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, - 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, - 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, - 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, - 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, - 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, - 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, - 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, - 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, - 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, - 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, - 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, - 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, - 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, - 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, - 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, - 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, - 558, 542, 530, 523, 531, 0, 196, 220, 364, 94, - 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 2377, 0, 0, 2376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, - 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, - 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, - 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, - 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, - 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, - 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, - 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, - 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, - 511, 512, 513, 515, 391, 265, 428, 1741, 0, 372, - 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 411, 0, 0, 0, 1743, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, - 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, - 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, - 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, - 0, 0, 0, 1745, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, - 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 1453, 0, 1454, 1455, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 94, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 2378, 0, 0, 2377, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 1741, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 1743, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 1745, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 1453, 0, 1454, 1455, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, - 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, - 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, - 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, - 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, - 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, - 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, - 367, 241, 230, 579, 600, 288, 451, 630, 212, 509, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, @@ -4580,7 +4646,224 @@ var yyAct = [...]int{ 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 94, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 95, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 2378, 0, 0, 2377, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 2326, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 1924, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 2324, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 1073, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 1079, 328, 197, 224, + 1077, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, @@ -4607,7 +4890,7 @@ var yyAct = [...]int{ 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 94, 449, 287, 637, 606, 601, + 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, @@ -4622,94 +4905,21 @@ var yyAct = [...]int{ 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 95, 0, 0, 0, 194, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 2377, 0, 0, 2376, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 2325, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 1924, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 0, 0, 2326, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 1924, 194, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4717,87 +4927,88 @@ 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, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 2323, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 1073, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 1718, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 1079, 328, 197, 224, 1077, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 3908, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, @@ -4841,179 +5052,107 @@ var yyAct = [...]int{ 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 2325, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 1924, 194, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 1718, 0, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 3905, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 2086, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 2085, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2087, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 2824, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, @@ -5064,15 +5203,15 @@ var yyAct = [...]int{ 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 2821, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, + 0, 709, 0, 0, 0, 0, 2809, 0, 0, 0, + 0, 237, 0, 0, 244, 2810, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2822, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5086,135 +5225,63 @@ var yyAct = [...]int{ 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 2806, 0, - 0, 0, 0, 237, 0, 0, 244, 2807, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 1764, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 1764, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 1763, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 1763, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5222,15 +5289,15 @@ 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, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, @@ -5302,7 +5369,224 @@ var yyAct = [...]int{ 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 4031, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 1924, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 3908, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, @@ -5352,86 +5636,14 @@ var yyAct = [...]int{ 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 202, 408, 492, 285, 0, 95, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 4028, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 1924, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5439,71 +5651,71 @@ 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, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 2379, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5511,15 +5723,15 @@ 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, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 3905, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, @@ -5569,173 +5781,101 @@ var yyAct = [...]int{ 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 1745, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 2378, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 194, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 1745, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 0, 0, 0, 0, 194, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, @@ -5762,7 +5902,7 @@ var yyAct = [...]int{ 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, + 523, 531, 0, 196, 220, 364, 2038, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, @@ -5786,7 +5926,7 @@ var yyAct = [...]int{ 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, + 2029, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, @@ -5808,135 +5948,63 @@ var yyAct = [...]int{ 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 2037, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 2028, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 1891, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 1891, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5944,15 +6012,15 @@ 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, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, @@ -6024,7 +6092,224 @@ var yyAct = [...]int{ 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 1887, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, + 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, + 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, + 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, + 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, + 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, + 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, + 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, + 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, + 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, + 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, + 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, + 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, + 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, + 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, + 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, + 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, + 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, + 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, + 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, + 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, + 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, + 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, + 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, + 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, + 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, + 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, + 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, + 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, + 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, + 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, + 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, + 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, + 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, + 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, + 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, + 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 1885, 0, 0, 0, + 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, + 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, + 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, + 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, + 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 1883, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, @@ -6062,98 +6347,25 @@ var yyAct = [...]int{ 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 1887, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 1885, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, + 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, + 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, + 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, + 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 411, 0, 1879, 0, 0, 0, 0, 0, 0, 269, + 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, + 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, + 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, + 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, + 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, + 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, + 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6161,87 +6373,88 @@ 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, 296, 0, 397, 256, 0, 448, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 1883, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, + 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, + 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, + 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, + 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, + 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, + 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, + 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, + 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 1877, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, @@ -6284,7 +6497,7 @@ var yyAct = [...]int{ 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 1879, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 1875, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, @@ -6293,155 +6506,83 @@ var yyAct = [...]int{ 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 1877, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 298, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 1875, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, + 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, + 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, + 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, + 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, + 408, 492, 285, 0, 1850, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, + 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, + 264, 319, 271, 263, 572, 0, 0, 0, 0, 0, + 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6450,14 +6591,14 @@ 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, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, + 296, 0, 397, 256, 0, 448, 0, 0, 0, 616, + 0, 0, 0, 0, 0, 0, 0, 361, 0, 328, + 197, 224, 0, 0, 407, 456, 468, 0, 0, 0, + 252, 0, 466, 421, 594, 232, 283, 453, 427, 464, + 435, 286, 0, 0, 465, 368, 577, 445, 591, 617, + 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, + 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, + 365, 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, @@ -6502,13 +6643,13 @@ var yyAct = [...]int{ 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, + 1749, 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 1850, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, + 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, @@ -6530,135 +6671,63 @@ var yyAct = [...]int{ 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, - 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, - 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, - 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, - 576, 587, 390, 379, 218, 585, 388, 378, 332, 351, - 352, 279, 305, 442, 371, 443, 304, 306, 399, 398, - 400, 206, 598, 0, 207, 0, 493, 599, 640, 447, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 301, - 302, 311, 363, 414, 441, 437, 446, 0, 571, 592, - 604, 615, 621, 622, 624, 625, 626, 627, 628, 631, - 629, 402, 309, 489, 331, 369, 0, 0, 420, 467, - 239, 596, 490, 199, 0, 0, 0, 0, 253, 254, - 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 641, 642, 643, 644, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 636, - 500, 506, 501, 502, 503, 504, 505, 0, 507, 0, - 0, 0, 0, 0, 0, 583, 584, 659, 380, 480, - 593, 333, 345, 348, 338, 357, 0, 358, 334, 335, - 340, 342, 343, 344, 349, 350, 354, 360, 248, 209, - 386, 394, 570, 310, 215, 216, 217, 516, 517, 518, - 519, 607, 608, 612, 204, 457, 458, 459, 460, 291, - 602, 307, 463, 462, 329, 330, 375, 444, 532, 534, - 545, 549, 551, 553, 559, 562, 533, 535, 546, 550, - 552, 554, 560, 563, 522, 524, 526, 528, 541, 540, - 537, 565, 566, 543, 548, 527, 539, 544, 557, 564, - 561, 521, 525, 529, 538, 556, 555, 536, 547, 558, - 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, - 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, - 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, - 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, - 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, - 485, 486, 494, 495, 508, 578, 580, 595, 613, 619, - 475, 299, 300, 439, 440, 312, 313, 633, 634, 298, - 590, 620, 588, 632, 614, 433, 374, 0, 0, 377, - 280, 303, 318, 0, 605, 496, 226, 461, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 322, 387, - 395, 424, 429, 295, 270, 243, 454, 240, 479, 511, - 512, 513, 515, 391, 265, 428, 392, 0, 372, 568, - 569, 314, 520, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, - 0, 0, 1749, 269, 0, 0, 0, 0, 362, 266, - 0, 0, 425, 0, 203, 0, 481, 251, 373, 370, - 575, 281, 272, 268, 249, 315, 381, 423, 510, 417, - 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, + 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, + 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, + 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, + 403, 576, 587, 390, 379, 218, 585, 388, 378, 332, + 351, 352, 279, 305, 442, 371, 443, 304, 306, 399, + 398, 400, 206, 598, 0, 207, 0, 493, 599, 640, + 447, 211, 233, 234, 236, 0, 278, 282, 290, 293, + 301, 302, 311, 363, 414, 441, 437, 446, 0, 571, + 592, 604, 615, 621, 622, 624, 625, 626, 627, 628, + 631, 629, 402, 309, 489, 331, 369, 0, 0, 420, + 467, 239, 596, 490, 199, 0, 0, 0, 0, 253, + 254, 0, 567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 641, 642, 643, 644, 645, 646, 647, 648, + 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, + 636, 500, 506, 501, 502, 503, 504, 505, 0, 507, + 0, 0, 0, 0, 0, 0, 583, 584, 659, 380, + 480, 593, 333, 345, 348, 338, 357, 0, 358, 334, + 335, 340, 342, 343, 344, 349, 350, 354, 360, 248, + 209, 386, 394, 570, 310, 215, 216, 217, 516, 517, + 518, 519, 607, 608, 612, 204, 457, 458, 459, 460, + 291, 602, 307, 463, 462, 329, 330, 375, 444, 532, + 534, 545, 549, 551, 553, 559, 562, 533, 535, 546, + 550, 552, 554, 560, 563, 522, 524, 526, 528, 541, + 540, 537, 565, 566, 543, 548, 527, 539, 544, 557, + 564, 561, 521, 525, 529, 538, 556, 555, 536, 547, + 558, 542, 530, 523, 531, 0, 196, 220, 364, 0, + 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, + 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, + 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, + 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, + 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, + 484, 485, 486, 494, 495, 508, 578, 580, 595, 613, + 619, 475, 299, 300, 439, 440, 312, 313, 633, 634, + 298, 590, 620, 588, 632, 614, 433, 374, 0, 0, + 377, 280, 303, 318, 0, 605, 496, 226, 461, 289, + 250, 0, 0, 210, 245, 229, 258, 273, 276, 322, + 387, 395, 424, 429, 295, 270, 243, 454, 240, 479, + 511, 512, 513, 515, 391, 265, 428, 392, 0, 372, + 568, 569, 314, 520, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, + 0, 0, 0, 0, 269, 0, 0, 0, 0, 362, + 266, 0, 0, 425, 0, 203, 0, 481, 251, 373, + 370, 575, 281, 272, 268, 249, 315, 381, 423, 510, + 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, + 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, + 95, 0, 0, 0, 941, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, + 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, + 359, 0, 0, 0, 0, 0, 264, 319, 271, 263, + 572, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 95, 0, 0, 0, 941, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6666,15 +6735,15 @@ 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, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, + 0, 0, 0, 0, 0, 0, 296, 0, 397, 256, + 0, 448, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 361, 0, 328, 197, 224, 0, 0, + 407, 456, 468, 0, 0, 0, 252, 0, 466, 421, + 594, 232, 283, 453, 427, 464, 435, 286, 0, 0, + 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, + 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, + 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, + 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, @@ -6746,136 +6815,64 @@ var yyAct = [...]int{ 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, - 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, - 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, - 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, - 227, 610, 219, 0, 609, 403, 576, 587, 390, 379, - 218, 585, 388, 378, 332, 351, 352, 279, 305, 442, - 371, 443, 304, 306, 399, 398, 400, 206, 598, 0, - 207, 0, 493, 599, 640, 447, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 301, 302, 311, 363, 414, - 441, 437, 446, 0, 571, 592, 604, 615, 621, 622, - 624, 625, 626, 627, 628, 631, 629, 402, 309, 489, - 331, 369, 0, 0, 420, 467, 239, 596, 490, 199, - 0, 0, 0, 0, 253, 254, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 641, 642, 643, - 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 636, 500, 506, 501, 502, - 503, 504, 505, 0, 507, 0, 0, 0, 0, 0, - 0, 583, 584, 659, 380, 480, 593, 333, 345, 348, - 338, 357, 0, 358, 334, 335, 340, 342, 343, 344, - 349, 350, 354, 360, 248, 209, 386, 394, 570, 310, - 215, 216, 217, 516, 517, 518, 519, 607, 608, 612, - 204, 457, 458, 459, 460, 291, 602, 307, 463, 462, - 329, 330, 375, 444, 532, 534, 545, 549, 551, 553, - 559, 562, 533, 535, 546, 550, 552, 554, 560, 563, - 522, 524, 526, 528, 541, 540, 537, 565, 566, 543, - 548, 527, 539, 544, 557, 564, 561, 521, 525, 529, - 538, 556, 555, 536, 547, 558, 542, 530, 523, 531, - 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, - 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, - 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, - 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, - 508, 578, 580, 595, 613, 619, 475, 299, 300, 439, - 440, 312, 313, 633, 634, 1431, 590, 620, 588, 632, - 614, 433, 374, 0, 0, 377, 280, 303, 318, 0, - 605, 496, 226, 461, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 322, 387, 395, 424, 429, 295, - 270, 243, 454, 240, 479, 511, 512, 513, 515, 391, - 265, 428, 392, 0, 372, 568, 569, 314, 520, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 411, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 362, 266, 0, 0, 425, 0, - 203, 0, 481, 251, 373, 370, 575, 281, 272, 268, - 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, - 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, - 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, - 0, 264, 319, 271, 263, 572, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 397, 256, 0, 448, 0, 0, 0, - 616, 0, 0, 0, 0, 0, 0, 0, 361, 0, - 328, 197, 224, 0, 0, 407, 456, 468, 0, 0, - 0, 252, 0, 466, 421, 594, 232, 283, 453, 427, - 464, 435, 286, 0, 0, 465, 368, 577, 445, 591, - 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, - 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, - 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 623, 223, 474, 367, 241, 230, 579, 600, 0, 288, + 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, + 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, + 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, + 639, 227, 610, 219, 0, 609, 403, 576, 587, 390, + 379, 218, 585, 388, 378, 332, 351, 352, 279, 305, + 442, 371, 443, 304, 306, 399, 398, 400, 206, 598, + 0, 207, 0, 493, 599, 640, 447, 211, 233, 234, + 236, 0, 278, 282, 290, 293, 301, 302, 311, 363, + 414, 441, 437, 446, 0, 571, 592, 604, 615, 621, + 622, 624, 625, 626, 627, 628, 631, 629, 402, 309, + 489, 331, 369, 0, 0, 420, 467, 239, 596, 490, + 199, 0, 0, 0, 0, 253, 254, 0, 567, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 636, 500, 506, 501, + 502, 503, 504, 505, 0, 507, 0, 0, 0, 0, + 0, 0, 583, 584, 659, 380, 480, 593, 333, 345, + 348, 338, 357, 0, 358, 334, 335, 340, 342, 343, + 344, 349, 350, 354, 360, 248, 209, 386, 394, 570, + 310, 215, 216, 217, 516, 517, 518, 519, 607, 608, + 612, 204, 457, 458, 459, 460, 291, 602, 307, 463, + 462, 329, 330, 375, 444, 532, 534, 545, 549, 551, + 553, 559, 562, 533, 535, 546, 550, 552, 554, 560, + 563, 522, 524, 526, 528, 541, 540, 537, 565, 566, + 543, 548, 527, 539, 544, 557, 564, 561, 521, 525, + 529, 538, 556, 555, 536, 547, 558, 542, 530, 523, + 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, + 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1030, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 392, 0, 372, 568, 569, 314, - 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 362, 266, 0, 0, - 425, 0, 203, 0, 481, 251, 373, 370, 575, 281, - 272, 268, 249, 315, 381, 423, 510, 417, 0, 366, - 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 247, 323, 202, 408, 492, 285, 0, 0, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, - 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, - 0, 0, 0, 264, 319, 271, 263, 572, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, + 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, + 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, + 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, + 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, + 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, + 495, 508, 578, 580, 595, 613, 619, 475, 299, 300, + 439, 440, 312, 313, 633, 634, 1431, 590, 620, 588, + 632, 614, 433, 374, 0, 0, 377, 280, 303, 318, + 0, 605, 496, 226, 461, 289, 250, 0, 0, 210, + 245, 229, 258, 273, 276, 322, 387, 395, 424, 429, + 295, 270, 243, 454, 240, 479, 511, 512, 513, 515, + 391, 265, 428, 392, 0, 372, 568, 569, 314, 520, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 0, 0, 0, 0, 362, 266, 0, 0, 425, + 0, 203, 0, 481, 251, 373, 370, 575, 281, 272, + 268, 249, 315, 381, 423, 510, 417, 0, 366, 0, + 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, + 323, 202, 408, 492, 285, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, + 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, + 0, 0, 264, 319, 271, 263, 572, 0, 0, 0, + 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6883,15 +6880,15 @@ 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, 296, 0, 397, 256, 0, 448, 0, - 662, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 361, 0, 328, 197, 224, 0, 0, 407, 456, 468, - 0, 0, 0, 252, 0, 466, 421, 594, 232, 283, - 453, 427, 464, 435, 286, 0, 0, 465, 368, 577, - 445, 591, 617, 618, 262, 401, 603, 514, 611, 635, - 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, - 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, - 579, 600, 288, 451, 630, 212, 509, 589, 238, 478, + 0, 0, 296, 0, 397, 256, 0, 448, 0, 0, + 0, 616, 0, 0, 0, 0, 0, 0, 0, 361, + 0, 328, 197, 224, 0, 0, 407, 456, 468, 0, + 0, 0, 252, 0, 466, 421, 594, 232, 283, 453, + 427, 464, 435, 286, 0, 0, 465, 368, 577, 445, + 591, 617, 618, 262, 401, 603, 514, 611, 635, 225, + 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, + 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, + 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, 609, 403, @@ -6920,7 +6917,7 @@ var yyAct = [...]int{ 542, 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 0, 0, 0, 0, 0, 1030, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, 418, 419, @@ -6941,173 +6938,101 @@ var yyAct = [...]int{ 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, - 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, - 448, 0, 0, 0, 616, 0, 0, 0, 0, 0, - 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, - 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, - 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, - 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, - 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, - 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, - 241, 230, 579, 600, 288, 451, 630, 212, 509, 589, - 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, - 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, - 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, - 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, - 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, - 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, - 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, - 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, - 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, - 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, - 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, - 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, - 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, - 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, - 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, - 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, - 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, - 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, - 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, - 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, - 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, - 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, - 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, - 383, 384, 385, 4036, 405, 406, 409, 412, 413, 416, - 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, - 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, - 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, - 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, - 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, - 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, - 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, - 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, - 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, - 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, - 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, - 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 264, 319, 271, 263, 572, + 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, - 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, - 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, - 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, - 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, - 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, - 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, - 474, 367, 241, 230, 579, 600, 288, 451, 630, 212, - 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, - 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, - 0, 0, 257, 410, 581, 582, 255, 639, 227, 610, - 219, 0, 609, 403, 576, 587, 390, 379, 218, 585, - 388, 378, 332, 351, 352, 279, 305, 442, 371, 443, - 304, 306, 399, 398, 400, 206, 598, 0, 207, 0, - 493, 599, 640, 447, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 301, 302, 311, 363, 414, 441, 437, - 446, 0, 571, 592, 604, 615, 621, 622, 624, 625, - 626, 627, 628, 631, 629, 402, 309, 489, 331, 369, - 0, 0, 420, 467, 239, 596, 490, 199, 0, 0, - 0, 0, 253, 254, 0, 567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 636, 500, 506, 501, 502, 503, 504, - 505, 0, 507, 0, 0, 0, 0, 0, 0, 583, - 584, 659, 380, 480, 593, 333, 345, 348, 338, 357, - 0, 358, 334, 335, 340, 342, 343, 344, 349, 350, - 354, 360, 248, 209, 386, 394, 570, 310, 215, 216, - 217, 516, 517, 518, 519, 607, 608, 612, 204, 457, - 458, 459, 460, 291, 602, 307, 463, 462, 329, 330, - 375, 444, 532, 534, 545, 549, 551, 553, 559, 562, - 533, 535, 546, 550, 552, 554, 560, 563, 522, 524, - 526, 528, 541, 540, 537, 565, 566, 543, 548, 527, - 539, 544, 557, 564, 561, 521, 525, 529, 538, 556, - 555, 536, 547, 558, 542, 530, 523, 531, 0, 196, - 220, 364, 0, 449, 287, 637, 606, 601, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 308, 316, 317, 320, 326, - 376, 382, 383, 384, 385, 404, 405, 406, 409, 412, - 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, - 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, - 477, 482, 483, 484, 485, 486, 494, 495, 508, 578, - 580, 595, 613, 619, 475, 299, 300, 439, 440, 312, - 313, 633, 634, 298, 590, 620, 588, 632, 614, 433, - 374, 0, 0, 377, 280, 303, 318, 0, 605, 496, - 226, 461, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 322, 387, 395, 424, 429, 295, 270, 243, - 454, 240, 479, 511, 512, 513, 515, 391, 265, 428, - 392, 0, 372, 568, 569, 314, 520, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 362, 266, 0, 0, 425, 0, 203, 0, - 481, 251, 373, 370, 575, 281, 272, 268, 249, 315, - 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, + 0, 0, 0, 0, 0, 296, 0, 397, 256, 0, + 448, 0, 662, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 361, 0, 328, 197, 224, 0, 0, 407, + 456, 468, 0, 0, 0, 252, 0, 466, 421, 594, + 232, 283, 453, 427, 464, 435, 286, 0, 0, 465, + 368, 577, 445, 591, 617, 618, 262, 401, 603, 514, + 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, + 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, + 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, + 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, + 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, + 0, 257, 410, 581, 582, 255, 639, 227, 610, 219, + 0, 609, 403, 576, 587, 390, 379, 218, 585, 388, + 378, 332, 351, 352, 279, 305, 442, 371, 443, 304, + 306, 399, 398, 400, 206, 598, 0, 207, 0, 493, + 599, 640, 447, 211, 233, 234, 236, 0, 278, 282, + 290, 293, 301, 302, 311, 363, 414, 441, 437, 446, + 0, 571, 592, 604, 615, 621, 622, 624, 625, 626, + 627, 628, 631, 629, 402, 309, 489, 331, 369, 0, + 0, 420, 467, 239, 596, 490, 199, 0, 0, 0, + 0, 253, 254, 0, 567, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 641, 642, 643, 644, 645, 646, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 636, 500, 506, 501, 502, 503, 504, 505, + 0, 507, 0, 0, 0, 0, 0, 0, 583, 584, + 659, 380, 480, 593, 333, 345, 348, 338, 357, 0, + 358, 334, 335, 340, 342, 343, 344, 349, 350, 354, + 360, 248, 209, 386, 394, 570, 310, 215, 216, 217, + 516, 517, 518, 519, 607, 608, 612, 204, 457, 458, + 459, 460, 291, 602, 307, 463, 462, 329, 330, 375, + 444, 532, 534, 545, 549, 551, 553, 559, 562, 533, + 535, 546, 550, 552, 554, 560, 563, 522, 524, 526, + 528, 541, 540, 537, 565, 566, 543, 548, 527, 539, + 544, 557, 564, 561, 521, 525, 529, 538, 556, 555, + 536, 547, 558, 542, 530, 523, 531, 0, 196, 220, + 364, 0, 449, 287, 637, 606, 601, 205, 222, 0, + 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 247, 323, 202, 408, - 492, 285, 0, 0, 0, 0, 0, 941, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, - 341, 346, 353, 359, 0, 0, 0, 0, 0, 264, - 319, 271, 263, 572, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, + 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, + 275, 277, 284, 297, 308, 316, 317, 320, 326, 376, + 382, 383, 384, 385, 404, 405, 406, 409, 412, 413, + 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, + 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, + 482, 483, 484, 485, 486, 494, 495, 508, 578, 580, + 595, 613, 619, 475, 299, 300, 439, 440, 312, 313, + 633, 634, 298, 590, 620, 588, 632, 614, 433, 374, + 0, 0, 377, 280, 303, 318, 0, 605, 496, 226, + 461, 289, 250, 0, 0, 210, 245, 229, 258, 273, + 276, 322, 387, 395, 424, 429, 295, 270, 243, 454, + 240, 479, 511, 512, 513, 515, 391, 265, 428, 392, + 0, 372, 568, 569, 314, 520, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 0, 362, 266, 0, 0, 425, 0, 203, 0, 481, + 251, 373, 370, 575, 281, 272, 268, 249, 315, 381, + 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 247, 323, 202, 408, 492, + 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, + 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, + 346, 353, 359, 0, 0, 0, 0, 0, 264, 319, + 271, 263, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 397, 256, 0, 448, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 0, 361, 0, 328, 197, - 224, 0, 0, 407, 456, 468, 0, 0, 0, 252, - 0, 466, 421, 594, 232, 283, 453, 427, 464, 435, - 286, 0, 0, 465, 368, 577, 445, 591, 617, 618, - 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, - 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, - 623, 223, 474, 367, 241, 230, 579, 600, 288, 451, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, + 397, 256, 0, 448, 0, 0, 0, 616, 0, 0, + 0, 0, 0, 0, 0, 361, 0, 328, 197, 224, + 0, 0, 407, 456, 468, 0, 0, 0, 252, 0, + 466, 421, 594, 232, 283, 453, 427, 464, 435, 286, + 0, 0, 465, 368, 577, 445, 591, 617, 618, 262, + 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, + 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, + 223, 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, 255, 639, @@ -7139,7 +7064,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, 316, 317, - 320, 326, 376, 382, 383, 384, 385, 404, 405, 406, + 320, 326, 376, 382, 383, 384, 385, 4039, 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, 494, 495, @@ -7157,7 +7082,7 @@ var yyAct = [...]int{ 249, 315, 381, 423, 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 247, 323, - 202, 408, 492, 285, 0, 0, 0, 0, 0, 194, + 202, 408, 492, 285, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, 0, 0, 0, @@ -7180,73 +7105,216 @@ var yyAct = [...]int{ 617, 618, 262, 401, 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, 230, 579, 600, - 288, 451, 630, 212, 509, 589, 238, 478, 0, 0, - 638, 246, 498, 214, 586, 497, 389, 324, 325, 213, - 0, 452, 267, 292, 0, 0, 257, 410, 581, 582, - 255, 639, 227, 610, 219, 0, 609, 403, 576, 587, - 390, 379, 218, 585, 388, 378, 332, 351, 352, 279, - 305, 442, 371, 443, 304, 306, 399, 398, 400, 206, - 598, 0, 207, 0, 493, 599, 640, 447, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 301, 302, 311, - 363, 414, 441, 437, 446, 0, 571, 592, 604, 615, - 621, 622, 624, 625, 626, 627, 628, 631, 629, 402, - 309, 489, 331, 369, 0, 0, 420, 467, 239, 596, - 490, 199, 0, 0, 0, 0, 253, 254, 0, 567, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 636, 500, 506, - 501, 502, 503, 504, 505, 0, 507, 0, 0, 0, - 0, 0, 0, 583, 584, 659, 380, 480, 593, 333, - 345, 348, 338, 357, 0, 358, 334, 335, 340, 342, - 343, 344, 349, 350, 354, 360, 248, 209, 386, 394, - 570, 310, 215, 216, 217, 516, 517, 518, 519, 607, - 608, 612, 204, 457, 458, 459, 460, 291, 602, 307, - 463, 462, 329, 330, 375, 444, 532, 534, 545, 549, - 551, 553, 559, 562, 533, 535, 546, 550, 552, 554, - 560, 563, 522, 524, 526, 528, 541, 540, 537, 565, - 566, 543, 548, 527, 539, 544, 557, 564, 561, 521, - 525, 529, 538, 556, 555, 536, 547, 558, 542, 530, - 523, 531, 0, 196, 220, 364, 0, 449, 287, 637, - 606, 601, 205, 222, 0, 261, 0, 0, 0, 0, + 0, 288, 451, 630, 212, 509, 589, 238, 478, 0, + 0, 638, 246, 498, 214, 586, 497, 389, 324, 325, + 213, 0, 452, 267, 292, 0, 0, 257, 410, 581, + 582, 255, 639, 227, 610, 219, 0, 609, 403, 576, + 587, 390, 379, 218, 585, 388, 378, 332, 351, 352, + 279, 305, 442, 371, 443, 304, 306, 399, 398, 400, + 206, 598, 0, 207, 0, 493, 599, 640, 447, 211, + 233, 234, 236, 0, 278, 282, 290, 293, 301, 302, + 311, 363, 414, 441, 437, 446, 0, 571, 592, 604, + 615, 621, 622, 624, 625, 626, 627, 628, 631, 629, + 402, 309, 489, 331, 369, 0, 0, 420, 467, 239, + 596, 490, 199, 0, 0, 0, 0, 253, 254, 0, + 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 636, 500, + 506, 501, 502, 503, 504, 505, 0, 507, 0, 0, + 0, 0, 0, 0, 583, 584, 659, 380, 480, 593, + 333, 345, 348, 338, 357, 0, 358, 334, 335, 340, + 342, 343, 344, 349, 350, 354, 360, 248, 209, 386, + 394, 570, 310, 215, 216, 217, 516, 517, 518, 519, + 607, 608, 612, 204, 457, 458, 459, 460, 291, 602, + 307, 463, 462, 329, 330, 375, 444, 532, 534, 545, + 549, 551, 553, 559, 562, 533, 535, 546, 550, 552, + 554, 560, 563, 522, 524, 526, 528, 541, 540, 537, + 565, 566, 543, 548, 527, 539, 544, 557, 564, 561, + 521, 525, 529, 538, 556, 555, 536, 547, 558, 542, + 530, 523, 531, 0, 196, 220, 364, 0, 449, 287, + 637, 606, 601, 205, 222, 0, 261, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, + 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, + 308, 316, 317, 320, 326, 376, 382, 383, 384, 385, + 404, 405, 406, 409, 412, 413, 416, 418, 419, 422, + 426, 430, 431, 432, 434, 436, 438, 450, 455, 469, + 470, 471, 472, 473, 476, 477, 482, 483, 484, 485, + 486, 494, 495, 508, 578, 580, 595, 613, 619, 475, + 299, 300, 439, 440, 312, 313, 633, 634, 298, 590, + 620, 588, 632, 614, 433, 374, 0, 0, 377, 280, + 303, 318, 0, 605, 496, 226, 461, 289, 250, 0, + 0, 210, 245, 229, 258, 273, 276, 322, 387, 395, + 424, 429, 295, 270, 243, 454, 240, 479, 511, 512, + 513, 515, 391, 265, 428, 392, 0, 372, 568, 569, + 314, 520, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, + 0, 0, 269, 0, 0, 0, 0, 362, 266, 0, + 0, 425, 0, 203, 0, 481, 251, 373, 370, 575, + 281, 272, 268, 249, 315, 381, 423, 510, 417, 0, + 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 321, 247, 323, 202, 408, 492, 285, 0, 0, 0, + 0, 0, 941, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 244, 0, 0, 0, 347, + 356, 355, 336, 337, 339, 341, 346, 353, 359, 0, + 0, 0, 0, 0, 264, 319, 271, 263, 572, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 296, 0, 397, 256, 0, 448, + 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 361, 0, 328, 197, 224, 0, 0, 407, 456, + 468, 0, 0, 0, 252, 0, 466, 421, 594, 232, + 283, 453, 427, 464, 435, 286, 0, 0, 465, 368, + 577, 445, 591, 617, 618, 262, 401, 603, 514, 611, + 635, 225, 259, 415, 499, 597, 488, 393, 573, 574, + 327, 487, 294, 201, 365, 623, 223, 474, 367, 241, + 230, 579, 600, 0, 288, 451, 630, 212, 509, 589, + 238, 478, 0, 0, 638, 246, 498, 214, 586, 497, + 389, 324, 325, 213, 0, 452, 267, 292, 0, 0, + 257, 410, 581, 582, 255, 639, 227, 610, 219, 0, + 609, 403, 576, 587, 390, 379, 218, 585, 388, 378, + 332, 351, 352, 279, 305, 442, 371, 443, 304, 306, + 399, 398, 400, 206, 598, 0, 207, 0, 493, 599, + 640, 447, 211, 233, 234, 236, 0, 278, 282, 290, + 293, 301, 302, 311, 363, 414, 441, 437, 446, 0, + 571, 592, 604, 615, 621, 622, 624, 625, 626, 627, + 628, 631, 629, 402, 309, 489, 331, 369, 0, 0, + 420, 467, 239, 596, 490, 199, 0, 0, 0, 0, + 253, 254, 0, 567, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 642, 643, 644, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 636, 500, 506, 501, 502, 503, 504, 505, 0, + 507, 0, 0, 0, 0, 0, 0, 583, 584, 659, + 380, 480, 593, 333, 345, 348, 338, 357, 0, 358, + 334, 335, 340, 342, 343, 344, 349, 350, 354, 360, + 248, 209, 386, 394, 570, 310, 215, 216, 217, 516, + 517, 518, 519, 607, 608, 612, 204, 457, 458, 459, + 460, 291, 602, 307, 463, 462, 329, 330, 375, 444, + 532, 534, 545, 549, 551, 553, 559, 562, 533, 535, + 546, 550, 552, 554, 560, 563, 522, 524, 526, 528, + 541, 540, 537, 565, 566, 543, 548, 527, 539, 544, + 557, 564, 561, 521, 525, 529, 538, 556, 555, 536, + 547, 558, 542, 530, 523, 531, 0, 196, 220, 364, + 0, 449, 287, 637, 606, 601, 205, 222, 0, 261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, + 277, 284, 297, 308, 316, 317, 320, 326, 376, 382, + 383, 384, 385, 404, 405, 406, 409, 412, 413, 416, + 418, 419, 422, 426, 430, 431, 432, 434, 436, 438, + 450, 455, 469, 470, 471, 472, 473, 476, 477, 482, + 483, 484, 485, 486, 494, 495, 508, 578, 580, 595, + 613, 619, 475, 299, 300, 439, 440, 312, 313, 633, + 634, 298, 590, 620, 588, 632, 614, 433, 374, 0, + 0, 377, 280, 303, 318, 0, 605, 496, 226, 461, + 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, + 322, 387, 395, 424, 429, 295, 270, 243, 454, 240, + 479, 511, 512, 513, 515, 391, 265, 428, 392, 0, + 372, 568, 569, 314, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, + 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, + 362, 266, 0, 0, 425, 0, 203, 0, 481, 251, + 373, 370, 575, 281, 272, 268, 249, 315, 381, 423, + 510, 417, 0, 366, 0, 0, 491, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 308, - 316, 317, 320, 326, 376, 382, 383, 384, 385, 404, - 405, 406, 409, 412, 413, 416, 418, 419, 422, 426, - 430, 431, 432, 434, 436, 438, 450, 455, 469, 470, - 471, 472, 473, 476, 477, 482, 483, 484, 485, 486, - 494, 495, 508, 578, 580, 595, 613, 619, 475, 299, - 300, 439, 440, 312, 313, 633, 634, 298, 590, 620, - 588, 632, 614, 433, 374, 0, 0, 377, 280, 303, - 318, 0, 605, 496, 226, 461, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 322, 387, 395, 424, - 429, 295, 270, 243, 454, 240, 479, 511, 512, 513, - 515, 391, 265, 428, 0, 0, 372, 568, 569, 314, + 0, 0, 0, 321, 247, 323, 202, 408, 492, 285, + 0, 0, 0, 0, 0, 194, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, + 0, 0, 347, 356, 355, 336, 337, 339, 341, 346, + 353, 359, 0, 0, 0, 0, 0, 264, 319, 271, + 263, 572, 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 296, 0, 397, + 256, 0, 448, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 361, 0, 328, 197, 224, 0, + 0, 407, 456, 468, 0, 0, 0, 252, 0, 466, + 421, 594, 232, 283, 453, 427, 464, 435, 286, 0, + 0, 465, 368, 577, 445, 591, 617, 618, 262, 401, + 603, 514, 611, 635, 225, 259, 415, 499, 597, 488, + 393, 573, 574, 327, 487, 294, 201, 365, 623, 223, + 474, 367, 241, 230, 579, 600, 0, 288, 451, 630, + 212, 509, 589, 238, 478, 0, 0, 638, 246, 498, + 214, 586, 497, 389, 324, 325, 213, 0, 452, 267, + 292, 0, 0, 257, 410, 581, 582, 255, 639, 227, + 610, 219, 0, 609, 403, 576, 587, 390, 379, 218, + 585, 388, 378, 332, 351, 352, 279, 305, 442, 371, + 443, 304, 306, 399, 398, 400, 206, 598, 0, 207, + 0, 493, 599, 640, 447, 211, 233, 234, 236, 0, + 278, 282, 290, 293, 301, 302, 311, 363, 414, 441, + 437, 446, 0, 571, 592, 604, 615, 621, 622, 624, + 625, 626, 627, 628, 631, 629, 402, 309, 489, 331, + 369, 0, 0, 420, 467, 239, 596, 490, 199, 0, + 0, 0, 0, 253, 254, 0, 567, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 636, 500, 506, 501, 502, 503, + 504, 505, 0, 507, 0, 0, 0, 0, 0, 0, + 583, 584, 659, 380, 480, 593, 333, 345, 348, 338, + 357, 0, 358, 334, 335, 340, 342, 343, 344, 349, + 350, 354, 360, 248, 209, 386, 394, 570, 310, 215, + 216, 217, 516, 517, 518, 519, 607, 608, 612, 204, + 457, 458, 459, 460, 291, 602, 307, 463, 462, 329, + 330, 375, 444, 532, 534, 545, 549, 551, 553, 559, + 562, 533, 535, 546, 550, 552, 554, 560, 563, 522, + 524, 526, 528, 541, 540, 537, 565, 566, 543, 548, + 527, 539, 544, 557, 564, 561, 521, 525, 529, 538, + 556, 555, 536, 547, 558, 542, 530, 523, 531, 0, + 196, 220, 364, 0, 449, 287, 637, 606, 601, 205, + 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, + 242, 260, 275, 277, 284, 297, 308, 316, 317, 320, + 326, 376, 382, 383, 384, 385, 404, 405, 406, 409, + 412, 413, 416, 418, 419, 422, 426, 430, 431, 432, + 434, 436, 438, 450, 455, 469, 470, 471, 472, 473, + 476, 477, 482, 483, 484, 485, 486, 494, 495, 508, + 578, 580, 595, 613, 619, 475, 299, 300, 439, 440, + 312, 313, 633, 634, 298, 590, 620, 588, 632, 614, + 433, 374, 0, 0, 377, 280, 303, 318, 0, 605, + 496, 226, 461, 289, 250, 0, 0, 210, 245, 229, + 258, 273, 276, 322, 387, 395, 424, 429, 295, 270, + 243, 454, 240, 479, 511, 512, 513, 515, 391, 265, + 428, 0, 0, 372, 568, 569, 314, } var yyPact = [...]int{ - -1000, -1000, 6231, -1000, -531, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 4460, -1000, -532, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2350, 2400, -1000, -1000, -1000, -1000, 2535, -1000, 1002, - 1986, -1000, 2335, 4910, -1000, 54918, 503, -1000, 52030, -434, - 871, 236, 36146, -1000, 195, -1000, 184, 53474, 188, -1000, - -1000, -1000, -1000, -434, 21704, 2285, 57, 52, 54918, -1000, - -1000, -1000, -1000, -355, 2510, 1962, -1000, 415, -1000, -1000, - -1000, -1000, -1000, -1000, 51308, -1000, 1084, -1000, -1000, 2358, - 2349, 2259, 898, 2272, -1000, 2451, 1962, -1000, 21704, 2492, - 2407, 20982, 20982, 462, -1000, -1000, 315, -1000, -1000, 31092, - 54918, 39034, 306, -1000, 2335, -1000, -1000, -1000, 192, -1000, - 384, 1895, -1000, 1894, -1000, 892, 1017, 407, 875, 862, - 406, 395, 394, 389, 385, 381, 379, 361, 413, -1000, - 928, 928, -204, -208, 1319, 457, 449, 449, 1041, 476, - 2301, 2300, -1000, -1000, 928, 928, 928, 346, 928, 928, - 928, 928, 328, 327, 928, 928, 928, 928, 928, 928, - 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, - 928, 860, 2335, 310, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2319, 2394, -1000, -1000, -1000, -1000, 2570, -1000, 1048, + 1981, -1000, 2298, 4124, -1000, 55594, 773, -1000, 52702, -434, + 903, 267, 36796, -1000, 199, -1000, 182, 54148, 188, -1000, + -1000, -1000, -1000, -434, 22334, 2218, 63, 55, 55594, -1000, + -1000, -1000, -1000, -354, 2528, 1957, -1000, 428, -1000, -1000, + -1000, -1000, -1000, -1000, 51979, -1000, 1198, -1000, -1000, 2324, + 2322, 2237, 930, 2268, -1000, 2434, 1957, -1000, 22334, 2502, + 2415, 21611, 21611, 457, -1000, -1000, 292, -1000, -1000, 31735, + 55594, 39688, 289, -1000, 2298, -1000, -1000, -1000, 216, -1000, + 331, 1880, -1000, 1879, -1000, 958, 470, 372, 478, 456, + 370, 368, 366, 365, 363, 347, 343, 342, 376, -1000, + 947, 947, -206, -210, 2008, 473, 432, 432, 1042, 494, + 2266, 2254, -1000, -1000, 947, 947, 947, 348, 947, 947, + 947, 947, 288, 283, 947, 947, 947, 947, 947, 947, + 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, + 947, 938, 2298, 269, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7291,68 +7359,68 @@ 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, - 54918, 181, 54918, -1000, 819, 495, -1000, -1000, -438, 1091, - 1091, 69, 1091, 1091, 1091, 1091, 186, 971, 50, -1000, - 185, 281, 173, 294, 1044, 321, -1000, -1000, 277, 1044, - 1769, -1000, 903, 286, 216, -1000, 1091, 1091, -1000, 14459, - 252, 14459, 14459, -1000, 2324, -1000, -1000, -1000, -1000, -1000, - 1341, -1000, -1000, -1000, -1000, -27, 475, -1000, -1000, -1000, - -1000, 53474, 50586, 275, -1000, -1000, 47, 1807, 1263, 21704, - 1256, 896, -1000, -1000, 1187, 873, -1000, -1000, -1000, -1000, - -1000, 522, -1000, 23870, 23870, 23870, 23870, -1000, -1000, 1897, - 49864, 1897, 1897, 23870, 1897, 23870, 1897, 1897, 1897, 21704, - 1897, 1897, 1897, 1897, -1000, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, -1000, -1000, -1000, -1000, 1897, 817, 1897, 1897, - 1897, 1897, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1897, 1897, 1897, 1897, 1897, 1897, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 26758, 1482, 1480, 1475, -1000, 18816, 1897, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 55594, 202, 55594, -1000, 840, 772, -1000, -1000, -438, 1084, + 1084, 88, 1084, 1084, 1084, 1084, 184, 1011, 54, -1000, + 180, 262, 171, 265, 1082, 800, -1000, -1000, 255, 1082, + 1744, -1000, 935, 264, 177, -1000, 1084, 1084, -1000, 15079, + 232, 15079, 15079, -1000, 2282, -1000, -1000, -1000, -1000, -1000, + 1362, -1000, -1000, -1000, -1000, -25, 488, -1000, -1000, -1000, + -1000, 54148, 51256, 263, -1000, -1000, 340, 1811, 1179, 22334, + 1118, 928, -1000, -1000, 1241, 907, -1000, -1000, -1000, -1000, + -1000, 826, -1000, 24503, 24503, 24503, 24503, -1000, -1000, 1883, + 50533, 1883, 1883, 24503, 1883, 24503, 1883, 1883, 1883, 22334, + 1883, 1883, 1883, 1883, -1000, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, -1000, -1000, -1000, -1000, 1883, 839, 1883, 1883, + 1883, 1883, 1883, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1883, 1883, 1883, 1883, 1883, 1883, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 27395, 1478, 1470, 1468, -1000, 19442, 1883, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54918, -1000, 1897, - 217, 53474, 53474, 349, 1336, -1000, -1000, 2451, 1962, -1000, - 2510, 2462, 415, -1000, 3317, 1694, 1510, 1506, 1962, 1870, - 54918, -1000, 1913, -1000, -1000, -1000, -313, -318, 2197, 1471, - 1755, -1000, -1000, -1000, -1000, 2251, 21704, -1000, -1000, 2532, - -1000, 28203, 816, 2531, 49142, -1000, 462, 462, 1888, 428, - 33, -1000, -1000, -1000, -1000, 942, 35424, -1000, -1000, -1000, - -1000, -1000, 1766, 54918, -1000, -1000, 4141, 1347, -1000, 1985, - -1000, 1748, -1000, 1931, 21704, 1998, 493, 1347, 484, 483, - 482, -1000, -53, -1000, -1000, -1000, -1000, -1000, -1000, 928, - 928, 928, -1000, 387, 2490, 4910, 6412, -1000, -1000, -1000, - 48420, 1984, 1347, -1000, 1980, -1000, 1007, 869, 865, 865, - 1347, -1000, -1000, 54196, 1347, 1006, 1004, 1347, 1347, 53474, - 53474, -1000, 47698, -1000, 46976, 46254, 1328, 53474, 45532, 44810, - 44088, 43366, 42644, -1000, 2238, -1000, 2058, -1000, -1000, -1000, - 54196, 1347, 1347, 54196, 53474, 54196, 54918, 1347, -1000, -1000, - 338, -1000, -1000, 1320, 1308, 1305, 928, 928, 1291, 1742, - 1741, 1733, 928, 928, 1284, 1732, 37590, 1729, 269, 1283, - 1282, 1281, 1246, 1721, 193, 1712, 1245, 1229, 1279, 53474, - 1976, 54918, -1000, 262, 970, 935, 940, 2335, 2281, 1884, - 471, 492, 1347, 452, 452, 53474, -1000, 15187, 54918, 227, - -1000, 1665, 21704, -1000, 1054, 1044, 1044, -1000, -1000, -1000, - -1000, -1000, -1000, 1091, 54918, 1054, -1000, -1000, -1000, 1044, - 1091, 54918, 1091, 1091, 1091, 1091, 1044, 1044, 1044, 1091, - 54918, 54918, 54918, 54918, 54918, 54918, 54918, 54918, 54918, 14459, - 903, 1091, -440, -1000, 1663, -1000, -1000, -1000, 2117, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 55594, -1000, 1883, + 227, 54148, 54148, 349, 1357, -1000, -1000, 2434, 1957, -1000, + 2528, 2524, 428, -1000, 2979, 1465, 1510, 1483, 1957, 1853, + 55594, -1000, 1911, -1000, -1000, -1000, -305, -333, 2108, 1432, + 1739, -1000, -1000, -1000, -1000, 1975, 22334, -1000, -1000, 2557, + -1000, 28842, 838, 2553, 49810, -1000, 457, 457, 1876, 420, + 8, -1000, -1000, -1000, -1000, 978, 36073, -1000, -1000, -1000, + -1000, -1000, 1749, 55594, -1000, -1000, 5471, 1350, -1000, 1980, + -1000, 1743, -1000, 1936, 22334, 1999, 771, 1350, 519, 502, + 472, -1000, -59, -1000, -1000, -1000, -1000, -1000, -1000, 947, + 947, 947, -1000, 333, 2500, 4124, 5503, -1000, -1000, -1000, + 49087, 1978, 1350, -1000, 1974, -1000, 1066, 841, 863, 863, + 1350, -1000, -1000, 54871, 1350, 1064, 1062, 1350, 1350, 54148, + 54148, -1000, 48364, -1000, 47641, 46918, 1355, 54148, 46195, 45472, + 44749, 44026, 43303, -1000, 2260, -1000, 2398, -1000, -1000, -1000, + 54871, 1350, 1350, 54871, 54148, 54871, 55594, 1350, -1000, -1000, + 359, -1000, -1000, 1354, 1353, 1352, 947, 947, 1349, 1736, + 1731, 1720, 947, 947, 1344, 1718, 38242, 1717, 284, 1343, + 1341, 1337, 1323, 1716, 203, 1714, 1285, 1282, 1334, 54148, + 1973, 55594, -1000, 251, 1037, 437, 977, 2298, 2212, 1875, + 480, 768, 1350, 454, 454, 54148, -1000, 15808, 55594, 225, + -1000, 1708, 22334, -1000, 1083, 1082, 1082, -1000, -1000, -1000, + -1000, -1000, -1000, 1084, 55594, 1083, -1000, -1000, -1000, 1082, + 1084, 55594, 1084, 1084, 1084, 1084, 1082, 1082, 1082, 1084, + 55594, 55594, 55594, 55594, 55594, 55594, 55594, 55594, 55594, 15079, + 935, 1084, -439, -1000, 1687, -1000, -1000, -1000, 2087, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7366,328 +7434,330 @@ 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, 14459, 14459, -1000, -1000, - -1000, -1000, -1000, 1882, -1000, 174, 19, 187, -1000, 41922, - 518, 938, -1000, 518, -1000, -1000, -1000, 1875, 41200, -1000, - -441, -442, -448, -449, -1000, -1000, -1000, -451, -455, -1000, - -1000, -1000, 21704, 21704, 21704, 21704, -238, -1000, 1191, 23870, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21704, 251, 941, - 23870, 23870, 23870, 23870, 23870, 23870, 23870, 25314, 24592, 23870, - 23870, 23870, 23870, 23870, 23870, -1000, -1000, 33258, 3221, 3221, - 873, 873, 873, 873, -1000, -164, 1872, 54196, -1000, -1000, - -1000, 815, 21704, 21704, 873, -1000, 1347, 1289, 18816, 20982, - 20982, 21704, 945, 1263, 54196, 21704, -1000, 1506, -1000, -1000, - -1000, -1000, 1159, -1000, -1000, 1043, 2309, 2309, 2309, 2309, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 2309, 21704, 213, 213, 1731, 21704, 21704, 21704, 21704, 21704, - 21704, 17371, 21704, 21704, 23870, 21704, 21704, 21704, 1506, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 1506, 21704, - 1418, 21704, 21704, 21704, 21704, 21704, 21704, 20982, 16643, 20982, - 20982, 20982, 20982, 20982, -1000, -1000, -1000, -1000, -1000, -1000, - 21704, 21704, 21704, 21704, 21704, 21704, 21704, 21704, 1506, 21704, - 21704, 21704, 21704, 21704, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1545, 1520, 1459, 21704, -1000, 1871, - -1000, -184, 30370, 21704, 1633, 2528, 2014, 53474, -1000, -1000, - -1000, -1000, 2451, -1000, 2451, 1545, 3299, 2202, 20982, -1000, - -1000, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1740, -1000, 54918, 1870, 2402, 53474, -1000, -268, -1000, -274, - 2194, 1626, 341, -1000, 21704, 21704, 1867, -1000, 2124, 54918, - -1000, -238, -1000, 40478, -1000, -1000, 13731, 54918, 358, 54918, - -1000, 29648, 39756, 304, -1000, 33, 1854, -1000, 23, 12, - 18093, 866, -1000, -1000, -1000, 1319, 26036, 1785, 866, 116, - -1000, -1000, -1000, 1931, -1000, 1931, 1931, 1931, 1931, 341, - 341, 341, 341, -1000, -1000, -1000, -1000, -1000, 1974, 1972, - -1000, 1931, 1931, 1931, 1931, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1969, 1969, 1969, 1967, 1967, 1949, 1949, 444, - -1000, 21704, 397, 39034, 2347, 1275, 1243, 262, 454, 2013, - 1347, 1347, 1347, 454, -1000, 1421, 1390, 1376, -1000, -509, - 1865, -1000, -1000, 2487, -1000, -1000, 905, 1050, 1042, 959, - 53474, 228, 348, -1000, 435, -1000, 39034, 1347, 994, 865, - 1347, -1000, 1347, -1000, -1000, -1000, -1000, -1000, 1347, -1000, - -1000, 1864, -1000, 1787, 1156, 1036, 1062, 987, 1864, -1000, - -1000, -173, 1864, -1000, 1864, -1000, 1864, -1000, 1864, -1000, - 1864, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 991, 300, -325, 53474, 228, 467, -1000, 466, 33258, -1000, - -1000, -1000, 33258, 33258, -1000, -1000, -1000, -1000, 1624, 1620, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 15079, 15079, -1000, -1000, + -1000, -1000, -1000, 1870, -1000, 178, 31, 185, -1000, 42580, + 474, 976, -1000, 474, -1000, -1000, -1000, 1868, 41857, -1000, + -441, -442, -445, -447, -1000, -1000, -1000, -450, -457, -1000, + -1000, -1000, 22334, 22334, 22334, 22334, -239, -1000, 1172, 24503, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22334, 224, 987, + 24503, 24503, 24503, 24503, 24503, 24503, 24503, 25949, 25226, 24503, + 24503, 24503, 24503, 24503, 24503, -1000, -1000, 33904, 4605, 4605, + 907, 907, 907, 907, -1000, -177, 1865, 54871, -1000, -1000, + -1000, 837, 22334, 22334, 907, -1000, 1350, 1137, 19442, 21611, + 21611, 22334, 986, 1179, 54871, 22334, -1000, 1483, -1000, -1000, + -1000, -1000, 1248, -1000, -1000, 1063, 2293, 2293, 2293, 2293, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 2293, 22334, 169, 169, 714, 22334, 22334, 22334, 22334, 22334, + 22334, 17995, 22334, 22334, 24503, 22334, 22334, 22334, 1483, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 1483, 22334, + 1264, 22334, 22334, 22334, 22334, 22334, 22334, 21611, 17266, 21611, + 21611, 21611, 21611, 21611, -1000, -1000, -1000, -1000, -1000, -1000, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 1483, 22334, + 22334, 22334, 22334, 22334, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1520, 1529, 1482, 22334, -1000, 1864, + -1000, -180, 31012, 22334, 1616, 2552, 2012, 54148, -1000, -1000, + -1000, -1000, 2434, -1000, 2434, 1520, 2755, 2132, 21611, -1000, + -1000, 2755, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1741, -1000, 55594, 1853, 2375, 54148, -1000, -284, -1000, -290, + 2128, 1611, 346, -1000, 22334, 22334, 1852, -1000, 1345, 55594, + -1000, -239, -1000, 41134, -1000, -1000, 14350, 55594, 337, 55594, + -1000, 30289, 40411, 316, -1000, 8, 1831, -1000, 26, 21, + 18718, 891, -1000, -1000, -1000, 2008, 26672, 1800, 891, 101, + -1000, -1000, -1000, 1936, -1000, 1936, 1936, 1936, 1936, 346, + 346, 346, 346, -1000, -1000, -1000, -1000, -1000, 1968, 1964, + -1000, 1936, 1936, 1936, 1936, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -500, - 54918, -1000, 235, 936, 333, 318, 322, 54918, 226, 2441, - 2439, 2434, 2433, 2409, 250, 325, 54918, 54918, 452, 2074, - 54918, 2365, 54918, -1000, -1000, -1000, -1000, -1000, 1613, 1602, - -1000, 1263, 54918, -1000, -1000, 1091, 1091, -1000, -1000, 54918, - 1091, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1091, + -1000, -1000, 1959, 1959, 1959, 1951, 1951, 1937, 1937, 441, + -1000, 22334, 395, 39688, 2353, 1331, 2181, 251, 463, 2005, + 1350, 1350, 1350, 463, -1000, 1427, 1425, 1422, -1000, -519, + 1849, -1000, -1000, 2496, -1000, -1000, 890, 1138, 1097, 1002, + 54148, 228, 313, -1000, 442, -1000, 39688, 1350, 1054, 863, + 1350, -1000, 1350, -1000, -1000, -1000, -1000, -1000, 1350, -1000, + -1000, 1846, -1000, 1843, 1168, 1092, 1163, 1089, 1846, -1000, + -1000, -175, 1846, -1000, 1846, -1000, 1846, -1000, 1846, -1000, + 1846, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 991, 325, -358, 54148, 228, 479, -1000, 469, 33904, -1000, + -1000, -1000, 33904, 33904, -1000, -1000, -1000, -1000, 1604, 1592, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 54918, -1000, -1000, -1000, -1000, - -27, 170, -1000, -1000, 53474, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -105, -1000, 255, 16, 416, -1000, - -1000, -1000, -1000, -1000, 2421, -1000, 1263, 986, 976, -1000, - 1897, -1000, -1000, 1176, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 251, 23870, 23870, 23870, 1304, 822, 1410, 1456, - 1317, 904, 904, 1132, 23870, 1132, 23870, 877, 877, 877, - 877, 877, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1598, -1000, 1897, 54196, 1727, 16643, 1496, 2842, 1506, 890, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -503, + 55594, -1000, 246, 968, 277, 374, 296, 55594, 377, 2428, + 2427, 2420, 2408, 2405, 2392, 250, 276, 55594, 55594, 454, + 2064, 55594, 2358, 55594, -1000, -1000, -1000, -1000, -1000, 1590, + 1585, -1000, 1179, 55594, -1000, -1000, 1084, 1084, -1000, -1000, + 55594, 1084, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1084, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 55594, -1000, -1000, -1000, + -1000, -25, 175, -1000, -1000, 54148, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -103, -1000, 301, 18, 367, + -1000, -1000, -1000, -1000, -1000, 2431, -1000, 1179, 1010, 1041, + -1000, 1883, -1000, -1000, 1246, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 224, 24503, 24503, 24503, 1572, 806, 1484, + 1159, 1613, 937, 937, 901, 24503, 901, 24503, 911, 911, + 911, 911, 911, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1583, -1000, 1883, 54871, 1703, 17266, 1541, 1755, 1483, + 923, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 4252, 1711, -1000, 1711, 1805, 961, -1000, 21704, 1506, 4247, - -1000, -1000, 1506, 1506, 21704, -1000, -1000, 21704, 21704, 21704, - 21704, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - 1243, 21704, 1243, 1863, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 4131, 1679, -1000, 1679, 1332, 994, -1000, 22334, 1483, + 4125, -1000, -1000, 1483, 1483, 22334, -1000, -1000, 22334, 22334, + 22334, 22334, 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, + 2181, 2181, 22334, 2181, 1839, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1861, 2527, 1415, 1243, 1243, 1243, 1243, 1243, - 21704, 1783, -1000, -1000, -1000, 1527, 4196, 1225, 4190, 1243, - 1243, -1000, 1243, 4183, 4166, 1506, 1807, 2869, 2862, 1243, - 1243, 1243, 1243, 1243, 2812, 2741, 1243, 1243, 2685, 1243, - 4162, 1243, 2679, 2660, 2649, 2639, 2621, 2616, 2599, 2593, - 2589, 2581, 2577, 2572, 2516, 2499, 2495, 2491, 2486, 2469, - 1243, 1243, 1243, 4158, 1243, 4153, 1243, 4149, 1243, 1243, - 4143, 2456, 2452, 1506, 1858, -1000, 4133, 1243, 4124, 4119, - 4105, 2425, 4100, 3884, 3866, 1243, 1243, 1243, 2420, 3860, - 3852, 3831, 3827, 3823, 3818, 3810, 3498, 3484, 1243, 1459, - 1459, 1459, 1459, 1459, 3480, -240, 1243, 1506, -1000, -1000, - -1000, -1000, -1000, 3467, 2412, 3463, 3456, 3395, 3389, 1506, - 1855, 1897, 814, -1000, -1000, 1711, 1506, 1506, 1711, 1711, - 3385, 3376, 3356, 3303, 3255, 3185, 1243, 1243, -1000, 1243, - 3029, 3025, 2391, 2354, 1506, -1000, 1459, 54918, -1000, -431, - -1000, 4, 960, 1897, -1000, 37590, 1506, -1000, 4165, -1000, - 1157, -1000, -1000, -1000, -1000, -1000, 34702, 1782, 3299, -1000, - -1000, 1897, 1705, -1000, -1000, -1000, -1000, 341, 76, 33980, - 870, 870, 129, 1263, 1263, 21704, -1000, -1000, -1000, -1000, - -1000, -1000, 804, 2505, 400, 1897, -1000, 1788, 2093, -1000, - -1000, -1000, 2399, 27481, -1000, -1000, 1897, 1897, 54918, 1820, - 1790, -1000, 803, -1000, 1349, 1854, 33, 9, -1000, -1000, - -1000, -1000, 1263, -1000, 1358, 360, 1394, -1000, 439, -1000, - -1000, -1000, -1000, 2292, 88, -1000, -1000, -1000, 787, 341, - -1000, -1000, -1000, -1000, -1000, -1000, 1595, 1595, -1000, -1000, - -1000, -1000, -1000, 1274, -1000, -1000, -1000, -1000, 1273, -1000, - -1000, 1272, -1000, -1000, 2165, 2044, 397, -1000, -1000, 928, - 1581, -1000, -1000, 2295, 928, 928, 53474, -1000, -1000, 1662, - 2347, 235, 54918, 964, 2073, -1000, 2013, 2013, 2013, 54918, - -1000, -1000, -1000, -1000, -1000, -1000, -511, 165, 382, -1000, - -1000, -1000, 5045, 53474, 1703, -1000, 221, -1000, 1640, -1000, - 53474, -1000, 1701, 1965, 1347, 1347, -1000, -1000, -1000, 53474, - 1897, -1000, -1000, -1000, -1000, 490, 2330, 347, -1000, -1000, - -258, -1000, -1000, 228, 221, 54196, 1347, 866, -1000, -1000, - -1000, -1000, -1000, -503, 1697, 480, 222, 489, 54918, 54918, - 54918, 54918, 54918, 54918, 785, -1000, -1000, 35, -1000, -1000, - 198, -1000, -1000, -1000, -1000, 198, -1000, -1000, -1000, -1000, - 314, 458, -1000, 54918, 54918, 924, -1000, -1000, -1000, -1000, - -1000, 1044, -1000, -1000, 1044, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2315, 54918, 11, - -470, -1000, -467, 21704, -1000, -1000, -1000, -1000, 1149, 798, - 1410, 23870, 23870, 1289, 1289, 23870, -1000, -1000, -1000, 832, - 832, 33258, -1000, 23870, 21704, 20982, -1000, -1000, 21704, 21704, - 947, -1000, 21704, 1359, -1000, 21704, -1000, -1000, 1459, 1243, - 1243, 1243, 1243, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1789, -1000, 21704, 21704, 21704, 1506, 309, - -1000, -1000, -1000, -1000, -1000, 2521, -1000, 21704, -1000, 33258, - 21704, 21704, 21704, -1000, -1000, -1000, 21704, 21704, -1000, -1000, - 21704, -1000, 21704, -1000, -1000, -1000, -1000, -1000, -1000, 21704, - -1000, 21704, -1000, -1000, -1000, 21704, -1000, 21704, -1000, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, -1000, 21704, -1000, 21704, -1000, 21704, - -1000, 21704, 21704, -1000, 21704, 21704, 21704, -1000, 21704, 21704, - 21704, 21704, -1000, -1000, -1000, -1000, 21704, 21704, 21704, 21704, - 21704, 21704, 21704, 21704, 21704, 21704, -1000, -1000, -1000, -1000, - -1000, -1000, 21704, -1000, 39034, 53, -240, 1418, 53, 1418, - 23148, 823, 786, 22426, -1000, 20982, 15915, -1000, -1000, -1000, - -1000, -1000, 21704, 21704, 21704, 21704, 21704, 21704, -1000, -1000, - -1000, 21704, 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, - -1000, -1000, 960, -1000, 865, 865, 865, 53474, -1000, -1000, - -1000, -1000, 1848, -1000, 2438, -1000, 2232, 2224, 2520, 2505, - -1000, 29648, 3299, -1000, -1000, 53474, -419, -1000, 2273, 2240, - 870, 870, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13003, - 2451, 21704, 2072, 54196, 253, -1000, 28926, 53474, 54196, 29648, - 29648, 29648, 29648, 29648, -1000, 2103, 2101, -1000, 2133, 2125, - 2134, 54918, -1000, 1545, 1689, -1000, 21704, 31814, 1829, 29648, - -1000, -1000, 29648, 54918, 12275, -1000, -1000, 10, -3, -1000, - -1000, -1000, -1000, 1319, -1000, -1000, 927, 2386, 2283, -1000, - -1000, -1000, -1000, -1000, 1677, -1000, 1675, 1844, 1673, 1661, - 300, -1000, 1997, 2313, 928, 928, -1000, 1271, -1000, 1347, - 1564, 1560, -1000, -1000, -1000, 478, -1000, 2363, 54918, 2071, - 2070, 2054, -1000, -521, 1269, 1963, 1910, 21704, 1959, 2485, - 1832, 53474, -1000, -1000, 54196, -1000, 274, -1000, 397, 53474, - -1000, -1000, -1000, 348, 54918, -1000, 7141, -1000, -1000, -1000, - 221, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 54918, 258, - -1000, 1955, 1195, -1000, -1000, 1990, -1000, -1000, -1000, -1000, - -1000, 223, 197, 1547, 201, 1524, 201, -1000, 54918, 921, - 2044, 54918, -1000, -1000, -1000, 1091, 1091, -1000, -1000, 2310, - -1000, 1347, 1243, 23870, 23870, -1000, 873, -1000, -1000, 419, - -216, 1931, 1931, -1000, 1931, 1949, -1000, 1931, 154, 1931, - 138, 1931, -1000, -1000, 1506, 1506, -1000, 1459, -1000, 2346, - 1114, -1000, 1263, 21704, 3020, -1000, -1000, -1000, -1000, -1000, - -60, 2979, 2963, 1243, -1000, 1929, 1927, 21704, 1243, 1506, - 2312, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - 1243, 1243, 1243, 2308, 2298, 2280, 2275, 2271, 2267, 2239, - 2211, 2198, 2189, 2056, 1994, 1981, 1977, 1946, 1915, 1243, - 1243, 1905, 1243, 1901, 1822, -1000, 1263, 1459, 2952, 1459, - 1243, 1243, 2915, 343, 1243, 1637, 1637, 1637, 1637, 1637, - 1459, 1459, 1459, 1459, 1243, 53474, -1000, -240, -1000, -1000, - -312, -316, -1000, 1506, -240, 1840, 23870, 1243, 23870, 23870, - 23870, 1243, 1506, -1000, 1814, 1791, 2892, 1754, 1243, 2746, - 1243, 1243, 1243, 1718, -1000, 2403, 2403, 2403, 1617, 1157, - 54918, -1000, -1000, -1000, -1000, 2505, 2459, 1834, -1000, -1000, - 76, 614, -1000, 2266, 2240, -1000, 2484, 2260, 2482, -1000, - -1000, -1000, -1000, -1000, 1263, -1000, 2339, 1804, -1000, 932, - 1812, -1000, -1000, 20260, 1631, 2210, 797, 1617, 1853, 2093, - 2007, 2048, 3006, -1000, -1000, -1000, -1000, 2092, -1000, 2068, - -1000, -1000, 1913, -1000, 2696, 358, 29648, 1851, 1851, -1000, - 537, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1063, 7141, - 2540, -1000, 1502, -1000, 1346, 205, 1250, -1000, -1000, 928, - 928, -1000, 993, 992, -1000, 54918, 1926, -1000, 341, 1498, - 341, 1234, -1000, -1000, 1233, -1000, -1000, -1000, -1000, 2055, - 2075, -1000, -1000, -1000, -1000, 54918, -1000, -1000, 54918, 54918, - 54918, 1923, 2478, -1000, 21704, 1922, 931, 2153, 53474, 53474, + -1000, -1000, -1000, 1838, 2551, 1523, 2181, 2181, 2181, 2181, + 2181, 22334, 1528, -1000, -1000, -1000, 1431, 4121, 1559, 4099, + 2181, 2181, -1000, 2181, 3887, 3883, 1483, 1811, 2655, 2646, + 2181, 2181, 2181, 2181, 2181, 2634, 2614, 2181, 2181, 2609, + 2181, 3864, 2181, 2596, 2540, 2535, 2515, 2505, 2493, 2467, + 2449, 2437, 2417, 2410, 2406, 2391, 2372, 2360, 2334, 2323, + 2316, 2181, 2181, 2181, 3853, 2181, 3826, 2181, 3820, 2181, + 2181, 3815, 2303, 2285, 1483, 1837, -1000, 3512, 2181, 3504, + 3487, 3470, 2247, 3466, 3459, 3451, 2181, 2181, 2181, 2228, + 3436, 3417, 3390, 3380, 3358, 3345, 3305, 3058, 3026, 2181, + 1482, 1482, 1482, 1482, 1482, 3021, -242, 2181, 1483, -1000, + -1000, -1000, -1000, -1000, 3002, 2220, 2981, 2973, 2968, 2951, + 1483, 1836, 1883, 834, -1000, -1000, 1679, 1483, 1483, 1679, + 1679, 2941, 2912, 2898, 2894, 2879, 2868, 2181, 2181, -1000, + 2181, 2833, 2777, 2215, 2208, 1483, -1000, 1482, 55594, -1000, + -430, -1000, 12, 974, 1883, -1000, 38242, 1483, -1000, 4966, + -1000, 1250, -1000, -1000, -1000, -1000, -1000, 35350, 1781, 2755, + -1000, -1000, 1883, 1677, -1000, -1000, -1000, -1000, 346, 81, + 34627, 888, 888, 120, 1179, 1179, 22334, -1000, -1000, -1000, + -1000, -1000, -1000, 833, 2511, 403, 1883, -1000, 1872, 2135, + -1000, -1000, -1000, 2373, 28119, -1000, -1000, 1883, 1883, 55594, + 1780, 1757, -1000, 822, -1000, 1367, 1831, 8, 4, -1000, + -1000, -1000, -1000, 1179, -1000, 1406, 341, 1447, -1000, 440, + -1000, -1000, -1000, -1000, 2230, 95, -1000, -1000, -1000, 361, + 346, -1000, -1000, -1000, -1000, -1000, -1000, 1579, 1579, -1000, + -1000, -1000, -1000, -1000, 1328, -1000, -1000, -1000, -1000, 1304, + -1000, -1000, 1303, -1000, -1000, 2742, 1995, 395, -1000, -1000, + 947, 1577, -1000, -1000, 2234, 947, 947, 54148, -1000, -1000, + 1792, 2353, 246, 55594, 999, 2061, -1000, 2005, 2005, 2005, + 55594, -1000, -1000, -1000, -1000, -1000, -1000, -509, 164, 572, + -1000, -1000, -1000, 4281, 54148, 1673, -1000, 218, -1000, 1771, + -1000, 54148, -1000, 1669, 1950, 1350, 1350, -1000, -1000, -1000, + 54148, 1883, -1000, -1000, -1000, -1000, 764, 2290, 357, -1000, + -1000, -263, -1000, -1000, 228, 218, 54871, 1350, 891, -1000, + -1000, -1000, -1000, -1000, -502, 1665, 499, 234, 328, 55594, + 55594, 55594, 55594, 55594, 55594, 814, -1000, -1000, 44, -1000, + -1000, 205, -1000, -1000, -1000, -1000, -1000, 205, -1000, -1000, + -1000, -1000, -1000, 268, 467, -1000, 55594, 55594, 956, -1000, + -1000, -1000, -1000, -1000, 1082, -1000, -1000, 1082, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 456, 928, -484, 320, 311, 928, 928, 928, -525, - -1000, -1000, 1610, 1577, -1000, -190, -1000, 21704, -1000, -1000, - -1000, -1000, -1000, 1241, 1241, 1482, 1480, 1475, -1000, 1913, - -1000, -1000, -1000, 1632, -1000, -1000, -180, 53474, 53474, 53474, - 53474, -1000, -1000, -1000, 1100, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 873, 1506, 345, - -189, 1506, -1000, -1000, 341, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 21704, -1000, 21704, -1000, 1263, - 21704, 2451, 1469, 21704, 21704, -1000, 1230, 1213, 1243, -1000, - -1000, -1000, 21704, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, - 21704, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, 21704, - -1000, -1000, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, - -1000, 21704, 234, 832, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1506, 351, -1000, -1000, -1000, - -1000, 2515, -1000, 1506, 21704, 1289, -1000, 1289, 1289, 1289, - -1000, -1000, -1000, 21704, -1000, 21704, 21704, -1000, 21704, -1000, - 21704, -1000, -1000, -1000, -1000, 21704, 1897, 2294, 1897, 1897, - 31814, -1000, -1000, 2459, 2501, 2473, 2237, 2245, 2245, 2266, - -1000, 2467, 2458, -1000, 1466, 2457, 1452, 975, -1000, 54196, - 21704, 253, -1000, 404, 53474, 253, 53474, -1000, 2498, -1000, - -1000, 21704, 1921, -1000, 21704, -1000, -1000, -1000, -1000, 3221, - 2505, 1851, -1000, -1000, 884, -1000, 21704, -1000, 9991, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1441, 1436, -1000, - -1000, 1920, 21704, -1000, -1000, -1000, 1611, 1578, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1913, -1000, -1000, -1000, - -1000, 348, -516, 2118, 53474, 1190, -1000, 1575, 1832, 337, - 253, 1434, 928, 928, 928, 1122, 1105, 37590, 1571, -1000, - 53474, 429, -1000, 348, -1000, -209, -213, 1243, -1000, -1000, - 2378, -1000, -1000, 15915, -1000, -1000, 1908, 2003, -1000, -1000, - -1000, -1000, 2167, -167, -198, -1000, -1000, 1243, 1243, 2161, - 1506, -1000, 1243, 1243, 1572, 1553, -1000, 1243, 1243, 1243, - 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1459, 1685, -1000, - 234, 1506, 2041, -1000, -1000, 3221, -1000, -1000, 2498, 2455, - 53, -1000, -1000, 240, 53, 1263, 968, 1506, 1506, 968, - 1639, 1243, 1629, 1569, 1243, 1243, 32536, -1000, 2454, 2442, - 38312, 38312, 960, 2501, -248, 21704, 21704, 2214, 1214, -1000, - -1000, -1000, -1000, 1426, 1407, -1000, 1404, -1000, 2538, -1000, - 1263, -1000, 253, -1000, 526, 1812, -1000, 2451, 1263, 53474, - 1263, 73, 2498, -1000, 1243, -1000, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, - 1897, 1897, 1897, 1897, 1897, -1000, -1000, 53474, 1987, -1000, - -1000, 2377, 1552, 163, -1000, 1511, 1832, -1000, -1000, 220, - -1000, 21704, -1000, 37590, 1378, 1363, -1000, -1000, -1000, -1000, - -525, -1000, -1000, -1000, -1000, -1000, -1000, 415, 1830, -1000, - 918, 53474, 54918, -1000, 2128, -1000, -1000, -1000, 21704, -1000, + 2272, 55594, 5, -471, -1000, -467, 22334, -1000, -1000, -1000, + -1000, 1295, 471, 1484, 24503, 24503, 1137, 1137, 24503, -1000, + -1000, -1000, 1018, 1018, 33904, -1000, 24503, 22334, 21611, -1000, + -1000, 22334, 22334, 981, -1000, 22334, 1283, -1000, 22334, -1000, + -1000, 1482, 2181, 2181, 2181, 2181, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1863, -1000, 22334, 22334, + 22334, 1483, 309, -1000, -1000, -1000, -1000, -1000, 2550, -1000, + 22334, -1000, 33904, 22334, 22334, 22334, -1000, -1000, -1000, 22334, + 22334, -1000, -1000, 22334, -1000, 22334, -1000, -1000, -1000, -1000, + -1000, -1000, 22334, -1000, 22334, -1000, -1000, -1000, 22334, -1000, + 22334, -1000, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, -1000, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, -1000, 22334, -1000, + 22334, -1000, 22334, -1000, 22334, 22334, -1000, 22334, 22334, 22334, + -1000, 22334, 22334, 22334, 22334, -1000, -1000, -1000, -1000, 22334, + 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, 22334, -1000, + -1000, -1000, -1000, -1000, -1000, 22334, -1000, 39688, 74, -242, + 1264, 74, 1264, 23780, 842, 815, 23057, -1000, 21611, 16537, + -1000, -1000, -1000, -1000, -1000, 22334, 22334, 22334, 22334, 22334, + 22334, -1000, -1000, -1000, 22334, 22334, -1000, 22334, -1000, 22334, + -1000, -1000, -1000, -1000, -1000, 974, -1000, 863, 863, 863, + 54148, -1000, -1000, -1000, -1000, 1829, -1000, 2383, -1000, 2159, + 2155, 2539, 2511, -1000, 30289, 2755, -1000, -1000, 54148, -422, + -1000, 2206, 2179, 888, 888, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 13621, 2434, 22334, 2059, 54871, 240, -1000, 29566, + 54148, 54871, 30289, 30289, 30289, 30289, 30289, -1000, 2096, 2081, + -1000, 2189, 2173, 2259, 55594, -1000, 1520, 1662, -1000, 22334, + 32458, 1802, 30289, -1000, -1000, 30289, 55594, 12892, -1000, -1000, + -4, -5, -1000, -1000, -1000, -1000, 2008, -1000, -1000, 940, + 2371, 2225, -1000, -1000, -1000, -1000, -1000, 1660, -1000, 1647, + 1828, 1631, 1629, 325, -1000, 1987, 2271, 947, 947, -1000, + 1301, -1000, 1350, 1574, 1571, -1000, -1000, -1000, 498, -1000, + 2357, 55594, 2055, 2052, 2044, -1000, -516, 1292, 1949, 1910, + 22334, 1941, 2491, 1822, 54148, -1000, -1000, 54871, -1000, 275, + -1000, 395, 54148, -1000, -1000, -1000, 313, 55594, -1000, 9344, + -1000, -1000, -1000, 218, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 55594, 233, -1000, 1940, 1336, -1000, -1000, 1984, -1000, + -1000, -1000, -1000, -1000, 209, 194, 1570, 198, 1558, 198, + -1000, 55594, 934, 1995, 55594, -1000, -1000, -1000, 1084, 1084, + -1000, -1000, 2249, -1000, 1350, 2181, 24503, 24503, -1000, 907, + -1000, -1000, 427, -221, 1936, 1936, -1000, 1936, 1937, -1000, + 1936, 173, 1936, 172, 1936, -1000, -1000, 1483, 1483, -1000, + 1482, -1000, 2191, 2170, -1000, 1179, 22334, 2736, -1000, -1000, + -1000, -1000, -1000, -65, 2728, 2622, 2181, -1000, 1931, 1930, + 22334, 2181, 1483, 2158, 2181, 2181, 2181, 2181, 2181, 2181, + 2181, 2181, 2181, 2181, 2181, 2181, 2145, 2133, 2126, 2122, + 2112, 2101, 2095, 2083, 2039, 2003, 1991, 1982, 1961, 1953, + 1946, 1942, 2181, 2181, 1914, 2181, 1905, 1866, -1000, 1179, + 1482, 2566, 1482, 2181, 2181, 2497, 291, 2181, 1614, 1614, + 1614, 1614, 1614, 1482, 1482, 1482, 1482, 2181, 54148, -1000, + -242, -1000, -1000, -301, -307, -1000, 1483, -242, 1826, 24503, + 2181, 24503, 24503, 24503, 2181, 1483, -1000, 1847, 1832, 2348, + 1819, 2181, 2277, 2181, 2181, 2181, 1805, -1000, 2395, 2395, + 2395, 1602, 1250, 55594, -1000, -1000, -1000, -1000, 2511, 2470, + 1823, -1000, -1000, 81, 557, -1000, 2238, 2179, -1000, 2490, + 2192, 2487, -1000, -1000, -1000, -1000, -1000, 1179, -1000, 2306, + 1784, -1000, 964, 1812, -1000, -1000, 20888, 1610, 2140, 816, + 1602, 1861, 2135, 2020, 2042, 3257, -1000, -1000, -1000, -1000, + 2080, -1000, 2077, -1000, -1000, 1911, -1000, 2054, 337, 30289, + 1851, 1851, -1000, 803, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1169, 9344, 2574, -1000, 1518, -1000, 1399, 192, 1288, + -1000, -1000, 947, 947, -1000, 1052, 1047, -1000, 55594, 1928, + -1000, 346, 1516, 346, 1284, -1000, -1000, 1280, -1000, -1000, + -1000, -1000, 1990, 2107, -1000, -1000, -1000, -1000, 55594, -1000, + -1000, 55594, 55594, 55594, 1927, 2484, -1000, 22334, 1926, 949, + 2686, 54148, 54148, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 412, 947, -483, 274, 273, 947, + 947, 947, -517, -1000, -1000, 1597, 1557, -1000, -211, -1000, + 22334, -1000, -1000, -1000, -1000, -1000, 1296, 1296, 1478, 1470, + 1468, -1000, 1911, -1000, -1000, -1000, 1713, -1000, -1000, -186, + 54148, 54148, 54148, 54148, -1000, -1000, -1000, 1222, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 907, 1483, 371, -189, 1483, -1000, -1000, 346, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22334, -1000, + 22334, -1000, 1179, 22334, 2434, 1466, 22334, 22334, -1000, 1279, + 1274, 2181, -1000, -1000, -1000, 22334, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, -1000, 22334, -1000, -1000, -1000, 22334, -1000, 22334, -1000, + 22334, -1000, -1000, -1000, 22334, 207, 1018, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1483, 336, + -1000, -1000, -1000, -1000, 2536, -1000, 1483, 22334, 1137, -1000, + 1137, 1137, 1137, -1000, -1000, -1000, 22334, -1000, 22334, 22334, + -1000, 22334, -1000, 22334, -1000, -1000, -1000, -1000, 22334, 1883, + 2342, 1883, 1883, 32458, -1000, -1000, 2470, 2499, 2476, 2176, + 2195, 2195, 2238, -1000, 2469, 2458, -1000, 1463, 2455, 1460, + 1016, -1000, 54871, 22334, 240, -1000, 423, 54148, 240, 54148, + -1000, 2438, -1000, -1000, 22334, 1925, -1000, 22334, -1000, -1000, + -1000, -1000, 4605, 2511, 1851, -1000, -1000, 920, -1000, 22334, + -1000, 10600, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1448, 1439, -1000, -1000, 1924, 22334, -1000, -1000, -1000, 1704, + 1686, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1911, + -1000, -1000, -1000, -1000, 313, -511, 2659, 54148, 1262, -1000, + 1555, 1822, 295, 240, 1412, 947, 947, 947, 1255, 1254, + 38242, 1551, -1000, 54148, 385, -1000, 313, -1000, -216, -218, + 2181, -1000, -1000, 2367, -1000, -1000, 16537, -1000, -1000, 1904, + 1994, -1000, -1000, -1000, -1000, 2117, -173, -203, -1000, -1000, + 2181, 2181, 2035, 1483, -1000, 2181, 2181, 1680, 1632, -1000, + 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, + 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2181, + 1482, 1790, -1000, 207, 1483, 2037, -1000, -1000, 4605, -1000, + -1000, 2438, 2452, 74, -1000, -1000, 220, 74, 1179, 1014, + 1483, 1483, 1014, 1712, 2181, 1685, 1675, 2181, 2181, 33181, + -1000, 2447, 2444, 38965, 38965, 974, 2499, -253, 22334, 22334, + 2161, 1219, -1000, -1000, -1000, -1000, 1409, 1403, -1000, 1390, + -1000, 2565, -1000, 1179, -1000, 240, -1000, 802, 1812, -1000, + 2434, 1179, 54148, 1179, 82, 2438, -1000, 2181, -1000, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, + 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, -1000, -1000, + 54148, 2642, -1000, -1000, 2362, 1533, 162, -1000, 1534, 1822, + -1000, -1000, 223, -1000, 22334, -1000, 38242, 1388, 1381, -1000, + -1000, -1000, -1000, -517, -1000, -1000, -1000, -1000, -1000, -1000, + 428, 1816, -1000, 942, 54148, 55594, -1000, 2110, -1000, -1000, + -1000, 22334, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 21704, -1000, 1506, 2034, - -1000, -344, -1000, -488, 21704, -240, -1000, -1000, -240, -1000, - -1000, -1000, -1000, -1000, 21704, -1000, -1000, 21704, -1000, 21704, - -1000, -1000, 1529, -1000, -1000, -1000, -1000, -1000, 1529, 1529, - -1000, -248, -1000, 1824, -1000, 53474, 1263, 1807, -1000, 1153, - -1000, -1000, -1000, -1000, -1000, 54196, 1812, 53474, -1000, 1519, - 1506, 1897, 2451, -1000, 1479, -1000, 415, -1000, 1900, 1910, - -1000, -1000, -1000, 19538, -1000, -1000, -1000, -1000, -1000, 276, - -176, 15915, 11547, 1474, -1000, -174, 1243, 1459, -1000, -460, - -1000, -1000, -1000, -1000, 289, -1000, -1000, 1807, -1000, -1000, - 1509, 1505, 1461, 36868, -1000, -1000, -1000, -1000, -248, -1000, - -1000, 2373, -1000, -1000, 1803, -1000, -1000, 31814, 52752, -1000, - -162, 352, -176, 21704, 1899, 1506, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -34, -1000, -1000, 506, -1000, -1000, - -1000, 1990, -195, -1000, -1000, -1000, 296, -473, -264, -294, - 23870, -1000, 21704, -1000, 21704, -1000, 21704, -1000, -1000, -1000, - 53474, 1897, -1000, 1450, -1000, 1883, -336, 2033, -1000, -103, - -1000, -1000, -1000, 1052, 1360, -1000, -1000, -1000, -1000, -1000, - -1000, 1513, 53474, -1000, 441, -1000, -1000, 15187, -180, -200, - 967, -1000, -1000, -1000, -1000, -1000, 1289, 1447, 1285, 1243, - -1000, 53474, -1000, 52752, -340, 866, 3221, -1000, 2018, 2017, - 2511, -1000, -1000, -1000, -1000, -1000, -1000, -527, 1431, 260, - -1000, -1000, -1000, 296, -296, -1000, 21704, -1000, 21704, -1000, - 1506, -1000, -1000, 2362, 73, -1000, 2537, -1000, 2512, 1022, - 1022, -1000, 1092, -527, -1000, -1000, -1000, -1000, 1243, 1243, - -1000, -337, -1000, -1000, -1000, -1000, -1000, 436, 1155, -1000, - -1000, -1000, -1000, -1000, 3221, -1000, -1000, -1000, 264, 264, - -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 22334, + -1000, 1483, 2036, -1000, -359, -1000, -487, 22334, -242, -1000, + -1000, -242, -1000, -1000, -1000, -1000, -1000, 22334, -1000, -1000, + 22334, -1000, 22334, -1000, -1000, 1515, -1000, -1000, -1000, -1000, + -1000, 1515, 1515, -1000, -253, -1000, 1814, -1000, 54148, 1179, + 1811, -1000, 1217, -1000, -1000, -1000, -1000, -1000, 54871, 1812, + 54148, -1000, 1513, 1483, 1883, 2434, -1000, 1489, -1000, 428, + -1000, 1901, 1910, -1000, -1000, -1000, 20165, -1000, -1000, -1000, + -1000, -1000, 248, -184, 16537, 12163, 1487, -1000, -179, 2181, + 1482, -1000, -459, -1000, -1000, -1000, -1000, 242, -1000, -1000, + 1811, -1000, -1000, 1553, 1473, 1394, 37519, -1000, -1000, -1000, + -1000, -253, -1000, -1000, 2343, -1000, -1000, 1804, -1000, -1000, + 32458, 53425, -1000, -169, 319, -184, 22334, 1894, 1483, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -36, -1000, -1000, + 795, -1000, -1000, -1000, 1984, -193, -1000, -1000, -1000, 300, + -474, -280, -286, 24503, -1000, 22334, -1000, 22334, -1000, 22334, + -1000, -1000, -1000, 54148, 1883, -1000, 1476, -1000, 3073, -322, + 2031, -1000, -128, -1000, -1000, -1000, 1167, 1369, -1000, -1000, + -1000, -1000, -1000, -1000, 2291, 54148, -1000, 417, -1000, -1000, + 15808, -186, -209, 1032, -1000, -1000, -1000, -1000, -1000, 1137, + 1368, 1358, 2181, -1000, 54148, -1000, 53425, -315, 891, 4605, + -1000, 2029, 2023, 2548, -1000, -1000, -1000, -1000, -1000, -1000, + -524, 1458, 241, -1000, -1000, -1000, 300, -299, -1000, 22334, + -1000, 22334, -1000, 1483, -1000, -1000, 2350, 82, -1000, 2563, + -1000, 2516, 922, 922, -1000, 1242, -524, -1000, -1000, -1000, + -1000, 2181, 2181, -1000, -376, -1000, -1000, -1000, -1000, -1000, + 413, 1252, -1000, -1000, -1000, -1000, -1000, 4605, -1000, -1000, + -1000, 282, 282, -1000, -1000, } var yyPgo = [...]int{ - 0, 3091, 3090, 28, 6, 41, 35, 3089, 3088, 3087, - 177, 3086, 3085, 3082, 3081, 3078, 3071, 2619, 2615, 2586, - 3069, 3064, 3061, 3060, 3054, 3053, 3052, 3050, 3049, 40, - 108, 62, 97, 209, 197, 3048, 179, 165, 200, 3047, - 3045, 3043, 118, 192, 80, 85, 193, 3042, 3039, 73, - 3038, 3037, 3036, 191, 186, 184, 1048, 3031, 183, 112, - 48, 3030, 3027, 3026, 3025, 3022, 3021, 3020, 3019, 3017, - 3016, 3015, 3014, 3013, 3010, 3000, 2992, 2991, 2990, 284, - 2989, 2986, 21, 2981, 76, 2979, 2976, 2973, 2971, 2970, - 8, 2969, 2968, 26, 42, 2966, 2964, 47, 2963, 2962, - 2960, 2959, 2933, 69, 2932, 22, 2929, 39, 2928, 2926, - 120, 2924, 2923, 2921, 44, 2918, 2917, 2914, 29, 163, - 2913, 2912, 134, 2910, 2908, 2907, 167, 206, 2898, 2232, - 180, 105, 103, 2897, 2892, 98, 194, 2890, 117, 2885, - 2880, 2879, 147, 2876, 3197, 2875, 2872, 60, 66, 199, - 2869, 2868, 287, 64, 11, 16, 17, 2865, 2861, 61, - 72, 2859, 104, 2858, 2857, 100, 75, 2856, 96, 99, - 2855, 2854, 5, 7, 2853, 1, 4, 2, 83, 2852, - 2833, 113, 2831, 2826, 2823, 91, 2817, 2815, 4988, 2813, - 89, 127, 101, 82, 2811, 172, 155, 2810, 2809, 2808, - 2807, 2805, 49, 2801, 2798, 2797, 132, 250, 162, 2796, - 145, 335, 52, 143, 2795, 189, 77, 198, 170, 2794, - 2790, 130, 128, 2788, 2787, 56, 166, 190, 2786, 95, - 126, 115, 168, 90, 131, 2783, 2780, 54, 71, 2778, - 2777, 2776, 2775, 176, 2772, 2771, 59, 2770, 55, 2769, - 164, 2766, 136, 68, 2765, 171, 175, 2762, 135, 2754, - 2753, 67, 93, 110, 38, 2752, 158, 161, 124, 173, - 2751, 2747, 53, 2744, 2743, 2740, 195, 289, 2734, 2730, - 294, 178, 139, 146, 81, 2725, 337, 2722, 2718, 13, - 4343, 7480, 2716, 37, 160, 2713, 2711, 6837, 20, 45, - 24, 2708, 205, 2707, 2706, 2703, 2702, 212, 202, 106, - 159, 57, 2701, 2697, 2696, 36, 2694, 2693, 2690, 2686, - 2685, 2684, 70, 34, 33, 32, 211, 58, 19, 94, - 153, 152, 63, 2680, 2679, 2676, 121, 84, 2675, 157, - 154, 123, 151, 2673, 181, 142, 116, 2672, 92, 31, - 2671, 2668, 2667, 2663, 87, 2662, 2655, 2652, 2651, 149, - 140, 119, 78, 2650, 79, 114, 144, 141, 51, 2649, - 46, 2646, 2645, 30, 188, 23, 2640, 15, 102, 109, - 2636, 5948, 187, 2632, 9, 317, 156, 2630, 2627, 10, - 12, 18, 2624, 2623, 2621, 2617, 129, 2608, 2607, 2606, - 2600, 27, 50, 25, 14, 111, 74, 2590, 2578, 137, - 2577, 2570, 2561, 0, 1005, 125, 2559, 207, + 0, 3162, 3160, 31, 6, 37, 35, 3158, 3147, 3143, + 164, 3141, 3137, 3136, 3134, 3133, 3132, 2608, 2596, 2595, + 3129, 3127, 3126, 3125, 3122, 3120, 3119, 3118, 3112, 41, + 99, 60, 98, 212, 198, 3107, 180, 165, 199, 3103, + 3102, 3099, 116, 193, 82, 85, 195, 3098, 3097, 76, + 3095, 3092, 3089, 192, 191, 188, 1066, 3088, 181, 114, + 50, 3087, 3086, 3085, 3082, 3080, 3079, 3078, 3077, 3074, + 3072, 3067, 3064, 3063, 3060, 3059, 3057, 3053, 3048, 299, + 3046, 3042, 19, 3035, 78, 3033, 3032, 3028, 3027, 3023, + 11, 3020, 3012, 26, 40, 3009, 3002, 46, 3001, 2995, + 2994, 2991, 2990, 47, 2989, 21, 2988, 39, 2987, 2984, + 121, 2974, 2971, 2970, 42, 2969, 2968, 2966, 28, 163, + 2965, 2963, 138, 2962, 2961, 2953, 182, 204, 2952, 2165, + 166, 104, 106, 2947, 2946, 102, 196, 2936, 118, 2935, + 2932, 2931, 145, 2929, 3809, 2927, 2924, 73, 75, 153, + 2922, 2915, 206, 74, 8, 16, 17, 2914, 2913, 67, + 71, 2911, 101, 2910, 2909, 100, 62, 2908, 108, 97, + 2901, 2896, 5, 7, 2895, 1, 4, 2, 81, 2894, + 2893, 113, 2892, 2890, 2889, 95, 2888, 2887, 5131, 2886, + 90, 128, 103, 69, 2874, 168, 130, 2869, 2867, 2861, + 2860, 2859, 51, 2858, 2857, 2850, 135, 250, 162, 2849, + 147, 336, 53, 143, 2842, 189, 80, 200, 176, 2841, + 2839, 133, 132, 2835, 2833, 57, 169, 190, 2822, 93, + 127, 117, 171, 91, 129, 2818, 2814, 55, 61, 2813, + 2812, 2811, 2810, 177, 2809, 2807, 65, 2806, 56, 2805, + 185, 2804, 137, 68, 2803, 173, 175, 2796, 64, 2791, + 2790, 72, 96, 66, 38, 2787, 157, 161, 125, 174, + 2783, 2778, 54, 2773, 2772, 2771, 197, 304, 2770, 2769, + 290, 178, 141, 144, 89, 2768, 315, 2767, 2766, 13, + 4953, 8093, 2761, 23, 159, 2759, 2753, 7391, 43, 45, + 30, 2747, 205, 2745, 2741, 2737, 2733, 221, 202, 112, + 158, 58, 2725, 2724, 2704, 36, 2701, 2700, 2699, 2695, + 2694, 2693, 70, 34, 33, 32, 211, 59, 20, 109, + 170, 154, 77, 2689, 2688, 2687, 123, 92, 2686, 156, + 155, 124, 160, 2681, 179, 140, 119, 2679, 94, 27, + 2676, 2673, 2672, 2671, 87, 2670, 2669, 2667, 2666, 152, + 142, 120, 83, 2665, 84, 115, 150, 149, 52, 2664, + 48, 2662, 2661, 24, 194, 29, 2653, 15, 105, 110, + 2651, 6818, 184, 2643, 9, 353, 151, 2642, 2641, 10, + 12, 18, 2634, 2632, 2631, 2630, 131, 2625, 2622, 2621, + 2617, 25, 49, 22, 14, 111, 79, 2614, 2602, 139, + 2601, 2597, 2588, 0, 1005, 126, 2563, 203, } -//line sql.y:8599 +//line sql.y:8612 type yySymType struct { union any empty struct{} @@ -8432,61 +8502,62 @@ var yyR1 = [...]int{ 43, 43, 43, 43, 43, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 110, 110, 111, 111, 111, - 111, 113, 113, 113, 369, 369, 60, 60, 3, 3, - 171, 173, 174, 174, 172, 172, 172, 172, 172, 172, - 62, 62, 61, 61, 176, 175, 177, 177, 177, 1, - 1, 2, 2, 4, 4, 374, 374, 374, 374, 374, + 23, 23, 23, 23, 23, 23, 23, 110, 110, 111, + 111, 111, 111, 113, 113, 113, 369, 369, 60, 60, + 3, 3, 171, 173, 174, 174, 172, 172, 172, 172, + 172, 172, 62, 62, 61, 61, 176, 175, 177, 177, + 177, 1, 1, 2, 2, 4, 4, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 335, 335, 335, - 368, 368, 370, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 116, 115, 115, 114, 117, 117, 117, - 117, 117, 117, 117, 117, 372, 372, 372, 63, 63, - 373, 323, 324, 325, 5, 6, 349, 371, 124, 124, - 24, 39, 39, 25, 25, 25, 25, 26, 26, 64, - 67, 67, 65, 65, 65, 65, 65, 65, 65, 65, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 335, + 335, 335, 368, 368, 370, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 116, 115, 115, 114, 117, + 117, 117, 117, 117, 117, 117, 117, 372, 372, 372, + 63, 63, 373, 323, 324, 325, 5, 6, 349, 371, + 124, 124, 24, 39, 39, 25, 25, 25, 25, 26, + 26, 64, 67, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 278, 278, 287, 287, 277, - 277, 302, 302, 302, 280, 280, 280, 281, 281, 398, - 398, 398, 274, 274, 66, 66, 66, 303, 303, 303, - 303, 69, 69, 407, 407, 408, 408, 409, 409, 409, - 70, 71, 71, 305, 305, 306, 306, 72, 73, 85, - 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, - 109, 109, 109, 10, 10, 10, 10, 81, 81, 81, - 9, 9, 11, 68, 68, 75, 395, 395, 396, 397, - 397, 397, 397, 76, 78, 27, 27, 27, 27, 27, - 27, 134, 134, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 129, 129, 129, 123, 123, - 416, 79, 80, 80, 127, 127, 127, 120, 120, 120, - 126, 126, 126, 12, 12, 13, 260, 260, 14, 14, - 131, 131, 133, 133, 133, 133, 133, 135, 135, 135, - 135, 135, 135, 135, 130, 130, 132, 132, 132, 132, - 295, 295, 295, 294, 294, 165, 165, 167, 166, 166, - 168, 168, 169, 169, 169, 169, 214, 214, 191, 191, - 253, 253, 254, 254, 252, 252, 259, 259, 255, 255, - 255, 255, 262, 262, 170, 170, 170, 170, 178, 178, - 179, 179, 180, 180, 304, 304, 300, 300, 300, 299, - 299, 184, 184, 184, 186, 185, 185, 185, 185, 187, - 187, 189, 189, 188, 188, 190, 195, 195, 194, 194, - 192, 192, 192, 192, 193, 193, 193, 193, 196, 196, - 144, 144, 144, 144, 144, 144, 144, 144, 157, 157, - 157, 157, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 243, 243, 149, 149, 149, 149, 149, + 65, 65, 65, 65, 65, 65, 65, 278, 278, 287, + 287, 277, 277, 302, 302, 302, 280, 280, 280, 281, + 281, 398, 398, 398, 274, 274, 66, 66, 66, 303, + 303, 303, 303, 69, 69, 407, 407, 408, 408, 409, + 409, 409, 70, 71, 71, 305, 305, 306, 306, 72, + 73, 85, 85, 85, 85, 85, 85, 85, 86, 86, + 86, 86, 109, 109, 109, 10, 10, 10, 10, 81, + 81, 81, 9, 9, 11, 68, 68, 75, 395, 395, + 396, 397, 397, 397, 397, 76, 78, 27, 27, 27, + 27, 27, 27, 134, 134, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 129, 129, 129, + 123, 123, 416, 79, 80, 80, 127, 127, 127, 120, + 120, 120, 126, 126, 126, 12, 12, 13, 260, 260, + 14, 14, 131, 131, 133, 133, 133, 133, 133, 135, + 135, 135, 135, 135, 135, 135, 130, 130, 132, 132, + 132, 132, 295, 295, 295, 294, 294, 165, 165, 167, + 166, 166, 168, 168, 169, 169, 169, 169, 214, 214, + 191, 191, 253, 253, 254, 254, 252, 252, 259, 259, + 255, 255, 255, 255, 262, 262, 170, 170, 170, 170, + 178, 178, 179, 179, 180, 180, 304, 304, 300, 300, + 300, 299, 299, 184, 184, 184, 186, 185, 185, 185, + 185, 187, 187, 189, 189, 188, 188, 190, 195, 195, + 194, 194, 192, 192, 192, 192, 193, 193, 193, 193, + 196, 196, 144, 144, 144, 144, 144, 144, 144, 144, + 157, 157, 157, 157, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 243, 243, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 219, 219, 218, 218, 87, - 87, 87, 88, 88, 89, 89, 89, 89, 89, 90, - 90, 90, 90, 90, 90, 90, 92, 92, 91, 91, - 209, 209, 292, 292, 93, 94, 94, 97, 97, 96, - 95, 95, 101, 101, 98, 98, 100, 100, 99, 102, - 102, 103, 104, 104, 275, 275, 197, 197, 205, 205, - 205, 205, 198, 198, 198, 198, 198, 198, 198, 206, - 206, 206, 213, 207, 207, 203, 203, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, + 152, 152, 152, 152, 152, 152, 152, 219, 219, 218, + 218, 87, 87, 87, 88, 88, 89, 89, 89, 89, + 89, 90, 90, 90, 90, 90, 90, 90, 92, 92, + 91, 91, 209, 209, 292, 292, 93, 94, 94, 97, + 97, 96, 95, 95, 101, 101, 98, 98, 100, 100, + 99, 102, 102, 103, 104, 104, 275, 275, 197, 197, + 205, 205, 205, 205, 198, 198, 198, 198, 198, 198, + 198, 206, 206, 206, 213, 207, 207, 203, 203, 201, + 201, 201, 201, 201, 201, 201, 201, 201, 201, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, @@ -8505,36 +8576,35 @@ var yyR1 = [...]int{ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 202, 162, 162, - 162, 162, 224, 224, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, - 151, 163, 163, 163, 163, 164, 164, 164, 164, 164, - 164, 164, 312, 312, 118, 118, 118, 118, 118, 118, + 162, 162, 162, 162, 224, 224, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 151, 151, 163, 163, 163, 163, 164, 164, 164, + 164, 164, 164, 164, 312, 312, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, + 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 417, 417, 326, 326, 326, 204, 204, 204, - 204, 204, 125, 125, 125, 125, 125, 309, 309, 309, - 313, 313, 313, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 314, 314, - 222, 222, 121, 121, 220, 220, 221, 223, 223, 215, - 215, 215, 215, 217, 217, 200, 200, 200, 225, 225, - 226, 226, 105, 106, 106, 107, 107, 227, 227, 229, - 228, 228, 230, 231, 231, 231, 232, 232, 233, 233, - 233, 49, 49, 49, 49, 49, 44, 44, 44, 44, - 45, 45, 45, 45, 136, 136, 136, 136, 138, 138, - 137, 137, 82, 82, 83, 83, 83, 142, 142, 143, - 143, 143, 140, 140, 141, 141, 250, 250, 250, 250, - 250, 250, 250, 234, 234, 234, 241, 241, 241, 237, - 237, 239, 239, 239, 240, 240, 240, 238, 247, 247, - 249, 249, 248, 248, 244, 244, 245, 245, 246, 246, - 246, 242, 242, 199, 199, 199, 199, 199, 251, 251, - 251, 251, 263, 263, 210, 210, 212, 212, 211, 211, - 161, 264, 264, 272, 269, 269, 270, 270, 296, 296, - 296, 273, 273, 286, 286, 282, 282, 283, 283, 276, - 276, 288, 288, 288, 77, 208, 208, 365, 365, 362, - 291, 291, 293, 293, 297, 297, 301, 301, 298, 298, - 8, 410, 410, 410, 289, 289, 289, 289, 289, 289, + 119, 119, 119, 119, 417, 417, 326, 326, 326, 204, + 204, 204, 204, 204, 125, 125, 125, 125, 125, 309, + 309, 309, 313, 313, 313, 311, 311, 311, 311, 311, + 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, + 314, 314, 222, 222, 121, 121, 220, 220, 221, 223, + 223, 215, 215, 215, 215, 217, 217, 200, 200, 200, + 225, 225, 226, 226, 105, 106, 106, 107, 107, 227, + 227, 229, 228, 228, 230, 231, 231, 231, 232, 232, + 233, 233, 233, 49, 49, 49, 49, 49, 44, 44, + 44, 44, 45, 45, 45, 45, 136, 136, 136, 136, + 138, 138, 137, 137, 82, 82, 83, 83, 83, 142, + 142, 143, 143, 143, 140, 140, 141, 141, 250, 250, + 250, 250, 250, 250, 250, 234, 234, 234, 241, 241, + 241, 237, 237, 239, 239, 239, 240, 240, 240, 238, + 247, 247, 249, 249, 248, 248, 244, 244, 245, 245, + 246, 246, 246, 242, 242, 199, 199, 199, 199, 199, + 251, 251, 251, 251, 263, 263, 210, 210, 212, 212, + 211, 211, 161, 264, 264, 272, 269, 269, 270, 270, + 296, 296, 296, 273, 273, 286, 286, 282, 282, 283, + 283, 276, 276, 288, 288, 288, 77, 208, 208, 365, + 365, 362, 291, 291, 293, 293, 297, 297, 301, 301, + 298, 298, 8, 410, 410, 410, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, @@ -8549,7 +8619,7 @@ var yyR1 = [...]int{ 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, + 289, 289, 289, 289, 289, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, @@ -8595,8 +8665,8 @@ var yyR1 = [...]int{ 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 290, 290, 290, 290, 290, 290, 413, 414, - 307, 308, 308, 308, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, + 413, 414, 307, 308, 308, 308, } var yyR2 = [...]int{ @@ -8660,109 +8730,109 @@ var yyR2 = [...]int{ 3, 3, 3, 2, 2, 3, 4, 4, 2, 11, 3, 6, 8, 6, 6, 6, 13, 8, 6, 6, 10, 7, 5, 5, 5, 7, 5, 5, 5, 5, - 5, 7, 7, 5, 5, 0, 6, 5, 6, 4, - 5, 0, 8, 9, 0, 3, 0, 1, 0, 3, - 8, 4, 1, 3, 3, 6, 7, 7, 8, 4, - 0, 1, 0, 1, 3, 3, 1, 1, 2, 1, - 1, 0, 2, 0, 2, 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, 2, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 1, 3, 3, 0, 2, 2, - 2, 2, 2, 2, 2, 4, 4, 3, 0, 1, - 4, 3, 4, 4, 3, 3, 3, 2, 1, 3, - 3, 3, 5, 7, 7, 6, 5, 3, 2, 4, - 5, 5, 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, 2, 2, - 4, 4, 4, 4, 4, 2, 3, 3, 3, 3, - 3, 5, 2, 3, 3, 2, 3, 4, 4, 4, - 3, 4, 4, 5, 3, 0, 1, 0, 1, 1, - 1, 0, 2, 2, 0, 2, 2, 0, 2, 0, - 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, - 1, 1, 3, 0, 1, 1, 3, 3, 2, 2, - 1, 1, 5, 0, 1, 0, 1, 2, 3, 0, - 3, 3, 3, 3, 3, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 4, 4, 4, 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, 5, 5, 4, 0, 2, 4, 4, - 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, 1, 2, 1, 3, - 1, 1, 1, 4, 3, 1, 1, 2, 3, 7, - 0, 3, 0, 1, 1, 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, 1, 1, 2, - 6, 5, 6, 6, 0, 2, 3, 3, 0, 2, - 3, 3, 3, 2, 3, 1, 3, 6, 3, 4, - 3, 1, 3, 4, 5, 6, 3, 4, 5, 6, - 3, 4, 1, 1, 1, 3, 3, 3, 3, 3, - 3, 5, 5, 3, 3, 3, 3, 3, 3, 1, - 1, 1, 1, 1, 3, 1, 1, 1, 2, 2, - 2, 2, 1, 1, 2, 7, 7, 6, 6, 2, - 2, 5, 6, 3, 3, 1, 3, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 4, 2, 4, 0, 1, 2, 5, - 0, 3, 0, 1, 4, 4, 2, 0, 1, 1, - 2, 2, 1, 1, 2, 2, 0, 1, 1, 1, - 1, 5, 1, 3, 0, 3, 1, 1, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 4, 6, 4, 4, 8, - 6, 8, 6, 5, 4, 10, 2, 2, 1, 2, - 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 8, 4, 8, 8, 6, 5, 4, 4, 4, 4, - 4, 7, 4, 4, 6, 6, 6, 8, 6, 6, - 4, 4, 3, 4, 6, 6, 4, 4, 6, 4, - 6, 4, 4, 4, 4, 4, 4, 6, 4, 6, - 4, 4, 4, 6, 4, 6, 4, 4, 6, 4, - 6, 4, 6, 8, 4, 6, 8, 4, 6, 8, - 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, + 5, 7, 7, 5, 5, 5, 5, 0, 6, 5, + 6, 4, 5, 0, 8, 9, 0, 3, 0, 1, + 0, 3, 8, 4, 1, 3, 3, 6, 7, 7, + 8, 4, 0, 1, 0, 1, 3, 3, 1, 1, + 2, 1, 1, 0, 2, 0, 2, 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, 2, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 3, 3, 0, + 2, 2, 2, 2, 2, 2, 2, 4, 4, 3, + 0, 1, 4, 3, 4, 4, 3, 3, 3, 2, + 1, 3, 3, 3, 5, 7, 7, 6, 5, 3, + 2, 4, 5, 5, 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, + 2, 2, 4, 4, 4, 4, 4, 2, 3, 3, + 3, 3, 3, 5, 2, 3, 3, 2, 3, 4, + 4, 4, 3, 4, 4, 5, 3, 0, 1, 0, + 1, 1, 1, 0, 2, 2, 0, 2, 2, 0, + 2, 0, 1, 1, 1, 1, 2, 1, 3, 1, + 1, 1, 1, 1, 3, 0, 1, 1, 3, 3, + 2, 2, 1, 1, 5, 0, 1, 0, 1, 2, + 3, 0, 3, 3, 3, 3, 3, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 4, 4, 4, 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, 5, 5, 4, 0, 2, + 4, 4, 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, 1, 2, + 1, 3, 1, 1, 1, 4, 3, 1, 1, 2, + 3, 7, 0, 3, 0, 1, 1, 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, 1, + 1, 2, 6, 5, 6, 6, 0, 2, 3, 3, + 0, 2, 3, 3, 3, 2, 3, 1, 3, 6, + 3, 4, 3, 1, 3, 4, 5, 6, 3, 4, + 5, 6, 3, 4, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 5, 5, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 2, 2, 2, 2, 1, 1, 2, 7, 7, 6, + 6, 2, 2, 5, 6, 3, 3, 1, 3, 1, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 4, 2, 4, 0, 1, + 2, 5, 0, 3, 0, 1, 4, 4, 2, 0, + 1, 1, 2, 2, 1, 1, 2, 2, 0, 1, + 1, 1, 1, 5, 1, 3, 0, 3, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 4, 6, 4, + 4, 8, 6, 8, 6, 5, 4, 10, 2, 2, + 1, 2, 2, 2, 2, 2, 4, 5, 5, 5, + 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 8, 4, 8, 8, 6, 5, 4, 4, + 4, 4, 4, 7, 4, 4, 6, 6, 6, 8, + 6, 6, 4, 4, 3, 4, 6, 6, 4, 4, + 6, 4, 6, 4, 4, 4, 4, 4, 4, 6, + 4, 6, 4, 4, 4, 6, 4, 6, 4, 4, + 6, 4, 6, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, - 4, 4, 6, 4, 6, 4, 8, 6, 4, 4, - 6, 4, 6, 8, 4, 6, 8, 4, 4, 6, - 8, 6, 4, 6, 6, 8, 10, 7, 8, 8, - 9, 4, 4, 4, 4, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, - 4, 6, 4, 6, 5, 9, 6, 9, 8, 6, - 8, 8, 8, 6, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 2, 6, 8, 10, 12, 14, 6, - 8, 8, 10, 12, 14, 6, 8, 10, 12, 6, - 8, 4, 4, 3, 4, 6, 6, 4, 6, 4, - 6, 8, 0, 2, 1, 1, 1, 1, 1, 1, + 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, + 8, 4, 4, 4, 6, 4, 6, 4, 8, 6, + 4, 4, 6, 4, 6, 8, 4, 6, 8, 4, + 4, 6, 8, 6, 4, 6, 6, 8, 10, 7, + 8, 8, 9, 4, 4, 4, 4, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, + 4, 4, 4, 6, 4, 6, 5, 9, 6, 9, + 8, 6, 8, 8, 8, 6, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 2, 6, 8, 10, 12, + 14, 6, 8, 8, 10, 12, 14, 6, 8, 10, + 12, 6, 8, 4, 4, 3, 4, 6, 6, 4, + 6, 4, 6, 8, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 2, 0, 2, 3, 4, 4, 4, - 4, 4, 0, 3, 4, 7, 3, 1, 1, 1, - 0, 5, 5, 2, 3, 1, 2, 2, 1, 2, - 1, 2, 2, 1, 2, 2, 1, 1, 0, 1, - 0, 1, 0, 2, 1, 2, 4, 0, 2, 1, - 1, 3, 5, 1, 1, 1, 2, 2, 0, 3, - 0, 2, 2, 1, 3, 0, 1, 0, 1, 3, - 1, 3, 2, 0, 1, 1, 0, 1, 2, 4, - 4, 0, 2, 2, 1, 1, 3, 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, 1, 0, 1, 2, 3, 4, 2, - 3, 4, 4, 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, 4, - 1, 1, 3, 3, 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, - 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 2, 0, 2, 3, 4, + 4, 4, 4, 4, 0, 3, 4, 7, 3, 1, + 1, 1, 0, 5, 5, 2, 3, 1, 2, 2, + 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, + 0, 1, 0, 1, 0, 2, 1, 2, 4, 0, + 2, 1, 1, 3, 5, 1, 1, 1, 2, 2, + 0, 3, 0, 2, 2, 1, 3, 0, 1, 0, + 1, 3, 1, 3, 2, 0, 1, 1, 0, 1, + 2, 4, 4, 0, 2, 2, 1, 1, 3, 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, 1, 0, 1, 2, 3, + 4, 2, 3, 4, 4, 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, 4, 1, 1, 3, 3, 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, 3, 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, @@ -8824,7 +8894,7 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, + 1, 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -8834,146 +8904,146 @@ var yyChk = [...]int{ -27, -28, -74, -75, -76, -77, -78, -12, -13, -14, -8, -32, -31, -30, 10, 11, -108, -35, 33, -40, -50, 227, -51, -41, 228, -52, 230, 229, 267, 231, - 379, 260, 75, 315, 316, 318, 319, 320, 321, -109, - 684, 265, 266, 233, 37, 46, 34, 35, 38, 237, - 273, 274, 236, 133, -33, -36, 9, -413, 12, 469, - 262, 261, 29, -34, 578, 87, -80, -412, 732, -250, + 380, 260, 75, 316, 317, 319, 320, 321, 322, -109, + 685, 265, 266, 233, 37, 46, 34, 35, 38, 237, + 273, 274, 236, 133, -33, -36, 9, -413, 12, 470, + 262, 261, 29, -34, 579, 87, -80, -412, 733, -250, -234, 23, 34, 30, -233, -229, -127, -234, 21, 19, 8, -79, -79, -79, 13, 14, -79, -350, -352, 87, 160, 87, -79, -57, -56, -54, -53, -55, -58, 32, -47, -48, -374, -46, -43, 232, 229, 277, 123, 124, 267, 268, 269, 231, 251, 266, 270, 265, 286, -42, - 82, 34, 578, 581, -357, 228, 234, 235, 230, 470, - 126, 125, 76, -354, 374, 611, 702, -58, 704, 101, - 104, 703, 45, 241, 705, 706, 707, 618, 708, 250, - 709, 710, 711, 712, 718, 659, 719, 720, 721, 127, - 8, -79, -301, -297, 91, -290, 575, 253, 609, 423, - 610, 302, 82, 42, 514, 584, 371, 374, 611, 499, - 702, 380, 315, 331, 325, 504, 505, 506, 354, 346, - 576, 612, 585, 305, 254, 290, 696, 344, 136, 704, - 309, 613, 268, 381, 382, 614, 383, 101, 318, 420, - 717, 308, 615, 715, 104, 703, 323, 80, 498, 52, - 699, 45, 263, 428, 429, 342, 236, 338, 705, 291, - 616, 587, 284, 126, 123, 724, 37, 334, 51, 31, - 714, 125, 50, 706, 151, 617, 707, 618, 385, 361, - 690, 49, 386, 269, 619, 85, 274, 580, 312, 698, - 387, 519, 335, 388, 301, 713, 233, 620, 679, 671, - 672, 389, 390, 691, 366, 362, 367, 521, 621, 412, - 503, 391, 675, 676, 731, 53, 622, 623, 692, 124, - 624, 79, 708, 81, 329, 330, 625, 299, 252, 524, - 525, 414, 358, 481, 488, 489, 111, 112, 484, 113, - 490, 114, 491, 492, 493, 482, 115, 108, 483, 494, - 495, 359, 360, 116, 496, 110, 109, 485, 487, 117, - 497, 250, 36, 392, 577, 303, 59, 307, 278, 415, - 47, 364, 728, 46, 686, 526, 626, 689, 357, 353, - 478, 54, 627, 628, 629, 630, 500, 709, 356, 328, - 352, 723, 4, 296, 501, 710, 63, 235, 369, 368, - 370, 285, 411, 349, 631, 632, 633, 257, 83, 634, - 339, 22, 635, 636, 393, 292, 637, 57, 638, 639, - 418, 266, 640, 55, 711, 40, 641, 271, 725, 712, - 642, 643, 644, 685, 645, 273, 646, 395, 647, 673, - 674, 394, 363, 365, 527, 280, 396, 379, 238, 579, - 648, 313, 333, 270, 716, 649, 258, 515, 516, 517, - 518, 697, 523, 522, 272, 277, 265, 419, 259, 650, - 651, 652, 653, 654, 306, 670, 655, 656, 319, 718, - 479, 44, 657, 658, 659, 660, 661, 300, 295, 413, - 422, 62, 84, 376, 662, 663, 695, 327, 324, 293, - 460, 462, 463, 464, 465, 466, 461, 468, 664, 316, - 56, 719, 720, 721, 287, 722, 507, 508, 509, 510, - 10, 561, 544, 572, 545, 562, 546, 555, 547, 563, - 571, 573, 528, 536, 529, 537, 567, 550, 564, 556, - 549, 548, 570, 553, 557, 530, 538, 568, 554, 531, - 539, 532, 540, 533, 541, 566, 565, 558, 569, 534, - 542, 560, 535, 543, 559, 551, 552, 431, 729, 730, - 502, 398, 127, 297, 298, 48, 350, 279, 665, 310, - 666, 340, 341, 475, 476, 355, 326, 351, 682, 317, - 680, 281, 399, 480, 267, 667, 421, 294, 372, 377, - 311, 583, 520, 286, 400, 694, 582, 511, 512, 348, - 345, 288, 513, 668, 684, 401, 242, 282, 283, 669, - 681, 402, 403, 304, 404, 405, 406, 407, 408, 410, - 314, 409, 683, 677, 678, 289, 459, 581, 322, 343, - 378, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 477, - 240, -79, 240, -188, -297, -129, 686, 688, 179, -269, - 382, -287, 384, 397, 392, 402, 390, -278, 393, 395, - 280, -398, 412, 240, 399, 227, 385, 394, 403, 404, - 304, 410, 405, 314, 409, 289, 406, 407, 408, -381, - 179, 707, 722, 136, 347, 389, 387, 413, 686, 91, - -303, 91, 92, 93, -290, 317, -305, 322, -291, -381, - -290, 320, -79, -79, -307, -307, -129, -207, -144, 144, + 82, 34, 579, 582, -357, 228, 234, 235, 230, 471, + 126, 125, 76, -354, 375, 612, 703, -58, 705, 101, + 104, 704, 45, 241, 706, 707, 708, 619, 709, 250, + 710, 711, 712, 713, 719, 660, 720, 721, 722, 127, + 8, -79, -301, -297, 91, -290, 576, 253, 610, 424, + 611, 302, 82, 42, 515, 585, 372, 375, 612, 500, + 703, 381, 316, 332, 326, 505, 506, 507, 355, 347, + 577, 613, 586, 305, 254, 290, 697, 345, 136, 705, + 309, 614, 268, 382, 383, 615, 384, 101, 319, 421, + 718, 308, 616, 716, 104, 704, 324, 80, 499, 52, + 700, 45, 263, 429, 430, 343, 236, 339, 706, 291, + 617, 588, 284, 126, 123, 725, 37, 335, 51, 31, + 715, 125, 50, 707, 151, 618, 708, 619, 386, 362, + 691, 49, 387, 269, 620, 85, 274, 581, 313, 699, + 388, 520, 336, 389, 301, 714, 233, 621, 680, 672, + 673, 390, 391, 692, 367, 363, 368, 522, 622, 413, + 504, 392, 676, 677, 732, 53, 623, 624, 693, 124, + 625, 79, 709, 81, 330, 331, 626, 299, 252, 525, + 526, 415, 359, 482, 489, 490, 111, 112, 485, 113, + 491, 114, 492, 493, 494, 483, 115, 108, 484, 495, + 496, 360, 361, 116, 497, 110, 109, 486, 488, 117, + 498, 250, 36, 393, 578, 303, 59, 307, 278, 416, + 47, 365, 729, 46, 687, 527, 627, 690, 358, 354, + 479, 54, 628, 629, 630, 631, 501, 710, 357, 329, + 353, 724, 4, 296, 502, 711, 63, 235, 370, 369, + 371, 285, 412, 350, 632, 633, 634, 257, 83, 635, + 340, 22, 636, 637, 394, 292, 638, 57, 639, 640, + 419, 266, 641, 55, 712, 40, 642, 271, 726, 713, + 643, 644, 645, 686, 646, 273, 647, 396, 648, 674, + 675, 395, 364, 366, 528, 280, 397, 380, 238, 580, + 649, 314, 334, 270, 717, 650, 258, 516, 517, 518, + 519, 698, 524, 523, 272, 277, 265, 420, 259, 651, + 652, 653, 654, 655, 306, 671, 656, 657, 320, 719, + 480, 44, 658, 659, 660, 661, 662, 300, 295, 414, + 423, 62, 84, 377, 663, 664, 696, 328, 325, 293, + 461, 463, 464, 465, 466, 467, 462, 469, 665, 317, + 56, 720, 721, 722, 287, 723, 508, 509, 510, 511, + 10, 562, 545, 573, 546, 563, 547, 556, 548, 564, + 572, 574, 529, 537, 530, 538, 568, 551, 565, 557, + 550, 549, 571, 554, 558, 531, 539, 569, 555, 532, + 540, 533, 541, 534, 542, 567, 566, 559, 570, 535, + 543, 561, 536, 544, 560, 552, 553, 432, 730, 731, + 503, 399, 127, 297, 298, 48, 351, 279, 666, 310, + 667, 341, 342, 476, 477, 356, 327, 352, 683, 318, + 681, 281, 400, 481, 267, 668, 422, 294, 373, 378, + 311, 584, 521, 286, 401, 695, 583, 512, 513, 349, + 346, 288, 514, 669, 685, 402, 242, 282, 283, 670, + 682, 403, 404, 304, 405, 406, 407, 408, 409, 411, + 315, 410, 684, 678, 679, 289, 460, 582, 323, 344, + 379, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 456, 457, 458, 459, 478, + 240, -79, 240, -188, -297, -129, 687, 689, 179, -269, + 383, -287, 385, 398, 393, 403, 391, -278, 394, 396, + 280, -398, 413, 240, 400, 227, 386, 395, 404, 405, + 304, 411, 406, 315, 410, 289, 407, 408, 409, -381, + 179, 708, 723, 136, 348, 390, 388, 414, 687, 91, + -303, 91, 92, 93, -290, 318, -305, 323, -291, -381, + -290, 321, -79, -79, -307, -307, -129, -207, -144, 144, -157, -258, -160, 92, -149, -152, -201, -202, -203, -204, -158, -217, -256, 168, 169, 176, 145, -213, -161, 27, - 574, 471, 470, 179, 32, 222, 69, 70, 473, 147, - 58, 12, 436, 437, -159, 426, 427, 438, 432, 433, - 498, 500, 501, 502, 499, 504, 505, 506, 507, 508, - 509, 510, 511, 512, 513, 503, 514, 475, 476, 118, - 477, 108, 110, 109, 478, 479, 480, 344, 526, 527, - 521, 524, 525, 523, 522, 359, 360, 481, 544, 545, - 549, 548, 546, 547, 550, 553, 554, 555, 556, 557, - 558, 560, 559, 551, 552, 529, 528, 530, 531, 532, - 533, 534, 535, 537, 536, 538, 539, 540, 541, 542, - 543, 561, 562, 563, 564, 565, 567, 566, 571, 570, - 568, 569, 573, 572, 482, 483, 111, 112, 113, 114, - 115, 116, 117, 484, 487, 485, 486, 488, 489, 490, - 495, 496, 491, 492, 493, 494, 497, 370, 368, 369, - 365, 364, 363, -89, -101, 600, 599, -102, 423, 428, - 429, 431, -150, -151, -163, -164, -291, -297, 245, 425, - 239, 174, 469, -153, -147, -215, 107, 93, -31, -211, - 424, 434, 435, 439, 430, 440, 586, 588, 603, 604, - 606, 591, 596, 595, 598, 515, 516, 517, 518, 519, - 520, 671, 672, 673, 674, 675, 676, 677, 678, -381, + 575, 472, 471, 179, 32, 222, 69, 70, 474, 147, + 58, 12, 437, 438, -159, 427, 428, 439, 433, 434, + 499, 501, 502, 503, 500, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 504, 515, 476, 477, 118, + 478, 108, 110, 109, 479, 480, 481, 345, 527, 528, + 522, 525, 526, 524, 523, 360, 361, 482, 545, 546, + 550, 549, 547, 548, 551, 554, 555, 556, 557, 558, + 559, 561, 560, 552, 553, 530, 529, 531, 532, 533, + 534, 535, 536, 538, 537, 539, 540, 541, 542, 543, + 544, 562, 563, 564, 565, 566, 568, 567, 572, 571, + 569, 570, 574, 573, 483, 484, 111, 112, 113, 114, + 115, 116, 117, 485, 488, 486, 487, 489, 490, 491, + 496, 497, 492, 493, 494, 495, 498, 371, 369, 370, + 366, 365, 364, -89, -101, 601, 600, -102, 424, 429, + 430, 432, -150, -151, -163, -164, -291, -297, 245, 426, + 239, 174, 470, -153, -147, -215, 107, 93, -31, -211, + 425, 435, 436, 440, 431, 441, 587, 589, 604, 605, + 607, 592, 597, 596, 599, 516, 517, 518, 519, 520, + 521, 672, 673, 674, 675, 676, 677, 678, 679, -381, -290, 91, -155, -154, -197, 94, 99, 102, 103, 105, - -404, 263, 340, 341, 119, -413, 700, 90, 95, 96, + -404, 263, 341, 342, 119, -413, 701, 90, 95, 96, 97, 98, 120, 121, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 45, 398, 398, -188, - -79, -79, -79, -79, -410, 703, 579, -227, -127, -229, + 216, 217, 218, 219, 220, 221, 45, 399, 399, -188, + -79, -79, -79, -79, -410, 704, 580, -227, -127, -229, -33, -31, -413, 9, -79, -31, -32, -30, -36, -38, - 605, -37, -297, 100, -234, -250, 13, 62, 163, 43, + 606, -37, -297, 100, -234, -250, 13, 62, 163, 43, 51, -232, -233, -34, -31, -144, 20, 24, 25, -132, 170, -144, -297, -132, -276, 244, -79, -79, -265, -310, - 317, -267, 413, 686, 412, -257, -270, 91, -256, -269, - 411, 92, -351, 160, -337, -341, -291, 255, -367, 251, + 318, -267, 414, 687, 413, -257, -270, 91, -256, -269, + 412, 92, -351, 160, -337, -341, -291, 255, -367, 251, -188, -360, -359, -291, -413, -128, -286, 241, 249, 248, - 137, -385, 140, 297, 425, 239, -53, -54, -55, -269, - 178, 706, -110, 272, 276, 88, 88, -341, -340, -339, + 137, -385, 140, 297, 426, 239, -53, -54, -55, -269, + 178, 707, -110, 272, 276, 88, 88, -341, -340, -339, -386, 276, 255, -366, -358, 247, 256, -347, 248, 249, -342, 241, 138, -386, -342, 246, 256, 251, 255, 276, 276, 127, 276, 127, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 271, -348, 152, -348, 582, 582, -354, + 276, 276, 276, 271, -348, 152, -348, 583, 583, -354, -386, 251, 241, -386, -386, 247, -288, -342, 243, 26, 243, 36, 36, -348, -348, -348, -269, 178, -348, -348, -348, -348, 284, 284, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, - -348, 240, -385, -136, 409, 304, 82, -56, 286, -39, - -188, -286, 241, 242, -385, 273, -188, 223, 240, 689, - -280, 160, 16, -280, -277, 398, 396, 383, 388, -280, - -280, -280, -280, 287, 381, -343, 241, 36, 252, 398, - 287, 381, 287, 288, 287, 288, 391, 401, 287, -302, - 15, 163, 425, 386, 390, 280, 240, 281, 242, 400, - 288, -302, 90, -281, 160, 287, 398, 392, 283, -280, + -348, 240, -385, -136, 410, 304, 82, -56, 286, -39, + -188, -286, 241, 242, -385, 273, -188, 223, 240, 690, + -280, 160, 16, -280, -277, 399, 397, 384, 389, -280, + -280, -280, -280, 287, 382, -343, 241, 36, 252, 399, + 287, 382, 287, 288, 287, 288, 392, 402, 287, -302, + 15, 163, 426, 387, 391, 280, 240, 281, 242, 401, + 288, -302, 90, -281, 160, 287, 399, 393, 283, -280, -280, -308, -413, -293, -291, -289, 232, 24, 143, 26, - 28, 146, 179, 130, 20, 147, 38, 234, 347, 251, - 178, 247, 470, 227, 73, 586, 426, 433, 424, 432, - 436, 472, 473, 425, 384, 32, 14, 588, 29, 261, - 25, 39, 172, 229, 150, 589, 264, 27, 262, 118, - 121, 591, 23, 76, 256, 15, 249, 41, 17, 592, - 593, 18, 245, 244, 163, 241, 71, 12, 222, 30, - 159, 67, 594, 138, 133, 595, 596, 597, 598, 131, - 69, 160, 21, 726, 434, 435, 34, 687, 574, 275, - 174, 74, 60, 688, 144, 430, 599, 600, 119, 601, - 122, 77, 693, 140, 19, 72, 43, 602, 276, 603, - 246, 727, 604, 416, 605, 161, 230, 469, 70, 162, - 700, 606, 701, 239, 397, 9, 474, 33, 260, 248, - 129, 68, 440, 607, 240, 149, 243, 132, 120, 8, - 137, 35, 13, 75, 78, 437, 438, 439, 58, 128, - 578, 148, 16, 608, 417, 142, -381, 689, -308, -308, - 33, 92, -407, -408, -409, 578, 416, 243, -291, -188, - -85, 679, 231, -86, 685, 24, 238, -134, 398, -122, - 179, 707, 690, 691, 692, 689, 395, 697, 695, 693, - 287, 694, 88, 140, 142, 143, 4, -144, 159, -198, + 28, 146, 179, 130, 20, 147, 38, 234, 348, 251, + 178, 247, 471, 227, 73, 587, 427, 434, 425, 433, + 437, 473, 474, 426, 385, 32, 14, 589, 29, 261, + 25, 39, 172, 229, 150, 590, 264, 27, 262, 118, + 121, 592, 23, 76, 256, 15, 249, 41, 17, 593, + 594, 18, 245, 244, 163, 241, 71, 12, 222, 30, + 159, 67, 595, 138, 133, 596, 597, 598, 599, 131, + 69, 160, 21, 727, 435, 436, 34, 688, 575, 275, + 174, 74, 60, 689, 144, 431, 600, 601, 119, 602, + 122, 77, 694, 140, 19, 72, 43, 603, 276, 604, + 246, 728, 605, 417, 606, 161, 230, 470, 70, 162, + 701, 607, 702, 239, 398, 9, 475, 33, 260, 248, + 129, 68, 441, 608, 240, 149, 243, 132, 120, 8, + 137, 35, 13, 75, 78, 438, 439, 440, 58, 128, + 579, 148, 16, 609, 418, 142, -381, 690, -308, -308, + 33, 92, -407, -408, -409, 579, 417, 243, -291, -188, + -85, 680, 231, -86, 686, 24, 238, -134, 399, -122, + 179, 708, 691, 692, 693, 690, 396, 698, 696, 694, + 287, 695, 88, 140, 142, 143, 4, -144, 159, -198, 152, 153, 154, 155, 156, 157, 158, 164, 163, 144, 146, 160, -243, 141, 165, 166, 167, 168, 169, 170, 171, 173, 172, 174, 175, 161, 162, 178, 225, 226, @@ -9000,18 +9070,18 @@ var yyChk = [...]int{ -396, -191, -188, -413, 304, -291, -291, 273, 96, -232, -34, -31, -227, -233, -229, -31, -79, -120, -133, 64, 65, -135, 25, 39, 68, 66, 24, -414, 89, -414, - -250, -414, 88, -38, -253, 87, 633, 663, 633, 663, + -250, -414, 88, -38, -253, 87, 634, 664, 634, 664, 62, 44, 90, 90, 88, 22, -228, -230, -144, 15, -295, 4, -294, 26, -291, 90, 223, 15, -189, 30, - -188, -276, -276, 88, 91, 317, -266, -268, 414, 416, + -188, -276, -276, 88, 91, 318, -266, -268, 415, 417, 152, -296, -291, 90, 32, 89, 88, -188, -315, -318, - -320, -319, -321, -316, -317, 344, 345, 179, 348, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 361, 33, - 263, 340, 341, 342, 343, 362, 363, 364, 365, 367, - 368, 369, 370, 325, 346, 576, 326, 327, 328, 329, - 330, 331, 333, 334, 337, 335, 336, 338, 339, -382, + -320, -319, -321, -316, -317, 345, 346, 179, 349, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 362, 33, + 263, 341, 342, 343, 344, 363, 364, 365, 366, 368, + 369, 370, 371, 326, 347, 577, 327, 328, 329, 330, + 331, 332, 334, 335, 338, 336, 337, 339, 340, -382, -381, 87, 89, 88, -322, 87, -144, -136, 240, -381, - 241, 241, 241, -79, 469, -348, -348, -348, 271, 20, + 241, 241, 241, -79, 470, -348, -348, -348, 271, 20, -46, -43, -374, 19, -42, -43, 232, 123, 124, 229, 87, -337, 87, -346, -382, -381, 87, 138, 246, 137, -345, -342, -345, -346, -381, -215, -381, 138, 138, -381, @@ -9021,388 +9091,388 @@ var yyChk = [...]int{ -215, -381, -381, -215, -337, -215, -188, -381, -269, 96, 96, 96, -348, -348, 96, 90, 90, 90, -348, -348, 96, 90, -299, -297, 90, 90, -387, 257, 301, 303, - 96, 96, 96, 96, 32, 90, -388, 32, 714, 713, - 715, 716, 717, 90, 96, 32, 96, 32, 96, -291, + 96, 96, 96, 96, 32, 90, -388, 32, 715, 714, + 716, 717, 718, 90, 96, 32, 96, 32, 96, -291, 87, -188, -142, 291, 227, 229, 232, 77, 90, 307, - 308, 305, 310, 311, 152, 45, 88, 243, 240, -381, - -282, 245, -282, -291, -298, -297, -289, -188, 243, 380, - 90, -144, -344, 15, 163, -302, -302, -280, -188, -344, - -302, -280, -188, -280, -280, -280, -280, -302, -302, -302, - -280, -297, -297, -188, -188, -188, -188, -188, -188, -188, - -308, -281, -280, 689, 90, -274, 15, 77, -308, -308, - 88, 323, 417, 418, -306, 320, -81, -291, 90, -10, - -29, -18, -17, -19, 152, -10, 88, 578, -181, -188, - 689, 689, 689, 689, 689, 689, -144, -144, -144, -144, - 601, -205, 119, 144, 120, 121, -160, -144, -206, -211, - -213, 106, 163, 146, 160, -243, -149, -152, -149, -149, - -149, -149, -149, -149, 222, -149, 222, -149, -149, -149, - -149, -149, -149, -309, -291, 90, 179, -156, -155, 105, - -404, -156, 575, 88, -218, 223, -144, -144, -381, -118, - 442, 443, 444, 445, 447, 448, 449, 452, 453, 457, - 458, 441, 459, 446, 451, 454, 455, 456, 450, 343, - -144, -130, -132, -130, -144, -220, -221, 148, -215, -144, - -414, -414, 96, 170, -126, 25, 39, -126, -126, -126, - -126, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -126, -144, -119, 441, 459, 446, 451, 454, 455, - 456, 450, 343, 460, 461, 462, 463, 464, 465, 466, - 467, 468, -119, -118, -144, -144, -144, -144, -144, -144, - -87, -144, 130, 131, 132, -207, -144, -149, -144, -144, - -144, -414, -144, -144, -144, -208, -207, -144, -144, -144, + 308, 305, 310, 311, 312, 152, 45, 88, 243, 240, + -381, -282, 245, -282, -291, -298, -297, -289, -188, 243, + 381, 90, -144, -344, 15, 163, -302, -302, -280, -188, + -344, -302, -280, -188, -280, -280, -280, -280, -302, -302, + -302, -280, -297, -297, -188, -188, -188, -188, -188, -188, + -188, -308, -281, -280, 690, 90, -274, 15, 77, -308, + -308, 88, 324, 418, 419, -306, 321, -81, -291, 90, + -10, -29, -18, -17, -19, 152, -10, 88, 579, -181, + -188, 690, 690, 690, 690, 690, 690, -144, -144, -144, + -144, 602, -205, 119, 144, 120, 121, -160, -144, -206, + -211, -213, 106, 163, 146, 160, -243, -149, -152, -149, + -149, -149, -149, -149, -149, 222, -149, 222, -149, -149, + -149, -149, -149, -149, -309, -291, 90, 179, -156, -155, + 105, -404, -156, 576, 88, -218, 223, -144, -144, -381, + -118, 443, 444, 445, 446, 448, 449, 450, 453, 454, + 458, 459, 442, 460, 447, 452, 455, 456, 457, 451, + 344, -144, -130, -132, -130, -144, -220, -221, 148, -215, + -144, -414, -414, 96, 170, -126, 25, 39, -126, -126, + -126, -126, -144, -144, -144, -144, -144, -144, -144, -144, + -144, -144, -126, -144, -119, 442, 460, 447, 452, 455, + 456, 457, 451, 344, 461, 462, 463, 464, 465, 466, + 467, 468, 469, -119, -118, -144, -144, -144, -144, -144, + -144, -87, -144, 130, 131, 132, -207, -144, -149, -144, + -144, -144, -414, -144, -144, -144, -208, -207, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -380, -379, -378, -144, -144, -144, -144, + -144, -144, -144, -144, -380, -379, -378, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -144, -144, -207, - -207, -207, -207, -207, -144, -414, -144, -162, -147, 96, - -258, 105, 92, -144, -144, -144, -144, -144, -144, -131, - -130, -293, -298, -289, -290, -130, -131, -131, -130, -130, - -144, -144, -144, -144, -144, -144, -144, -144, -414, -144, - -144, -144, -144, -144, -250, -414, -207, 88, -397, 416, - 417, 687, -300, 276, -299, 26, -208, 90, 15, -260, - 78, -291, -232, -232, 64, 65, 60, -130, -135, -414, - -37, 26, -252, -291, 626, 626, 63, 90, -327, -269, - 371, 372, 179, -144, -144, 88, -231, 28, 29, -188, - -294, 170, -298, -188, -261, 276, -188, -166, -168, -169, - -170, -191, -214, -413, -171, -31, 597, 594, 15, -181, - -182, -190, -297, -267, -310, -266, 88, 415, 417, 418, - 77, 122, -144, -328, 178, -356, -355, -354, -337, -339, - -340, -341, 89, -328, -333, 377, 376, -322, -322, -322, - -322, -322, -327, -327, -327, -327, 87, 87, -322, -322, - -322, -322, -330, 87, -330, -330, -331, -330, 87, -331, - -332, 87, -332, -367, -144, -364, -363, -361, -362, 250, - 101, 669, 625, 578, 618, 659, 78, -359, -231, 96, - -414, -142, -283, 245, -365, -362, -381, -381, -381, -283, - 91, 90, 91, 90, 91, 90, -111, -60, -1, 726, - 727, 728, 88, 20, -338, -337, -59, 301, -370, -371, - 276, -366, -360, -346, 138, -345, -346, -346, -381, 88, - 30, 127, 127, 127, 127, 578, 229, 33, -284, 617, - 144, 669, 625, -337, -59, 243, 243, -309, -309, -309, - 90, 90, -279, 722, -181, -138, 293, 152, 282, 282, - 240, 295, 240, 295, -188, 306, 309, 307, 308, 305, - 310, 311, 24, 24, 24, 24, 24, 294, 296, 298, - 284, -188, -188, -282, 77, -183, -188, 27, -297, 90, - 90, -188, -280, -280, -188, -280, -280, -188, -409, 324, - -291, 358, 680, 681, 683, 682, -122, 416, 88, 578, - 23, -123, 23, -413, 119, 120, 121, -206, -149, -152, - -149, 143, 264, -149, -149, -413, -215, -414, -293, 26, - 88, 78, -414, 168, 88, 88, -414, -414, 88, 15, - -223, -221, 150, -144, -414, 88, -414, -414, -207, -144, - -144, -144, -144, -414, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -207, -414, 88, 88, 15, -313, 26, - -414, -414, -414, -414, -414, -222, -414, 15, -414, 78, - 88, 163, 88, -414, -414, -414, 88, 88, -414, -414, - 88, -414, 88, -414, -414, -414, -414, -414, -414, 88, - -414, 88, -414, -414, -414, 88, -414, 88, -414, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, -414, -414, 88, -414, - 88, -414, 88, -414, -414, 88, -414, 88, -414, 88, - -414, 88, 88, -414, 88, 88, 88, -414, 88, 88, - 88, 88, -414, -414, -414, -414, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, -414, -414, -414, -414, - -414, -414, 88, -94, 602, -414, -414, 88, -414, 88, - 88, 88, 88, 88, -414, -413, 223, -414, -414, -414, - -414, -414, 88, 88, 88, 88, 88, 88, -414, -414, - -414, 88, 88, -414, 88, -414, 88, -414, -396, 686, - 417, -195, -194, -192, 75, 244, 76, -413, -299, -414, - -156, -258, -259, -258, -200, -291, 96, 105, -234, -165, - -167, 15, -135, -213, 89, 88, -327, -238, -244, -277, - -291, 90, 179, -329, 179, -329, 371, 372, -230, 223, - -196, 16, -199, 33, 58, -29, -413, -413, 33, 88, - -184, -186, -185, -187, 67, 71, 73, 68, 69, 70, - 74, -304, 26, -31, -166, -31, -413, -188, -181, -415, - 15, 78, -415, 88, 223, -268, -271, 419, 416, 422, - -381, 90, -110, 88, -354, -341, -235, -139, 41, -334, - 378, -327, 585, -327, -336, 90, -336, 96, 96, 96, - 89, -49, -44, -45, 34, 82, -361, -348, 90, 40, - -348, -348, -291, 89, -231, -138, -188, 144, 77, -365, - -365, -365, -297, -2, 725, 731, 138, 87, 383, 19, - -252, 88, 89, -216, 302, 89, -112, -291, 89, 87, - -346, -346, -291, -413, 240, 32, 32, 669, 625, 617, - -59, -216, -215, -381, -328, 724, 723, 89, 242, 300, - -143, 436, -140, 90, 91, -188, -188, -188, -188, -188, - -188, 232, 229, 406, -405, 312, -405, 285, 243, -181, - -188, 88, -84, 259, 254, -302, -302, 34, -188, 416, - 698, 696, -144, 143, 264, -160, -152, -118, -118, -149, - -311, 179, 344, 263, 342, 338, 358, 349, 376, 340, - 377, 335, 334, 333, -311, -309, -149, -207, -132, -144, - -144, 151, -144, 149, -144, -414, -414, -414, -414, -414, - -227, -144, -144, -144, -414, 179, 344, 15, -144, -309, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -207, -207, -207, -207, -207, -144, -414, -144, -162, -147, + 96, -258, 105, 92, -144, -144, -144, -144, -144, -144, + -131, -130, -293, -298, -289, -290, -130, -131, -131, -130, + -130, -144, -144, -144, -144, -144, -144, -144, -144, -414, + -144, -144, -144, -144, -144, -250, -414, -207, 88, -397, + 417, 418, 688, -300, 276, -299, 26, -208, 90, 15, + -260, 78, -291, -232, -232, 64, 65, 60, -130, -135, + -414, -37, 26, -252, -291, 627, 627, 63, 90, -327, + -269, 372, 373, 179, -144, -144, 88, -231, 28, 29, + -188, -294, 170, -298, -188, -261, 276, -188, -166, -168, + -169, -170, -191, -214, -413, -171, -31, 598, 595, 15, + -181, -182, -190, -297, -267, -310, -266, 88, 416, 418, + 419, 77, 122, -144, -328, 178, -356, -355, -354, -337, + -339, -340, -341, 89, -328, -333, 378, 377, -322, -322, + -322, -322, -322, -327, -327, -327, -327, 87, 87, -322, + -322, -322, -322, -330, 87, -330, -330, -331, -330, 87, + -331, -332, 87, -332, -367, -144, -364, -363, -361, -362, + 250, 101, 670, 626, 579, 619, 660, 78, -359, -231, + 96, -414, -142, -283, 245, -365, -362, -381, -381, -381, + -283, 91, 90, 91, 90, 91, 90, -111, -60, -1, + 727, 728, 729, 88, 20, -338, -337, -59, 301, -370, + -371, 276, -366, -360, -346, 138, -345, -346, -346, -381, + 88, 30, 127, 127, 127, 127, 579, 229, 33, -284, + 618, 144, 670, 626, -337, -59, 243, 243, -309, -309, + -309, 90, 90, -279, 723, -181, -138, 293, 152, 282, + 282, 240, 295, 240, 295, -188, 306, 309, 307, 308, + 305, 310, 311, 312, 24, 24, 24, 24, 24, 24, + 294, 296, 298, 284, -188, -188, -282, 77, -183, -188, + 27, -297, 90, 90, -188, -280, -280, -188, -280, -280, + -188, -409, 325, -291, 359, 681, 682, 684, 683, -122, + 417, 88, 579, 23, -123, 23, -413, 119, 120, 121, + -206, -149, -152, -149, 143, 264, -149, -149, -413, -215, + -414, -293, 26, 88, 78, -414, 168, 88, 88, -414, + -414, 88, 15, -223, -221, 150, -144, -414, 88, -414, + -414, -207, -144, -144, -144, -144, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -207, -414, 88, 88, + 15, -313, 26, -414, -414, -414, -414, -414, -222, -414, + 15, -414, 78, 88, 163, 88, -414, -414, -414, 88, + 88, -414, -414, 88, -414, 88, -414, -414, -414, -414, + -414, -414, 88, -414, 88, -414, -414, -414, 88, -414, + 88, -414, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, -414, + -414, 88, -414, 88, -414, 88, -414, -414, 88, -414, + 88, -414, 88, -414, 88, 88, -414, 88, 88, 88, + -414, 88, 88, 88, 88, -414, -414, -414, -414, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, -414, + -414, -414, -414, -414, -414, 88, -94, 603, -414, -414, + 88, -414, 88, 88, 88, 88, 88, -414, -413, 223, + -414, -414, -414, -414, -414, 88, 88, 88, 88, 88, + 88, -414, -414, -414, 88, 88, -414, 88, -414, 88, + -414, -396, 687, 418, -195, -194, -192, 75, 244, 76, + -413, -299, -414, -156, -258, -259, -258, -200, -291, 96, + 105, -234, -165, -167, 15, -135, -213, 89, 88, -327, + -238, -244, -277, -291, 90, 179, -329, 179, -329, 372, + 373, -230, 223, -196, 16, -199, 33, 58, -29, -413, + -413, 33, 88, -184, -186, -185, -187, 67, 71, 73, + 68, 69, 70, 74, -304, 26, -31, -166, -31, -413, + -188, -181, -415, 15, 78, -415, 88, 223, -268, -271, + 420, 417, 423, -381, 90, -110, 88, -354, -341, -235, + -139, 41, -334, 379, -327, 586, -327, -336, 90, -336, + 96, 96, 96, 89, -49, -44, -45, 34, 82, -361, + -348, 90, 40, -348, -348, -291, 89, -231, -138, -188, + 144, 77, -365, -365, -365, -297, -2, 726, 732, 138, + 87, 384, 19, -252, 88, 89, -216, 302, 89, -112, + -291, 89, 87, -346, -346, -291, -413, 240, 32, 32, + 670, 626, 618, -59, -216, -215, -381, -328, 725, 724, + 89, 242, 300, -143, 437, -140, 90, 91, -188, -188, + -188, -188, -188, -188, 232, 229, 407, -405, 313, -405, + 285, 243, -181, -188, 88, -84, 259, 254, -302, -302, + 34, -188, 417, 699, 697, -144, 143, 264, -160, -152, + -118, -118, -149, -311, 179, 345, 263, 343, 339, 359, + 350, 377, 341, 378, 336, 335, 334, -311, -309, -149, + -207, -132, -144, -144, 151, -144, 149, -144, -414, -414, + -414, -414, -414, -227, -144, -144, -144, -414, 179, 345, + 15, -144, -309, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -378, -144, -207, -144, -207, - -144, -144, -144, -144, -144, -379, -379, -379, -379, -379, - -207, -207, -207, -207, -144, -413, -291, -97, -96, -95, - 652, 244, -94, -162, -97, -162, 222, -144, 222, 222, - 222, -144, -131, -293, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -192, -342, -342, -342, -262, 88, - -273, 23, 15, 58, 58, -165, -196, -166, -135, -291, - -241, 679, -247, 47, -245, -246, 48, -242, 49, 57, - -329, -329, 170, -232, -144, -263, 77, -264, -272, -215, - -210, -212, -211, -413, -251, -414, -291, -262, -264, -168, - -169, -169, -168, -169, 67, 67, 67, 72, 67, 72, - 67, -185, -297, -414, -144, -300, 78, -166, -166, -190, - -297, 170, 416, 420, 421, -354, -403, 119, 144, 32, - 77, 374, 101, -401, 178, 614, 664, 669, 625, 618, - 659, -402, 246, 137, 138, 258, 26, 42, 89, 88, - 89, 88, 89, 89, 88, -285, -284, -45, -44, -348, - -348, 96, -381, 90, 90, 242, 27, -188, 77, 77, - 77, -113, 729, 96, 87, -3, 82, -144, 87, 20, - -337, -215, -372, -323, -373, -324, -325, -5, -6, -349, - -116, 58, 101, -63, 45, 241, 709, 710, 127, -413, - 722, -364, -252, -368, -370, -188, -148, -413, -159, -146, - -145, -147, -153, 168, 169, 263, 340, 341, -216, -188, - -137, 291, 299, 87, -141, 92, -384, 78, 282, 374, - 282, 374, 90, -406, 313, 90, -406, -188, -84, -49, - -188, -280, -280, 34, -381, -414, -160, -152, -125, 163, - 578, -314, 584, -322, -322, -322, -332, -322, 330, -322, - 330, -322, -414, -414, -414, 88, -414, 23, -414, -144, - 88, -121, 474, 88, 88, -414, 87, 87, -144, -414, - -414, -414, 88, -414, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, 88, -414, - 88, -414, 88, -414, 88, -414, 88, -414, -414, 88, - -414, -414, -414, 88, -414, 88, -414, 88, -414, -414, - -414, 88, -312, 670, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -93, -292, -291, -94, 634, - 634, -414, -94, -224, 88, -149, -414, -149, -149, -149, - -414, -414, -414, 88, -414, 88, 88, -414, 88, -414, - 88, -414, -414, -414, -414, 88, -193, 23, -193, -193, - -414, -258, -188, -196, -225, 17, -238, 52, 350, -249, - -248, 56, 48, -246, 20, 50, 20, 31, -263, 88, - 152, 88, -414, -414, 88, 58, 223, -414, -196, -179, - -178, 77, 78, -180, 77, -178, 67, 67, -253, 88, - -261, -166, -196, -196, 223, 119, -413, -148, 13, 90, - 90, -381, -400, 713, 714, 32, 96, -348, -348, 138, - 138, -188, 87, -327, 90, -327, 96, 96, 32, 83, - 84, 85, 32, 79, 80, 81, -188, -188, -188, -188, - -369, 87, 20, -144, 87, 152, 89, -252, -252, 278, - 163, -348, 707, 284, 284, -348, -348, -348, -115, -114, - 729, 89, -414, 88, -335, 578, 581, -144, -154, -154, - -253, 89, -377, 578, -383, -291, -291, -291, -291, 96, - 98, -414, 576, 74, 579, -414, -327, -144, -144, -144, - -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -144, -378, -144, + -207, -144, -207, -144, -144, -144, -144, -144, -379, -379, + -379, -379, -379, -207, -207, -207, -207, -144, -413, -291, + -97, -96, -95, 653, 244, -94, -162, -97, -162, 222, + -144, 222, 222, 222, -144, -131, -293, -144, -144, -144, + -144, -144, -144, -144, -144, -144, -144, -192, -342, -342, + -342, -262, 88, -273, 23, 15, 58, 58, -165, -196, + -166, -135, -291, -241, 680, -247, 47, -245, -246, 48, + -242, 49, 57, -329, -329, 170, -232, -144, -263, 77, + -264, -272, -215, -210, -212, -211, -413, -251, -414, -291, + -262, -264, -168, -169, -169, -168, -169, 67, 67, 67, + 72, 67, 72, 67, -185, -297, -414, -144, -300, 78, + -166, -166, -190, -297, 170, 417, 421, 422, -354, -403, + 119, 144, 32, 77, 375, 101, -401, 178, 615, 665, + 670, 626, 619, 660, -402, 246, 137, 138, 258, 26, + 42, 89, 88, 89, 88, 89, 89, 88, -285, -284, + -45, -44, -348, -348, 96, -381, 90, 90, 242, 27, + -188, 77, 77, 77, -113, 730, 96, 87, -3, 82, + -144, 87, 20, -337, -215, -372, -323, -373, -324, -325, + -5, -6, -349, -116, 58, 101, -63, 45, 241, 710, + 711, 127, -413, 723, -364, -252, -368, -370, -188, -148, + -413, -159, -146, -145, -147, -153, 168, 169, 263, 341, + 342, -216, -188, -137, 291, 299, 87, -141, 92, -384, + 78, 282, 375, 282, 375, 90, -406, 314, 90, -406, + -188, -84, -49, -188, -280, -280, 34, -381, -414, -160, + -152, -125, 163, 579, -314, 585, -322, -322, -322, -332, + -322, 331, -322, 331, -322, -414, -414, -414, 88, -414, + 23, -414, -144, 88, -121, 475, 88, 88, -414, 87, + 87, -144, -414, -414, -414, 88, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, 88, -414, 88, -414, 88, -414, 88, -414, 88, + -414, -414, 88, -414, -414, -414, 88, -414, 88, -414, + 88, -414, -414, -414, 88, -312, 671, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -93, -292, + -291, -94, 635, 635, -414, -94, -224, 88, -149, -414, + -149, -149, -149, -414, -414, -414, 88, -414, 88, 88, + -414, 88, -414, 88, -414, -414, -414, -414, 88, -193, + 23, -193, -193, -414, -258, -188, -196, -225, 17, -238, + 52, 351, -249, -248, 56, 48, -246, 20, 50, 20, + 31, -263, 88, 152, 88, -414, -414, 88, 58, 223, + -414, -196, -179, -178, 77, 78, -180, 77, -178, 67, + 67, -253, 88, -261, -166, -196, -196, 223, 119, -413, + -148, 13, 90, 90, -381, -400, 714, 715, 32, 96, + -348, -348, 138, 138, -188, 87, -327, 90, -327, 96, + 96, 32, 83, 84, 85, 32, 79, 80, 81, -188, + -188, -188, -188, -369, 87, 20, -144, 87, 152, 89, + -252, -252, 278, 163, -348, 708, 284, 284, -348, -348, + -348, -115, -114, 730, 89, -414, 88, -335, 579, 582, + -144, -154, -154, -253, 89, -377, 579, -383, -291, -291, + -291, -291, 96, 98, -414, 577, 74, 580, -414, -327, + -144, -144, -144, -232, 90, -144, -144, 96, 96, -414, -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, -144, -144, -144, -144, -207, -144, -414, - -176, -175, -177, 690, 119, 32, -311, -414, -209, 276, - -100, -99, -98, 15, -414, -144, -118, -118, -118, -118, - -144, -144, -144, -144, -144, -144, -413, 67, 19, 17, - -413, -413, -300, -225, -226, 18, 20, -239, 54, -237, - 53, -237, -248, 20, 20, 90, 20, 90, 138, -272, - -144, -212, 58, -29, -291, -210, -291, -227, -144, 87, - -144, -156, -196, -196, -144, -202, 498, 500, 501, 502, - 499, 504, 505, 506, 507, 508, 509, 510, 511, 512, - 513, 503, 514, 475, 476, 477, 108, 110, 109, 478, - 479, 480, 344, 526, 527, 521, 524, 525, 523, 522, - 359, 360, 481, 544, 545, 549, 548, 546, 547, 550, - 553, 554, 555, 556, 557, 558, 560, 559, 551, 552, - 529, 528, 530, 531, 532, 533, 534, 535, 537, 536, - 538, 539, 540, 541, 542, 543, 561, 562, 563, 564, - 565, 567, 566, 571, 570, 568, 569, 573, 572, 482, - 483, 111, 112, 113, 114, 115, 116, 117, 484, 487, - 485, 488, 489, 490, 495, 496, 491, 492, 493, 494, - 497, 370, 368, 369, 365, 364, 363, 423, 428, 429, - 431, 515, 516, 517, 518, 519, 520, 671, 672, 673, - 674, 675, 676, 677, 678, 90, 90, 87, -144, 89, - 89, -253, -368, -60, 89, -254, -252, 96, 89, 279, - -211, -413, 90, -348, -348, -348, 96, 96, -299, -414, - 88, -291, -402, -370, 582, 582, -414, 26, -376, -375, - -293, 87, 78, 63, 577, 580, -414, -414, 88, -414, - -414, -414, 89, 89, -414, -414, -414, -414, -414, -414, + -144, -144, -144, -144, -144, -144, -144, -144, -144, -144, + -207, -144, -414, -176, -175, -177, 691, 119, 32, -311, + -414, -209, 276, -100, -99, -98, 15, -414, -144, -118, + -118, -118, -118, -144, -144, -144, -144, -144, -144, -413, + 67, 19, 17, -413, -413, -300, -225, -226, 18, 20, + -239, 54, -237, 53, -237, -248, 20, 20, 90, 20, + 90, 138, -272, -144, -212, 58, -29, -291, -210, -291, + -227, -144, 87, -144, -156, -196, -196, -144, -202, 499, + 501, 502, 503, 500, 505, 506, 507, 508, 509, 510, + 511, 512, 513, 514, 504, 515, 476, 477, 478, 108, + 110, 109, 479, 480, 481, 345, 527, 528, 522, 525, + 526, 524, 523, 360, 361, 482, 545, 546, 550, 549, + 547, 548, 551, 554, 555, 556, 557, 558, 559, 561, + 560, 552, 553, 530, 529, 531, 532, 533, 534, 535, + 536, 538, 537, 539, 540, 541, 542, 543, 544, 562, + 563, 564, 565, 566, 568, 567, 572, 571, 569, 570, + 574, 573, 483, 484, 111, 112, 113, 114, 115, 116, + 117, 485, 488, 486, 489, 490, 491, 496, 497, 492, + 493, 494, 495, 498, 371, 369, 370, 366, 365, 364, + 424, 429, 430, 432, 516, 517, 518, 519, 520, 521, + 672, 673, 674, 675, 676, 677, 678, 679, 90, 90, + 87, -144, 89, 89, -253, -368, -60, 89, -254, -252, + 96, 89, 279, -211, -413, 90, -348, -348, -348, 96, + 96, -299, -414, 88, -291, -402, -370, 583, 583, -414, + 26, -376, -375, -293, 87, 78, 63, 578, 581, -414, + -414, 88, -414, -414, -414, 89, 89, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, - -414, -414, -414, -414, -414, -414, 88, -414, -175, -177, - -414, 77, -156, -227, 20, -97, 301, 303, -97, -414, - -414, -414, -414, -414, 88, -414, -414, 88, -414, 88, - -414, -414, -255, -414, -291, 246, 20, 20, -255, -255, - -195, -226, -107, -106, -105, 608, -144, -207, -240, 55, - 77, 122, 90, 90, 90, 13, -210, 223, -232, -252, - -173, 383, -227, -414, -252, 89, 26, 89, 731, 138, - 89, -211, -124, -413, 275, -299, 90, 90, -114, -117, - -29, 88, 152, -252, -188, 63, -144, -207, -414, 77, - 589, 690, -92, -91, -88, 701, 727, -207, -94, -94, - -144, -144, -144, 88, -414, -414, -414, -107, 88, -104, - -103, -291, 77, 122, -264, -291, 89, -414, -413, -232, - 89, -236, -29, 87, -3, 275, -323, -373, -324, -325, - -5, -6, -349, -82, 578, -375, -353, -297, -293, 90, - 96, 89, 578, -414, -414, -90, 146, 699, 667, -154, - 222, -414, 88, -414, 88, -414, 88, -291, 246, -105, - 88, 26, -300, -174, -172, -291, 631, -393, -392, 574, - -403, -399, 119, 144, 101, -401, 669, 625, 128, 129, - -82, -144, 87, -414, -83, 290, 686, 223, -384, 579, - -90, 700, 645, 620, 645, 620, -149, -144, -144, -144, - -103, -413, -414, 88, 23, -315, -62, 642, -390, -391, - 77, -394, 389, 641, 662, 119, 90, 89, -252, 251, - -298, -377, 580, 143, -118, -414, 88, -414, 88, -414, - -93, -172, 638, -328, -156, -391, 77, -390, 77, 14, - 13, -4, 730, 89, 292, -90, 645, 620, -144, -144, - -414, -61, 27, -173, -389, 259, 254, 257, 33, -389, - 96, -4, -414, -414, 642, 253, 32, 119, -156, -176, - -175, -175, + -414, -414, -414, -414, -414, -414, -414, -414, -414, 88, + -414, -175, -177, -414, 77, -156, -227, 20, -97, 301, + 303, -97, -414, -414, -414, -414, -414, 88, -414, -414, + 88, -414, 88, -414, -414, -255, -414, -291, 246, 20, + 20, -255, -255, -195, -226, -107, -106, -105, 609, -144, + -207, -240, 55, 77, 122, 90, 90, 90, 13, -210, + 223, -232, -252, -173, 384, -227, -414, -252, 89, 26, + 89, 732, 138, 89, -211, -124, -413, 275, -299, 90, + 90, -114, -117, -29, 88, 152, -252, -188, 63, -144, + -207, -414, 77, 590, 691, -92, -91, -88, 702, 728, + -207, -94, -94, -144, -144, -144, 88, -414, -414, -414, + -107, 88, -104, -103, -291, 77, 122, -264, -291, 89, + -414, -413, -232, 89, -236, -29, 87, -3, 275, -323, + -373, -324, -325, -5, -6, -349, -82, 579, -375, -353, + -297, -293, 90, 96, 89, 579, -414, -414, -90, 146, + 700, 668, -154, 222, -414, 88, -414, 88, -414, 88, + -291, 246, -105, 88, 26, -300, -174, -172, -291, 632, + -393, -392, 575, -403, -399, 119, 144, 101, -401, 670, + 626, 128, 129, -82, -144, 87, -414, -83, 290, 687, + 223, -384, 580, -90, 701, 646, 621, 646, 621, -149, + -144, -144, -144, -103, -413, -414, 88, 23, -315, -62, + 643, -390, -391, 77, -394, 390, 642, 663, 119, 90, + 89, -252, 251, -298, -377, 581, 143, -118, -414, 88, + -414, 88, -414, -93, -172, 639, -328, -156, -391, 77, + -390, 77, 14, 13, -4, 731, 89, 292, -90, 646, + 621, -144, -144, -414, -61, 27, -173, -389, 259, 254, + 257, 33, -389, 96, -4, -414, -414, 643, 253, 32, + 119, -156, -176, -175, -175, } var yyDef = [...]int{ - 880, -2, -2, 882, 2, 4, 5, 6, 7, 8, + 882, -2, -2, 884, 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, 34, 35, 36, 37, 38, - 39, 72, 74, 75, 880, 880, 880, 0, 880, 0, - 0, 880, -2, -2, 880, 1616, 0, 880, 0, 875, - 0, -2, 795, 801, 0, 810, -2, 0, 0, 880, - 880, 2240, 2240, 875, 0, 0, 0, 0, 0, 880, - 880, 880, 880, 1621, 1477, 52, 880, 0, 87, 88, - 830, 831, 832, 67, 0, 2238, 881, 1, 3, 73, - 77, 0, 0, 0, 60, 1486, 0, 80, 0, 0, - 884, 0, 0, 1599, 880, 880, 0, 128, 129, 0, + 39, 72, 74, 75, 882, 882, 882, 0, 882, 0, + 0, 882, -2, -2, 882, 1618, 0, 882, 0, 877, + 0, -2, 797, 803, 0, 812, -2, 0, 0, 882, + 882, 2242, 2242, 877, 0, 0, 0, 0, 0, 882, + 882, 882, 882, 1623, 1479, 52, 882, 0, 87, 88, + 832, 833, 834, 67, 0, 2240, 883, 1, 3, 73, + 77, 0, 0, 0, 60, 1488, 0, 80, 0, 0, + 886, 0, 0, 1601, 882, 882, 0, 128, 129, 0, 0, 0, -2, 132, -2, 161, 162, 163, 0, 168, - 605, 526, 578, 524, 563, -2, 512, 0, 0, 0, + 607, 526, 578, 524, 563, -2, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, - 401, 401, 0, 0, -2, 512, 512, 512, 1601, 0, + 401, 401, 0, 0, -2, 512, 512, 512, 1603, 0, 0, 0, 560, 463, 401, 401, 401, 0, 401, 401, 401, 401, 0, 0, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 1504, 167, 1617, 1614, 1615, 1774, 1775, 1776, 1777, - 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, - 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, - 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, - 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, - 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, - 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, - 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, - 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, - 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, - 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, - 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, - 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, - 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, - 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, - 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, - 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, - 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, - 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, - 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, - 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, - 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, - 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, - 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, - 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, - 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, - 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, - 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, - 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, - 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, - 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, - 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, - 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, - 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, - 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, - 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, - 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, - 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, - 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, - 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, - 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, - 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, - 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, - 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, - 0, 1593, 0, 718, 983, 0, 876, 877, 0, 784, - 784, 0, 784, 784, 784, 784, 0, 0, 0, 732, - 0, 0, 0, 0, 781, 0, 748, 749, 0, 781, - 0, 755, 787, 0, 0, 762, 784, 784, 765, 2241, - 0, 2241, 2241, 1584, 0, 778, 776, 790, 791, 42, - 794, 797, 798, 799, 800, 803, 0, 814, 817, 1610, - 1611, 0, 819, 826, 843, 844, 0, 47, 1133, 0, - 1005, 0, 1011, -2, 1022, 1039, 1040, 1041, 1042, 1043, - 1045, 1046, 1047, 0, 0, 0, 0, 1052, 1053, 0, - 0, 0, 0, 0, 1114, 0, 0, 0, 0, 1450, - 0, 0, 1412, 1412, 1148, 1412, 1412, 1414, 1414, 1414, - 1826, 1964, 1972, 2148, 1787, 1793, 1794, 1795, 2094, 2095, - 2096, 2097, 2185, 2186, 2190, 1888, 1782, 2161, 2162, 0, - 2237, 1925, 1933, 1934, 1958, 2058, 2171, 1805, 1953, 2022, - 1885, 1907, 1908, 2040, 2041, 1929, 1930, 1911, 2100, 2102, - 2118, 2119, 2104, 2106, 2115, 2121, 2126, 2105, 2117, 2122, - 2135, 2139, 2142, 2143, 2144, 2112, 2110, 2123, 2127, 2129, - 2131, 2137, 2140, 2113, 2111, 2124, 2128, 2130, 2132, 2138, - 2141, 2099, 2103, 2107, 2116, 2134, 2114, 2133, 2108, 2120, - 2125, 2136, 2109, 2101, 1923, 1926, 1914, 1915, 1917, 1919, - 1924, 1931, 1937, 1916, 1936, 1935, 0, 1912, 1913, 1918, - 1928, 1932, 1920, 1921, 1922, 1927, 1938, 1978, 1977, 1976, - 2021, 1949, 2020, 0, 0, 0, 0, 0, 1777, 1831, - 1832, 2145, 1334, 1335, 1336, 1337, 0, 0, 0, 0, - 0, 0, 0, 293, 294, 1463, 1464, 46, 1132, 1580, - 1414, 1414, 1414, 1414, 1414, 1414, 1074, 1075, 1076, 1077, - 1078, 1102, 1103, 1109, 1110, 2035, 2036, 2037, 2038, 1869, - 2180, 1877, 1878, 2017, 2018, 1890, 1891, 2211, 2212, -2, + 401, 1506, 167, 1619, 1616, 1617, 1776, 1777, 1778, 1779, + 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, + 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, + 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, + 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, + 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, + 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, + 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, + 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, + 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, + 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, + 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, + 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, + 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, + 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, + 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, + 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, + 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, + 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, + 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, + 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, + 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, + 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, + 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, + 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, + 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, + 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, + 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, + 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, + 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, + 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, + 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, + 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, + 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, + 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, + 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, + 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, + 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, + 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, + 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, + 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, + 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, + 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, + 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, + 0, 1595, 0, 720, 985, 0, 878, 879, 0, 786, + 786, 0, 786, 786, 786, 786, 0, 0, 0, 734, + 0, 0, 0, 0, 783, 0, 750, 751, 0, 783, + 0, 757, 789, 0, 0, 764, 786, 786, 767, 2243, + 0, 2243, 2243, 1586, 0, 780, 778, 792, 793, 42, + 796, 799, 800, 801, 802, 805, 0, 816, 819, 1612, + 1613, 0, 821, 828, 845, 846, 0, 47, 1135, 0, + 1007, 0, 1013, -2, 1024, 1041, 1042, 1043, 1044, 1045, + 1047, 1048, 1049, 0, 0, 0, 0, 1054, 1055, 0, + 0, 0, 0, 0, 1116, 0, 0, 0, 0, 1452, + 0, 0, 1414, 1414, 1150, 1414, 1414, 1416, 1416, 1416, + 1828, 1966, 1974, 2150, 1789, 1795, 1796, 1797, 2096, 2097, + 2098, 2099, 2187, 2188, 2192, 1890, 1784, 2163, 2164, 0, + 2239, 1927, 1935, 1936, 1960, 2060, 2173, 1807, 1955, 2024, + 1887, 1909, 1910, 2042, 2043, 1931, 1932, 1913, 2102, 2104, + 2120, 2121, 2106, 2108, 2117, 2123, 2128, 2107, 2119, 2124, + 2137, 2141, 2144, 2145, 2146, 2114, 2112, 2125, 2129, 2131, + 2133, 2139, 2142, 2115, 2113, 2126, 2130, 2132, 2134, 2140, + 2143, 2101, 2105, 2109, 2118, 2136, 2116, 2135, 2110, 2122, + 2127, 2138, 2111, 2103, 1925, 1928, 1916, 1917, 1919, 1921, + 1926, 1933, 1939, 1918, 1938, 1937, 0, 1914, 1915, 1920, + 1930, 1934, 1922, 1923, 1924, 1929, 1940, 1980, 1979, 1978, + 2023, 1951, 2022, 0, 0, 0, 0, 0, 1779, 1833, + 1834, 2147, 1336, 1337, 1338, 1339, 0, 0, 0, 0, + 0, 0, 0, 293, 294, 1465, 1466, 46, 1134, 1582, + 1416, 1416, 1416, 1416, 1416, 1416, 1076, 1077, 1078, 1079, + 1080, 1104, 1105, 1111, 1112, 2037, 2038, 2039, 2040, 1871, + 2182, 1879, 1880, 2019, 2020, 1892, 1893, 2213, 2214, -2, -2, -2, 234, 235, 236, 237, 238, 239, 240, 241, - 0, 1830, 2159, 2160, 230, 0, 0, 298, 299, 295, - 296, 297, 1116, 1117, 251, 252, 253, 254, 255, 256, + 0, 1832, 2161, 2162, 230, 0, 0, 298, 299, 295, + 296, 297, 1118, 1119, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 2240, 0, 853, 0, - 0, 0, 0, 0, 0, 1622, 1623, 1486, 0, 1478, - 1477, 65, 0, 880, -2, 0, 0, 0, 0, 49, - 0, 54, 940, 883, 79, 78, 1526, 1529, 0, 0, - 0, 61, 1487, 69, 71, 1488, 0, 885, 886, 0, - 916, 920, 0, 0, 0, 1600, 1599, 1599, 104, 0, - 0, 105, 125, 126, 127, 0, 0, 111, 112, 1586, - 1587, 45, 0, 0, 179, 180, 0, 43, 428, 0, - 175, 0, 421, 360, 0, 1504, 0, 0, 0, 0, - 0, 880, 0, 1594, 156, 157, 164, 165, 166, 401, + 287, 288, 289, 290, 291, 292, 2242, 0, 855, 0, + 0, 0, 0, 0, 0, 1624, 1625, 1488, 0, 1480, + 1479, 65, 0, 882, -2, 0, 0, 0, 0, 49, + 0, 54, 942, 885, 79, 78, 1528, 1531, 0, 0, + 0, 61, 1489, 69, 71, 1490, 0, 887, 888, 0, + 918, 922, 0, 0, 0, 1602, 1601, 1601, 104, 0, + 0, 105, 125, 126, 127, 0, 0, 111, 112, 1588, + 1589, 45, 0, 0, 179, 180, 0, 43, 428, 0, + 175, 0, 421, 360, 0, 1506, 0, 0, 0, 0, + 0, 882, 0, 1596, 156, 157, 164, 165, 166, 401, 401, 401, 575, 0, 0, 167, 167, 533, 534, 535, 0, 0, -2, 426, 0, 513, 0, 0, 415, 415, 419, 417, 418, 0, 0, 0, 0, 0, 0, 0, 0, 552, 0, 553, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 666, 0, 402, 0, 573, 574, 464, - 0, 0, 0, 0, 0, 0, 0, 0, 1602, 1603, + 0, 0, 0, 668, 0, 402, 0, 573, 574, 464, + 0, 0, 0, 0, 0, 0, 0, 0, 1604, 1605, 0, 550, 551, 0, 0, 0, 401, 401, 0, 0, 0, 0, 401, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 155, 1517, 0, 0, 0, -2, 0, 710, - 0, 0, 0, 1595, 1595, 0, 717, 0, 0, 0, - 722, 0, 0, 723, 0, 781, 781, 779, 780, 725, - 726, 727, 728, 784, 0, 0, 410, 411, 412, 781, - 784, 0, 784, 784, 784, 784, 781, 781, 781, 784, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2241, - 787, 784, 0, 756, 0, 757, 758, 759, 760, 763, - 764, 766, 2242, 2243, 1612, 1613, 1624, 1625, 1626, 1627, - 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, - 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, - 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, - 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, - 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, - 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, - 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, - 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, - 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, - 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, - 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, - 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, - 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, - 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, - 1768, 1769, 1770, 1771, 1772, 1773, 2241, 2241, 770, 774, - 1585, 796, 802, 804, 805, 0, 0, 815, 818, 837, - 51, 1876, 825, 51, 827, 828, 829, 855, 856, 861, - 0, 0, 0, 0, 867, 868, 869, 0, 0, 872, - 873, 874, 0, 0, 0, 0, 0, 1003, 0, 0, - 1122, 1123, 1124, 1125, 1126, 1127, 1128, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1023, 1024, 0, 0, 0, - 1048, 1049, 1050, 1051, 1054, 0, 1065, 0, 1067, 1459, - -2, 0, 0, 0, 1059, 1060, 0, 0, 0, 0, - 0, 0, 0, 1451, 0, 0, 1146, 0, 1147, 1149, - 1150, 1151, 0, 1152, 1153, 890, 890, 890, 890, 890, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 890, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1605, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 155, 1519, 0, 0, 0, -2, 0, 712, + 0, 0, 0, 1597, 1597, 0, 719, 0, 0, 0, + 724, 0, 0, 725, 0, 783, 783, 781, 782, 727, + 728, 729, 730, 786, 0, 0, 410, 411, 412, 783, + 786, 0, 786, 786, 786, 786, 783, 783, 783, 786, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2243, + 789, 786, 0, 758, 0, 759, 760, 761, 762, 765, + 766, 768, 2244, 2245, 1614, 1615, 1626, 1627, 1628, 1629, + 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, + 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, + 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, + 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, + 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, + 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, + 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, + 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, + 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, + 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, + 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, + 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, + 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, + 1770, 1771, 1772, 1773, 1774, 1775, 2243, 2243, 772, 776, + 1587, 798, 804, 806, 807, 0, 0, 817, 820, 839, + 51, 1878, 827, 51, 829, 830, 831, 857, 858, 863, + 0, 0, 0, 0, 869, 870, 871, 0, 0, 874, + 875, 876, 0, 0, 0, 0, 0, 1005, 0, 0, + 1124, 1125, 1126, 1127, 1128, 1129, 1130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1025, 1026, 0, 0, 0, + 1050, 1051, 1052, 1053, 1056, 0, 1067, 0, 1069, 1461, + -2, 0, 0, 0, 1061, 1062, 0, 0, 0, 0, + 0, 0, 0, 1453, 0, 0, 1148, 0, 1149, 1151, + 1152, 1153, 0, 1154, 1155, 892, 892, 892, 892, 892, + 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, 1607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -9410,257 +9480,257 @@ var yyDef = [...]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, 900, 0, 0, - 900, 900, 0, 0, 222, 223, 224, 225, 226, 227, + 0, 0, 0, 0, 0, 0, 0, 902, 0, 0, + 902, 902, 0, 0, 222, 223, 224, 225, 226, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 243, 244, 245, 246, 247, - 300, 248, 249, 250, 1132, 0, 0, 0, 48, 845, - 846, 0, 966, 1605, 0, 0, 896, 0, 1620, 59, - 68, 70, 1486, 63, 1486, 0, 902, 0, 0, -2, - -2, 903, 909, 910, 911, 912, 913, 56, 2239, 57, - 0, 76, 0, 50, 0, 0, 1527, 0, 1530, 0, - 0, 0, 374, 1534, 0, 0, 1479, 1480, 1483, 0, - 917, 1970, 921, 0, 923, 924, 0, 0, 102, 0, - 982, 0, 0, 0, 113, 0, 115, 116, 0, 0, - 0, 385, 1588, 1589, 1590, -2, 408, 0, 385, 369, + 300, 248, 249, 250, 1134, 0, 0, 0, 48, 847, + 848, 0, 968, 1607, 0, 0, 898, 0, 1622, 59, + 68, 70, 1488, 63, 1488, 0, 904, 0, 0, -2, + -2, 905, 911, 912, 913, 914, 915, 56, 2241, 57, + 0, 76, 0, 50, 0, 0, 1529, 0, 1532, 0, + 0, 0, 374, 1536, 0, 0, 1481, 1482, 1485, 0, + 919, 1972, 923, 0, 925, 926, 0, 0, 102, 0, + 984, 0, 0, 0, 113, 0, 115, 116, 0, 0, + 0, 385, 1590, 1591, 1592, -2, 408, 0, 385, 369, 308, 309, 310, 360, 312, 360, 360, 360, 360, 374, 374, 374, 374, 343, 344, 345, 346, 347, 0, 0, 329, 360, 360, 360, 360, 350, 351, 352, 353, 354, 355, 356, 357, 313, 314, 315, 316, 317, 318, 319, 320, 321, 362, 362, 362, 362, 362, 366, 366, 0, - 44, 0, 389, 0, 1483, 0, 0, 1517, 1597, 1607, - 0, 0, 0, 1597, 134, 0, 0, 0, 576, 616, + 44, 0, 389, 0, 1485, 0, 0, 1519, 1599, 1609, + 0, 0, 0, 1599, 134, 0, 0, 0, 576, 618, 527, 564, 577, 0, 530, 531, -2, 0, 0, 512, 0, 514, 0, 409, 0, -2, 0, 419, 0, 415, 419, 416, 419, 407, 420, 554, 555, 556, 0, 558, - 559, 646, 952, 0, 0, 0, 0, 0, 652, 653, - 654, 0, 656, 657, 658, 659, 660, 661, 662, 663, - 664, 665, 565, 566, 567, 568, 569, 570, 571, 572, + 559, 648, 954, 0, 0, 0, 0, 0, 654, 655, + 656, 0, 658, 659, 660, 661, 662, 663, 664, 665, + 666, 667, 565, 566, 567, 568, 569, 570, 571, 572, 0, 0, 0, 0, 514, 0, 561, 0, 0, 465, 466, 467, 0, 0, 470, 471, 472, 473, 0, 0, - 476, 477, 478, 969, 970, 479, 480, 505, 506, 507, + 476, 477, 478, 971, 972, 479, 480, 505, 506, 507, 481, 482, 483, 484, 485, 486, 487, 499, 500, 501, 502, 503, 504, 488, 489, 490, 491, 492, 493, 496, - 0, 149, 1508, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1595, 0, - 0, 0, 0, 899, 984, 1618, 1619, 719, 0, 0, - 785, 786, 0, 413, 414, 784, 784, 729, 771, 0, - 784, 733, 772, 734, 736, 735, 737, 750, 751, 784, - 740, 782, 783, 741, 742, 743, 744, 745, 746, 747, - 767, 752, 753, 754, 788, 0, 792, 793, 768, 769, - 0, 0, 808, 809, 0, 816, 840, 838, 839, 841, - 833, 834, 835, 836, 0, 842, 0, 0, 858, 98, - 863, 864, 865, 866, 878, 871, 1134, 1000, 1001, 1002, - 0, 1004, 1008, 0, 1118, 1120, 1010, 1006, 1012, 1129, - 1130, 1131, 0, 0, 0, 0, 0, 1016, 1020, 1025, - 1026, 1027, 1028, 1029, 0, 1030, 0, 1033, 1034, 1035, - 1036, 1037, 1038, 1044, 1427, 1428, 1429, 1063, 301, 302, - 0, 1064, 0, 0, 0, 0, 0, 0, 0, 0, - 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, - 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, - 1133, 0, 914, 0, 0, 1457, 1454, 0, 0, 0, - 1413, 1415, 0, 0, 0, 891, 892, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1394, 1395, 1396, 1397, 1398, 1399, - 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, - 1410, 1411, 0, 0, 1430, 0, 0, 0, 0, 0, - 1450, 0, 1069, 1070, 1071, 0, 0, 0, 0, 0, - 0, 1192, 0, 0, 0, 0, 1606, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 144, 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, 0, 0, 1338, 1339, - 1340, 1341, 41, 0, 0, 0, 0, 0, 0, 0, - 901, 1461, 0, -2, -2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1363, 0, - 0, 0, 0, 0, 0, 1578, 0, 0, 848, 849, - 851, 0, 986, 0, 967, 0, 0, 854, 0, 895, - 0, 898, 62, 64, 907, 908, 0, 925, 904, 58, - 53, 0, 0, 944, 1528, 1531, 1532, 374, 1554, 0, - 383, 383, 380, 1489, 1490, 0, 1482, 1484, 1485, 81, - 922, 918, 0, 998, 0, 0, 981, 0, 928, 930, - 931, 932, 964, 0, 935, 936, 0, 0, 0, 0, - 0, 100, 983, 106, 0, 114, 0, 0, 119, 120, - 107, 108, 109, 110, 0, 605, -2, 460, 181, 183, - 184, 185, 176, -2, 372, 370, 371, 311, 374, 374, - 337, 338, 339, 340, 341, 342, 0, 0, 330, 331, - 332, 333, 322, 0, 323, 324, 325, 364, 0, 326, - 327, 0, 328, 427, 0, 1491, 390, 391, 393, 401, - 0, 396, 397, 0, 401, 401, 0, 422, 423, 0, - 1483, 1508, 0, 0, 0, 1608, 1607, 1607, 1607, 0, - 169, 170, 171, 172, 173, 174, 641, 0, 0, 617, - 639, 640, 167, 0, 0, 177, 516, 515, 0, 673, - 0, 425, 0, 0, 419, 419, 404, 405, 557, 0, - 0, 648, 649, 650, 651, 0, 0, 0, 543, 454, - 0, 544, 545, 514, 516, 0, 0, 385, 468, 469, - 474, 475, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 592, 593, 594, 597, 599, - 518, 603, 596, 598, 600, 518, 604, 1505, 1506, 1507, - 0, 0, 711, 0, 0, 451, 96, 1596, 716, 720, - 721, 781, 739, 773, 781, 731, 738, 761, 806, 807, - 812, 820, 821, 822, 823, 824, 862, 0, 0, 0, - 0, 870, 0, 0, 1009, 1119, 1121, 1013, 0, 1017, - 1021, 0, 0, 0, 0, 0, 1068, 1066, 1461, 0, - 0, 0, 1115, 0, 0, 0, 1137, 1138, 0, 0, - 0, 1455, 0, 0, 1144, 0, 1416, 1154, 0, 0, - 0, 0, 0, 1160, 1161, 1162, 1163, 1164, 1165, 1166, - 1167, 1168, 1169, 1477, 1171, 0, 0, 0, 0, 0, - 1176, 1177, 1178, 1179, 1180, 0, 1182, 0, 1183, 0, - 0, 0, 0, 1190, 1191, 1193, 0, 0, 1196, 1197, - 0, 1199, 0, 1201, 1202, 1203, 1204, 1205, 1206, 0, - 1208, 0, 1210, 1211, 1212, 0, 1214, 0, 1216, 1217, - 0, 1219, 0, 1221, 0, 1224, 0, 1227, 0, 1230, - 0, 1233, 0, 1236, 0, 1239, 0, 1242, 0, 1245, - 0, 1248, 0, 1251, 0, 1254, 0, 1257, 0, 1260, - 0, 1263, 0, 1266, 0, 1269, 1270, 1271, 0, 1273, - 0, 1275, 0, 1278, 1279, 0, 1281, 0, 1284, 0, - 1287, 0, 0, 1288, 0, 0, 0, 1292, 0, 0, - 0, 0, 1301, 1302, 1303, 1304, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1315, 1316, 1317, 1318, - 1319, 1320, 0, 1322, 0, 1097, 0, 0, 1097, 0, - 0, 0, 0, 0, 1135, 900, 0, 1417, 1418, 1419, - 1420, 1421, 0, 0, 0, 0, 0, 0, 1361, 1362, - 1364, 0, 0, 1367, 0, 1369, 0, 1579, 847, 850, - 852, 938, 987, 988, 0, 0, 0, 0, 968, 1604, - 893, 894, 897, 946, 0, 1465, 0, 0, 925, 998, - 926, 0, 905, 55, 941, 0, 1536, 1535, 1548, 1561, - 383, 383, 377, 378, 384, 379, 381, 382, 1481, 0, - 1486, 0, 1572, 0, 0, 1564, 0, 0, 0, 0, - 0, 0, 0, 0, 971, 0, 0, 974, 0, 0, - 0, 0, 965, 936, 0, 937, 0, -2, 0, 0, - 94, 95, 0, 0, 0, 117, 118, 0, 0, 124, - 386, 387, 158, 167, 462, 182, 435, 0, 0, 307, - 373, 334, 335, 336, 0, 358, 0, 0, 0, 0, - 456, 130, 1495, 1494, 401, 401, 392, 0, 395, 0, - 0, 0, 1609, 361, 424, 0, 148, 0, 0, 0, - 0, 0, 154, 611, 0, 0, 618, 0, 0, 0, - 525, 0, 536, 537, 0, 645, -2, 707, 389, 0, - 403, 406, 953, 0, 0, 538, 0, 541, 542, 455, - 516, 547, 548, 562, 549, 497, 498, 495, 0, 0, - 1518, 1519, 1524, 1522, 1523, 135, 583, 585, 589, 584, - 588, 0, 0, 0, 520, 0, 520, 581, 0, 451, - 1491, 0, 715, 452, 453, 784, 784, 857, 99, 0, - 860, 0, 0, 0, 0, 1014, 1018, 1031, 1032, 1422, - 1448, 360, 360, 1435, 360, 366, 1438, 360, 1440, 360, - 1443, 360, 1446, 1447, 0, 0, 1061, 0, 915, 0, - 0, 1143, 1458, 0, 0, 1155, 1156, 1157, 1158, 1159, - 1452, 0, 0, 0, 1175, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 146, 147, 0, 0, 0, - 0, 0, 0, 1372, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1092, 1096, 0, 1098, 1099, - 0, 0, 1324, 0, 0, 1342, 0, 0, 0, 0, - 0, 0, 0, 1462, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 989, 994, 994, 994, 0, 0, - 0, 1591, 1592, 1466, 1467, 998, 1468, 927, 906, 945, - 1554, 0, 1547, 0, -2, 1556, 0, 0, 0, 1562, - 375, 376, 919, 82, 999, 85, 0, 1572, 1581, 0, - 1563, 1574, 1576, 0, 0, 0, 1568, 0, 998, 929, - 960, 962, 0, 957, 972, 973, 975, 0, 977, 0, - 979, 980, 940, 934, 0, 102, 0, 998, 998, 101, - 0, 985, 121, 122, 123, 461, 186, 191, 0, 0, - 0, 196, 0, 198, 0, 0, 0, 203, 204, 401, - 401, 436, 0, 304, 306, 0, 0, 189, 374, 0, - 374, 0, 365, 367, 0, 437, 457, 1492, 1493, 0, - 0, 394, 398, 399, 400, 0, 1598, 150, 0, 0, - 0, 614, 0, 642, 0, 0, 0, 0, 0, 0, - 178, 517, 674, 675, 676, 677, 678, 679, 680, 681, - 682, 0, 401, 0, 0, 0, 401, 401, 401, 0, - 699, 388, 0, 0, 670, 667, 539, 0, 220, 221, - 228, 229, 231, 0, 0, 0, 0, 0, 546, 940, - 1509, 1510, 1511, 0, 1521, 1525, 138, 0, 0, 0, - 0, 591, 595, 601, 0, 519, 602, 712, 713, 714, - 97, 724, 730, 859, 879, 1007, 1015, 1019, 0, 0, - 0, 0, 1449, 1433, 374, 1436, 1437, 1439, 1441, 1442, - 1444, 1445, 1057, 1058, 1062, 0, 1140, 0, 1142, 1456, - 0, 1486, 0, 0, 0, 1174, 0, 0, 0, 1185, - 1184, 1186, 0, 1188, 1189, 1194, 1195, 1198, 1200, 1207, - 1209, 1213, 1215, 1218, 1220, 1222, 0, 1225, 0, 1228, - 0, 1231, 0, 1234, 0, 1237, 0, 1240, 0, 1243, - 0, 1246, 0, 1249, 0, 1252, 0, 1255, 0, 1258, - 0, 1261, 0, 1264, 0, 1267, 0, 1272, 1274, 0, - 1277, 1280, 1282, 0, 1285, 0, 1289, 0, 1291, 1293, - 1294, 0, 0, 0, 1305, 1306, 1307, 1308, 1309, 1310, - 1311, 1312, 1313, 1314, 1321, 0, 1090, 1093, 1323, 1100, - 1101, 1106, 1326, 0, 0, 0, 1329, 0, 0, 0, - 1333, 1136, 1344, 0, 1349, 0, 0, 1355, 0, 1359, - 0, 1365, 1366, 1368, 1370, 0, 0, 0, 0, 0, - 966, 947, 66, 1468, 1470, 0, 1541, 1539, 1539, 1549, - 1550, 0, 0, 1557, 0, 0, 0, 0, 86, 0, - 0, 0, 1577, 0, 0, 0, 0, 103, 1477, 954, - 961, 0, 0, 955, 0, 956, 976, 978, 933, 0, - 998, 998, 92, 93, 0, 192, 0, 194, 0, 197, - 199, 200, 201, 207, 208, 209, 202, 0, 0, 303, - 305, 0, 0, 348, 359, 349, 0, 0, 1496, 1497, - 1498, 1499, 1500, 1501, 1502, 1503, 940, 151, 152, 153, - 606, 0, 616, 0, 942, 0, 609, 0, 528, 0, - 0, 0, 401, 401, 401, 0, 0, 0, 0, 684, - 0, 0, 647, 0, 655, 0, 0, 0, 232, 233, - 0, 1520, 582, 0, 136, 137, 0, 0, 587, 521, - 522, 1055, 0, 0, 0, 1056, 1434, 0, 0, 0, - 0, 1453, 0, 0, 0, 0, 1181, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1297, - 0, 0, 0, 636, 637, 0, 1373, 1095, 1477, 0, - 1097, 1107, 1108, 0, 1097, 1343, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 995, 0, 0, - 0, 0, 986, 1470, 1475, 0, 0, 1544, 0, 1537, - 1540, 1538, 1551, 0, 0, 1558, 0, 1560, 0, 1582, - 1583, 1575, 0, 1567, 1570, 1566, 1569, 1486, 958, 0, - 963, 0, 1477, 91, 0, 195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 205, 206, 0, 0, 363, - 368, 0, 0, 0, 607, 0, 943, 619, 610, 0, - 697, 0, 701, 0, 0, 0, 704, 705, 706, 683, - 0, 687, 429, 671, 668, 669, 540, 0, 139, 140, - 0, 0, 0, 1423, 0, 1426, 1139, 1141, 0, 1170, - 1172, 1173, 1431, 1432, 1187, 1223, 1226, 1229, 1232, 1235, - 1238, 1241, 1244, 1247, 1250, 1253, 1256, 1259, 1262, 1265, - 1268, 1276, 1283, 1286, 1290, 1295, 0, 1298, 0, 0, - 1299, 0, 638, 1086, 0, 0, 1104, 1105, 0, 1328, - 1330, 1331, 1332, 1345, 0, 1350, 1351, 0, 1356, 0, - 1360, 1371, 0, 991, 948, 949, 996, 997, 0, 0, - 939, 1475, 84, 1476, 1473, 0, 1471, 1469, 1533, 0, - 1542, 1543, 1552, 1553, 1559, 0, 1565, 0, 89, 0, - 0, 0, 1486, 193, 0, 212, 0, 615, 0, 618, - 608, 695, 696, 0, 708, 700, 702, 703, 685, -2, - 1512, 0, 0, 0, 590, 1424, 0, 0, 1300, 0, - 634, 635, 1094, 1087, 0, 1072, 1073, 1091, 1325, 1327, - 0, 0, 0, 0, 990, 992, 993, 83, 0, 1472, - 1112, 0, 1545, 1546, 1573, 1571, 959, 966, 0, 90, - 442, 435, 1512, 0, 0, 0, 688, 689, 690, 691, - 692, 693, 694, 579, 1514, 141, 142, 0, 509, 510, - 511, 135, 0, 1145, 1296, 1088, 0, 0, 0, 0, - 0, 1346, 0, 1352, 0, 1357, 0, 950, 951, 1474, - 0, 0, 620, 0, 622, 0, -2, 430, 443, 0, - 187, 213, 214, 0, 0, 217, 218, 219, 210, 211, - 131, 0, 0, 709, 0, 1515, 1516, 0, 138, 0, - 0, 1079, 1080, 1081, 1082, 1084, 0, 0, 0, 0, - 1113, 1092, 621, 0, 0, 385, 0, 631, 431, 432, - 0, 438, 439, 440, 441, 215, 216, 643, 0, 0, - 508, 586, 1425, 0, 0, 1347, 0, 1353, 0, 1358, - 0, 623, 624, 632, 0, 433, 0, 434, 0, 0, - 0, 612, 0, 643, 1513, 1089, 1083, 1085, 0, 0, - 1111, 0, 633, 629, 444, 446, 447, 0, 0, 445, - 644, 613, 1348, 1354, 0, 448, 449, 450, 625, 626, - 627, 628, + 0, 149, 1510, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1597, + 0, 0, 0, 0, 901, 986, 1620, 1621, 721, 0, + 0, 787, 788, 0, 413, 414, 786, 786, 731, 773, + 0, 786, 735, 774, 736, 738, 737, 739, 752, 753, + 786, 742, 784, 785, 743, 744, 745, 746, 747, 748, + 749, 769, 754, 755, 756, 790, 0, 794, 795, 770, + 771, 0, 0, 810, 811, 0, 818, 842, 840, 841, + 843, 835, 836, 837, 838, 0, 844, 0, 0, 860, + 98, 865, 866, 867, 868, 880, 873, 1136, 1002, 1003, + 1004, 0, 1006, 1010, 0, 1120, 1122, 1012, 1008, 1014, + 1131, 1132, 1133, 0, 0, 0, 0, 0, 1018, 1022, + 1027, 1028, 1029, 1030, 1031, 0, 1032, 0, 1035, 1036, + 1037, 1038, 1039, 1040, 1046, 1429, 1430, 1431, 1065, 301, + 302, 0, 1066, 0, 0, 0, 0, 0, 0, 0, + 0, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, + 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, + 1395, 1135, 0, 916, 0, 0, 1459, 1456, 0, 0, + 0, 1415, 1417, 0, 0, 0, 893, 894, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1396, 1397, 1398, 1399, 1400, + 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, + 1411, 1412, 1413, 0, 0, 1432, 0, 0, 0, 0, + 0, 1452, 0, 1071, 1072, 1073, 0, 0, 0, 0, + 0, 0, 1194, 0, 0, 0, 0, 1608, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 144, 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, 0, 0, 1340, + 1341, 1342, 1343, 41, 0, 0, 0, 0, 0, 0, + 0, 903, 1463, 0, -2, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, + 0, 0, 0, 0, 0, 0, 1580, 0, 0, 850, + 851, 853, 0, 988, 0, 969, 0, 0, 856, 0, + 897, 0, 900, 62, 64, 909, 910, 0, 927, 906, + 58, 53, 0, 0, 946, 1530, 1533, 1534, 374, 1556, + 0, 383, 383, 380, 1491, 1492, 0, 1484, 1486, 1487, + 81, 924, 920, 0, 1000, 0, 0, 983, 0, 930, + 932, 933, 934, 966, 0, 937, 938, 0, 0, 0, + 0, 0, 100, 985, 106, 0, 114, 0, 0, 119, + 120, 107, 108, 109, 110, 0, 607, -2, 460, 181, + 183, 184, 185, 176, -2, 372, 370, 371, 311, 374, + 374, 337, 338, 339, 340, 341, 342, 0, 0, 330, + 331, 332, 333, 322, 0, 323, 324, 325, 364, 0, + 326, 327, 0, 328, 427, 0, 1493, 390, 391, 393, + 401, 0, 396, 397, 0, 401, 401, 0, 422, 423, + 0, 1485, 1510, 0, 0, 0, 1610, 1609, 1609, 1609, + 0, 169, 170, 171, 172, 173, 174, 643, 0, 0, + 619, 641, 642, 167, 0, 0, 177, 516, 515, 0, + 675, 0, 425, 0, 0, 419, 419, 404, 405, 557, + 0, 0, 650, 651, 652, 653, 0, 0, 0, 543, + 454, 0, 544, 545, 514, 516, 0, 0, 385, 468, + 469, 474, 475, 494, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 592, 593, 594, 597, + 599, 518, 603, 605, 596, 598, 600, 518, 604, 606, + 1507, 1508, 1509, 0, 0, 713, 0, 0, 451, 96, + 1598, 718, 722, 723, 783, 741, 775, 783, 733, 740, + 763, 808, 809, 814, 822, 823, 824, 825, 826, 864, + 0, 0, 0, 0, 872, 0, 0, 1011, 1121, 1123, + 1015, 0, 1019, 1023, 0, 0, 0, 0, 0, 1070, + 1068, 1463, 0, 0, 0, 1117, 0, 0, 0, 1139, + 1140, 0, 0, 0, 1457, 0, 0, 1146, 0, 1418, + 1156, 0, 0, 0, 0, 0, 1162, 1163, 1164, 1165, + 1166, 1167, 1168, 1169, 1170, 1171, 1479, 1173, 0, 0, + 0, 0, 0, 1178, 1179, 1180, 1181, 1182, 0, 1184, + 0, 1185, 0, 0, 0, 0, 1192, 1193, 1195, 0, + 0, 1198, 1199, 0, 1201, 0, 1203, 1204, 1205, 1206, + 1207, 1208, 0, 1210, 0, 1212, 1213, 1214, 0, 1216, + 0, 1218, 1219, 0, 1221, 0, 1223, 0, 1226, 0, + 1229, 0, 1232, 0, 1235, 0, 1238, 0, 1241, 0, + 1244, 0, 1247, 0, 1250, 0, 1253, 0, 1256, 0, + 1259, 0, 1262, 0, 1265, 0, 1268, 0, 1271, 1272, + 1273, 0, 1275, 0, 1277, 0, 1280, 1281, 0, 1283, + 0, 1286, 0, 1289, 0, 0, 1290, 0, 0, 0, + 1294, 0, 0, 0, 0, 1303, 1304, 1305, 1306, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1317, + 1318, 1319, 1320, 1321, 1322, 0, 1324, 0, 1099, 0, + 0, 1099, 0, 0, 0, 0, 0, 1137, 902, 0, + 1419, 1420, 1421, 1422, 1423, 0, 0, 0, 0, 0, + 0, 1363, 1364, 1366, 0, 0, 1369, 0, 1371, 0, + 1581, 849, 852, 854, 940, 989, 990, 0, 0, 0, + 0, 970, 1606, 895, 896, 899, 948, 0, 1467, 0, + 0, 927, 1000, 928, 0, 907, 55, 943, 0, 1538, + 1537, 1550, 1563, 383, 383, 377, 378, 384, 379, 381, + 382, 1483, 0, 1488, 0, 1574, 0, 0, 1566, 0, + 0, 0, 0, 0, 0, 0, 0, 973, 0, 0, + 976, 0, 0, 0, 0, 967, 938, 0, 939, 0, + -2, 0, 0, 94, 95, 0, 0, 0, 117, 118, + 0, 0, 124, 386, 387, 158, 167, 462, 182, 435, + 0, 0, 307, 373, 334, 335, 336, 0, 358, 0, + 0, 0, 0, 456, 130, 1497, 1496, 401, 401, 392, + 0, 395, 0, 0, 0, 1611, 361, 424, 0, 148, + 0, 0, 0, 0, 0, 154, 613, 0, 0, 620, + 0, 0, 0, 525, 0, 536, 537, 0, 647, -2, + 709, 389, 0, 403, 406, 955, 0, 0, 538, 0, + 541, 542, 455, 516, 547, 548, 562, 549, 497, 498, + 495, 0, 0, 1520, 1521, 1526, 1524, 1525, 135, 583, + 585, 589, 584, 588, 0, 0, 0, 520, 0, 520, + 581, 0, 451, 1493, 0, 717, 452, 453, 786, 786, + 859, 99, 0, 862, 0, 0, 0, 0, 1016, 1020, + 1033, 1034, 1424, 1450, 360, 360, 1437, 360, 366, 1440, + 360, 1442, 360, 1445, 360, 1448, 1449, 0, 0, 1063, + 0, 917, 0, 0, 1145, 1460, 0, 0, 1157, 1158, + 1159, 1160, 1161, 1454, 0, 0, 0, 1177, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 146, 147, + 0, 0, 0, 0, 0, 0, 1374, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1094, 1098, + 0, 1100, 1101, 0, 0, 1326, 0, 0, 1344, 0, + 0, 0, 0, 0, 0, 0, 1464, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 991, 996, 996, + 996, 0, 0, 0, 1593, 1594, 1468, 1469, 1000, 1470, + 929, 908, 947, 1556, 0, 1549, 0, -2, 1558, 0, + 0, 0, 1564, 375, 376, 921, 82, 1001, 85, 0, + 1574, 1583, 0, 1565, 1576, 1578, 0, 0, 0, 1570, + 0, 1000, 931, 962, 964, 0, 959, 974, 975, 977, + 0, 979, 0, 981, 982, 942, 936, 0, 102, 0, + 1000, 1000, 101, 0, 987, 121, 122, 123, 461, 186, + 191, 0, 0, 0, 196, 0, 198, 0, 0, 0, + 203, 204, 401, 401, 436, 0, 304, 306, 0, 0, + 189, 374, 0, 374, 0, 365, 367, 0, 437, 457, + 1494, 1495, 0, 0, 394, 398, 399, 400, 0, 1600, + 150, 0, 0, 0, 616, 0, 644, 0, 0, 0, + 0, 0, 0, 178, 517, 676, 677, 678, 679, 680, + 681, 682, 683, 684, 0, 401, 0, 0, 0, 401, + 401, 401, 0, 701, 388, 0, 0, 672, 669, 539, + 0, 220, 221, 228, 229, 231, 0, 0, 0, 0, + 0, 546, 942, 1511, 1512, 1513, 0, 1523, 1527, 138, + 0, 0, 0, 0, 591, 595, 601, 0, 519, 602, + 714, 715, 716, 97, 726, 732, 861, 881, 1009, 1017, + 1021, 0, 0, 0, 0, 1451, 1435, 374, 1438, 1439, + 1441, 1443, 1444, 1446, 1447, 1059, 1060, 1064, 0, 1142, + 0, 1144, 1458, 0, 1488, 0, 0, 0, 1176, 0, + 0, 0, 1187, 1186, 1188, 0, 1190, 1191, 1196, 1197, + 1200, 1202, 1209, 1211, 1215, 1217, 1220, 1222, 1224, 0, + 1227, 0, 1230, 0, 1233, 0, 1236, 0, 1239, 0, + 1242, 0, 1245, 0, 1248, 0, 1251, 0, 1254, 0, + 1257, 0, 1260, 0, 1263, 0, 1266, 0, 1269, 0, + 1274, 1276, 0, 1279, 1282, 1284, 0, 1287, 0, 1291, + 0, 1293, 1295, 1296, 0, 0, 0, 1307, 1308, 1309, + 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1323, 0, 1092, + 1095, 1325, 1102, 1103, 1108, 1328, 0, 0, 0, 1331, + 0, 0, 0, 1335, 1138, 1346, 0, 1351, 0, 0, + 1357, 0, 1361, 0, 1367, 1368, 1370, 1372, 0, 0, + 0, 0, 0, 968, 949, 66, 1470, 1472, 0, 1543, + 1541, 1541, 1551, 1552, 0, 0, 1559, 0, 0, 0, + 0, 86, 0, 0, 0, 1579, 0, 0, 0, 0, + 103, 1479, 956, 963, 0, 0, 957, 0, 958, 978, + 980, 935, 0, 1000, 1000, 92, 93, 0, 192, 0, + 194, 0, 197, 199, 200, 201, 207, 208, 209, 202, + 0, 0, 303, 305, 0, 0, 348, 359, 349, 0, + 0, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 942, + 151, 152, 153, 608, 0, 618, 0, 944, 0, 611, + 0, 528, 0, 0, 0, 401, 401, 401, 0, 0, + 0, 0, 686, 0, 0, 649, 0, 657, 0, 0, + 0, 232, 233, 0, 1522, 582, 0, 136, 137, 0, + 0, 587, 521, 522, 1057, 0, 0, 0, 1058, 1436, + 0, 0, 0, 0, 1455, 0, 0, 0, 0, 1183, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1299, 0, 0, 0, 638, 639, 0, 1375, + 1097, 1479, 0, 1099, 1109, 1110, 0, 1099, 1345, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 997, 0, 0, 0, 0, 988, 1472, 1477, 0, 0, + 1546, 0, 1539, 1542, 1540, 1553, 0, 0, 1560, 0, + 1562, 0, 1584, 1585, 1577, 0, 1569, 1572, 1568, 1571, + 1488, 960, 0, 965, 0, 1479, 91, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 205, 206, + 0, 0, 363, 368, 0, 0, 0, 609, 0, 945, + 621, 612, 0, 699, 0, 703, 0, 0, 0, 706, + 707, 708, 685, 0, 689, 429, 673, 670, 671, 540, + 0, 139, 140, 0, 0, 0, 1425, 0, 1428, 1141, + 1143, 0, 1172, 1174, 1175, 1433, 1434, 1189, 1225, 1228, + 1231, 1234, 1237, 1240, 1243, 1246, 1249, 1252, 1255, 1258, + 1261, 1264, 1267, 1270, 1278, 1285, 1288, 1292, 1297, 0, + 1300, 0, 0, 1301, 0, 640, 1088, 0, 0, 1106, + 1107, 0, 1330, 1332, 1333, 1334, 1347, 0, 1352, 1353, + 0, 1358, 0, 1362, 1373, 0, 993, 950, 951, 998, + 999, 0, 0, 941, 1477, 84, 1478, 1475, 0, 1473, + 1471, 1535, 0, 1544, 1545, 1554, 1555, 1561, 0, 1567, + 0, 89, 0, 0, 0, 1488, 193, 0, 212, 0, + 617, 0, 620, 610, 697, 698, 0, 710, 702, 704, + 705, 687, -2, 1514, 0, 0, 0, 590, 1426, 0, + 0, 1302, 0, 636, 637, 1096, 1089, 0, 1074, 1075, + 1093, 1327, 1329, 0, 0, 0, 0, 992, 994, 995, + 83, 0, 1474, 1114, 0, 1547, 1548, 1575, 1573, 961, + 968, 0, 90, 442, 435, 1514, 0, 0, 0, 690, + 691, 692, 693, 694, 695, 696, 579, 1516, 141, 142, + 0, 509, 510, 511, 135, 0, 1147, 1298, 1090, 0, + 0, 0, 0, 0, 1348, 0, 1354, 0, 1359, 0, + 952, 953, 1476, 0, 0, 622, 0, 624, 0, -2, + 430, 443, 0, 187, 213, 214, 0, 0, 217, 218, + 219, 210, 211, 131, 0, 0, 711, 0, 1517, 1518, + 0, 138, 0, 0, 1081, 1082, 1083, 1084, 1086, 0, + 0, 0, 0, 1115, 1094, 623, 0, 0, 385, 0, + 633, 431, 432, 0, 438, 439, 440, 441, 215, 216, + 645, 0, 0, 508, 586, 1427, 0, 0, 1349, 0, + 1355, 0, 1360, 0, 625, 626, 634, 0, 433, 0, + 434, 0, 0, 0, 614, 0, 645, 1515, 1091, 1085, + 1087, 0, 0, 1113, 0, 635, 631, 444, 446, 447, + 0, 0, 445, 646, 615, 1350, 1356, 0, 448, 449, + 450, 627, 628, 629, 630, } var yyTok1 = [...]int{ @@ -9669,7 +9739,7 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 145, 3, 3, 3, 173, 165, 3, 87, 89, 170, 168, 88, 169, 223, 171, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 732, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 733, 153, 152, 154, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -9800,7 +9870,7 @@ var yyTok3 = [...]int{ 58040, 715, 58041, 716, 58042, 717, 58043, 718, 58044, 719, 58045, 720, 58046, 721, 58047, 722, 58048, 723, 58049, 724, 58050, 725, 58051, 726, 58052, 727, 58053, 728, 58054, 729, - 58055, 730, 58056, 731, 0, + 58055, 730, 58056, 731, 58057, 732, 0, } var yyErrorMessages = [...]struct { @@ -14398,17 +14468,38 @@ yydefault: } yyVAL.union = yyLOCAL case 605: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL Statement +//line sql.y:3369 + { + yyLOCAL = &AlterMigration{ + Type: ForceCutOverMigrationType, + UUID: string(yyDollar[4].str), + } + } + yyVAL.union = yyLOCAL + case 606: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL Statement +//line sql.y:3376 + { + yyLOCAL = &AlterMigration{ + Type: ForceCutOverAllMigrationType, + } + } + yyVAL.union = yyLOCAL + case 607: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3370 +//line sql.y:3383 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 606: + case 608: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3374 +//line sql.y:3387 { yyDollar[3].partitionOptionUnion().Partitions = yyDollar[4].integerUnion() yyDollar[3].partitionOptionUnion().SubPartition = yyDollar[5].subPartitionUnion() @@ -14416,10 +14507,10 @@ yydefault: yyLOCAL = yyDollar[3].partitionOptionUnion() } yyVAL.union = yyLOCAL - case 607: + case 609: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3383 +//line sql.y:3396 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14428,10 +14519,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 608: + case 610: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3391 +//line sql.y:3404 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14441,10 +14532,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 609: + case 611: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3400 +//line sql.y:3413 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14452,10 +14543,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 610: + case 612: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3407 +//line sql.y:3420 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14463,18 +14554,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 611: + case 613: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3415 +//line sql.y:3428 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 612: + case 614: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3419 +//line sql.y:3432 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14484,10 +14575,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 613: + case 615: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3428 +//line sql.y:3441 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14498,682 +14589,682 @@ yydefault: } } yyVAL.union = yyLOCAL - case 614: + case 616: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3439 +//line sql.y:3452 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 615: + case 617: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3443 +//line sql.y:3456 { yyLOCAL = yyDollar[2].partDefsUnion() } yyVAL.union = yyLOCAL - case 616: + case 618: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3448 +//line sql.y:3461 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 617: + case 619: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3452 +//line sql.y:3465 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 618: + case 620: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3457 +//line sql.y:3470 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 619: + case 621: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3461 +//line sql.y:3474 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 620: + case 622: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3467 +//line sql.y:3480 { yyLOCAL = &JSONTableExpr{Expr: yyDollar[3].exprUnion(), Filter: yyDollar[5].exprUnion(), Columns: yyDollar[6].jtColumnListUnion(), Alias: yyDollar[8].identifierCS} } yyVAL.union = yyLOCAL - case 621: + case 623: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3473 +//line sql.y:3486 { yyLOCAL = yyDollar[3].jtColumnListUnion() } yyVAL.union = yyLOCAL - case 622: + case 624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3479 +//line sql.y:3492 { yyLOCAL = []*JtColumnDefinition{yyDollar[1].jtColumnDefinitionUnion()} } yyVAL.union = yyLOCAL - case 623: + case 625: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3483 +//line sql.y:3496 { yySLICE := (*[]*JtColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jtColumnDefinitionUnion()) } - case 624: + case 626: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3489 +//line sql.y:3502 { yyLOCAL = &JtColumnDefinition{JtOrdinal: &JtOrdinalColDef{Name: yyDollar[1].identifierCI}} } yyVAL.union = yyLOCAL - case 625: + case 627: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3493 +//line sql.y:3506 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 626: + case 628: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3499 +//line sql.y:3512 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 627: + case 629: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3505 +//line sql.y:3518 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 628: + case 630: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3511 +//line sql.y:3524 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 629: + case 631: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3517 +//line sql.y:3530 { jtNestedPath := &JtNestedPathColDef{Path: yyDollar[3].exprUnion(), Columns: yyDollar[4].jtColumnListUnion()} yyLOCAL = &JtColumnDefinition{JtNestedPath: jtNestedPath} } yyVAL.union = yyLOCAL - case 630: + case 632: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3523 +//line sql.y:3536 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 631: + case 633: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3527 +//line sql.y:3540 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 632: + case 634: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3531 +//line sql.y:3544 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 633: + case 635: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3535 +//line sql.y:3548 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 634: + case 636: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3541 +//line sql.y:3554 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 635: + case 637: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3547 +//line sql.y:3560 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 636: + case 638: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3553 +//line sql.y:3566 { yyLOCAL = &JtOnResponse{ResponseType: ErrorJSONType} } yyVAL.union = yyLOCAL - case 637: + case 639: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3557 +//line sql.y:3570 { yyLOCAL = &JtOnResponse{ResponseType: NullJSONType} } yyVAL.union = yyLOCAL - case 638: + case 640: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3561 +//line sql.y:3574 { yyLOCAL = &JtOnResponse{ResponseType: DefaultJSONType, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 639: + case 641: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3567 +//line sql.y:3580 { yyLOCAL = RangeType } yyVAL.union = yyLOCAL - case 640: + case 642: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3571 +//line sql.y:3584 { yyLOCAL = ListType } yyVAL.union = yyLOCAL - case 641: + case 643: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3576 +//line sql.y:3589 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 642: + case 644: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3580 +//line sql.y:3593 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 643: + case 645: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3585 +//line sql.y:3598 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 644: + case 646: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3589 +//line sql.y:3602 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 645: + case 647: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3595 +//line sql.y:3608 { yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} } yyVAL.union = yyLOCAL - case 646: + case 648: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3599 +//line sql.y:3612 { yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 647: + case 649: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3603 +//line sql.y:3616 { yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} } yyVAL.union = yyLOCAL - case 648: + case 650: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3607 +//line sql.y:3620 { yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 649: + case 651: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3611 +//line sql.y:3624 { yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} } yyVAL.union = yyLOCAL - case 650: + case 652: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3615 +//line sql.y:3628 { yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 651: + case 653: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3619 +//line sql.y:3632 { yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} } yyVAL.union = yyLOCAL - case 652: + case 654: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3623 +//line sql.y:3636 { yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 653: + case 655: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3627 +//line sql.y:3640 { yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} } yyVAL.union = yyLOCAL - case 654: + case 656: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3631 +//line sql.y:3644 { yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 655: + case 657: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3635 +//line sql.y:3648 { yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].identifierCI}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} } yyVAL.union = yyLOCAL - case 656: + case 658: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3639 +//line sql.y:3652 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 657: + case 659: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3643 +//line sql.y:3656 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} } yyVAL.union = yyLOCAL - case 658: + case 660: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3647 +//line sql.y:3660 { yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 659: + case 661: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3651 +//line sql.y:3664 { yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} } yyVAL.union = yyLOCAL - case 660: + case 662: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3655 +//line sql.y:3668 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 661: + case 663: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3659 +//line sql.y:3672 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} } yyVAL.union = yyLOCAL - case 662: + case 664: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3663 +//line sql.y:3676 { yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 663: + case 665: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3667 +//line sql.y:3680 { yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} } yyVAL.union = yyLOCAL - case 664: + case 666: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3671 +//line sql.y:3684 { yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 665: + case 667: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3675 +//line sql.y:3688 { yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} } yyVAL.union = yyLOCAL - case 666: + case 668: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3679 +//line sql.y:3692 { yyLOCAL = &PartitionSpec{Action: UpgradeAction} } yyVAL.union = yyLOCAL - case 667: + case 669: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3684 +//line sql.y:3697 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 668: + case 670: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3688 +//line sql.y:3701 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 669: + case 671: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3692 +//line sql.y:3705 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 670: + case 672: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3698 +//line sql.y:3711 { yyLOCAL = []*PartitionDefinition{yyDollar[1].partDefUnion()} } yyVAL.union = yyLOCAL - case 671: + case 673: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3702 +//line sql.y:3715 { yySLICE := (*[]*PartitionDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].partDefUnion()) } - case 672: + case 674: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3708 +//line sql.y:3721 { yyVAL.partDefUnion().Options = yyDollar[2].partitionDefinitionOptionsUnion() } - case 673: + case 675: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3713 +//line sql.y:3726 { yyLOCAL = &PartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 674: + case 676: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3717 +//line sql.y:3730 { yyDollar[1].partitionDefinitionOptionsUnion().ValueRange = yyDollar[2].partitionValueRangeUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 675: + case 677: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3722 +//line sql.y:3735 { yyDollar[1].partitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 676: + case 678: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3727 +//line sql.y:3740 { yyDollar[1].partitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 677: + case 679: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3732 +//line sql.y:3745 { yyDollar[1].partitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 678: + case 680: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3737 +//line sql.y:3750 { yyDollar[1].partitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 679: + case 681: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3742 +//line sql.y:3755 { val := yyDollar[2].integerUnion() yyDollar[1].partitionDefinitionOptionsUnion().MaxRows = &val yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 680: + case 682: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3748 +//line sql.y:3761 { val := yyDollar[2].integerUnion() yyDollar[1].partitionDefinitionOptionsUnion().MinRows = &val yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 681: + case 683: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3754 +//line sql.y:3767 { yyDollar[1].partitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 682: + case 684: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3759 +//line sql.y:3772 { yyDollar[1].partitionDefinitionOptionsUnion().SubPartitionDefinitions = yyDollar[2].subPartitionDefinitionsUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 683: + case 685: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3765 +//line sql.y:3778 { yyLOCAL = yyDollar[2].subPartitionDefinitionsUnion() } yyVAL.union = yyLOCAL - case 684: + case 686: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3771 +//line sql.y:3784 { yyLOCAL = SubPartitionDefinitions{yyDollar[1].subPartitionDefinitionUnion()} } yyVAL.union = yyLOCAL - case 685: + case 687: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3775 +//line sql.y:3788 { yySLICE := (*SubPartitionDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].subPartitionDefinitionUnion()) } - case 686: + case 688: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SubPartitionDefinition -//line sql.y:3781 +//line sql.y:3794 { yyLOCAL = &SubPartitionDefinition{Name: yyDollar[2].identifierCI, Options: yyDollar[3].subPartitionDefinitionOptionsUnion()} } yyVAL.union = yyLOCAL - case 687: + case 689: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3786 +//line sql.y:3799 { yyLOCAL = &SubPartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 688: + case 690: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3790 +//line sql.y:3803 { yyDollar[1].subPartitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 689: + case 691: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3795 +//line sql.y:3808 { yyDollar[1].subPartitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 690: + case 692: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3800 +//line sql.y:3813 { yyDollar[1].subPartitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 691: + case 693: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3805 +//line sql.y:3818 { yyDollar[1].subPartitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 692: + case 694: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3810 +//line sql.y:3823 { val := yyDollar[2].integerUnion() yyDollar[1].subPartitionDefinitionOptionsUnion().MaxRows = &val yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 693: + case 695: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3816 +//line sql.y:3829 { val := yyDollar[2].integerUnion() yyDollar[1].subPartitionDefinitionOptionsUnion().MinRows = &val yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 694: + case 696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3822 +//line sql.y:3835 { yyDollar[1].subPartitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 695: + case 697: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3829 +//line sql.y:3842 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15181,10 +15272,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 696: + case 698: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3836 +//line sql.y:3849 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15192,10 +15283,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 697: + case 699: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3843 +//line sql.y:3856 { yyLOCAL = &PartitionValueRange{ Type: InType, @@ -15203,131 +15294,131 @@ yydefault: } } yyVAL.union = yyLOCAL - case 698: + case 700: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3851 +//line sql.y:3864 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 699: + case 701: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3855 +//line sql.y:3868 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 700: + case 702: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionEngine -//line sql.y:3861 +//line sql.y:3874 { yyLOCAL = &PartitionEngine{Storage: yyDollar[1].booleanUnion(), Name: yyDollar[4].identifierCS.String()} } yyVAL.union = yyLOCAL - case 701: + case 703: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Literal -//line sql.y:3867 +//line sql.y:3880 { yyLOCAL = NewStrLiteral(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 702: + case 704: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3873 +//line sql.y:3886 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 703: + case 705: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3879 +//line sql.y:3892 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 704: + case 706: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3885 +//line sql.y:3898 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 705: + case 707: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3891 +//line sql.y:3904 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 706: + case 708: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3897 +//line sql.y:3910 { yyVAL.str = yyDollar[3].identifierCS.String() } - case 707: + case 709: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:3903 +//line sql.y:3916 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 708: + case 710: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3909 +//line sql.y:3922 { yyVAL.str = "" } - case 709: + case 711: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3913 +//line sql.y:3926 { yyVAL.str = "" } - case 710: + case 712: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3919 +//line sql.y:3932 { yyLOCAL = &RenameTable{TablePairs: yyDollar[3].renameTablePairsUnion()} } yyVAL.union = yyLOCAL - case 711: + case 713: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*RenameTablePair -//line sql.y:3925 +//line sql.y:3938 { yyLOCAL = []*RenameTablePair{{FromTable: yyDollar[1].tableName, ToTable: yyDollar[3].tableName}} } yyVAL.union = yyLOCAL - case 712: + case 714: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3929 +//line sql.y:3942 { yySLICE := (*[]*RenameTablePair)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &RenameTablePair{FromTable: yyDollar[3].tableName, ToTable: yyDollar[5].tableName}) } - case 713: + case 715: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3935 +//line sql.y:3948 { yyLOCAL = &DropTable{FromTables: yyDollar[6].tableNamesUnion(), IfExists: yyDollar[5].booleanUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Temp: yyDollar[3].booleanUnion()} } yyVAL.union = yyLOCAL - case 714: + case 716: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3939 +//line sql.y:3952 { // Change this to an alter statement if yyDollar[4].identifierCI.Lowered() == "primary" { @@ -15337,1343 +15428,1343 @@ yydefault: } } yyVAL.union = yyLOCAL - case 715: + case 717: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3948 +//line sql.y:3961 { yyLOCAL = &DropView{FromTables: yyDollar[5].tableNamesUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 716: + case 718: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3952 +//line sql.y:3965 { yyLOCAL = &DropDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 717: + case 719: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3958 +//line sql.y:3971 { yyLOCAL = &TruncateTable{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 718: + case 720: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:3962 +//line sql.y:3975 { yyLOCAL = &TruncateTable{Table: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 719: + case 721: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3968 +//line sql.y:3981 { yyLOCAL = &Analyze{IsLocal: yyDollar[2].booleanUnion(), Table: yyDollar[4].tableName} } yyVAL.union = yyLOCAL - case 720: + case 722: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3974 +//line sql.y:3987 { yyLOCAL = &PurgeBinaryLogs{To: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 721: + case 723: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3978 +//line sql.y:3991 { yyLOCAL = &PurgeBinaryLogs{Before: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 722: + case 724: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3984 +//line sql.y:3997 { yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 723: + case 725: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3988 +//line sql.y:4001 { yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 724: + case 726: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3992 +//line sql.y:4005 { yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 725: + case 727: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3996 +//line sql.y:4009 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 726: + case 728: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4000 +//line sql.y:4013 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 727: + case 729: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4004 +//line sql.y:4017 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 728: + case 730: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4008 +//line sql.y:4021 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 729: + case 731: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4012 +//line sql.y:4025 { yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 730: + case 732: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4016 +//line sql.y:4029 { yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 731: + case 733: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4020 +//line sql.y:4033 { yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 732: + case 734: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4024 +//line sql.y:4037 { yyLOCAL = &Show{&ShowBasic{Command: Privilege}} } yyVAL.union = yyLOCAL - case 733: + case 735: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4028 +//line sql.y:4041 { yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 734: + case 736: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4032 +//line sql.y:4045 { yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 735: + case 737: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4036 +//line sql.y:4049 { yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 736: + case 738: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4040 +//line sql.y:4053 { yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 737: + case 739: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4044 +//line sql.y:4057 { yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 738: + case 740: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4048 +//line sql.y:4061 { yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 739: + case 741: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4052 +//line sql.y:4065 { yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 740: + case 742: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4056 +//line sql.y:4069 { yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].identifierCS, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 741: + case 743: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4060 +//line sql.y:4073 { yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 742: + case 744: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4064 +//line sql.y:4077 { yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 743: + case 745: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4068 +//line sql.y:4081 { yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 744: + case 746: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4072 +//line sql.y:4085 { yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 745: + case 747: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4076 +//line sql.y:4089 { yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 746: + case 748: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4080 +//line sql.y:4093 { yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 747: + case 749: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4084 +//line sql.y:4097 { yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL - case 748: + case 750: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4088 +//line sql.y:4101 { yyLOCAL = &Show{&ShowBasic{Command: Engines}} } yyVAL.union = yyLOCAL - case 749: + case 751: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4092 +//line sql.y:4105 { yyLOCAL = &Show{&ShowBasic{Command: Plugins}} } yyVAL.union = yyLOCAL - case 750: + case 752: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4096 +//line sql.y:4109 { yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL - case 751: + case 753: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4100 +//line sql.y:4113 { yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL - case 752: + case 754: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4104 +//line sql.y:4117 { yyLOCAL = &Show{&ShowBasic{Command: VitessVariables, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 753: + case 755: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4108 +//line sql.y:4121 { yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 754: + case 756: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4112 +//line sql.y:4125 { yyLOCAL = &ShowMigrationLogs{UUID: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 755: + case 757: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4116 +//line sql.y:4129 { yyLOCAL = &ShowThrottledApps{} } yyVAL.union = yyLOCAL - case 756: + case 758: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4120 +//line sql.y:4133 { yyLOCAL = &Show{&ShowBasic{Command: VitessReplicationStatus, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 757: + case 759: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4124 +//line sql.y:4137 { yyLOCAL = &ShowThrottlerStatus{} } yyVAL.union = yyLOCAL - case 758: + case 760: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4128 +//line sql.y:4141 { yyLOCAL = &Show{&ShowBasic{Command: VschemaTables}} } yyVAL.union = yyLOCAL - case 759: + case 761: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4132 +//line sql.y:4145 { yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} } yyVAL.union = yyLOCAL - case 760: + case 762: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4136 +//line sql.y:4149 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} } yyVAL.union = yyLOCAL - case 761: + case 763: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4140 +//line sql.y:4153 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} } yyVAL.union = yyLOCAL - case 762: + case 764: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4144 +//line sql.y:4157 { yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } yyVAL.union = yyLOCAL - case 763: + case 765: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4148 +//line sql.y:4161 { yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 764: + case 766: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4152 +//line sql.y:4165 { yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL - case 765: + case 767: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4156 +//line sql.y:4169 { yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} } yyVAL.union = yyLOCAL - case 766: + case 768: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4163 +//line sql.y:4176 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} } yyVAL.union = yyLOCAL - case 767: + case 769: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4167 +//line sql.y:4180 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 768: + case 770: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4171 +//line sql.y:4184 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} } yyVAL.union = yyLOCAL - case 769: + case 771: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4175 +//line sql.y:4188 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 770: + case 772: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4179 +//line sql.y:4192 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL - case 771: + case 773: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4183 +//line sql.y:4196 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL - case 772: + case 774: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4187 +//line sql.y:4200 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL - case 773: + case 775: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4191 +//line sql.y:4204 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL - case 774: + case 776: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4195 +//line sql.y:4208 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL - case 775: + case 777: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4201 +//line sql.y:4214 { yyVAL.str = "" } - case 776: + case 778: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4205 +//line sql.y:4218 { yyVAL.str = "extended " } - case 777: + case 779: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4211 +//line sql.y:4224 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 778: + case 780: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4215 +//line sql.y:4228 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 779: + case 781: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4221 +//line sql.y:4234 { yyVAL.str = string(yyDollar[1].str) } - case 780: + case 782: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4225 +//line sql.y:4238 { yyVAL.str = string(yyDollar[1].str) } - case 781: + case 783: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4231 +//line sql.y:4244 { yyVAL.identifierCS = NewIdentifierCS("") } - case 782: + case 784: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4235 +//line sql.y:4248 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 783: + case 785: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4239 +//line sql.y:4252 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 784: + case 786: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4245 +//line sql.y:4258 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 785: + case 787: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4249 +//line sql.y:4262 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 786: + case 788: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4253 +//line sql.y:4266 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 787: + case 789: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4259 +//line sql.y:4272 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 788: + case 790: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4263 +//line sql.y:4276 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 789: + case 791: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4269 +//line sql.y:4282 { yyVAL.empty = struct{}{} } - case 790: + case 792: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4273 +//line sql.y:4286 { yyVAL.empty = struct{}{} } - case 791: + case 793: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4277 +//line sql.y:4290 { yyVAL.empty = struct{}{} } - case 792: + case 794: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4283 +//line sql.y:4296 { yyVAL.str = string(yyDollar[1].str) } - case 793: + case 795: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4287 +//line sql.y:4300 { yyVAL.str = string(yyDollar[1].str) } - case 794: + case 796: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4293 +//line sql.y:4306 { yyLOCAL = &Use{DBName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 795: + case 797: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4297 +//line sql.y:4310 { yyLOCAL = &Use{DBName: IdentifierCS{v: ""}} } yyVAL.union = yyLOCAL - case 796: + case 798: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4301 +//line sql.y:4314 { yyLOCAL = &Use{DBName: NewIdentifierCS(yyDollar[2].identifierCS.String() + "@" + string(yyDollar[3].str))} } yyVAL.union = yyLOCAL - case 797: + case 799: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4308 +//line sql.y:4321 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 798: + case 800: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4312 +//line sql.y:4325 { yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) } - case 799: + case 801: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4316 +//line sql.y:4329 { yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) } - case 800: + case 802: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4320 +//line sql.y:4333 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 801: + case 803: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4327 +//line sql.y:4340 { yyLOCAL = &Begin{} } yyVAL.union = yyLOCAL - case 802: + case 804: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4331 +//line sql.y:4344 { yyLOCAL = &Begin{TxAccessModes: yyDollar[3].txAccessModesUnion()} } yyVAL.union = yyLOCAL - case 803: + case 805: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4336 +//line sql.y:4349 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 804: + case 806: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4340 +//line sql.y:4353 { yyLOCAL = yyDollar[1].txAccessModesUnion() } yyVAL.union = yyLOCAL - case 805: + case 807: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4346 +//line sql.y:4359 { yyLOCAL = []TxAccessMode{yyDollar[1].txAccessModeUnion()} } yyVAL.union = yyLOCAL - case 806: + case 808: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4350 +//line sql.y:4363 { yySLICE := (*[]TxAccessMode)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].txAccessModeUnion()) } - case 807: + case 809: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4356 +//line sql.y:4369 { yyLOCAL = WithConsistentSnapshot } yyVAL.union = yyLOCAL - case 808: + case 810: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4360 +//line sql.y:4373 { yyLOCAL = ReadWrite } yyVAL.union = yyLOCAL - case 809: + case 811: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4364 +//line sql.y:4377 { yyLOCAL = ReadOnly } yyVAL.union = yyLOCAL - case 810: + case 812: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4371 +//line sql.y:4384 { yyLOCAL = &Commit{} } yyVAL.union = yyLOCAL - case 811: + case 813: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4377 +//line sql.y:4390 { yyLOCAL = &Rollback{} } yyVAL.union = yyLOCAL - case 812: + case 814: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4381 +//line sql.y:4394 { yyLOCAL = &SRollback{Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 813: + case 815: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4386 +//line sql.y:4399 { yyVAL.empty = struct{}{} } - case 814: + case 816: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4388 +//line sql.y:4401 { yyVAL.empty = struct{}{} } - case 815: + case 817: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4391 +//line sql.y:4404 { yyVAL.empty = struct{}{} } - case 816: + case 818: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4393 +//line sql.y:4406 { yyVAL.empty = struct{}{} } - case 817: + case 819: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4397 +//line sql.y:4410 { yyLOCAL = &Savepoint{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 818: + case 820: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4403 +//line sql.y:4416 { yyLOCAL = &Release{Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 819: + case 821: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4408 +//line sql.y:4421 { yyLOCAL = EmptyType } yyVAL.union = yyLOCAL - case 820: + case 822: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4412 +//line sql.y:4425 { yyLOCAL = JSONType } yyVAL.union = yyLOCAL - case 821: + case 823: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4416 +//line sql.y:4429 { yyLOCAL = TreeType } yyVAL.union = yyLOCAL - case 822: + case 824: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4420 +//line sql.y:4433 { yyLOCAL = VitessType } yyVAL.union = yyLOCAL - case 823: + case 825: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4424 +//line sql.y:4437 { yyLOCAL = VTExplainType } yyVAL.union = yyLOCAL - case 824: + case 826: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4428 +//line sql.y:4441 { yyLOCAL = TraditionalType } yyVAL.union = yyLOCAL - case 825: + case 827: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4432 +//line sql.y:4445 { yyLOCAL = AnalyzeType } yyVAL.union = yyLOCAL - case 826: + case 828: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4437 +//line sql.y:4450 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 827: + case 829: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4441 +//line sql.y:4454 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 828: + case 830: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4445 +//line sql.y:4458 { yyLOCAL = AllVExplainType } yyVAL.union = yyLOCAL - case 829: + case 831: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4449 +//line sql.y:4462 { yyLOCAL = QueriesVExplainType } yyVAL.union = yyLOCAL - case 830: + case 832: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4455 +//line sql.y:4468 { yyVAL.str = yyDollar[1].str } - case 831: + case 833: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4459 +//line sql.y:4472 { yyVAL.str = yyDollar[1].str } - case 832: + case 834: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4463 +//line sql.y:4476 { yyVAL.str = yyDollar[1].str } - case 833: + case 835: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4469 +//line sql.y:4482 { yyLOCAL = yyDollar[1].selStmtUnion() } yyVAL.union = yyLOCAL - case 834: + case 836: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4473 +//line sql.y:4486 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 835: + case 837: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4477 +//line sql.y:4490 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 836: + case 838: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4481 +//line sql.y:4494 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 837: + case 839: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4486 +//line sql.y:4499 { yyVAL.str = "" } - case 838: + case 840: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4490 +//line sql.y:4503 { yyVAL.str = yyDollar[1].identifierCI.val } - case 839: + case 841: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4494 +//line sql.y:4507 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 840: + case 842: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4500 +//line sql.y:4513 { yyLOCAL = &ExplainTab{Table: yyDollar[3].tableName, Wild: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 841: + case 843: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4504 +//line sql.y:4517 { yyLOCAL = &ExplainStmt{Type: yyDollar[3].explainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 842: + case 844: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4510 +//line sql.y:4523 { yyLOCAL = &VExplainStmt{Type: yyDollar[3].vexplainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 843: + case 845: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4516 +//line sql.y:4529 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 844: + case 846: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4520 +//line sql.y:4533 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 845: + case 847: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4526 +//line sql.y:4539 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } yyVAL.union = yyLOCAL - case 846: + case 848: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:4532 +//line sql.y:4545 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL - case 847: + case 849: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4536 +//line sql.y:4549 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) } - case 848: + case 850: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:4542 +//line sql.y:4555 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } yyVAL.union = yyLOCAL - case 849: + case 851: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4548 +//line sql.y:4561 { yyLOCAL = Read } yyVAL.union = yyLOCAL - case 850: + case 852: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4552 +//line sql.y:4565 { yyLOCAL = ReadLocal } yyVAL.union = yyLOCAL - case 851: + case 853: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4556 +//line sql.y:4569 { yyLOCAL = Write } yyVAL.union = yyLOCAL - case 852: + case 854: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4560 +//line sql.y:4573 { yyLOCAL = LowPriorityWrite } yyVAL.union = yyLOCAL - case 853: + case 855: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4566 +//line sql.y:4579 { yyLOCAL = &UnlockTables{} } yyVAL.union = yyLOCAL - case 854: + case 856: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4572 +//line sql.y:4585 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs).Parsed(), UUID: string(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 855: + case 857: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4578 +//line sql.y:4591 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } yyVAL.union = yyLOCAL - case 856: + case 858: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4582 +//line sql.y:4595 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } yyVAL.union = yyLOCAL - case 857: + case 859: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4586 +//line sql.y:4599 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 858: + case 860: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4590 +//line sql.y:4603 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 859: + case 861: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4594 +//line sql.y:4607 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 860: + case 862: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4598 +//line sql.y:4611 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL - case 861: + case 863: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4604 +//line sql.y:4617 { yyVAL.strs = []string{yyDollar[1].str} } - case 862: + case 864: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4608 +//line sql.y:4621 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } - case 863: + case 865: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4614 +//line sql.y:4627 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 864: + case 866: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4618 +//line sql.y:4631 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 865: + case 867: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4622 +//line sql.y:4635 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 866: + case 868: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4626 +//line sql.y:4639 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 867: + case 869: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4630 +//line sql.y:4643 { yyVAL.str = string(yyDollar[1].str) } - case 868: + case 870: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4634 +//line sql.y:4647 { yyVAL.str = string(yyDollar[1].str) } - case 869: + case 871: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4638 +//line sql.y:4651 { yyVAL.str = string(yyDollar[1].str) } - case 870: + case 872: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4642 +//line sql.y:4655 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } - case 871: + case 873: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4646 +//line sql.y:4659 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 872: + case 874: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4650 +//line sql.y:4663 { yyVAL.str = string(yyDollar[1].str) } - case 873: + case 875: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4654 +//line sql.y:4667 { yyVAL.str = string(yyDollar[1].str) } - case 874: + case 876: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4658 +//line sql.y:4671 { yyVAL.str = string(yyDollar[1].str) } - case 875: + case 877: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4663 +//line sql.y:4676 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 876: + case 878: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4667 +//line sql.y:4680 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 877: + case 879: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4671 +//line sql.y:4684 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 878: + case 880: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4676 +//line sql.y:4689 { yyVAL.str = "" } - case 879: + case 881: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4680 +//line sql.y:4693 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String() } - case 880: + case 882: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4685 +//line sql.y:4698 { setAllowComments(yylex, true) } - case 881: + case 883: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4689 +//line sql.y:4702 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } - case 882: + case 884: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4695 +//line sql.y:4708 { yyVAL.strs = nil } - case 883: + case 885: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4699 +//line sql.y:4712 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 884: + case 886: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4705 +//line sql.y:4718 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 885: + case 887: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4709 +//line sql.y:4722 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 886: + case 888: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4713 +//line sql.y:4726 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 887: + case 889: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4718 +//line sql.y:4731 { yyVAL.str = "" } - case 888: + case 890: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4722 +//line sql.y:4735 { yyVAL.str = SQLNoCacheStr } - case 889: + case 891: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4726 +//line sql.y:4739 { yyVAL.str = SQLCacheStr } - case 890: + case 892: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4731 +//line sql.y:4744 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 891: + case 893: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4735 +//line sql.y:4748 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 892: + case 894: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4739 +//line sql.y:4752 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 893: + case 895: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4745 +//line sql.y:4758 { yyLOCAL = &PrepareStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Statement: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 894: + case 896: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4749 +//line sql.y:4762 { yyLOCAL = &PrepareStmt{ Name: yyDollar[3].identifierCI, @@ -16682,595 +16773,595 @@ yydefault: } } yyVAL.union = yyLOCAL - case 895: + case 897: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4759 +//line sql.y:4772 { yyLOCAL = &ExecuteStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Arguments: yyDollar[4].variablesUnion()} } yyVAL.union = yyLOCAL - case 896: + case 898: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4764 +//line sql.y:4777 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 897: + case 899: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4768 +//line sql.y:4781 { yyLOCAL = yyDollar[2].variablesUnion() } yyVAL.union = yyLOCAL - case 898: + case 900: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4774 +//line sql.y:4787 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 899: + case 901: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4778 +//line sql.y:4791 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 900: + case 902: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4783 +//line sql.y:4796 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 901: + case 903: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4787 +//line sql.y:4800 { yyLOCAL = yyDollar[1].selectExprsUnion() } yyVAL.union = yyLOCAL - case 902: + case 904: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4792 +//line sql.y:4805 { yyVAL.strs = nil } - case 903: + case 905: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4796 +//line sql.y:4809 { yyVAL.strs = []string{yyDollar[1].str} } - case 904: + case 906: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4800 +//line sql.y:4813 { // 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 905: + case 907: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4804 +//line sql.y:4817 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str} } - case 906: + case 908: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4808 +//line sql.y:4821 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str, yyDollar[4].str} } - case 907: + case 909: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4814 +//line sql.y:4827 { yyVAL.str = SQLNoCacheStr } - case 908: + case 910: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4818 +//line sql.y:4831 { yyVAL.str = SQLCacheStr } - case 909: + case 911: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4822 +//line sql.y:4835 { yyVAL.str = DistinctStr } - case 910: + case 912: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4826 +//line sql.y:4839 { yyVAL.str = DistinctStr } - case 911: + case 913: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4830 +//line sql.y:4843 { yyVAL.str = StraightJoinHint } - case 912: + case 914: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4834 +//line sql.y:4847 { yyVAL.str = SQLCalcFoundRowsStr } - case 913: + case 915: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4838 +//line sql.y:4851 { 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 914: + case 916: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4844 +//line sql.y:4857 { yyLOCAL = SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL - case 915: + case 917: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4848 +//line sql.y:4861 { yySLICE := (*SelectExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].selectExprUnion()) } - case 916: + case 918: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4854 +//line sql.y:4867 { yyLOCAL = &StarExpr{} } yyVAL.union = yyLOCAL - case 917: + case 919: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4858 +//line sql.y:4871 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 918: + case 920: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4862 +//line sql.y:4875 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } yyVAL.union = yyLOCAL - case 919: + case 921: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4866 +//line sql.y:4879 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 920: + case 922: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4871 +//line sql.y:4884 { yyVAL.identifierCI = IdentifierCI{} } - case 921: + case 923: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4875 +//line sql.y:4888 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 922: + case 924: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4879 +//line sql.y:4892 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 924: + case 926: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4886 +//line sql.y:4899 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 925: + case 927: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4891 +//line sql.y:4904 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } yyVAL.union = yyLOCAL - case 926: + case 928: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4895 +//line sql.y:4908 { yyLOCAL = yyDollar[1].tableExprsUnion() } yyVAL.union = yyLOCAL - case 927: + case 929: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4901 +//line sql.y:4914 { yyLOCAL = yyDollar[2].tableExprsUnion() } yyVAL.union = yyLOCAL - case 928: + case 930: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4907 +//line sql.y:4920 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL - case 929: + case 931: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4911 +//line sql.y:4924 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) } - case 932: + case 934: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4921 +//line sql.y:4934 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } yyVAL.union = yyLOCAL - case 933: + case 935: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4925 +//line sql.y:4938 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 934: + case 936: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4929 +//line sql.y:4942 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } yyVAL.union = yyLOCAL - case 935: + case 937: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4933 +//line sql.y:4946 { yyLOCAL = yyDollar[1].tableExprUnion() } yyVAL.union = yyLOCAL - case 936: + case 938: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4939 +//line sql.y:4952 { yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 937: + case 939: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4943 +//line sql.y:4956 { yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].selStmtUnion()} } yyVAL.union = yyLOCAL - case 938: + case 940: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4949 +//line sql.y:4962 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 939: + case 941: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4953 +//line sql.y:4966 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 940: + case 942: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4958 +//line sql.y:4971 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 941: + case 943: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:4962 +//line sql.y:4975 { yyLOCAL = yyDollar[2].columnsUnion() } yyVAL.union = yyLOCAL - case 942: + case 944: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4967 +//line sql.y:4980 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 943: + case 945: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4971 +//line sql.y:4984 { yyLOCAL = yyDollar[1].columnsUnion() } yyVAL.union = yyLOCAL - case 944: + case 946: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4977 +//line sql.y:4990 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 945: + case 947: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4981 +//line sql.y:4994 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 946: + case 948: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4987 +//line sql.y:5000 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL - case 947: + case 949: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4991 +//line sql.y:5004 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) } - case 948: + case 950: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4997 +//line sql.y:5010 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 949: + case 951: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5001 +//line sql.y:5014 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 950: + case 952: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5005 +//line sql.y:5018 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 951: + case 953: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5009 +//line sql.y:5022 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) } - case 952: + case 954: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5015 +//line sql.y:5028 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 953: + case 955: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5019 +//line sql.y:5032 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 954: + case 956: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5032 +//line sql.y:5045 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 955: + case 957: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5036 +//line sql.y:5049 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 956: + case 958: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5040 +//line sql.y:5053 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 957: + case 959: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5044 +//line sql.y:5057 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 958: + case 960: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5050 +//line sql.y:5063 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 959: + case 961: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5052 +//line sql.y:5065 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 960: + case 962: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5056 +//line sql.y:5069 { yyVAL.joinCondition = &JoinCondition{} } - case 961: + case 963: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5058 +//line sql.y:5071 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 962: + case 964: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5062 +//line sql.y:5075 { yyVAL.joinCondition = &JoinCondition{} } - case 963: + case 965: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5064 +//line sql.y:5077 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 964: + case 966: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5067 +//line sql.y:5080 { yyVAL.empty = struct{}{} } - case 965: + case 967: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5069 +//line sql.y:5082 { yyVAL.empty = struct{}{} } - case 966: + case 968: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5072 +//line sql.y:5085 { yyVAL.identifierCS = NewIdentifierCS("") } - case 967: + case 969: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5076 +//line sql.y:5089 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 968: + case 970: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5080 +//line sql.y:5093 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 970: + case 972: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5087 +//line sql.y:5100 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 971: + case 973: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5093 +//line sql.y:5106 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 972: + case 974: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5097 +//line sql.y:5110 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 973: + case 975: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5101 +//line sql.y:5114 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 974: + case 976: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5107 +//line sql.y:5120 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 975: + case 977: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5113 +//line sql.y:5126 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 976: + case 978: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5117 +//line sql.y:5130 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 977: + case 979: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5121 +//line sql.y:5134 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 978: + case 980: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5125 +//line sql.y:5138 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 979: + case 981: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5131 +//line sql.y:5144 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 980: + case 982: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5135 +//line sql.y:5148 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -17279,617 +17370,617 @@ yydefault: } } yyVAL.union = yyLOCAL - case 981: + case 983: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5145 +//line sql.y:5158 { yyVAL.tableName = yyDollar[2].tableName } - case 982: + case 984: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5149 +//line sql.y:5162 { yyVAL.tableName = yyDollar[1].tableName } - case 983: + case 985: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5155 +//line sql.y:5168 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 984: + case 986: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5159 +//line sql.y:5172 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } - case 985: + case 987: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5165 +//line sql.y:5178 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 986: + case 988: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5170 +//line sql.y:5183 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 987: + case 989: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5174 +//line sql.y:5187 { yyLOCAL = yyDollar[1].indexHintsUnion() } yyVAL.union = yyLOCAL - case 988: + case 990: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5180 +//line sql.y:5193 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL - case 989: + case 991: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5184 +//line sql.y:5197 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) } - case 990: + case 992: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5190 +//line sql.y:5203 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 991: + case 993: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5194 +//line sql.y:5207 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } yyVAL.union = yyLOCAL - case 992: + case 994: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5198 +//line sql.y:5211 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 993: + case 995: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5202 +//line sql.y:5215 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 994: + case 996: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5207 +//line sql.y:5220 { yyLOCAL = NoForType } yyVAL.union = yyLOCAL - case 995: + case 997: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5211 +//line sql.y:5224 { yyLOCAL = JoinForType } yyVAL.union = yyLOCAL - case 996: + case 998: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5215 +//line sql.y:5228 { yyLOCAL = OrderByForType } yyVAL.union = yyLOCAL - case 997: + case 999: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5219 +//line sql.y:5232 { yyLOCAL = GroupByForType } yyVAL.union = yyLOCAL - case 998: + case 1000: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5225 +//line sql.y:5238 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 999: + case 1001: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5229 +//line sql.y:5242 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1000: + case 1002: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5236 +//line sql.y:5249 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1001: + case 1003: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5240 +//line sql.y:5253 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1002: + case 1004: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5244 +//line sql.y:5257 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1003: + case 1005: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5248 +//line sql.y:5261 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1004: + case 1006: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5252 +//line sql.y:5265 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } yyVAL.union = yyLOCAL - case 1005: + case 1007: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5256 +//line sql.y:5269 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1006: + case 1008: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5260 +//line sql.y:5273 { yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1007: + case 1009: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5264 +//line sql.y:5277 { yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1008: + case 1010: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5270 +//line sql.y:5283 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } yyVAL.union = yyLOCAL - case 1009: + case 1011: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5274 +//line sql.y:5287 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } yyVAL.union = yyLOCAL - case 1010: + case 1012: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5278 +//line sql.y:5291 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1011: + case 1013: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5282 +//line sql.y:5295 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1012: + case 1014: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5288 +//line sql.y:5301 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1013: + case 1015: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5292 +//line sql.y:5305 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1014: + case 1016: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5296 +//line sql.y:5309 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1015: + case 1017: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5300 +//line sql.y:5313 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1016: + case 1018: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5304 +//line sql.y:5317 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1017: + case 1019: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5308 +//line sql.y:5321 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1018: + case 1020: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5312 +//line sql.y:5325 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1019: + case 1021: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5316 +//line sql.y:5329 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1020: + case 1022: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5320 +//line sql.y:5333 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1021: + case 1023: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5324 +//line sql.y:5337 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1022: + case 1024: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5328 +//line sql.y:5341 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1023: + case 1025: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5334 +//line sql.y:5347 { } - case 1024: + case 1026: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5337 +//line sql.y:5350 { } - case 1025: + case 1027: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5343 +//line sql.y:5356 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1026: + case 1028: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5347 +//line sql.y:5360 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1027: + case 1029: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5351 +//line sql.y:5364 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1028: + case 1030: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5355 +//line sql.y:5368 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1029: + case 1031: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5359 +//line sql.y:5372 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1030: + case 1032: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5363 +//line sql.y:5376 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1031: + case 1033: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5367 +//line sql.y:5380 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1032: + case 1034: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5371 +//line sql.y:5384 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1033: + case 1035: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5375 +//line sql.y:5388 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1034: + case 1036: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5379 +//line sql.y:5392 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1035: + case 1037: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5383 +//line sql.y:5396 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1036: + case 1038: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5387 +//line sql.y:5400 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1037: + case 1039: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5391 +//line sql.y:5404 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1038: + case 1040: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5395 +//line sql.y:5408 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1039: + case 1041: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5399 +//line sql.y:5412 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1040: + case 1042: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5405 +//line sql.y:5418 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1041: + case 1043: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5409 +//line sql.y:5422 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1042: + case 1044: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5413 +//line sql.y:5426 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1043: + case 1045: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5417 +//line sql.y:5430 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1044: + case 1046: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5421 +//line sql.y:5434 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 1045: + case 1047: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5425 +//line sql.y:5438 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1046: + case 1048: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5429 +//line sql.y:5442 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1047: + case 1049: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5433 +//line sql.y:5446 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1048: + case 1050: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5437 +//line sql.y:5450 { yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } yyVAL.union = yyLOCAL - case 1049: + case 1051: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5441 +//line sql.y:5454 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1050: + case 1052: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5445 +//line sql.y:5458 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1051: + case 1053: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5449 +//line sql.y:5462 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1052: + case 1054: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5453 +//line sql.y:5466 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1053: + case 1055: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5457 +//line sql.y:5470 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1054: + case 1056: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5461 +//line sql.y:5474 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1055: + case 1057: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5465 +//line sql.y:5478 { yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } yyVAL.union = yyLOCAL - case 1056: + case 1058: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5469 +//line sql.y:5482 { yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } yyVAL.union = yyLOCAL - case 1057: + case 1059: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5473 +//line sql.y:5486 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1058: + case 1060: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5477 +//line sql.y:5490 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1059: + case 1061: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5481 +//line sql.y:5494 { // From: https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#operator_binary // To convert a string expression to a binary string, these constructs are equivalent: @@ -17898,3169 +17989,3169 @@ yydefault: yyLOCAL = &ConvertExpr{Expr: yyDollar[2].exprUnion(), Type: &ConvertType{Type: yyDollar[1].str}} } yyVAL.union = yyLOCAL - case 1060: + case 1062: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5489 +//line sql.y:5502 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1061: + case 1063: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5493 +//line sql.y:5506 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1062: + case 1064: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5497 +//line sql.y:5510 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1063: + case 1065: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5501 +//line sql.y:5514 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1064: + case 1066: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5505 +//line sql.y:5518 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1065: + case 1067: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5511 +//line sql.y:5524 { yyLOCAL = yyDollar[1].colNamesUnion() } yyVAL.union = yyLOCAL - case 1066: + case 1068: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5515 +//line sql.y:5528 { yyLOCAL = yyDollar[2].colNamesUnion() } yyVAL.union = yyLOCAL - case 1067: + case 1069: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5521 +//line sql.y:5534 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL - case 1068: + case 1070: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5525 +//line sql.y:5538 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) } - case 1069: + case 1071: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5531 +//line sql.y:5544 { yyLOCAL = BothTrimType } yyVAL.union = yyLOCAL - case 1070: + case 1072: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5535 +//line sql.y:5548 { yyLOCAL = LeadingTrimType } yyVAL.union = yyLOCAL - case 1071: + case 1073: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5539 +//line sql.y:5552 { yyLOCAL = TrailingTrimType } yyVAL.union = yyLOCAL - case 1072: + case 1074: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5545 +//line sql.y:5558 { yyLOCAL = FrameRowsType } yyVAL.union = yyLOCAL - case 1073: + case 1075: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5549 +//line sql.y:5562 { yyLOCAL = FrameRangeType } yyVAL.union = yyLOCAL - case 1074: + case 1076: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5556 +//line sql.y:5569 { yyLOCAL = CumeDistExprType } yyVAL.union = yyLOCAL - case 1075: + case 1077: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5560 +//line sql.y:5573 { yyLOCAL = DenseRankExprType } yyVAL.union = yyLOCAL - case 1076: + case 1078: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5564 +//line sql.y:5577 { yyLOCAL = PercentRankExprType } yyVAL.union = yyLOCAL - case 1077: + case 1079: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5568 +//line sql.y:5581 { yyLOCAL = RankExprType } yyVAL.union = yyLOCAL - case 1078: + case 1080: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5572 +//line sql.y:5585 { yyLOCAL = RowNumberExprType } yyVAL.union = yyLOCAL - case 1079: + case 1081: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5578 +//line sql.y:5591 { yyLOCAL = &FramePoint{Type: CurrentRowType} } yyVAL.union = yyLOCAL - case 1080: + case 1082: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5582 +//line sql.y:5595 { yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } yyVAL.union = yyLOCAL - case 1081: + case 1083: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5586 +//line sql.y:5599 { yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } yyVAL.union = yyLOCAL - case 1082: + case 1084: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5590 +//line sql.y:5603 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1083: + case 1085: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5594 +//line sql.y:5607 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1084: + case 1086: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5598 +//line sql.y:5611 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1085: + case 1087: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5602 +//line sql.y:5615 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1086: + case 1088: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5607 +//line sql.y:5620 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1087: + case 1089: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5611 +//line sql.y:5624 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1088: + case 1090: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5617 +//line sql.y:5630 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } yyVAL.union = yyLOCAL - case 1089: + case 1091: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5621 +//line sql.y:5634 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } yyVAL.union = yyLOCAL - case 1090: + case 1092: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:5626 +//line sql.y:5639 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1091: + case 1093: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:5630 +//line sql.y:5643 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1092: + case 1094: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5635 +//line sql.y:5648 { } - case 1093: + case 1095: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5638 +//line sql.y:5651 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1094: + case 1096: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:5644 +//line sql.y:5657 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } yyVAL.union = yyLOCAL - case 1095: + case 1097: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5650 +//line sql.y:5663 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1096: + case 1098: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5654 +//line sql.y:5667 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 1097: + case 1099: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5659 +//line sql.y:5672 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1099: + case 1101: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5666 +//line sql.y:5679 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } yyVAL.union = yyLOCAL - case 1100: + case 1102: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5672 +//line sql.y:5685 { yyLOCAL = RespectNullsType } yyVAL.union = yyLOCAL - case 1101: + case 1103: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5676 +//line sql.y:5689 { yyLOCAL = IgnoreNullsType } yyVAL.union = yyLOCAL - case 1102: + case 1104: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5682 +//line sql.y:5695 { yyLOCAL = FirstValueExprType } yyVAL.union = yyLOCAL - case 1103: + case 1105: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5686 +//line sql.y:5699 { yyLOCAL = LastValueExprType } yyVAL.union = yyLOCAL - case 1104: + case 1106: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5692 +//line sql.y:5705 { yyLOCAL = FromFirstType } yyVAL.union = yyLOCAL - case 1105: + case 1107: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5696 +//line sql.y:5709 { yyLOCAL = FromLastType } yyVAL.union = yyLOCAL - case 1106: + case 1108: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5701 +//line sql.y:5714 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1108: + case 1110: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5708 +//line sql.y:5721 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } yyVAL.union = yyLOCAL - case 1109: + case 1111: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5714 +//line sql.y:5727 { yyLOCAL = LagExprType } yyVAL.union = yyLOCAL - case 1110: + case 1112: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5718 +//line sql.y:5731 { yyLOCAL = LeadExprType } yyVAL.union = yyLOCAL - case 1111: + case 1113: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:5724 +//line sql.y:5737 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1112: + case 1114: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:5730 +//line sql.y:5743 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL - case 1113: + case 1115: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5734 +//line sql.y:5747 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } - case 1114: + case 1116: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5740 +//line sql.y:5753 { yyVAL.str = "" } - case 1115: + case 1117: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5744 +//line sql.y:5757 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 1116: + case 1118: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5750 +//line sql.y:5763 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 1117: + case 1119: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5754 +//line sql.y:5767 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 1118: + case 1120: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5761 +//line sql.y:5774 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 1119: + case 1121: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5765 +//line sql.y:5778 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 1120: + case 1122: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5769 +//line sql.y:5782 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 1121: + case 1123: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5773 +//line sql.y:5786 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 1122: + case 1124: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5779 +//line sql.y:5792 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 1123: + case 1125: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5783 +//line sql.y:5796 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 1124: + case 1126: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5787 +//line sql.y:5800 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 1125: + case 1127: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5791 +//line sql.y:5804 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 1126: + case 1128: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5795 +//line sql.y:5808 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 1127: + case 1129: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5799 +//line sql.y:5812 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 1128: + case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5803 +//line sql.y:5816 { yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL - case 1129: + case 1131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5809 +//line sql.y:5822 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1130: + case 1132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5813 +//line sql.y:5826 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1131: + case 1133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5817 +//line sql.y:5830 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 1132: + case 1134: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:5824 +//line sql.y:5837 { yyLOCAL = &Subquery{yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1133: + case 1135: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:5830 +//line sql.y:5843 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1134: + case 1136: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5834 +//line sql.y:5847 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 1135: + case 1137: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5844 +//line sql.y:5857 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1136: + case 1138: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5848 +//line sql.y:5861 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1137: + case 1139: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5858 +//line sql.y:5871 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1138: + case 1140: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5862 +//line sql.y:5875 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1139: + case 1141: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5866 +//line sql.y:5879 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1140: + case 1142: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5870 +//line sql.y:5883 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1141: + case 1143: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5874 +//line sql.y:5887 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1142: + case 1144: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5878 +//line sql.y:5891 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1143: + case 1145: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5882 +//line sql.y:5895 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1144: + case 1146: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5886 +//line sql.y:5899 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 1145: + case 1147: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:5890 +//line sql.y:5903 { yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1146: + case 1148: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5894 +//line sql.y:5907 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1147: + case 1149: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5905 +//line sql.y:5918 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } yyVAL.union = yyLOCAL - case 1148: + case 1150: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5909 +//line sql.y:5922 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1149: + case 1151: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5915 +//line sql.y:5928 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } yyVAL.union = yyLOCAL - case 1150: + case 1152: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5919 +//line sql.y:5932 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } yyVAL.union = yyLOCAL - case 1151: + case 1153: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5923 +//line sql.y:5936 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1152: + case 1154: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5928 +//line sql.y:5941 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1153: + case 1155: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5933 +//line sql.y:5946 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1154: + case 1156: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5937 +//line sql.y:5950 { yyLOCAL = &CountStar{} } yyVAL.union = yyLOCAL - case 1155: + case 1157: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5941 +//line sql.y:5954 { yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1156: + case 1158: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5945 +//line sql.y:5958 { yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1157: + case 1159: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5949 +//line sql.y:5962 { yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1158: + case 1160: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5953 +//line sql.y:5966 { yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1159: + case 1161: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5957 +//line sql.y:5970 { yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1160: + case 1162: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5961 +//line sql.y:5974 { yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1161: + case 1163: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5965 +//line sql.y:5978 { yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1162: + case 1164: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5969 +//line sql.y:5982 { yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1163: + case 1165: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5973 +//line sql.y:5986 { yyLOCAL = &Std{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1164: + case 1166: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5977 +//line sql.y:5990 { yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1165: + case 1167: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5981 +//line sql.y:5994 { yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1166: + case 1168: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5985 +//line sql.y:5998 { yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1167: + case 1169: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5989 +//line sql.y:6002 { yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1168: + case 1170: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5993 +//line sql.y:6006 { yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1169: + case 1171: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5997 +//line sql.y:6010 { yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1170: + case 1172: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6001 +//line sql.y:6014 { yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL - case 1171: + case 1173: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6005 +//line sql.y:6018 { yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1172: + case 1174: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6009 +//line sql.y:6022 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1173: + case 1175: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6013 +//line sql.y:6026 { yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1174: + case 1176: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6017 +//line sql.y:6030 { yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1175: + case 1177: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6021 +//line sql.y:6034 { yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1176: + case 1178: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6025 +//line sql.y:6038 { yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1177: + case 1179: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6029 +//line sql.y:6042 { yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1178: + case 1180: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6033 +//line sql.y:6046 { yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1179: + case 1181: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6037 +//line sql.y:6050 { yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1180: + case 1182: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6041 +//line sql.y:6054 { yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1181: + case 1183: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6045 +//line sql.y:6058 { yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1182: + case 1184: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6049 +//line sql.y:6062 { yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1183: + case 1185: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6053 +//line sql.y:6066 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1184: + case 1186: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6057 +//line sql.y:6070 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1185: + case 1187: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6061 +//line sql.y:6074 { yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1186: + case 1188: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6065 +//line sql.y:6078 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1187: + case 1189: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6069 +//line sql.y:6082 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1188: + case 1190: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6073 +//line sql.y:6086 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1189: + case 1191: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6077 +//line sql.y:6090 { yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1190: + case 1192: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6081 +//line sql.y:6094 { yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1191: + case 1193: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6085 +//line sql.y:6098 { yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1192: + case 1194: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6089 +//line sql.y:6102 { yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } yyVAL.union = yyLOCAL - case 1193: + case 1195: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6093 +//line sql.y:6106 { yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1194: + case 1196: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6097 +//line sql.y:6110 { yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1195: + case 1197: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6101 +//line sql.y:6114 { yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1196: + case 1198: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6105 +//line sql.y:6118 { yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1197: + case 1199: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6109 +//line sql.y:6122 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1198: + case 1200: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6113 +//line sql.y:6126 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1199: + case 1201: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6117 +//line sql.y:6130 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1200: + case 1202: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6121 +//line sql.y:6134 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1201: + case 1203: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6125 +//line sql.y:6138 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1202: + case 1204: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6129 +//line sql.y:6142 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1203: + case 1205: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6133 +//line sql.y:6146 { yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1204: + case 1206: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6137 +//line sql.y:6150 { yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1205: + case 1207: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6141 +//line sql.y:6154 { yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1206: + case 1208: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6145 +//line sql.y:6158 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1207: + case 1209: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6149 +//line sql.y:6162 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1208: + case 1210: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6153 +//line sql.y:6166 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1209: + case 1211: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6157 +//line sql.y:6170 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1210: + case 1212: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6161 +//line sql.y:6174 { yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1211: + case 1213: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6165 +//line sql.y:6178 { yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1212: + case 1214: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6169 +//line sql.y:6182 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1213: + case 1215: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6173 +//line sql.y:6186 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1214: + case 1216: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6177 +//line sql.y:6190 { yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1215: + case 1217: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6181 +//line sql.y:6194 { yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1216: + case 1218: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6185 +//line sql.y:6198 { yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1217: + case 1219: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6189 +//line sql.y:6202 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1218: + case 1220: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6193 +//line sql.y:6206 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1219: + case 1221: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6197 +//line sql.y:6210 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1220: + case 1222: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6201 +//line sql.y:6214 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1221: + case 1223: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6205 +//line sql.y:6218 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1222: + case 1224: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6209 +//line sql.y:6222 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1223: + case 1225: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6213 +//line sql.y:6226 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1224: + case 1226: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6217 +//line sql.y:6230 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1225: + case 1227: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6221 +//line sql.y:6234 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1226: + case 1228: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6225 +//line sql.y:6238 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1227: + case 1229: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6229 +//line sql.y:6242 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1228: + case 1230: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6233 +//line sql.y:6246 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1229: + case 1231: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6237 +//line sql.y:6250 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1230: + case 1232: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6241 +//line sql.y:6254 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1231: + case 1233: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6245 +//line sql.y:6258 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1232: + case 1234: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6249 +//line sql.y:6262 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1233: + case 1235: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6253 +//line sql.y:6266 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1234: + case 1236: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6257 +//line sql.y:6270 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1235: + case 1237: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6261 +//line sql.y:6274 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1236: + case 1238: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6265 +//line sql.y:6278 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1237: + case 1239: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6269 +//line sql.y:6282 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1238: + case 1240: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6273 +//line sql.y:6286 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1239: + case 1241: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6277 +//line sql.y:6290 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1240: + case 1242: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6281 +//line sql.y:6294 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1241: + case 1243: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6285 +//line sql.y:6298 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1242: + case 1244: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6289 +//line sql.y:6302 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1243: + case 1245: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6293 +//line sql.y:6306 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1244: + case 1246: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6297 +//line sql.y:6310 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1245: + case 1247: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6301 +//line sql.y:6314 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1246: + case 1248: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6305 +//line sql.y:6318 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1247: + case 1249: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6309 +//line sql.y:6322 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1248: + case 1250: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6313 +//line sql.y:6326 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1249: + case 1251: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6317 +//line sql.y:6330 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1250: + case 1252: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6321 +//line sql.y:6334 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1251: + case 1253: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6325 +//line sql.y:6338 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1252: + case 1254: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6329 +//line sql.y:6342 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1253: + case 1255: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6333 +//line sql.y:6346 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1254: + case 1256: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6337 +//line sql.y:6350 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1255: + case 1257: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6341 +//line sql.y:6354 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1256: + case 1258: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6345 +//line sql.y:6358 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1257: + case 1259: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6349 +//line sql.y:6362 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1258: + case 1260: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6353 +//line sql.y:6366 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1259: + case 1261: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6357 +//line sql.y:6370 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1260: + case 1262: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6361 +//line sql.y:6374 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1261: + case 1263: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6365 +//line sql.y:6378 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1262: + case 1264: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6369 +//line sql.y:6382 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1263: + case 1265: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6373 +//line sql.y:6386 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1264: + case 1266: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6377 +//line sql.y:6390 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1265: + case 1267: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6381 +//line sql.y:6394 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1266: + case 1268: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6385 +//line sql.y:6398 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1267: + case 1269: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6389 +//line sql.y:6402 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1268: + case 1270: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6393 +//line sql.y:6406 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1269: + case 1271: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6397 +//line sql.y:6410 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1270: + case 1272: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6401 +//line sql.y:6414 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1271: + case 1273: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6405 +//line sql.y:6418 { yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1272: + case 1274: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6409 +//line sql.y:6422 { yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1273: + case 1275: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6413 +//line sql.y:6426 { yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1274: + case 1276: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6417 +//line sql.y:6430 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1275: + case 1277: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6421 +//line sql.y:6434 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1276: + case 1278: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6425 +//line sql.y:6438 { yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1277: + case 1279: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6429 +//line sql.y:6442 { yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1278: + case 1280: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6433 +//line sql.y:6446 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1279: + case 1281: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6437 +//line sql.y:6450 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1280: + case 1282: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6441 +//line sql.y:6454 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1281: + case 1283: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6445 +//line sql.y:6458 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1282: + case 1284: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6449 +//line sql.y:6462 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1283: + case 1285: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6453 +//line sql.y:6466 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1284: + case 1286: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6457 +//line sql.y:6470 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1285: + case 1287: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6461 +//line sql.y:6474 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1286: + case 1288: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6465 +//line sql.y:6478 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1287: + case 1289: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6469 +//line sql.y:6482 { yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1288: + case 1290: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6473 +//line sql.y:6486 { yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1289: + case 1291: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6477 +//line sql.y:6490 { yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1290: + case 1292: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6481 +//line sql.y:6494 { yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } yyVAL.union = yyLOCAL - case 1291: + case 1293: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6485 +//line sql.y:6498 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1292: + case 1294: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6489 +//line sql.y:6502 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1293: + case 1295: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6493 +//line sql.y:6506 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1294: + case 1296: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6497 +//line sql.y:6510 { yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1295: + case 1297: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6501 +//line sql.y:6514 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1296: + case 1298: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6505 +//line sql.y:6518 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1297: + case 1299: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6509 +//line sql.y:6522 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1298: + case 1300: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6513 +//line sql.y:6526 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1299: + case 1301: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6517 +//line sql.y:6530 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1300: + case 1302: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6521 +//line sql.y:6534 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1301: + case 1303: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6525 +//line sql.y:6538 { yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1302: + case 1304: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6529 +//line sql.y:6542 { yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1303: + case 1305: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6533 +//line sql.y:6546 { yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1304: + case 1306: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6537 +//line sql.y:6550 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1305: + case 1307: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6541 +//line sql.y:6554 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1306: + case 1308: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6545 +//line sql.y:6558 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1307: + case 1309: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6549 +//line sql.y:6562 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1308: + case 1310: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6553 +//line sql.y:6566 { yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1309: + case 1311: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6557 +//line sql.y:6570 { yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1310: + case 1312: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6561 +//line sql.y:6574 { yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1311: + case 1313: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6565 +//line sql.y:6578 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1312: + case 1314: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6569 +//line sql.y:6582 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1313: + case 1315: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6573 +//line sql.y:6586 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1314: + case 1316: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6577 +//line sql.y:6590 { yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1315: + case 1317: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6581 +//line sql.y:6594 { yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1316: + case 1318: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6585 +//line sql.y:6598 { yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1317: + case 1319: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6589 +//line sql.y:6602 { yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1318: + case 1320: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6593 +//line sql.y:6606 { yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1319: + case 1321: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6597 +//line sql.y:6610 { yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1320: + case 1322: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6601 +//line sql.y:6614 { yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1321: + case 1323: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6605 +//line sql.y:6618 { yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1322: + case 1324: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6609 +//line sql.y:6622 { yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1323: + case 1325: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6613 +//line sql.y:6626 { yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1324: + case 1326: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6617 +//line sql.y:6630 { yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1325: + case 1327: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6621 +//line sql.y:6634 { yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1326: + case 1328: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6625 +//line sql.y:6638 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1327: + case 1329: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6629 +//line sql.y:6642 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1328: + case 1330: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6633 +//line sql.y:6646 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1329: + case 1331: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6637 +//line sql.y:6650 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1330: + case 1332: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6641 +//line sql.y:6654 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1331: + case 1333: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6645 +//line sql.y:6658 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1332: + case 1334: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6649 +//line sql.y:6662 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1333: + case 1335: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6653 +//line sql.y:6666 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1338: + case 1340: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6663 +//line sql.y:6676 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1339: + case 1341: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6667 +//line sql.y:6680 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1340: + case 1342: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6671 +//line sql.y:6684 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1341: + case 1343: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6675 +//line sql.y:6688 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1342: + case 1344: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:6680 +//line sql.y:6693 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1343: + case 1345: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6684 +//line sql.y:6697 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1344: + case 1346: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6690 +//line sql.y:6703 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1345: + case 1347: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6694 +//line sql.y:6707 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1346: + case 1348: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6698 +//line sql.y:6711 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1347: + case 1349: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6702 +//line sql.y:6715 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1348: + case 1350: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6706 +//line sql.y:6719 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1349: + case 1351: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6711 +//line sql.y:6724 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1350: + case 1352: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6715 +//line sql.y:6728 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1351: + case 1353: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6719 +//line sql.y:6732 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1352: + case 1354: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6723 +//line sql.y:6736 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1353: + case 1355: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6727 +//line sql.y:6740 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1354: + case 1356: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6731 +//line sql.y:6744 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1355: + case 1357: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6736 +//line sql.y:6749 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1356: + case 1358: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6740 +//line sql.y:6753 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1357: + case 1359: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6744 +//line sql.y:6757 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1358: + case 1360: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6748 +//line sql.y:6761 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), MatchType: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1359: + case 1361: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6755 +//line sql.y:6768 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1360: + case 1362: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6759 +//line sql.y:6772 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1361: + case 1363: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6765 +//line sql.y:6778 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1362: + case 1364: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6769 +//line sql.y:6782 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1363: + case 1365: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6773 +//line sql.y:6786 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } yyVAL.union = yyLOCAL - case 1364: + case 1366: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6777 +//line sql.y:6790 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1365: + case 1367: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6783 +//line sql.y:6796 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1366: + case 1368: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6787 +//line sql.y:6800 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1367: + case 1369: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6791 +//line sql.y:6804 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1368: + case 1370: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6795 +//line sql.y:6808 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1369: + case 1371: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6799 +//line sql.y:6812 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1370: + case 1372: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6803 +//line sql.y:6816 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1371: + case 1373: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6807 +//line sql.y:6820 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1372: + case 1374: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6812 +//line sql.y:6825 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1373: + case 1375: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6816 +//line sql.y:6829 { yyLOCAL = yyDollar[2].convertTypeUnion() } yyVAL.union = yyLOCAL - case 1374: + case 1376: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6822 +//line sql.y:6835 { yyLOCAL = IntervalDayHour } yyVAL.union = yyLOCAL - case 1375: + case 1377: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6826 +//line sql.y:6839 { yyLOCAL = IntervalDayMicrosecond } yyVAL.union = yyLOCAL - case 1376: + case 1378: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6830 +//line sql.y:6843 { yyLOCAL = IntervalDayMinute } yyVAL.union = yyLOCAL - case 1377: + case 1379: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6834 +//line sql.y:6847 { yyLOCAL = IntervalDaySecond } yyVAL.union = yyLOCAL - case 1378: + case 1380: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6838 +//line sql.y:6851 { yyLOCAL = IntervalHourMicrosecond } yyVAL.union = yyLOCAL - case 1379: + case 1381: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6842 +//line sql.y:6855 { yyLOCAL = IntervalHourMinute } yyVAL.union = yyLOCAL - case 1380: + case 1382: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6846 +//line sql.y:6859 { yyLOCAL = IntervalHourSecond } yyVAL.union = yyLOCAL - case 1381: + case 1383: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6850 +//line sql.y:6863 { yyLOCAL = IntervalMinuteMicrosecond } yyVAL.union = yyLOCAL - case 1382: + case 1384: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6854 +//line sql.y:6867 { yyLOCAL = IntervalMinuteSecond } yyVAL.union = yyLOCAL - case 1383: + case 1385: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6858 +//line sql.y:6871 { yyLOCAL = IntervalSecondMicrosecond } yyVAL.union = yyLOCAL - case 1384: + case 1386: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6862 +//line sql.y:6875 { yyLOCAL = IntervalYearMonth } yyVAL.union = yyLOCAL - case 1385: + case 1387: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6866 +//line sql.y:6879 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1386: + case 1388: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6870 +//line sql.y:6883 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1387: + case 1389: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6874 +//line sql.y:6887 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1388: + case 1390: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6878 +//line sql.y:6891 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1389: + case 1391: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6882 +//line sql.y:6895 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1390: + case 1392: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6886 +//line sql.y:6899 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1391: + case 1393: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6890 +//line sql.y:6903 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1392: + case 1394: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6894 +//line sql.y:6907 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1393: + case 1395: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6898 +//line sql.y:6911 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1394: + case 1396: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6904 +//line sql.y:6917 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1395: + case 1397: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6908 +//line sql.y:6921 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1396: + case 1398: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6912 +//line sql.y:6925 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1397: + case 1399: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6916 +//line sql.y:6929 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1398: + case 1400: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6920 +//line sql.y:6933 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1399: + case 1401: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6924 +//line sql.y:6937 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1400: + case 1402: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6928 +//line sql.y:6941 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1401: + case 1403: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6932 +//line sql.y:6945 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1402: + case 1404: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6936 +//line sql.y:6949 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1403: + case 1405: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6940 +//line sql.y:6953 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1404: + case 1406: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6944 +//line sql.y:6957 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1405: + case 1407: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6948 +//line sql.y:6961 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1406: + case 1408: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6952 +//line sql.y:6965 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1407: + case 1409: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6956 +//line sql.y:6969 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1408: + case 1410: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6960 +//line sql.y:6973 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1409: + case 1411: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6964 +//line sql.y:6977 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1410: + case 1412: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6968 +//line sql.y:6981 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1411: + case 1413: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6972 +//line sql.y:6985 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1414: + case 1416: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:6982 +//line sql.y:6995 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1415: + case 1417: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:6986 +//line sql.y:6999 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1416: + case 1418: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:6990 +//line sql.y:7003 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1417: + case 1419: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7000 +//line sql.y:7013 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1418: + case 1420: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7004 +//line sql.y:7017 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1419: + case 1421: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7008 +//line sql.y:7021 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1420: + case 1422: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7012 +//line sql.y:7025 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1421: + case 1423: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7016 +//line sql.y:7029 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 1422: + case 1424: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7022 +//line sql.y:7035 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 1423: + case 1425: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7026 +//line sql.y:7039 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 1424: + case 1426: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7030 +//line sql.y:7043 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 1425: + case 1427: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7034 +//line sql.y:7047 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 1426: + case 1428: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7038 +//line sql.y:7051 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 1427: + case 1429: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7044 +//line sql.y:7057 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 1428: + case 1430: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7048 +//line sql.y:7061 { yyVAL.str = string(yyDollar[1].str) } - case 1429: + case 1431: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7052 +//line sql.y:7065 { yyVAL.str = string(yyDollar[1].str) } - case 1430: + case 1432: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7058 +//line sql.y:7071 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1431: + case 1433: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7062 +//line sql.y:7075 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: NewIntLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 1432: + case 1434: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7066 +//line sql.y:7079 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: NewIntLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 1433: + case 1435: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7072 +//line sql.y:7085 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 1434: + case 1436: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7076 +//line sql.y:7089 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: yyDollar[3].columnCharset} } yyVAL.union = yyLOCAL - case 1435: + case 1437: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7080 +//line sql.y:7093 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1436: + case 1438: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7084 +//line sql.y:7097 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 1437: + case 1439: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7088 +//line sql.y:7101 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 1438: + case 1440: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7094 +//line sql.y:7107 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1439: + case 1441: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7098 +//line sql.y:7111 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 1440: + case 1442: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7102 +//line sql.y:7115 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1441: + case 1443: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7106 +//line sql.y:7119 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1442: + case 1444: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7110 +//line sql.y:7123 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 1443: + case 1445: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7114 +//line sql.y:7127 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1444: + case 1446: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7118 +//line sql.y:7131 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1445: + case 1447: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7122 +//line sql.y:7135 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 1446: + case 1448: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7126 +//line sql.y:7139 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1447: + case 1449: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7130 +//line sql.y:7143 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1448: + case 1450: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7136 +//line sql.y:7149 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1449: + case 1451: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7140 +//line sql.y:7153 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1450: + case 1452: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7145 +//line sql.y:7158 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1451: + case 1453: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7149 +//line sql.y:7162 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1452: + case 1454: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7154 +//line sql.y:7167 { yyVAL.str = string("") } - case 1453: + case 1455: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7158 +//line sql.y:7171 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 1454: + case 1456: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7164 +//line sql.y:7177 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 1455: + case 1457: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7168 +//line sql.y:7181 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 1456: + case 1458: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7174 +//line sql.y:7187 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1457: + case 1459: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7179 +//line sql.y:7192 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1458: + case 1460: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7183 +//line sql.y:7196 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1459: + case 1461: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7189 +//line sql.y:7202 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1460: + case 1462: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7193 +//line sql.y:7206 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1461: + case 1463: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7197 +//line sql.y:7210 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1462: + case 1464: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7201 +//line sql.y:7214 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 1463: + case 1465: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7207 +//line sql.y:7220 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 1464: + case 1466: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7211 +//line sql.y:7224 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1465: + case 1467: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7217 +//line sql.y:7230 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -21070,426 +21161,426 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 1466: + case 1468: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7226 +//line sql.y:7239 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1467: + case 1469: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7230 +//line sql.y:7243 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1468: + case 1470: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7235 +//line sql.y:7248 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1469: + case 1471: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:7239 +//line sql.y:7252 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1470: + case 1472: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7244 +//line sql.y:7257 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1471: + case 1473: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7248 +//line sql.y:7261 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1472: + case 1474: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7254 +//line sql.y:7267 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 1473: + case 1475: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7260 +//line sql.y:7273 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL - case 1474: + case 1476: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7264 +//line sql.y:7277 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) } - case 1475: + case 1477: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7269 +//line sql.y:7282 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1476: + case 1478: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7273 +//line sql.y:7286 { yyLOCAL = yyDollar[1].namedWindowsUnion() } yyVAL.union = yyLOCAL - case 1477: + case 1479: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7278 +//line sql.y:7291 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1478: + case 1480: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7282 +//line sql.y:7295 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 1479: + case 1481: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7288 +//line sql.y:7301 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 1480: + case 1482: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7294 +//line sql.y:7307 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 1481: + case 1483: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7298 +//line sql.y:7311 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 1482: + case 1484: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7304 +//line sql.y:7317 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 1483: + case 1485: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7309 +//line sql.y:7322 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1484: + case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7313 +//line sql.y:7326 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1485: + case 1487: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7317 +//line sql.y:7330 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 1486: + case 1488: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7322 +//line sql.y:7335 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1487: + case 1489: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7326 +//line sql.y:7339 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 1488: + case 1490: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7332 +//line sql.y:7345 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1489: + case 1491: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7336 +//line sql.y:7349 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1490: + case 1492: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7340 +//line sql.y:7353 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1491: + case 1493: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7345 +//line sql.y:7358 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1492: + case 1494: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7349 +//line sql.y:7362 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1493: + case 1495: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7353 +//line sql.y:7366 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1494: + case 1496: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7357 +//line sql.y:7370 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1495: + case 1497: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7361 +//line sql.y:7374 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1496: + case 1498: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7368 +//line sql.y:7381 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 1497: + case 1499: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7372 +//line sql.y:7385 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 1498: + case 1500: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7376 +//line sql.y:7389 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 1499: + case 1501: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7380 +//line sql.y:7393 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 1500: + case 1502: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7386 +//line sql.y:7399 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1501: + case 1503: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7390 +//line sql.y:7403 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1502: + case 1504: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7394 +//line sql.y:7407 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1503: + case 1505: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7398 +//line sql.y:7411 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1504: + case 1506: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7403 +//line sql.y:7416 { yyVAL.str = "" } - case 1505: + case 1507: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7407 +//line sql.y:7420 { yyVAL.str = string(yyDollar[3].str) } - case 1506: + case 1508: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7411 +//line sql.y:7424 { yyVAL.str = string(yyDollar[3].str) } - case 1507: + case 1509: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7415 +//line sql.y:7428 { yyVAL.str = string(yyDollar[3].str) } - case 1508: + case 1510: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7420 +//line sql.y:7433 { yyVAL.str = "" } - case 1509: + case 1511: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7424 +//line sql.y:7437 { yyVAL.str = yyDollar[3].str } - case 1510: + case 1512: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7430 +//line sql.y:7443 { yyVAL.str = string(yyDollar[1].str) } - case 1511: + case 1513: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7434 +//line sql.y:7447 { yyVAL.str = string(yyDollar[1].str) } - case 1512: + case 1514: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7439 +//line sql.y:7452 { yyVAL.str = "" } - case 1513: + case 1515: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7443 +//line sql.y:7456 { yyVAL.str = yyDollar[2].str } - case 1514: + case 1516: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7448 +//line sql.y:7461 { yyVAL.str = "cascaded" } - case 1515: + case 1517: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7452 +//line sql.y:7465 { yyVAL.str = string(yyDollar[1].str) } - case 1516: + case 1518: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7456 +//line sql.y:7469 { yyVAL.str = string(yyDollar[1].str) } - case 1517: + case 1519: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:7461 +//line sql.y:7474 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1518: + case 1520: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7465 +//line sql.y:7478 { yyLOCAL = yyDollar[3].definerUnion() } yyVAL.union = yyLOCAL - case 1519: + case 1521: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:7471 +//line sql.y:7484 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1520: + case 1522: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7477 +//line sql.y:7490 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1521: + case 1523: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:7483 +//line sql.y:7496 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -21497,409 +21588,409 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1522: + case 1524: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7492 +//line sql.y:7505 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 1523: + case 1525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7496 +//line sql.y:7509 { yyVAL.str = formatIdentifier(yyDollar[1].str) } - case 1524: + case 1526: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7501 +//line sql.y:7514 { yyVAL.str = "" } - case 1525: + case 1527: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7505 +//line sql.y:7518 { yyVAL.str = formatAddress(yyDollar[1].str) } - case 1526: + case 1528: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7511 +//line sql.y:7524 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 1527: + case 1529: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7515 +//line sql.y:7528 { yyLOCAL = ForUpdateLockNoWait } yyVAL.union = yyLOCAL - case 1528: + case 1530: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7519 +//line sql.y:7532 { yyLOCAL = ForUpdateLockSkipLocked } yyVAL.union = yyLOCAL - case 1529: + case 1531: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7523 +//line sql.y:7536 { yyLOCAL = ForShareLock } yyVAL.union = yyLOCAL - case 1530: + case 1532: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7527 +//line sql.y:7540 { yyLOCAL = ForShareLockNoWait } yyVAL.union = yyLOCAL - case 1531: + case 1533: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7531 +//line sql.y:7544 { yyLOCAL = ForShareLockSkipLocked } yyVAL.union = yyLOCAL - case 1532: + case 1534: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7535 +//line sql.y:7548 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 1533: + case 1535: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7541 +//line sql.y:7554 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 1534: + case 1536: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7545 +//line sql.y:7558 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1535: + case 1537: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7549 +//line sql.y:7562 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1536: + case 1538: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7554 +//line sql.y:7567 { yyVAL.str = "" } - case 1537: + case 1539: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7558 +//line sql.y:7571 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1538: + case 1540: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7562 +//line sql.y:7575 { yyVAL.str = " format text" + yyDollar[3].str } - case 1539: + case 1541: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7567 +//line sql.y:7580 { yyVAL.str = "" } - case 1540: + case 1542: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7571 +//line sql.y:7584 { yyVAL.str = " header" } - case 1541: + case 1543: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7576 +//line sql.y:7589 { yyVAL.str = "" } - case 1542: + case 1544: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7580 +//line sql.y:7593 { yyVAL.str = " manifest on" } - case 1543: + case 1545: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7584 +//line sql.y:7597 { yyVAL.str = " manifest off" } - case 1544: + case 1546: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7589 +//line sql.y:7602 { yyVAL.str = "" } - case 1545: + case 1547: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7593 +//line sql.y:7606 { yyVAL.str = " overwrite on" } - case 1546: + case 1548: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7597 +//line sql.y:7610 { yyVAL.str = " overwrite off" } - case 1547: + case 1549: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7603 +//line sql.y:7616 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1548: + case 1550: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7608 +//line sql.y:7621 { yyVAL.str = "" } - case 1549: + case 1551: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7612 +//line sql.y:7625 { yyVAL.str = " lines" + yyDollar[2].str } - case 1550: + case 1552: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7618 +//line sql.y:7631 { yyVAL.str = yyDollar[1].str } - case 1551: + case 1553: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7622 +//line sql.y:7635 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1552: + case 1554: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7628 +//line sql.y:7641 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1553: + case 1555: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7632 +//line sql.y:7645 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1554: + case 1556: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7637 +//line sql.y:7650 { yyVAL.str = "" } - case 1555: + case 1557: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7641 +//line sql.y:7654 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1556: + case 1558: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7647 +//line sql.y:7660 { yyVAL.str = yyDollar[1].str } - case 1557: + case 1559: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7651 +//line sql.y:7664 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1558: + case 1560: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7657 +//line sql.y:7670 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1559: + case 1561: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7661 +//line sql.y:7674 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1560: + case 1562: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7665 +//line sql.y:7678 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1561: + case 1563: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7670 +//line sql.y:7683 { yyVAL.str = "" } - case 1562: + case 1564: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7674 +//line sql.y:7687 { yyVAL.str = " optionally" } - case 1563: + case 1565: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Insert -//line sql.y:7687 +//line sql.y:7700 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion()} } yyVAL.union = yyLOCAL - case 1564: + case 1566: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:7691 +//line sql.y:7704 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1565: + case 1567: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:7695 +//line sql.y:7708 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion()} } yyVAL.union = yyLOCAL - case 1566: + case 1568: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7699 +//line sql.y:7712 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion()} } yyVAL.union = yyLOCAL - case 1567: + case 1569: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7703 +//line sql.y:7716 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1568: + case 1570: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:7709 +//line sql.y:7722 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1569: + case 1571: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:7713 +//line sql.y:7726 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1570: + case 1572: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7717 +//line sql.y:7730 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1571: + case 1573: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:7721 +//line sql.y:7734 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1572: + case 1574: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7726 +//line sql.y:7739 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1573: + case 1575: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7730 +//line sql.y:7743 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1574: + case 1576: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:7736 +//line sql.y:7749 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1575: + case 1577: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7740 +//line sql.y:7753 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1576: + case 1578: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7746 +//line sql.y:7759 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1577: + case 1579: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7750 +//line sql.y:7763 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1578: + case 1580: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7756 +//line sql.y:7769 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1579: + case 1581: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7760 +//line sql.y:7773 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1580: + case 1582: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7765 +//line sql.y:7778 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -21908,300 +21999,300 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1581: + case 1583: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7775 +//line sql.y:7788 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1582: + case 1584: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7779 +//line sql.y:7792 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1583: + case 1585: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:7785 +//line sql.y:7798 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1585: + case 1587: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7792 +//line sql.y:7805 { yyVAL.str = "charset" } - case 1588: + case 1590: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7802 +//line sql.y:7815 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1589: + case 1591: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7806 +//line sql.y:7819 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1590: + case 1592: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7810 +//line sql.y:7823 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1593: + case 1595: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7819 +//line sql.y:7832 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1594: + case 1596: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7821 +//line sql.y:7834 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1595: + case 1597: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7824 +//line sql.y:7837 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1596: + case 1598: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7826 +//line sql.y:7839 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1597: + case 1599: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7829 +//line sql.y:7842 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1598: + case 1600: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:7831 +//line sql.y:7844 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1599: + case 1601: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:7834 +//line sql.y:7847 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1600: + case 1602: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:7836 +//line sql.y:7849 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1601: + case 1603: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7839 +//line sql.y:7852 { yyVAL.empty = struct{}{} } - case 1602: + case 1604: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7841 +//line sql.y:7854 { yyVAL.empty = struct{}{} } - case 1603: + case 1605: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7843 +//line sql.y:7856 { yyVAL.empty = struct{}{} } - case 1604: + case 1606: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:7847 +//line sql.y:7860 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1605: + case 1607: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7852 +//line sql.y:7865 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1606: + case 1608: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:7856 +//line sql.y:7869 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1607: + case 1609: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7861 +//line sql.y:7874 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1608: + case 1610: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7863 +//line sql.y:7876 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1609: + case 1611: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:7867 +//line sql.y:7880 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1610: + case 1612: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7873 +//line sql.y:7886 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1611: + case 1613: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7877 +//line sql.y:7890 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1613: + case 1615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7884 +//line sql.y:7897 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1614: + case 1616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7890 +//line sql.y:7903 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1615: + case 1617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7894 +//line sql.y:7907 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1616: + case 1618: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7900 +//line sql.y:7913 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1617: + case 1619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7904 +//line sql.y:7917 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1619: + case 1621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7911 +//line sql.y:7924 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1620: + case 1622: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:7917 +//line sql.y:7930 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1621: + case 1623: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:7923 +//line sql.y:7936 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1622: + case 1624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7927 +//line sql.y:7940 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1623: + case 1625: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7931 +//line sql.y:7944 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2238: + case 2240: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8574 +//line sql.y:8587 { } - case 2239: + case 2241: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8579 +//line sql.y:8592 { } - case 2240: + case 2242: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8583 +//line sql.y:8596 { skipToEnd(yylex) } - case 2241: + case 2243: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8588 +//line sql.y:8601 { skipToEnd(yylex) } - case 2242: + case 2244: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8592 +//line sql.y:8605 { skipToEnd(yylex) } - case 2243: + case 2245: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8596 +//line sql.y:8609 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index a71e8e6ac4c..59ebfdf82bc 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -303,7 +303,7 @@ func markBindVariable(yylex yyLexer, bvar string) { %token SEQUENCE MERGE TEMPORARY TEMPTABLE INVOKER SECURITY FIRST AFTER LAST // Migration tokens -%token VITESS_MIGRATION CANCEL RETRY LAUNCH COMPLETE CLEANUP THROTTLE UNTHROTTLE EXPIRE RATIO +%token VITESS_MIGRATION CANCEL RETRY LAUNCH COMPLETE CLEANUP THROTTLE UNTHROTTLE FORCE_CUTOVER EXPIRE RATIO // Throttler tokens %token VITESS_THROTTLER @@ -3365,6 +3365,19 @@ alter_statement: Type: UnthrottleAllMigrationType, } } +| ALTER comment_opt VITESS_MIGRATION STRING FORCE_CUTOVER + { + $$ = &AlterMigration{ + Type: ForceCutOverMigrationType, + UUID: string($4), + } + } +| ALTER comment_opt VITESS_MIGRATION FORCE_CUTOVER ALL + { + $$ = &AlterMigration{ + Type: ForceCutOverAllMigrationType, + } + } partitions_options_opt: { diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 087b566fe5d..4020afa3307 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -128,6 +128,15 @@ func (client *gRPCVtctldClient) CleanupSchemaMigration(ctx context.Context, in * return client.c.CleanupSchemaMigration(ctx, in, opts...) } +// ForceCutOverSchemaMigration is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) ForceCutOverSchemaMigration(ctx context.Context, in *vtctldatapb.ForceCutOverSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldatapb.ForceCutOverSchemaMigrationResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.ForceCutOverSchemaMigration(ctx, in, opts...) +} + // CompleteSchemaMigration is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) CompleteSchemaMigration(ctx context.Context, in *vtctldatapb.CompleteSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldatapb.CompleteSchemaMigrationResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index de63ba2cdc2..b0b7bd370f7 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -679,6 +679,37 @@ func (s *VtctldServer) CleanupSchemaMigration(ctx context.Context, req *vtctldat return resp, nil } +// ForceCutOverSchemaMigration is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) ForceCutOverSchemaMigration(ctx context.Context, req *vtctldatapb.ForceCutOverSchemaMigrationRequest) (resp *vtctldatapb.ForceCutOverSchemaMigrationResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.ForceCutOverSchemaMigration") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("keyspace", req.Keyspace) + span.Annotate("uuid", req.Uuid) + + query, err := alterSchemaMigrationQuery("force_cutover", req.Uuid) + if err != nil { + return nil, err + } + + log.Infof("Calling ApplySchema to force cut-over migration %s", req.Uuid) + qr, err := s.ApplySchema(ctx, &vtctldatapb.ApplySchemaRequest{ + Keyspace: req.Keyspace, + Sql: []string{query}, + WaitReplicasTimeout: protoutil.DurationToProto(DefaultWaitReplicasTimeout), + }) + if err != nil { + return nil, err + } + + resp = &vtctldatapb.ForceCutOverSchemaMigrationResponse{ + RowsAffectedByShard: qr.RowsAffectedByShard, + } + return resp, nil +} + // CompleteSchemaMigration is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) CompleteSchemaMigration(ctx context.Context, req *vtctldatapb.CompleteSchemaMigrationRequest) (resp *vtctldatapb.CompleteSchemaMigrationResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.CompleteSchemaMigration") diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 60f29221a3c..124c7096bc4 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -1775,6 +1775,208 @@ func TestCleanupSchemaMigration(t *testing.T) { } } +func TestForceCutOverSchemaMigration(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + tablets []*topodatapb.Tablet + tmc *testutil.TabletManagerClient + req *vtctldatapb.ForceCutOverSchemaMigrationRequest + expected *vtctldatapb.ForceCutOverSchemaMigrationResponse + shouldErr bool + }{ + { + tablets: []*topodatapb.Tablet{ + { + Keyspace: "ks", + Shard: "-80", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + { + Keyspace: "ks", + Shard: "80-", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + }, + tmc: &testutil.TabletManagerClient{ + ExecuteQueryResults: map[string]struct { + Response *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + Response: &querypb.QueryResult{ + RowsAffected: 1, + }, + }, + "zone1-0000000200": { + Response: &querypb.QueryResult{}, + }, + }, + PrimaryPositionResults: map[string]struct { + Position string + Error error + }{ + "zone1-0000000100": {}, + "zone1-0000000200": {}, + }, + ReloadSchemaResults: map[string]error{ + "zone1-0000000100": nil, + "zone1-0000000200": nil, + }, + }, + req: &vtctldatapb.ForceCutOverSchemaMigrationRequest{ + Keyspace: "ks", + Uuid: "abc", + }, + expected: &vtctldatapb.ForceCutOverSchemaMigrationResponse{ + RowsAffectedByShard: map[string]uint64{ + "-80": 1, + "80-": 0, + }, + }, + }, + { + name: "no shard primary", + tablets: []*topodatapb.Tablet{ + { + Keyspace: "ks", + Shard: "-80", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + { + Keyspace: "ks", + Shard: "80-", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + tmc: &testutil.TabletManagerClient{ + ExecuteQueryResults: map[string]struct { + Response *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + Response: &querypb.QueryResult{}, + }, + "zone1-0000000200": { + Response: &querypb.QueryResult{}, + }, + }, + PrimaryPositionResults: map[string]struct { + Position string + Error error + }{ + "zone1-0000000100": {}, + "zone1-0000000200": {}, + }, + ReloadSchemaResults: map[string]error{ + "zone1-0000000100": nil, + "zone1-0000000200": nil, + }, + }, + req: &vtctldatapb.ForceCutOverSchemaMigrationRequest{ + Keyspace: "ks", + Uuid: "abc", + }, + shouldErr: true, + }, + { + name: "executeQuery failure", + tablets: []*topodatapb.Tablet{ + { + Keyspace: "ks", + Shard: "-80", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + { + Keyspace: "ks", + Shard: "80-", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_PRIMARY, + }, + }, + tmc: &testutil.TabletManagerClient{ + ExecuteQueryResults: map[string]struct { + Response *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + Error: assert.AnError, + }, + "zone1-0000000200": { + Response: &querypb.QueryResult{}, + }, + }, + PrimaryPositionResults: map[string]struct { + Position string + Error error + }{ + "zone1-0000000100": {}, + "zone1-0000000200": {}, + }, + ReloadSchemaResults: map[string]error{ + "zone1-0000000100": nil, + "zone1-0000000200": nil, + }, + }, + req: &vtctldatapb.ForceCutOverSchemaMigrationRequest{ + Keyspace: "ks", + Uuid: "abc", + }, + shouldErr: true, + }, + // execute query failure + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts := memorytopo.NewServer(ctx, "zone1") + + testutil.AddTablets(ctx, t, ts, &testutil.AddTabletOptions{ + AlsoSetShardPrimary: true, + }, test.tablets...) + + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, test.tmc, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) + + resp, err := vtctld.ForceCutOverSchemaMigration(ctx, test.req) + if test.shouldErr { + assert.Error(t, err) + return + } + + require.NoError(t, err) + utils.MustMatch(t, test.expected, resp) + }) + } +} + func TestCompleteSchemaMigration(t *testing.T) { t.Parallel() diff --git a/go/vt/vtctl/localvtctldclient/client_gen.go b/go/vt/vtctl/localvtctldclient/client_gen.go index 198fc12908f..019ce619054 100644 --- a/go/vt/vtctl/localvtctldclient/client_gen.go +++ b/go/vt/vtctl/localvtctldclient/client_gen.go @@ -176,6 +176,11 @@ func (client *localVtctldClient) CleanupSchemaMigration(ctx context.Context, in return client.s.CleanupSchemaMigration(ctx, in) } +// ForceCutOverSchemaMigration is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) ForceCutOverSchemaMigration(ctx context.Context, in *vtctldatapb.ForceCutOverSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldatapb.ForceCutOverSchemaMigrationResponse, error) { + return client.s.ForceCutOverSchemaMigration(ctx, in) +} + // CompleteSchemaMigration is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) CompleteSchemaMigration(ctx context.Context, in *vtctldatapb.CompleteSchemaMigrationRequest, opts ...grpc.CallOption) (*vtctldatapb.CompleteSchemaMigrationResponse, error) { return client.s.CompleteSchemaMigration(ctx, in) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index cdd890ef5d7..a5d642b0abf 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -95,6 +95,10 @@ var ( retainOnlineDDLTables = 24 * time.Hour defaultCutOverThreshold = 10 * time.Second maxConcurrentOnlineDDLs = 256 + + migrationNextCheckIntervals = []time.Duration{1 * time.Second, 5 * time.Second, 10 * time.Second, 20 * time.Second} + maxConstraintNameLength = 64 + cutoverIntervals = []time.Duration{0, 1 * time.Minute, 5 * time.Minute, 10 * time.Minute, 30 * time.Minute} ) func init() { @@ -110,9 +114,6 @@ func registerOnlineDDLFlags(fs *pflag.FlagSet) { fs.IntVar(&maxConcurrentOnlineDDLs, "max_concurrent_online_ddl", maxConcurrentOnlineDDLs, "Maximum number of online DDL changes that may run concurrently") } -var migrationNextCheckIntervals = []time.Duration{1 * time.Second, 5 * time.Second, 10 * time.Second, 20 * time.Second} -var maxConstraintNameLength = 64 - const ( maxPasswordLength = 32 // MySQL's *replication* password may not exceed 32 characters staleMigrationMinutes = 180 @@ -769,8 +770,100 @@ func (e *Executor) terminateVReplMigration(ctx context.Context, uuid string) err return nil } +// killTableLockHoldersAndAccessors kills any active queries using the given table, and also kills +// connections with open transactions, holding locks on the table. +// This is done on a best-effort basis, by issuing `KILL` and `KILL QUERY` commands. As MySQL goes, +// it is not guaranteed that the queries/transactions will terminate in a timely manner. +func (e *Executor) killTableLockHoldersAndAccessors(ctx context.Context, tableName string) error { + log.Infof("killTableLockHoldersAndAccessors: %v", tableName) + conn, err := dbconnpool.NewDBConnection(ctx, e.env.Config().DB.DbaWithDB()) + if err != nil { + return err + } + defer conn.Close() + + { + // First, let's look at PROCESSLIST for queries that _might_ be operating on our table. This may have + // plenty false positives as we're simply looking for the table name as a query substring. + likeVariable := "%" + tableName + "%" + query, err := sqlparser.ParseAndBind(sqlFindProcessByInfo, sqltypes.StringBindVariable(likeVariable)) + if err != nil { + return err + } + rs, err := conn.Conn.ExecuteFetch(query, -1, true) + if err != nil { + return err + } + + log.Infof("killTableLockHoldersAndAccessors: found %v potential queries", len(rs.Rows)) + // Now that we have some list of queries, we actually parse them to find whether the query actually references our table: + for _, row := range rs.Named().Rows { + threadId := row.AsInt64("id", 0) + infoQuery := row.AsString("info", "") + stmt, err := sqlparser.Parse(infoQuery) + if err != nil { + log.Error(vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unable to parse processlist Info query: %v", infoQuery)) + continue + } + queryUsesTable := false + _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + switch node := node.(type) { + case *sqlparser.TableName: + if node.Name.String() == tableName { + queryUsesTable = true + return false, nil + } + case *sqlparser.AliasedTableExpr: + if alasedTableName, ok := node.Expr.(sqlparser.TableName); ok { + if alasedTableName.Name.String() == tableName { + queryUsesTable = true + return false, nil + } + } + } + return true, nil + }, stmt) + + if queryUsesTable { + log.Infof("killTableLockHoldersAndAccessors: killing query %v: %.100s", threadId, infoQuery) + killQuery := fmt.Sprintf("KILL QUERY %d", threadId) + if _, err := conn.Conn.ExecuteFetch(killQuery, 1, false); err != nil { + log.Error(vterrors.Errorf(vtrpcpb.Code_ABORTED, "could not kill query %v. Ignoring", threadId)) + } + } + } + } + _, capableOf, _ := mysql.GetFlavor(conn.ServerVersion, nil) + capable, err := capableOf(mysql.PerformanceSchemaDataLocksTableCapability) + if err != nil { + return err + } + if capable { + { + // Kill connections that have open transactions locking the table. These potentially (probably?) are not + // actively running a query on our table. They're doing other things while holding locks on our table. + query, err := sqlparser.ParseAndBind(sqlProcessWithLocksOnTable, sqltypes.StringBindVariable(tableName)) + if err != nil { + return err + } + rs, err := conn.Conn.ExecuteFetch(query, -1, true) + if err != nil { + return err + } + log.Infof("killTableLockHoldersAndAccessors: found %v locking transactions", len(rs.Rows)) + for _, row := range rs.Named().Rows { + threadId := row.AsInt64("trx_mysql_thread_id", 0) + log.Infof("killTableLockHoldersAndAccessors: killing connection %v with transaction on table", threadId) + killConnection := fmt.Sprintf("KILL %d", threadId) + _, _ = conn.Conn.ExecuteFetch(killConnection, 1, false) + } + } + } + return nil +} + // cutOverVReplMigration stops vreplication, then removes the _vt.vreplication entry for the given migration -func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) error { +func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, shouldForceCutOver bool) error { if err := e.incrementCutoverAttempts(ctx, s.workflow); err != nil { return err } @@ -978,6 +1071,12 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) er e.updateMigrationStage(ctx, onlineDDL.UUID, "graceful wait for buffering") time.Sleep(100 * time.Millisecond) + if shouldForceCutOver { + if err := e.killTableLockHoldersAndAccessors(ctx, onlineDDL.Table); err != nil { + return err + } + } + if isVreplicationTestSuite { // The testing suite may inject queries internally from the server via a recurring EVENT. // Those queries are unaffected by query rules (ACLs) because they don't go through Vitess. @@ -3558,6 +3657,46 @@ func (e *Executor) isVReplMigrationReadyToCutOver(ctx context.Context, onlineDDL return true, nil } +// shouldCutOverAccordingToBackoff is called when a vitess migration (ALTER TABLE) is generally ready to cut-over. +// This function further determines whether the migration should cut-over or not, by considering: +// - backoff: we cut-over by increasing intervals, see `cutoverIntervals` +// - forced cut-over: either via `--force-cut-over-after` DDL strategy, or via user command, we override +// any backoff (and will also potentially KILL queries and connections holding locks on the migrated tabl) +func shouldCutOverAccordingToBackoff( + shouldForceCutOverIndicator bool, + forceCutOverAfter time.Duration, + sinceReadyToComplete time.Duration, + sinceLastCutoverAttempt time.Duration, + cutoverAttempts int64, +) ( + shouldCutOver bool, shouldForceCutOver bool, +) { + if shouldForceCutOverIndicator { + // That's very simple: the user indicated they want to force cut over. + return true, true + } + // shouldForceCutOver means the time since migration was ready to complete + // is beyond the --force-cut-over-after setting, or the column `force_cutover` is "1", and this means: + // - we do not want to backoff, we want to cutover asap + // - we agree to brute-force KILL any pending queries on the migrated table so as to ensure it's unlocked. + if forceCutOverAfter > 0 && sinceReadyToComplete > forceCutOverAfter { + // time since migration was ready to complete is beyond the --force-cut-over-after setting + return true, true + } + + // Backoff mechanism. Do not attempt to cut-over every single minute. Check how much time passed since last cut-over attempt + desiredTimeSinceLastCutover := cutoverIntervals[len(cutoverIntervals)-1] + if int(cutoverAttempts) < len(cutoverIntervals) { + desiredTimeSinceLastCutover = cutoverIntervals[cutoverAttempts] + } + if sinceLastCutoverAttempt >= desiredTimeSinceLastCutover { + // Yes! Time since last cut-over complies with our expected cut-over interval + return true, false + } + // Don't cut-over yet + return false, false +} + // reviewRunningMigrations iterates migrations in 'running' state. Normally there's only one running, which was // spawned by this tablet; but vreplication migrations could also resume from failure. func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning int, cancellable []*cancellableMigration, err error) { @@ -3589,30 +3728,42 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i uuidsFoundRunning := map[string]bool{} for _, row := range r.Named().Rows { uuid := row["migration_uuid"].ToString() + cutoverAttempts := row.AsInt64("cutover_attempts", 0) + sinceLastCutoverAttempt := time.Second * time.Duration(row.AsInt64("seconds_since_last_cutover_attempt", 0)) + sinceReadyToComplete := time.Second * time.Duration(row.AsInt64("seconds_since_ready_to_complete", 0)) onlineDDL, migrationRow, err := e.readMigration(ctx, uuid) if err != nil { return countRunnning, cancellable, err } postponeCompletion := row.AsBool("postpone_completion", false) + shouldForceCutOver := row.AsBool("force_cutover", false) elapsedSeconds := row.AsInt64("elapsed_seconds", 0) + strategySetting := onlineDDL.StrategySetting() + // --force-cut-over-after flag is validated when DDL strategy is first parsed. + // There should never be an error here. But if there is, we choose to skip it, + // otherwise migrations will never complete. + forceCutOverAfter, errForceCutOverAfter := strategySetting.ForceCutOverAfter() + if errForceCutOverAfter != nil { + forceCutOverAfter = 0 + } uuidsFoundRunning[uuid] = true _ = e.updateMigrationUserThrottleRatio(ctx, uuid, currentUserThrottleRatio) - switch onlineDDL.StrategySetting().Strategy { + switch strategySetting.Strategy { case schema.DDLStrategyOnline, schema.DDLStrategyVitess: - { + reviewVReplRunningMigration := func() error { // We check the _vt.vreplication table s, err := e.readVReplStream(ctx, uuid, true) if err != nil { - return countRunnning, cancellable, err + return err } - isVreplicationTestSuite := onlineDDL.StrategySetting().IsVreplicationTestSuite() + isVreplicationTestSuite := strategySetting.IsVreplicationTestSuite() if isVreplicationTestSuite { e.triggerNextCheckInterval() } if s == nil { - continue + return nil } // Let's see if vreplication indicates an error. Many errors are recoverable, and // we do not wish to fail on first sight. We will use LastError to repeatedly @@ -3629,65 +3780,77 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i if isTerminal || !lastError.ShouldRetry() { cancellable = append(cancellable, newCancellableMigration(uuid, s.message)) } - if s.isRunning() { - // This VRepl migration may have started from outside this tablet, so - // this executor may not own the migration _yet_. We make sure to own it. - // VReplication migrations are unique in this respect: we are able to complete - // a vreplication migration started by another tablet. - e.ownedRunningMigrations.Store(uuid, onlineDDL) - if lastVitessLivenessIndicator := migrationRow.AsInt64("vitess_liveness_indicator", 0); lastVitessLivenessIndicator < s.livenessTimeIndicator() { - _ = e.updateMigrationTimestamp(ctx, "liveness_timestamp", uuid) - _ = e.updateVitessLivenessIndicator(ctx, uuid, s.livenessTimeIndicator()) - } - if onlineDDL.TabletAlias != e.TabletAliasString() { - _ = e.updateMigrationTablet(ctx, uuid) - log.Infof("migration %s adopted by tablet %s", uuid, e.TabletAliasString()) - } - _ = e.updateRowsCopied(ctx, uuid, s.rowsCopied) - _ = e.updateMigrationProgressByRowsCopied(ctx, uuid, s.rowsCopied) - _ = e.updateMigrationETASecondsByProgress(ctx, uuid) - _ = e.updateMigrationLastThrottled(ctx, uuid, time.Unix(s.timeThrottled, 0), s.componentThrottled) + if !s.isRunning() { + return nil + } + // This VRepl migration may have started from outside this tablet, so + // this executor may not own the migration _yet_. We make sure to own it. + // VReplication migrations are unique in this respect: we are able to complete + // a vreplication migration started by another tablet. + e.ownedRunningMigrations.Store(uuid, onlineDDL) + if lastVitessLivenessIndicator := migrationRow.AsInt64("vitess_liveness_indicator", 0); lastVitessLivenessIndicator < s.livenessTimeIndicator() { + _ = e.updateMigrationTimestamp(ctx, "liveness_timestamp", uuid) + _ = e.updateVitessLivenessIndicator(ctx, uuid, s.livenessTimeIndicator()) + } + if onlineDDL.TabletAlias != e.TabletAliasString() { + _ = e.updateMigrationTablet(ctx, uuid) + log.Infof("migration %s adopted by tablet %s", uuid, e.TabletAliasString()) + } + _ = e.updateRowsCopied(ctx, uuid, s.rowsCopied) + _ = e.updateMigrationProgressByRowsCopied(ctx, uuid, s.rowsCopied) + _ = e.updateMigrationETASecondsByProgress(ctx, uuid) + _ = e.updateMigrationLastThrottled(ctx, uuid, time.Unix(s.timeThrottled, 0), s.componentThrottled) - isReady, err := e.isVReplMigrationReadyToCutOver(ctx, onlineDDL, s) - if err != nil { - _ = e.updateMigrationMessage(ctx, uuid, err.Error()) - return countRunnning, cancellable, err - } - if isReady && isVreplicationTestSuite { - // This is a endtoend test suite execution. We intentionally delay it by at least - // vreplicationTestSuiteWaitSeconds - if elapsedSeconds < vreplicationTestSuiteWaitSeconds { - isReady = false - } - } - // Indicate to outside observers whether the migration is generally ready to complete. - // In the case of a postponed migration, we will not complete it, but the user will - // understand whether "now is a good time" or "not there yet" - _ = e.updateMigrationReadyToComplete(ctx, uuid, isReady) - if postponeCompletion { - // override. Even if migration is ready, we do not complete it. + isReady, err := e.isVReplMigrationReadyToCutOver(ctx, onlineDDL, s) + if err != nil { + _ = e.updateMigrationMessage(ctx, uuid, err.Error()) + return err + } + if isReady && isVreplicationTestSuite { + // This is a endtoend test suite execution. We intentionally delay it by at least + // vreplicationTestSuiteWaitSeconds + if elapsedSeconds < vreplicationTestSuiteWaitSeconds { isReady = false } - if isReady && onlineDDL.StrategySetting().IsInOrderCompletion() { - if len(pendingMigrationsUUIDs) > 0 && pendingMigrationsUUIDs[0] != onlineDDL.UUID { - // wait for earlier pending migrations to complete - isReady = false - } + } + // Indicate to outside observers whether the migration is generally ready to complete. + // In the case of a postponed migration, we will not complete it, but the user will + // understand whether "now is a good time" or "not there yet" + _ = e.updateMigrationReadyToComplete(ctx, uuid, isReady) + if !isReady { + return nil + } + if postponeCompletion { + // override. Even if migration is ready, we do not complete it. + return nil + } + if strategySetting.IsInOrderCompletion() { + if len(pendingMigrationsUUIDs) > 0 && pendingMigrationsUUIDs[0] != onlineDDL.UUID { + // wait for earlier pending migrations to complete + return nil } - if isReady { - if err := e.cutOverVReplMigration(ctx, s); err != nil { - _ = e.updateMigrationMessage(ctx, uuid, err.Error()) - log.Errorf("cutOverVReplMigration failed: err=%v", err) - if merr, ok := err.(*sqlerror.SQLError); ok { - switch merr.Num { - case sqlerror.ERTooLongIdent: - go e.CancelMigration(ctx, uuid, err.Error(), false) - } - } - return countRunnning, cancellable, err + } + shouldCutOver, shouldForceCutOver := shouldCutOverAccordingToBackoff( + shouldForceCutOver, forceCutOverAfter, sinceReadyToComplete, sinceLastCutoverAttempt, cutoverAttempts, + ) + if !shouldCutOver { + return nil + } + if err := e.cutOverVReplMigration(ctx, s, shouldForceCutOver); err != nil { + _ = e.updateMigrationMessage(ctx, uuid, err.Error()) + log.Errorf("cutOverVReplMigration failed: err=%v", err) + if merr, ok := err.(*sqlerror.SQLError); ok { + switch merr.Num { + case sqlerror.ERTooLongIdent: + go e.CancelMigration(ctx, uuid, err.Error(), false) } } + return err } + return nil + } + if err := reviewVReplRunningMigration(); err != nil { + return countRunnning, cancellable, err } case schema.DDLStrategyPTOSC: { @@ -4511,6 +4674,65 @@ func (e *Executor) CleanupMigration(ctx context.Context, uuid string) (result *s return rs, nil } +// ForceCutOverMigration markes the given migration for forced cut-over. This has two implications: +// - No backoff for the given migration's cut-over (cut-over will be attempted at the next scheduler cycle, +// irrespective of how many cut-over attempts have been made and when these attempts have been made). +// - During the cut-over, Online DDL will try and temrinate all existing queries on the migrated table, and +// transactions (killing their connections) holding a lock on the migrated table. This is likely to cause the +// cut-over to succeed. Of course, it's not guaranteed, and it's possible that next cut-over will fail. +// The force_cutover flag, once set, remains set, and so all future cut-over attempts will again KILL interfering +// queries and connections. +func (e *Executor) ForceCutOverMigration(ctx context.Context, uuid string) (result *sqltypes.Result, err error) { + if atomic.LoadInt64(&e.isOpen) == 0 { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, schema.ErrOnlineDDLDisabled.Error()) + } + if !schema.IsOnlineDDLUUID(uuid) { + return nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "Not a valid migration ID in FORCE_CUTOVER: %s", uuid) + } + log.Infof("ForceCutOverMigration: request to force cut-over migration %s", uuid) + e.migrationMutex.Lock() + defer e.migrationMutex.Unlock() + + query, err := sqlparser.ParseAndBind(sqlUpdateForceCutOver, + sqltypes.StringBindVariable(uuid), + ) + if err != nil { + return nil, err + } + rs, err := e.execQuery(ctx, query) + if err != nil { + return nil, err + } + e.triggerNextCheckInterval() + log.Infof("ForceCutOverMigration: migration %s marked for forced cut-over", uuid) + return rs, nil +} + +// ForceCutOverPendingMigrations sets force_cutover flag for all pending migrations +func (e *Executor) ForceCutOverPendingMigrations(ctx context.Context) (result *sqltypes.Result, err error) { + if atomic.LoadInt64(&e.isOpen) == 0 { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, schema.ErrOnlineDDLDisabled.Error()) + } + + uuids, err := e.readPendingMigrationsUUIDs(ctx) + if err != nil { + return result, err + } + log.Infof("ForceCutOverPendingMigrations: iterating %v migrations %s", len(uuids)) + + result = &sqltypes.Result{} + for _, uuid := range uuids { + log.Infof("ForceCutOverPendingMigrations: applying to %s", uuid) + res, err := e.ForceCutOverMigration(ctx, uuid) + if err != nil { + return result, err + } + result.AppendResult(res) + } + log.Infof("ForceCutOverPendingMigrations: done iterating %v migrations %s", len(uuids)) + return result, nil +} + // CompleteMigration clears the postpone_completion flag for a given migration, assuming it was set in the first place func (e *Executor) CompleteMigration(ctx context.Context, uuid string) (result *sqltypes.Result, err error) { if atomic.LoadInt64(&e.isOpen) == 0 { @@ -4524,7 +4746,7 @@ func (e *Executor) CompleteMigration(ctx context.Context, uuid string) (result * e.migrationMutex.Lock() defer e.migrationMutex.Unlock() - query, err := sqlparser.ParseAndBind(sqlUpdateCompleteMigration, + query, err := sqlparser.ParseAndBind(sqlClearPostponeCompletion, sqltypes.StringBindVariable(uuid), ) if err != nil { @@ -4582,7 +4804,7 @@ func (e *Executor) LaunchMigration(ctx context.Context, uuid string, shardsArg s // Does not apply to this shard! return &sqltypes.Result{}, nil } - log.Infof("LaunchMigration: request to execute migration %s", uuid) + log.Infof("LaunchMigration: request to launch migration %s", uuid) e.migrationMutex.Lock() defer e.migrationMutex.Unlock() diff --git a/go/vt/vttablet/onlineddl/executor_test.go b/go/vt/vttablet/onlineddl/executor_test.go index 4eb0d54a418..9e100fa43eb 100644 --- a/go/vt/vttablet/onlineddl/executor_test.go +++ b/go/vt/vttablet/onlineddl/executor_test.go @@ -23,6 +23,7 @@ package onlineddl import ( "context" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -356,3 +357,109 @@ func TestDuplicateCreateTable(t *testing.T) { }) } } + +func TestShouldCutOverAccordingToBackoff(t *testing.T) { + tcases := []struct { + name string + + shouldForceCutOverIndicator bool + forceCutOverAfter time.Duration + sinceReadyToComplete time.Duration + sinceLastCutoverAttempt time.Duration + cutoverAttempts int64 + + expectShouldCutOver bool + expectShouldForceCutOver bool + }{ + { + name: "no reason why not, normal cutover", + expectShouldCutOver: true, + }, + { + name: "backoff", + cutoverAttempts: 1, + expectShouldCutOver: false, + }, + { + name: "more backoff", + cutoverAttempts: 3, + expectShouldCutOver: false, + }, + { + name: "more backoff, since last cutover", + cutoverAttempts: 3, + sinceLastCutoverAttempt: time.Second, + expectShouldCutOver: false, + }, + { + name: "no backoff, long since last cutover", + cutoverAttempts: 3, + sinceLastCutoverAttempt: time.Hour, + expectShouldCutOver: true, + }, + { + name: "many attempts, long since last cutover", + cutoverAttempts: 3000, + sinceLastCutoverAttempt: time.Hour, + expectShouldCutOver: true, + }, + { + name: "force cutover", + shouldForceCutOverIndicator: true, + expectShouldCutOver: true, + expectShouldForceCutOver: true, + }, + { + name: "force cutover overrides backoff", + cutoverAttempts: 3, + shouldForceCutOverIndicator: true, + expectShouldCutOver: true, + expectShouldForceCutOver: true, + }, + { + name: "backoff; cutover-after not in effect yet", + cutoverAttempts: 3, + forceCutOverAfter: time.Second, + expectShouldCutOver: false, + expectShouldForceCutOver: false, + }, + { + name: "backoff; cutover-after still not in effect yet", + cutoverAttempts: 3, + forceCutOverAfter: time.Second, + sinceReadyToComplete: time.Millisecond, + expectShouldCutOver: false, + expectShouldForceCutOver: false, + }, + { + name: "cutover-after overrides backoff", + cutoverAttempts: 3, + forceCutOverAfter: time.Second, + sinceReadyToComplete: time.Second * 2, + expectShouldCutOver: true, + expectShouldForceCutOver: true, + }, + { + name: "cutover-after overrides backoff, realistic value", + cutoverAttempts: 300, + sinceLastCutoverAttempt: time.Minute, + forceCutOverAfter: time.Hour, + sinceReadyToComplete: time.Hour * 2, + expectShouldCutOver: true, + expectShouldForceCutOver: true, + }, + } + for _, tcase := range tcases { + t.Run(tcase.name, func(t *testing.T) { + shouldCutOver, shouldForceCutOver := shouldCutOverAccordingToBackoff( + tcase.shouldForceCutOverIndicator, + tcase.forceCutOverAfter, + tcase.sinceReadyToComplete, + tcase.sinceLastCutoverAttempt, + tcase.cutoverAttempts, + ) + assert.Equal(t, tcase.expectShouldCutOver, shouldCutOver) + assert.Equal(t, tcase.expectShouldForceCutOver, shouldForceCutOver) + }) + } +} diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index c072da2dc7b..ebf0aa1813b 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -98,7 +98,7 @@ const ( ` sqlSetMigrationReadyToComplete = `UPDATE _vt.schema_migrations SET ready_to_complete=1, - ready_to_complete_timestamp=NOW(6) + ready_to_complete_timestamp=IFNULL(ready_to_complete_timestamp, NOW(6)) WHERE migration_uuid=%a ` @@ -159,7 +159,8 @@ const ( migration_uuid=%a ` sqlIncrementCutoverAttempts = `UPDATE _vt.schema_migrations - SET cutover_attempts=cutover_attempts+1 + SET cutover_attempts=cutover_attempts+1, + last_cutover_attempt_timestamp=NOW() WHERE migration_uuid=%a ` @@ -168,13 +169,18 @@ const ( WHERE migration_uuid=%a ` + sqlUpdateForceCutOver = `UPDATE _vt.schema_migrations + SET force_cutover=1 + WHERE + migration_uuid=%a + ` sqlUpdateLaunchMigration = `UPDATE _vt.schema_migrations SET postpone_launch=0 WHERE migration_uuid=%a AND postpone_launch != 0 ` - sqlUpdateCompleteMigration = `UPDATE _vt.schema_migrations + sqlClearPostponeCompletion = `UPDATE _vt.schema_migrations SET postpone_completion=0 WHERE migration_uuid=%a @@ -254,6 +260,7 @@ const ( liveness_timestamp=NULL, cancelled_timestamp=NULL, completed_timestamp=NULL, + last_cutover_attempt_timestamp=NULL, cleanup_timestamp=NULL WHERE migration_status IN ('failed', 'cancelled') @@ -274,6 +281,7 @@ const ( liveness_timestamp=NULL, cancelled_timestamp=NULL, completed_timestamp=NULL, + last_cutover_attempt_timestamp=NULL, cleanup_timestamp=NULL WHERE migration_status IN ('failed', 'cancelled') @@ -287,6 +295,10 @@ const ( sqlSelectRunningMigrations = `SELECT migration_uuid, postpone_completion, + force_cutover, + cutover_attempts, + ifnull(timestampdiff(second, ready_to_complete_timestamp, now()), 0) as seconds_since_ready_to_complete, + ifnull(timestampdiff(second, last_cutover_attempt_timestamp, now()), 0) as seconds_since_last_cutover_attempt, timestampdiff(second, started_timestamp, now()) as elapsed_seconds FROM _vt.schema_migrations WHERE @@ -570,12 +582,22 @@ const ( _vt.copy_state WHERE vrepl_id=%a ` - sqlSwapTables = "RENAME TABLE `%a` TO `%a`, `%a` TO `%a`, `%a` TO `%a`" - sqlRenameTable = "RENAME TABLE `%a` TO `%a`" - sqlLockTwoTablesWrite = "LOCK TABLES `%a` WRITE, `%a` WRITE" - sqlUnlockTables = "UNLOCK TABLES" - sqlCreateSentryTable = "CREATE TABLE IF NOT EXISTS `%a` (id INT PRIMARY KEY)" - sqlFindProcess = "SELECT id, Info as info FROM information_schema.processlist WHERE id=%a AND Info LIKE %a" + sqlSwapTables = "RENAME TABLE `%a` TO `%a`, `%a` TO `%a`, `%a` TO `%a`" + sqlRenameTable = "RENAME TABLE `%a` TO `%a`" + sqlLockTwoTablesWrite = "LOCK TABLES `%a` WRITE, `%a` WRITE" + sqlUnlockTables = "UNLOCK TABLES" + sqlCreateSentryTable = "CREATE TABLE IF NOT EXISTS `%a` (id INT PRIMARY KEY)" + sqlFindProcess = "SELECT id, Info as info FROM information_schema.processlist WHERE id=%a AND Info LIKE %a" + sqlFindProcessByInfo = "SELECT id, Info as info FROM information_schema.processlist WHERE Info LIKE %a and id != connection_id()" + sqlProcessWithLocksOnTable = ` + SELECT + DISTINCT innodb_trx.trx_mysql_thread_id + from + performance_schema.data_locks + join information_schema.innodb_trx on (data_locks.ENGINE_TRANSACTION_ID=innodb_trx.trx_id) + where + data_locks.OBJECT_SCHEMA=database() AND data_locks.OBJECT_NAME=%a + ` ) var ( diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index e53bdaec754..ef86249996a 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -950,6 +950,10 @@ func (qre *QueryExecutor) execAlterMigration() (*sqltypes.Result, error) { return qre.tsv.onlineDDLExecutor.UnthrottleMigration(qre.ctx, alterMigration.UUID) case sqlparser.UnthrottleAllMigrationType: return qre.tsv.onlineDDLExecutor.UnthrottleAllMigrations(qre.ctx) + case sqlparser.ForceCutOverMigrationType: + return qre.tsv.onlineDDLExecutor.ForceCutOverMigration(qre.ctx, alterMigration.UUID) + case sqlparser.ForceCutOverAllMigrationType: + return qre.tsv.onlineDDLExecutor.ForceCutOverPendingMigrations(qre.ctx) } return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "ALTER VITESS_MIGRATION not implemented") } diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 61b75ce4e09..92b91066060 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -449,7 +449,6 @@ message CleanupSchemaMigrationResponse { map rows_affected_by_shard = 1; } - message CompleteSchemaMigrationRequest { string keyspace = 1; string uuid = 2; @@ -682,6 +681,15 @@ message FindAllShardsInKeyspaceResponse { map shards = 1; } +message ForceCutOverSchemaMigrationRequest { + string keyspace = 1; + string uuid = 2; +} + +message ForceCutOverSchemaMigrationResponse { + map rows_affected_by_shard = 1; +} + message GetBackupsRequest { string keyspace = 1; string shard = 2; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 59c24dc8445..56bd30e540e 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -103,6 +103,8 @@ service Vtctld { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. rpc FindAllShardsInKeyspace(vtctldata.FindAllShardsInKeyspaceRequest) returns (vtctldata.FindAllShardsInKeyspaceResponse) {}; + // ForceCutOverSchemaMigration marks a schema migration for forced cut-over. + rpc ForceCutOverSchemaMigration(vtctldata.ForceCutOverSchemaMigrationRequest) returns (vtctldata.ForceCutOverSchemaMigrationResponse) {}; // GetBackups returns all the backups for a shard. rpc GetBackups(vtctldata.GetBackupsRequest) returns (vtctldata.GetBackupsResponse) {}; // GetCellInfo returns the information for a cell. diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 39add452fd6..fca693ed3e1 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -49033,6 +49033,206 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a ForceCutOverSchemaMigrationRequest. */ + interface IForceCutOverSchemaMigrationRequest { + + /** ForceCutOverSchemaMigrationRequest keyspace */ + keyspace?: (string|null); + + /** ForceCutOverSchemaMigrationRequest uuid */ + uuid?: (string|null); + } + + /** Represents a ForceCutOverSchemaMigrationRequest. */ + class ForceCutOverSchemaMigrationRequest implements IForceCutOverSchemaMigrationRequest { + + /** + * Constructs a new ForceCutOverSchemaMigrationRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IForceCutOverSchemaMigrationRequest); + + /** ForceCutOverSchemaMigrationRequest keyspace. */ + public keyspace: string; + + /** ForceCutOverSchemaMigrationRequest uuid. */ + public uuid: string; + + /** + * Creates a new ForceCutOverSchemaMigrationRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns ForceCutOverSchemaMigrationRequest instance + */ + public static create(properties?: vtctldata.IForceCutOverSchemaMigrationRequest): vtctldata.ForceCutOverSchemaMigrationRequest; + + /** + * Encodes the specified ForceCutOverSchemaMigrationRequest message. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationRequest.verify|verify} messages. + * @param message ForceCutOverSchemaMigrationRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IForceCutOverSchemaMigrationRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ForceCutOverSchemaMigrationRequest message, length delimited. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationRequest.verify|verify} messages. + * @param message ForceCutOverSchemaMigrationRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IForceCutOverSchemaMigrationRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ForceCutOverSchemaMigrationRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ForceCutOverSchemaMigrationRequest + * @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.ForceCutOverSchemaMigrationRequest; + + /** + * Decodes a ForceCutOverSchemaMigrationRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ForceCutOverSchemaMigrationRequest + * @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.ForceCutOverSchemaMigrationRequest; + + /** + * Verifies a ForceCutOverSchemaMigrationRequest 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 ForceCutOverSchemaMigrationRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ForceCutOverSchemaMigrationRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ForceCutOverSchemaMigrationRequest; + + /** + * Creates a plain object from a ForceCutOverSchemaMigrationRequest message. Also converts values to other types if specified. + * @param message ForceCutOverSchemaMigrationRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ForceCutOverSchemaMigrationRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ForceCutOverSchemaMigrationRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ForceCutOverSchemaMigrationRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a ForceCutOverSchemaMigrationResponse. */ + interface IForceCutOverSchemaMigrationResponse { + + /** ForceCutOverSchemaMigrationResponse rows_affected_by_shard */ + rows_affected_by_shard?: ({ [k: string]: (number|Long) }|null); + } + + /** Represents a ForceCutOverSchemaMigrationResponse. */ + class ForceCutOverSchemaMigrationResponse implements IForceCutOverSchemaMigrationResponse { + + /** + * Constructs a new ForceCutOverSchemaMigrationResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IForceCutOverSchemaMigrationResponse); + + /** ForceCutOverSchemaMigrationResponse rows_affected_by_shard. */ + public rows_affected_by_shard: { [k: string]: (number|Long) }; + + /** + * Creates a new ForceCutOverSchemaMigrationResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns ForceCutOverSchemaMigrationResponse instance + */ + public static create(properties?: vtctldata.IForceCutOverSchemaMigrationResponse): vtctldata.ForceCutOverSchemaMigrationResponse; + + /** + * Encodes the specified ForceCutOverSchemaMigrationResponse message. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationResponse.verify|verify} messages. + * @param message ForceCutOverSchemaMigrationResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IForceCutOverSchemaMigrationResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ForceCutOverSchemaMigrationResponse message, length delimited. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationResponse.verify|verify} messages. + * @param message ForceCutOverSchemaMigrationResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IForceCutOverSchemaMigrationResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ForceCutOverSchemaMigrationResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ForceCutOverSchemaMigrationResponse + * @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.ForceCutOverSchemaMigrationResponse; + + /** + * Decodes a ForceCutOverSchemaMigrationResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ForceCutOverSchemaMigrationResponse + * @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.ForceCutOverSchemaMigrationResponse; + + /** + * Verifies a ForceCutOverSchemaMigrationResponse 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 ForceCutOverSchemaMigrationResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ForceCutOverSchemaMigrationResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ForceCutOverSchemaMigrationResponse; + + /** + * Creates a plain object from a ForceCutOverSchemaMigrationResponse message. Also converts values to other types if specified. + * @param message ForceCutOverSchemaMigrationResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ForceCutOverSchemaMigrationResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ForceCutOverSchemaMigrationResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ForceCutOverSchemaMigrationResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a GetBackupsRequest. */ interface IGetBackupsRequest { diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 4d314e2b299..2bc5ebb7795 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -120255,6 +120255,481 @@ export const vtctldata = $root.vtctldata = (() => { return FindAllShardsInKeyspaceResponse; })(); + vtctldata.ForceCutOverSchemaMigrationRequest = (function() { + + /** + * Properties of a ForceCutOverSchemaMigrationRequest. + * @memberof vtctldata + * @interface IForceCutOverSchemaMigrationRequest + * @property {string|null} [keyspace] ForceCutOverSchemaMigrationRequest keyspace + * @property {string|null} [uuid] ForceCutOverSchemaMigrationRequest uuid + */ + + /** + * Constructs a new ForceCutOverSchemaMigrationRequest. + * @memberof vtctldata + * @classdesc Represents a ForceCutOverSchemaMigrationRequest. + * @implements IForceCutOverSchemaMigrationRequest + * @constructor + * @param {vtctldata.IForceCutOverSchemaMigrationRequest=} [properties] Properties to set + */ + function ForceCutOverSchemaMigrationRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ForceCutOverSchemaMigrationRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @instance + */ + ForceCutOverSchemaMigrationRequest.prototype.keyspace = ""; + + /** + * ForceCutOverSchemaMigrationRequest uuid. + * @member {string} uuid + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @instance + */ + ForceCutOverSchemaMigrationRequest.prototype.uuid = ""; + + /** + * Creates a new ForceCutOverSchemaMigrationRequest instance using the specified properties. + * @function create + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationRequest=} [properties] Properties to set + * @returns {vtctldata.ForceCutOverSchemaMigrationRequest} ForceCutOverSchemaMigrationRequest instance + */ + ForceCutOverSchemaMigrationRequest.create = function create(properties) { + return new ForceCutOverSchemaMigrationRequest(properties); + }; + + /** + * Encodes the specified ForceCutOverSchemaMigrationRequest message. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationRequest} message ForceCutOverSchemaMigrationRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ForceCutOverSchemaMigrationRequest.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.uuid != null && Object.hasOwnProperty.call(message, "uuid")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.uuid); + return writer; + }; + + /** + * Encodes the specified ForceCutOverSchemaMigrationRequest message, length delimited. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationRequest} message ForceCutOverSchemaMigrationRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ForceCutOverSchemaMigrationRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ForceCutOverSchemaMigrationRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ForceCutOverSchemaMigrationRequest} ForceCutOverSchemaMigrationRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ForceCutOverSchemaMigrationRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ForceCutOverSchemaMigrationRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyspace = reader.string(); + break; + } + case 2: { + message.uuid = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ForceCutOverSchemaMigrationRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ForceCutOverSchemaMigrationRequest} ForceCutOverSchemaMigrationRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ForceCutOverSchemaMigrationRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ForceCutOverSchemaMigrationRequest message. + * @function verify + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ForceCutOverSchemaMigrationRequest.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.uuid != null && message.hasOwnProperty("uuid")) + if (!$util.isString(message.uuid)) + return "uuid: string expected"; + return null; + }; + + /** + * Creates a ForceCutOverSchemaMigrationRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ForceCutOverSchemaMigrationRequest} ForceCutOverSchemaMigrationRequest + */ + ForceCutOverSchemaMigrationRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ForceCutOverSchemaMigrationRequest) + return object; + let message = new $root.vtctldata.ForceCutOverSchemaMigrationRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.uuid != null) + message.uuid = String(object.uuid); + return message; + }; + + /** + * Creates a plain object from a ForceCutOverSchemaMigrationRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {vtctldata.ForceCutOverSchemaMigrationRequest} message ForceCutOverSchemaMigrationRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ForceCutOverSchemaMigrationRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.keyspace = ""; + object.uuid = ""; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.uuid != null && message.hasOwnProperty("uuid")) + object.uuid = message.uuid; + return object; + }; + + /** + * Converts this ForceCutOverSchemaMigrationRequest to JSON. + * @function toJSON + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @instance + * @returns {Object.} JSON object + */ + ForceCutOverSchemaMigrationRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ForceCutOverSchemaMigrationRequest + * @function getTypeUrl + * @memberof vtctldata.ForceCutOverSchemaMigrationRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ForceCutOverSchemaMigrationRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ForceCutOverSchemaMigrationRequest"; + }; + + return ForceCutOverSchemaMigrationRequest; + })(); + + vtctldata.ForceCutOverSchemaMigrationResponse = (function() { + + /** + * Properties of a ForceCutOverSchemaMigrationResponse. + * @memberof vtctldata + * @interface IForceCutOverSchemaMigrationResponse + * @property {Object.|null} [rows_affected_by_shard] ForceCutOverSchemaMigrationResponse rows_affected_by_shard + */ + + /** + * Constructs a new ForceCutOverSchemaMigrationResponse. + * @memberof vtctldata + * @classdesc Represents a ForceCutOverSchemaMigrationResponse. + * @implements IForceCutOverSchemaMigrationResponse + * @constructor + * @param {vtctldata.IForceCutOverSchemaMigrationResponse=} [properties] Properties to set + */ + function ForceCutOverSchemaMigrationResponse(properties) { + this.rows_affected_by_shard = {}; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ForceCutOverSchemaMigrationResponse rows_affected_by_shard. + * @member {Object.} rows_affected_by_shard + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @instance + */ + ForceCutOverSchemaMigrationResponse.prototype.rows_affected_by_shard = $util.emptyObject; + + /** + * Creates a new ForceCutOverSchemaMigrationResponse instance using the specified properties. + * @function create + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationResponse=} [properties] Properties to set + * @returns {vtctldata.ForceCutOverSchemaMigrationResponse} ForceCutOverSchemaMigrationResponse instance + */ + ForceCutOverSchemaMigrationResponse.create = function create(properties) { + return new ForceCutOverSchemaMigrationResponse(properties); + }; + + /** + * Encodes the specified ForceCutOverSchemaMigrationResponse message. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationResponse} message ForceCutOverSchemaMigrationResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ForceCutOverSchemaMigrationResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.rows_affected_by_shard != null && Object.hasOwnProperty.call(message, "rows_affected_by_shard")) + for (let keys = Object.keys(message.rows_affected_by_shard), i = 0; i < keys.length; ++i) + writer.uint32(/* id 1, wireType 2 =*/10).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 0 =*/16).uint64(message.rows_affected_by_shard[keys[i]]).ldelim(); + return writer; + }; + + /** + * Encodes the specified ForceCutOverSchemaMigrationResponse message, length delimited. Does not implicitly {@link vtctldata.ForceCutOverSchemaMigrationResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {vtctldata.IForceCutOverSchemaMigrationResponse} message ForceCutOverSchemaMigrationResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ForceCutOverSchemaMigrationResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ForceCutOverSchemaMigrationResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ForceCutOverSchemaMigrationResponse} ForceCutOverSchemaMigrationResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ForceCutOverSchemaMigrationResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ForceCutOverSchemaMigrationResponse(), key, value; + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (message.rows_affected_by_shard === $util.emptyObject) + message.rows_affected_by_shard = {}; + let end2 = reader.uint32() + reader.pos; + key = ""; + value = 0; + while (reader.pos < end2) { + let tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.string(); + break; + case 2: + value = reader.uint64(); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.rows_affected_by_shard[key] = value; + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ForceCutOverSchemaMigrationResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ForceCutOverSchemaMigrationResponse} ForceCutOverSchemaMigrationResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ForceCutOverSchemaMigrationResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ForceCutOverSchemaMigrationResponse message. + * @function verify + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ForceCutOverSchemaMigrationResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.rows_affected_by_shard != null && message.hasOwnProperty("rows_affected_by_shard")) { + if (!$util.isObject(message.rows_affected_by_shard)) + return "rows_affected_by_shard: object expected"; + let key = Object.keys(message.rows_affected_by_shard); + for (let i = 0; i < key.length; ++i) + if (!$util.isInteger(message.rows_affected_by_shard[key[i]]) && !(message.rows_affected_by_shard[key[i]] && $util.isInteger(message.rows_affected_by_shard[key[i]].low) && $util.isInteger(message.rows_affected_by_shard[key[i]].high))) + return "rows_affected_by_shard: integer|Long{k:string} expected"; + } + return null; + }; + + /** + * Creates a ForceCutOverSchemaMigrationResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ForceCutOverSchemaMigrationResponse} ForceCutOverSchemaMigrationResponse + */ + ForceCutOverSchemaMigrationResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ForceCutOverSchemaMigrationResponse) + return object; + let message = new $root.vtctldata.ForceCutOverSchemaMigrationResponse(); + if (object.rows_affected_by_shard) { + if (typeof object.rows_affected_by_shard !== "object") + throw TypeError(".vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard: object expected"); + message.rows_affected_by_shard = {}; + for (let keys = Object.keys(object.rows_affected_by_shard), i = 0; i < keys.length; ++i) + if ($util.Long) + (message.rows_affected_by_shard[keys[i]] = $util.Long.fromValue(object.rows_affected_by_shard[keys[i]])).unsigned = true; + else if (typeof object.rows_affected_by_shard[keys[i]] === "string") + message.rows_affected_by_shard[keys[i]] = parseInt(object.rows_affected_by_shard[keys[i]], 10); + else if (typeof object.rows_affected_by_shard[keys[i]] === "number") + message.rows_affected_by_shard[keys[i]] = object.rows_affected_by_shard[keys[i]]; + else if (typeof object.rows_affected_by_shard[keys[i]] === "object") + message.rows_affected_by_shard[keys[i]] = new $util.LongBits(object.rows_affected_by_shard[keys[i]].low >>> 0, object.rows_affected_by_shard[keys[i]].high >>> 0).toNumber(true); + } + return message; + }; + + /** + * Creates a plain object from a ForceCutOverSchemaMigrationResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {vtctldata.ForceCutOverSchemaMigrationResponse} message ForceCutOverSchemaMigrationResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ForceCutOverSchemaMigrationResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.objects || options.defaults) + object.rows_affected_by_shard = {}; + let keys2; + if (message.rows_affected_by_shard && (keys2 = Object.keys(message.rows_affected_by_shard)).length) { + object.rows_affected_by_shard = {}; + for (let j = 0; j < keys2.length; ++j) + if (typeof message.rows_affected_by_shard[keys2[j]] === "number") + object.rows_affected_by_shard[keys2[j]] = options.longs === String ? String(message.rows_affected_by_shard[keys2[j]]) : message.rows_affected_by_shard[keys2[j]]; + else + object.rows_affected_by_shard[keys2[j]] = options.longs === String ? $util.Long.prototype.toString.call(message.rows_affected_by_shard[keys2[j]]) : options.longs === Number ? new $util.LongBits(message.rows_affected_by_shard[keys2[j]].low >>> 0, message.rows_affected_by_shard[keys2[j]].high >>> 0).toNumber(true) : message.rows_affected_by_shard[keys2[j]]; + } + return object; + }; + + /** + * Converts this ForceCutOverSchemaMigrationResponse to JSON. + * @function toJSON + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @instance + * @returns {Object.} JSON object + */ + ForceCutOverSchemaMigrationResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ForceCutOverSchemaMigrationResponse + * @function getTypeUrl + * @memberof vtctldata.ForceCutOverSchemaMigrationResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ForceCutOverSchemaMigrationResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ForceCutOverSchemaMigrationResponse"; + }; + + return ForceCutOverSchemaMigrationResponse; + })(); + vtctldata.GetBackupsRequest = (function() { /** From 39ad5e6f3f975535a1ed2713e60b8ae2dfcda810 Mon Sep 17 00:00:00 2001 From: "Eduardo J. Ortega U" <5791035+ejortegau@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:18:49 +0100 Subject: [PATCH 119/119] TxThrottler only throttles if current lag is above threshold. Signed-off-by: Eduardo J. Ortega U <5791035+ejortegau@users.noreply.github.com> --- examples/common/scripts/vttablet-up.sh | 4 ++++ go/vt/throttler/throttler.go | 23 +++++++++++++++++++ .../tabletserver/txthrottler/tx_throttler.go | 14 ++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/examples/common/scripts/vttablet-up.sh b/examples/common/scripts/vttablet-up.sh index 56d212af218..3947ee8190f 100755 --- a/examples/common/scripts/vttablet-up.sh +++ b/examples/common/scripts/vttablet-up.sh @@ -56,6 +56,10 @@ vttablet \ --heartbeat_enable \ --heartbeat_interval=250ms \ --heartbeat_on_demand_duration=5s \ + --enable-tx-throttler \ + --tx-throttler-config "target_replication_lag_sec: 5 max_replication_lag_sec: 25 initial_rate: 10000 max_increase: 1 emergency_decrease: 0.5 min_duration_between_increases_sec: 2 max_duration_between_increases_sec: 5 min_duration_between_decreases_sec: 1 spread_backlog_across_sec: 20 age_bad_rate_after_sec: 60 bad_rate_increase: 0.1 max_rate_approach_threshold: 0.1" \ + --tx-throttler-healthcheck-cells zone1 \ + --tx-throttler-default-priority 0 \ > $VTDATAROOT/$tablet_dir/vttablet.out 2>&1 & # Block waiting for the tablet to be listening diff --git a/go/vt/throttler/throttler.go b/go/vt/throttler/throttler.go index 83a1c52225e..2a11d406b11 100644 --- a/go/vt/throttler/throttler.go +++ b/go/vt/throttler/throttler.go @@ -35,6 +35,7 @@ import ( "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/proto/topodata" throttlerdatapb "vitess.io/vitess/go/vt/proto/throttlerdata" ) @@ -224,6 +225,28 @@ func (t *Throttler) Throttle(threadID int) time.Duration { return t.threadThrottlers[threadID].throttle(t.nowFunc()) } +// LastMaxLagNotIgnoredForTabletType returns the max of all the last replication lag values seen across all tablets of +// the provided type, excluding ignored tablets. +func (t *Throttler) LastMaxLagNotIgnoredForTabletType(tabletType topodata.TabletType) uint32 { + cache := t.maxReplicationLagModule.lagCacheByType(tabletType) + + var maxLag uint32 + cacheEntries := cache.entries + + for key, _ := range cacheEntries { + if cache.isIgnored(key) { + continue + } + + lag := cache.latest(key).Stats.ReplicationLagSeconds + if lag > maxLag { + maxLag = lag + } + } + + return maxLag +} + // ThreadFinished marks threadID as finished and redistributes the thread's // rate allotment across the other threads. // After ThreadFinished() is called, Throttle() must not be called anymore. diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go index 78392a4b078..1c8d62d523b 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go @@ -81,6 +81,7 @@ type ThrottlerInterface interface { GetConfiguration() *throttlerdatapb.Configuration UpdateConfiguration(configuration *throttlerdatapb.Configuration, copyZeroValues bool) error ResetConfiguration() + LastMaxLagNotIgnoredForTabletType(tabletType topodatapb.TabletType) uint32 } // TxThrottlerName is the name the wrapped go/vt/throttler object will be registered with @@ -356,7 +357,18 @@ func (ts *txThrottlerStateImpl) throttle() bool { // Serialize calls to ts.throttle.Throttle() ts.throttleMu.Lock() defer ts.throttleMu.Unlock() - return ts.throttler.Throttle(0 /* threadId */) > 0 + + var maxLag uint32 + + for tabletType, _ := range ts.tabletTypes { + maxLagPerTabletType := ts.throttler.LastMaxLagNotIgnoredForTabletType(tabletType) + if maxLagPerTabletType > maxLag { + maxLag = maxLagPerTabletType + } + } + + return ts.throttler.Throttle(0 /* threadId */) > 0 && + int64(maxLag) > ts.config.TxThrottlerConfig.TargetReplicationLagSec } func (ts *txThrottlerStateImpl) deallocateResources() {
HealthCheck Tablet Cache%s
Cell