diff --git a/changelog/18.0/18.0.0/summary.md b/changelog/18.0/18.0.0/summary.md index 199c26b3483..56285439541 100644 --- a/changelog/18.0/18.0.0/summary.md +++ b/changelog/18.0/18.0.0/summary.md @@ -8,6 +8,7 @@ - [VTOrc flag `--allow-emergency-reparent`](#new-flag-toggle-ers) - **[Deprecations and Deletions](#deprecations-and-deletions)** - [Deprecated Flags](#deprecated-flags) + - [Deleted `V3` planner](#deleted-v3) - [Deleted `k8stopo`](#deleted-k8stopo) - [Deleted `vtgr`](#deleted-vtgr) - **[New stats](#new-stats)** @@ -49,6 +50,10 @@ Throttler related `vttablet` flags: - `--throttle_check_as_check_self` is deprecated and will be removed in `v19.0` - `--throttler-config-via-topo` is deprecated after asummed `true` in `v17.0`. It will be removed in a future version. +#### Deleted `v3` planner + +The `Gen4` planner has been the default planner since Vitess 14. The `v3` planner was deprecated in Vitess 15 and has now been removed in this release. + #### Deleted `k8stopo` The `k8stopo` has been deprecated in Vitess 17, also see https://github.com/vitessio/vitess/issues/13298. With Vitess 18 diff --git a/go/cmd/vtcombo/main.go b/go/cmd/vtcombo/main.go index affbf0520e7..695cf8b7e73 100644 --- a/go/cmd/vtcombo/main.go +++ b/go/cmd/vtcombo/main.go @@ -61,7 +61,7 @@ var ( mysqlPort = flags.Int("mysql_port", 3306, "mysql port") externalTopoServer = flags.Bool("external_topo_server", false, "Should vtcombo use an external topology server instead of starting its own in-memory topology server. "+ "If true, vtcombo will use the flags defined in topo/server.go to open topo server") - plannerName = flags.String("planner-version", "", "Sets the default planner to use when the session has not changed it. Valid values are: V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the gen4 planner and falls back to the V3 planner if the gen4 fails.") + plannerName = flags.String("planner-version", "", "Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right") tpb vttestpb.VTTestTopology ts *topo.Server diff --git a/go/cmd/vtexplain/vtexplain.go b/go/cmd/vtexplain/vtexplain.go index 2fa59dc0476..721bc98358a 100644 --- a/go/cmd/vtexplain/vtexplain.go +++ b/go/cmd/vtexplain/vtexplain.go @@ -63,7 +63,7 @@ func registerFlags(fs *pflag.FlagSet) { fs.StringVar(&replicationMode, "replication-mode", replicationMode, "The replication mode to simulate -- must be set to either ROW or STATEMENT") fs.BoolVar(&normalize, "normalize", normalize, "Whether to enable vtgate normalization") fs.StringVar(&dbName, "dbname", dbName, "Optional database target to override normal routing") - fs.StringVar(&plannerVersionStr, "planner-version", plannerVersionStr, "Sets the query planner version to use when generating the explain output. Valid values are V3 and Gen4. An empty value will use VTGate's default planner") + fs.StringVar(&plannerVersionStr, "planner-version", plannerVersionStr, "Sets the default planner to use. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right") fs.IntVar(&numShards, "shards", numShards, "Number of shards per keyspace. Passing --ks-shard-map/--ks-shard-map-file causes this flag to be ignored.") fs.StringVar(&executionMode, "execution-mode", executionMode, "The execution mode to simulate -- must be set to multi, legacy-autocommit, or twopc") fs.StringVar(&outputMode, "output-mode", outputMode, "Output in human-friendly text or json") @@ -113,8 +113,8 @@ func main() { func parseAndRun() error { plannerVersion, _ := plancontext.PlannerNameToVersion(plannerVersionStr) - if plannerVersionStr != "" && plannerVersion != querypb.ExecuteOptions_V3 && plannerVersion != querypb.ExecuteOptions_Gen4 { - return fmt.Errorf("invalid value specified for planner-version of '%s' -- valid values are V3 and Gen4 or an empty value to use the default planner", plannerVersionStr) + if plannerVersionStr != "" && plannerVersion != querypb.ExecuteOptions_Gen4 { + return fmt.Errorf("invalid value specified for planner-version of '%s' -- valid value is Gen4 or an empty value to use the default planner", plannerVersionStr) } sql, err := getFileParam(sqlFlag, sqlFileFlag, "sql", true) diff --git a/go/cmd/vtgate/vtgate.go b/go/cmd/vtgate/vtgate.go index f4fc21000a2..d98353bcd17 100644 --- a/go/cmd/vtgate/vtgate.go +++ b/go/cmd/vtgate/vtgate.go @@ -48,7 +48,7 @@ var ( func registerFlags(fs *pflag.FlagSet) { fs.StringVar(&cell, "cell", cell, "cell to use") fs.Var((*topoproto.TabletTypeListFlag)(&tabletTypesToWait), "tablet_types_to_wait", "Wait till connected for specified tablet types during Gateway initialization. Should be provided as a comma-separated set of tablet types.") - fs.StringVar(&plannerName, "planner-version", plannerName, "Sets the default planner to use when the session has not changed it. Valid values are: V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the gen4 planner and falls back to the V3 planner if the gen4 fails.") + fs.StringVar(&plannerName, "planner-version", plannerName, "Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right") acl.RegisterFlags(fs) } diff --git a/go/cmd/vttestserver/main.go b/go/cmd/vttestserver/main.go index e73b722d154..e3ff5828031 100644 --- a/go/cmd/vttestserver/main.go +++ b/go/cmd/vttestserver/main.go @@ -141,7 +141,7 @@ func registerFlags(fs *pflag.FlagSet) { fs.StringVar(&config.Charset, "charset", "utf8mb4", "MySQL charset") - fs.StringVar(&config.PlannerVersion, "planner-version", "", "Sets the default planner to use when the session has not changed it. Valid values are: V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the new gen4 planner and falls back to the V3 planner if the gen4 fails.") + fs.StringVar(&config.PlannerVersion, "planner-version", "", "Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right") fs.StringVar(&config.SnapshotFile, "snapshot_file", "", "A MySQL DB snapshot file") diff --git a/go/flags/endtoend/vtexplain.txt b/go/flags/endtoend/vtexplain.txt index 0b55c9dd947..83128e65eb1 100644 --- a/go/flags/endtoend/vtexplain.txt +++ b/go/flags/endtoend/vtexplain.txt @@ -44,7 +44,7 @@ Usage of vtexplain: --mysql_server_version string MySQL server version to advertise. (default "8.0.30-Vitess") --normalize Whether to enable vtgate normalization --output-mode string Output in human-friendly text or json (default "text") - --planner-version string Sets the query planner version to use when generating the explain output. Valid values are V3 and Gen4. An empty value will use VTGate's default planner + --planner-version string Sets the default planner to use. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right --pprof strings enable profiling --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --replication-mode string The replication mode to simulate -- must be set to either ROW or STATEMENT (default "ROW") diff --git a/go/flags/endtoend/vtgate.txt b/go/flags/endtoend/vtgate.txt index 901c5c9f81e..3793db70c8c 100644 --- a/go/flags/endtoend/vtgate.txt +++ b/go/flags/endtoend/vtgate.txt @@ -155,7 +155,7 @@ Usage of vtgate: --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --opentsdb_uri string URI of opentsdb /api/put method --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the gen4 planner and falls back to the V3 planner if the gen4 fails. + --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right --port int port for the server --pprof strings enable profiling --proxy_protocol Enable HAProxy PROXY protocol on MySQL listener socket diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index 668e31f1656..7ff7374b48b 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -91,7 +91,7 @@ Usage of vttestserver: --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --persistent_mode If this flag is set, the MySQL data directory is not cleaned up when LocalCluster.TearDown() is called. This is useful for running vttestserver as a database container in local developer environments. Note that db migration files (--schema_dir option) and seeding of random data (--initialize_with_random_data option) will only run during cluster startup if the data directory does not already exist. vschema migrations are run every time the cluster starts, since persistence for the topology server has not been implemented yet --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the new gen4 planner and falls back to the V3 planner if the gen4 fails. + --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right --pool_hostname_resolve_interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled) --port int Port to use for vtcombo. If this is 0, a random port will be chosen. --pprof strings enable profiling diff --git a/go/test/endtoend/cluster/vtgate_process.go b/go/test/endtoend/cluster/vtgate_process.go index f037f53a055..3bf29c8af9b 100644 --- a/go/test/endtoend/cluster/vtgate_process.go +++ b/go/test/endtoend/cluster/vtgate_process.go @@ -65,7 +65,7 @@ type VtgateProcess struct { exit chan error } -const defaultVtGatePlannerVersion = planbuilder.Gen4CompareV3 +const defaultVtGatePlannerVersion = planbuilder.Gen4 // Setup starts Vtgate process with required arguements func (vtgate *VtgateProcess) Setup() (err error) { diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index 710f4934786..f695aeb6f24 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -151,12 +151,12 @@ func TestQueryTimeoutWithTables(t *testing.T) { } // too much data added in the loop, do drop and recreate the table. defer func() { - mcmp.Exec("drop table t1") + mcmp.Exec("drop /*vt+ QUERY_TIMEOUT_MS=1000 */ table t1") mcmp.Exec(schemaSQL) }() - utils.Exec(t, mcmp.VtConn, "select count(*) from t1 where id1 > 31") - utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=100 */ count(*) from t1 where id1 > 31") + utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=1000 */ count(*) from t1 where id1 > 31") + utils.Exec(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=1000 */ count(*) from t1 where id1 > 31") // the query usually takes more than 5ms to return. So this should fail. _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ PLANNER=gen4 QUERY_TIMEOUT_MS=1 */ count(*) from t1 where id1 > 31") diff --git a/go/test/endtoend/vtgate/queries/misc/schema.sql b/go/test/endtoend/vtgate/queries/misc/schema.sql index ceac0c07e6d..6dac568ed1a 100644 --- a/go/test/endtoend/vtgate/queries/misc/schema.sql +++ b/go/test/endtoend/vtgate/queries/misc/schema.sql @@ -1,4 +1,4 @@ -create table if not exists t1( +create /*vt+ QUERY_TIMEOUT_MS=1000 */ table if not exists t1( id1 bigint, id2 bigint, primary key(id1) diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go index 577155f16cb..11325a0f2f8 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go @@ -179,9 +179,17 @@ func TestServingChangeStreaming(t *testing.T) { rdonlyTablet.Type = "replica" // this should fail as there is no rdonly present + // This can also close the streaming connection if it goes to 80- shard first and sends the fields from that. + // Current, stream logic is to close the server connection if partial stream result is sent and an error is received later. _, err = utils.ExecAllowError(t, conn, "select * from test") require.Error(t, err) + // check if connection is still available + _, err = utils.ExecAllowError(t, conn, "select 1") + if err != nil { + t.Skip("connection is closed, cannot continue with the test") + } + // changing replica tablet to rdonly to make rdonly available for serving. replicaTablet := clusterInstance.Keyspaces[0].Shards[0].Replica() err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", replicaTablet.Alias, "rdonly") diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index b6959c983d6..291a433cfae 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -2289,11 +2289,6 @@ type ( // ColName represents a column name. ColName struct { - // Metadata is not populated by the parser. - // It's a placeholder for analyzers to store - // additional data, typically info about which - // table or column this node references. - Metadata any Name IdentifierCI Qualifier TableName } diff --git a/go/vt/sqlparser/cached_size.go b/go/vt/sqlparser/cached_size.go index ec816085caa..bccfbbe96a3 100644 --- a/go/vt/sqlparser/cached_size.go +++ b/go/vt/sqlparser/cached_size.go @@ -649,7 +649,7 @@ func (cached *ColName) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(80) + size += int64(64) } // field Name vitess.io/vitess/go/vt/sqlparser.IdentifierCI size += cached.Name.CachedSize(false) diff --git a/go/vt/sqlparser/predicate_rewriting.go b/go/vt/sqlparser/predicate_rewriting.go index 0348f95f115..40e9a953f57 100644 --- a/go/vt/sqlparser/predicate_rewriting.go +++ b/go/vt/sqlparser/predicate_rewriting.go @@ -43,10 +43,6 @@ func RewritePredicate(ast SQLNode) SQLNode { exprChanged = true cursor.Replace(rewritten) } - - if col, isCol := cursor.node.(*ColName); isCol { - col.Metadata = nil - } return !exprChanged }) diff --git a/go/vt/vtgate/engine/boost_compare.go b/go/vt/vtgate/engine/boost_compare.go index a2f65bd7c72..bd3dbb1ca7a 100644 --- a/go/vt/vtgate/engine/boost_compare.go +++ b/go/vt/vtgate/engine/boost_compare.go @@ -2,6 +2,7 @@ package engine import ( "context" + "encoding/json" "sync" "vitess.io/vitess/go/sqltypes" @@ -181,3 +182,50 @@ func (b *BoostCompare) compareResults(result *sqltypes.Result, gen4Res *sqltypes } return nil } + +func printMismatch(leftResult, rightResult *sqltypes.Result, leftPrimitive, rightPrimitive Primitive, leftName, rightName string) { + log.Errorf("Results of %s and %s are not equal. Displaying diff.", rightName, leftName) + + // get right plan and print it + rightplan := &Plan{ + Instructions: rightPrimitive, + } + rightJSON, _ := json.MarshalIndent(rightplan, "", " ") + log.Errorf("%s's plan:\n%s", rightName, string(rightJSON)) + + // get left's plan and print it + leftplan := &Plan{ + Instructions: leftPrimitive, + } + leftJSON, _ := json.MarshalIndent(leftplan, "", " ") + log.Errorf("%s's plan:\n%s", leftName, string(leftJSON)) + + log.Errorf("%s's results:\n", rightName) + log.Errorf("\t[rows affected: %d]\n", rightResult.RowsAffected) + for _, row := range rightResult.Rows { + log.Errorf("\t%s", row) + } + log.Errorf("%s's results:\n", leftName) + log.Errorf("\t[rows affected: %d]\n", leftResult.RowsAffected) + for _, row := range leftResult.Rows { + log.Errorf("\t%s", row) + } + log.Error("End of diff.") +} + +// CompareErrors compares the two errors, and if they don't match, produces an error +func CompareErrors(leftErr, rightErr error, leftName, rightName string) error { + if leftErr != nil && rightErr != nil { + if leftErr.Error() == rightErr.Error() { + return rightErr + } + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s and %s failed with different errors: %s: [%s], %s: [%s]", leftName, rightName, leftErr.Error(), rightErr.Error(), leftName, rightName) + } + if leftErr == nil && rightErr != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s failed while %s did not: %s", rightName, rightErr.Error(), leftName) + } + if leftErr != nil && rightErr == nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s failed while %s did not: %s", leftName, leftErr.Error(), rightName) + } + return nil +} diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index d27a1bb1359..a50aab5175a 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -217,20 +217,6 @@ func (cached *Distinct) CachedSize(alloc bool) int64 { } return size } -func (cached *DistinctV3) CachedSize(alloc bool) int64 { - if cached == nil { - return int64(0) - } - size := int64(0) - if alloc { - size += int64(16) - } - // field Source vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.Source.(cachedObject); ok { - size += cc.CachedSize(true) - } - return size -} func (cached *ExecStmt) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -274,24 +260,6 @@ func (cached *Filter) CachedSize(alloc bool) int64 { } return size } -func (cached *Gen4CompareV3) CachedSize(alloc bool) int64 { - if cached == nil { - return int64(0) - } - size := int64(0) - if alloc { - size += int64(48) - } - // field V3 vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.V3.(cachedObject); ok { - size += cc.CachedSize(true) - } - // field Gen4 vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.Gen4.(cachedObject); ok { - size += cc.CachedSize(true) - } - return size -} func (cached *Generate) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -551,7 +519,7 @@ func (cached *MemorySort) CachedSize(alloc bool) int64 { } // field OrderBy []vitess.io/vitess/go/vt/vtgate/engine.OrderByParams { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(34)) } // field Input vitess.io/vitess/go/vt/vtgate/engine.Primitive if cc, ok := cached.Input.(cachedObject); ok { @@ -578,7 +546,7 @@ func (cached *MergeSort) CachedSize(alloc bool) int64 { } // field OrderBy []vitess.io/vitess/go/vt/vtgate/engine.OrderByParams { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(34)) } return size } @@ -793,7 +761,7 @@ func (cached *Route) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.FieldQuery))) // field OrderBy []vitess.io/vitess/go/vt/vtgate/engine.OrderByParams { - size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(36)) + size += hack.RuntimeAllocSize(int64(cap(cached.OrderBy)) * int64(34)) } // field RoutingParameters *vitess.io/vitess/go/vt/vtgate/engine.RoutingParameters size += cached.RoutingParameters.CachedSize(true) diff --git a/go/vt/vtgate/engine/compare_utils.go b/go/vt/vtgate/engine/compare_utils.go deleted file mode 100644 index c854d6723d3..00000000000 --- a/go/vt/vtgate/engine/compare_utils.go +++ /dev/null @@ -1,73 +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 engine - -import ( - "encoding/json" - - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/log" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" -) - -func printMismatch(leftResult, rightResult *sqltypes.Result, leftPrimitive, rightPrimitive Primitive, leftName, rightName string) { - log.Errorf("Results of %s and %s are not equal. Displaying diff.", rightName, leftName) - - // get right plan and print it - rightplan := &Plan{ - Instructions: rightPrimitive, - } - rightJSON, _ := json.MarshalIndent(rightplan, "", " ") - log.Errorf("%s's plan:\n%s", rightName, string(rightJSON)) - - // get left's plan and print it - leftplan := &Plan{ - Instructions: leftPrimitive, - } - leftJSON, _ := json.MarshalIndent(leftplan, "", " ") - log.Errorf("%s's plan:\n%s", leftName, string(leftJSON)) - - log.Errorf("%s's results:\n", rightName) - log.Errorf("\t[rows affected: %d]\n", rightResult.RowsAffected) - for _, row := range rightResult.Rows { - log.Errorf("\t%s", row) - } - log.Errorf("%s's results:\n", leftName) - log.Errorf("\t[rows affected: %d]\n", leftResult.RowsAffected) - for _, row := range leftResult.Rows { - log.Errorf("\t%s", row) - } - log.Error("End of diff.") -} - -// CompareErrors compares the two errors, and if they don't match, produces an error -func CompareErrors(leftErr, rightErr error, leftName, rightName string) error { - if leftErr != nil && rightErr != nil { - if leftErr.Error() == rightErr.Error() { - return rightErr - } - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s and %s failed with different errors: %s: [%s], %s: [%s]", leftName, rightName, leftErr.Error(), rightErr.Error(), leftName, rightName) - } - if leftErr == nil && rightErr != nil { - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s failed while %s did not: %s", rightName, rightErr.Error(), leftName) - } - if leftErr != nil && rightErr == nil { - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "%s failed while %s did not: %s", leftName, leftErr.Error(), rightName) - } - return nil -} diff --git a/go/vt/vtgate/engine/distinctV3.go b/go/vt/vtgate/engine/distinctV3.go deleted file mode 100644 index 0506331d9c6..00000000000 --- a/go/vt/vtgate/engine/distinctV3.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -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/mysql/collations" - "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/vtgate/evalengine" -) - -// DistinctV3 Primitive is used to uniqueify results -// It does not always work, and should be removed once the V3 planner has been removed -var _ Primitive = (*DistinctV3)(nil) - -// Distinct Primitive is used to uniqueify results -type DistinctV3 struct { - Source Primitive -} - -type row = []sqltypes.Value - -type probeTableV3 struct { - m map[evalengine.HashCode][]row -} - -func (pt *probeTableV3) exists(inputRow row) (bool, error) { - // calculate hashcode from all column values in the input row - code := evalengine.HashCode(17) - for _, value := range inputRow { - hashcode, err := evalengine.NullsafeHashcode(value, collations.Unknown, value.Type()) - if err != nil { - return false, err - } - code = code*31 + hashcode - } - - existingRows, found := pt.m[code] - if !found { - // nothing with this hash code found, we can be sure it's a not seen row - pt.m[code] = []row{inputRow} - return false, nil - } - - // we found something in the map - still need to check all individual values - // so we don't just fall for a hash collision - for _, existingRow := range existingRows { - exists, err := equalV3(existingRow, inputRow) - if err != nil { - return false, err - } - if exists { - return true, nil - } - } - - pt.m[code] = append(existingRows, inputRow) - - return false, nil -} - -func equalV3(a, b []sqltypes.Value) (bool, error) { - for i, aVal := range a { - cmp, err := evalengine.NullsafeCompare(aVal, b[i], collations.Unknown) - if err != nil { - return false, err - } - if cmp != 0 { - return false, nil - } - } - return true, nil -} - -func newProbeTableV3() *probeTableV3 { - return &probeTableV3{m: map[evalengine.HashCode][]row{}} -} - -// TryExecute implements the Primitive interface -func (d *DistinctV3) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { - input, err := vcursor.ExecutePrimitive(ctx, d.Source, bindVars, wantfields) - if err != nil { - return nil, err - } - - result := &sqltypes.Result{ - Fields: input.Fields, - InsertID: input.InsertID, - } - - pt := newProbeTableV3() - - for _, row := range input.Rows { - exists, err := pt.exists(row) - if err != nil { - return nil, err - } - if !exists { - result.Rows = append(result.Rows, row) - } - } - - return result, err -} - -// TryStreamExecute implements the Primitive interface -func (d *DistinctV3) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - pt := newProbeTableV3() - - err := vcursor.StreamExecutePrimitive(ctx, d.Source, bindVars, wantfields, func(input *sqltypes.Result) error { - result := &sqltypes.Result{ - Fields: input.Fields, - InsertID: input.InsertID, - } - for _, row := range input.Rows { - exists, err := pt.exists(row) - if err != nil { - return err - } - if !exists { - result.Rows = append(result.Rows, row) - } - } - return callback(result) - }) - - return err -} - -// RouteType implements the Primitive interface -func (d *DistinctV3) RouteType() string { - return d.Source.RouteType() -} - -// GetKeyspaceName implements the Primitive interface -func (d *DistinctV3) GetKeyspaceName() string { - return d.Source.GetKeyspaceName() -} - -// GetTableName implements the Primitive interface -func (d *DistinctV3) GetTableName() string { - return d.Source.GetTableName() -} - -// GetFields implements the Primitive interface -func (d *DistinctV3) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - return d.Source.GetFields(ctx, vcursor, bindVars) -} - -// NeedsTransaction implements the Primitive interface -func (d *DistinctV3) NeedsTransaction() bool { - return d.Source.NeedsTransaction() -} - -// Inputs implements the Primitive interface -func (d *DistinctV3) Inputs() []Primitive { - return []Primitive{d.Source} -} - -func (d *DistinctV3) description() PrimitiveDescription { - return PrimitiveDescription{ - OperatorType: "Distinct", - } -} diff --git a/go/vt/vtgate/engine/gen4_compare_v3.go b/go/vt/vtgate/engine/gen4_compare_v3.go deleted file mode 100644 index a913c442a2c..00000000000 --- a/go/vt/vtgate/engine/gen4_compare_v3.go +++ /dev/null @@ -1,144 +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 engine - -import ( - "context" - "sync" - - "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" -) - -// Gen4CompareV3 is a Primitive used to compare V3 and Gen4's plans. -type Gen4CompareV3 struct { - V3, Gen4 Primitive - HasOrderBy bool -} - -var _ Primitive = (*Gen4CompareV3)(nil) -var _ Gen4Comparer = (*Gen4CompareV3)(nil) - -// GetGen4Primitive implements the Gen4Comparer interface -func (gc *Gen4CompareV3) GetGen4Primitive() Primitive { - return gc.Gen4 -} - -// RouteType implements the Primitive interface -func (gc *Gen4CompareV3) RouteType() string { - return gc.Gen4.RouteType() -} - -// GetKeyspaceName implements the Primitive interface -func (gc *Gen4CompareV3) GetKeyspaceName() string { - return gc.Gen4.GetKeyspaceName() -} - -// GetTableName implements the Primitive interface -func (gc *Gen4CompareV3) GetTableName() string { - return gc.Gen4.GetTableName() -} - -// GetFields implements the Primitive interface -func (gc *Gen4CompareV3) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - return gc.Gen4.GetFields(ctx, vcursor, bindVars) -} - -// NeedsTransaction implements the Primitive interface -func (gc *Gen4CompareV3) NeedsTransaction() bool { - return gc.Gen4.NeedsTransaction() -} - -// TryExecute implements the Primitive interface -func (gc *Gen4CompareV3) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { - var v3Err, gen4Err error - v3Result, gen4Result := &sqltypes.Result{}, &sqltypes.Result{} - if gc.Gen4 != nil { - gen4Result, gen4Err = gc.Gen4.TryExecute(ctx, vcursor, bindVars, wantfields) - } - if gc.V3 != nil { - v3Result, v3Err = gc.V3.TryExecute(ctx, vcursor, bindVars, wantfields) - } - - if err := CompareErrors(v3Err, gen4Err, "v3", "Gen4"); err != nil { - return nil, err - } - - if err := gc.compareResults(v3Result, gen4Result); err != nil { - return nil, err - } - return gen4Result, nil -} - -// TryStreamExecute implements the Primitive interface -func (gc *Gen4CompareV3) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - var mu sync.Mutex - var v3Err, gen4Err error - v3Result, gen4Result := &sqltypes.Result{}, &sqltypes.Result{} - - if gc.Gen4 != nil { - gen4Err = gc.Gen4.TryStreamExecute(ctx, vcursor, bindVars, wantfields, func(result *sqltypes.Result) error { - mu.Lock() - defer mu.Unlock() - gen4Result.AppendResult(result) - return nil - }) - } - if gc.V3 != nil { - v3Err = gc.V3.TryStreamExecute(ctx, vcursor, bindVars, wantfields, func(result *sqltypes.Result) error { - mu.Lock() - defer mu.Unlock() - v3Result.AppendResult(result) - return nil - }) - } - - if err := CompareErrors(v3Err, gen4Err, "v3", "Gen4"); err != nil { - return err - } - - if err := gc.compareResults(v3Result, gen4Result); err != nil { - return err - } - return callback(gen4Result) -} - -func (gc *Gen4CompareV3) compareResults(v3Result *sqltypes.Result, gen4Result *sqltypes.Result) error { - var match bool - if gc.HasOrderBy { - match = sqltypes.ResultsEqual([]sqltypes.Result{*v3Result}, []sqltypes.Result{*gen4Result}) - } else { - match = sqltypes.ResultsEqualUnordered([]sqltypes.Result{*v3Result}, []sqltypes.Result{*gen4Result}) - } - if !match { - printMismatch(v3Result, gen4Result, gc.V3, gc.Gen4, "V3", "Gen4") - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "results did not match, see VTGate's logs for more information") - } - return nil -} - -// Inputs implements the Primitive interface -func (gc *Gen4CompareV3) Inputs() []Primitive { - return []Primitive{gc.Gen4, gc.V3} -} - -// description implements the Primitive interface -func (gc *Gen4CompareV3) description() PrimitiveDescription { - return PrimitiveDescription{OperatorType: "Gen4CompareV3"} -} diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 7da6edc3454..cae65df9e29 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -124,15 +124,6 @@ func NewQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query stri } } -// NewSimpleInsert creates an Insert for a Table. -func NewSimpleInsert(opcode InsertOpcode, table *vindexes.Table, keyspace *vindexes.Keyspace) *Insert { - return &Insert{ - Opcode: opcode, - Table: table, - Keyspace: keyspace, - } -} - // NewInsert creates a new Insert. func NewInsert( opcode InsertOpcode, diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index ddded092887..e133340154e 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -54,7 +54,6 @@ type ( // if the max memory rows override directive is set to true ExceedsMaxMemoryRows(numRows int) bool - // V3 functions. Execute(ctx context.Context, method string, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) AutocommitApproval() bool @@ -234,12 +233,6 @@ type ( // txNeeded is a default implementation for Primitives that need transaction handling txNeeded struct{} - - // Gen4Comparer interfaces all Primitive used to compare Gen4 with other planners (V3, MySQL, ...). - Gen4Comparer interface { - Primitive - GetGen4Primitive() Primitive - } ) // Find will return the first Primitive that matches the evaluate function. If no match is found, nil will be returned diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index db129d91f34..726b36f5379 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -89,16 +89,6 @@ type Route struct { noTxNeeded } -// NewSimpleRoute creates a Route with the bare minimum of parameters. -func NewSimpleRoute(opcode Opcode, keyspace *vindexes.Keyspace) *Route { - return &Route{ - RoutingParameters: &RoutingParameters{ - Opcode: opcode, - Keyspace: keyspace, - }, - } -} - // NewRoute creates a Route. func NewRoute(opcode Opcode, keyspace *vindexes.Keyspace, query, fieldQuery string) *Route { return &Route{ @@ -120,8 +110,6 @@ type OrderByParams struct { WeightStringCol int Desc bool StarColFixedIndex int - // v3 specific boolean. Used to also add weight strings originating from GroupBys to the Group by clause - FromGroupBy bool // Collation ID for comparison using collation CollationID collations.ID } diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 6fc46000894..8f927760161 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1349,7 +1349,6 @@ func (e *Executor) prepare(ctx context.Context, safeSession *SafeSession, sql st } func (e *Executor) handlePrepare(ctx context.Context, safeSession *SafeSession, sql string, bindVars map[string]*querypb.BindVariable, logStats *logstats.LogStats) ([]*querypb.Field, error) { - // V3 mode. query, comments := sqlparser.SplitMarginComments(sql) vcursor, _ := newVCursorImpl(safeSession, comments, e, logStats, e.vm, e.VSchema(), e.resolver.resolver, e.serv, e.warnShardedOnly, e.pv) diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index 4ccca009dcf..9e1ed126479 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -1158,7 +1158,6 @@ func TestDeleteUseHigherCostVindexIfBackfilling(t *testing.T) { func TestDeleteByDestination(t *testing.T) { executor, sbc1, sbc2, _ := createExecutorEnv() - // This query is not supported in v3, so we know for sure is taking the DeleteByDestination route _, err := executorExec(executor, "delete from `TestExecutor[-]`.user_extra limit 10", nil) require.NoError(t, err) // Queries get annotatted. @@ -2379,7 +2378,7 @@ func TestUpdateReference(t *testing.T) { sbclookup.Queries = nil _, err = executorExec(executor, "update TestExecutor.zip_detail set status = 'CLOSED' where id = 1", nil) - require.Error(t, err) + require.NoError(t, err) // Gen4 planner can redirect the query to correct source for update when reference table is involved. } func TestDeleteLookupOwnedEqual(t *testing.T) { @@ -2444,7 +2443,7 @@ func TestDeleteReference(t *testing.T) { sbclookup.Queries = nil _, err = executorExec(executor, "delete from TestExecutor.zip_detail where id = 1", nil) - require.Error(t, err) + require.NoError(t, err) // Gen4 planner can redirect the query to correct source for update when reference table is involved. } func TestReservedConnDML(t *testing.T) { @@ -2740,6 +2739,9 @@ func TestInsertSelectFromDual(t *testing.T) { query := "insert into user(id, v, name) select 1, 2, 'myname' from dual" wantQueries := []*querypb.BoundQuery{{ + Sql: "select 1, 2, 'myname' from dual lock in share mode", + BindVariables: map[string]*querypb.BindVariable{}, + }, { Sql: "insert into `user`(id, v, `name`) values (:_c0_0, :_c0_1, :_c0_2)", BindVariables: map[string]*querypb.BindVariable{ "_c0_0": sqltypes.Int64BindVariable(1), @@ -2757,23 +2759,28 @@ func TestInsertSelectFromDual(t *testing.T) { }} for _, workload := range []string{"olap", "oltp"} { - sbc1.Queries = nil - sbc2.Queries = nil - sbclookup.Queries = nil - wQuery := fmt.Sprintf("set @@workload = %s", workload) - _, err := executor.Execute(context.Background(), "TestInsertSelect", session, wQuery, nil) - require.NoError(t, err) + t.Run(workload, func(t *testing.T) { + sbc1.Queries = nil + sbc2.Queries = nil + sbclookup.Queries = nil + wQuery := fmt.Sprintf("set @@workload = %s", workload) + // set result for dual query. + sbc1.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult(sqltypes.MakeTestFields("1|2|myname", "int64|int64|varchar"), "1|2|myname")}) + + _, err := executor.Execute(context.Background(), "TestInsertSelect", session, wQuery, nil) + require.NoError(t, err) - _, err = executor.Execute(context.Background(), "TestInsertSelect", session, query, nil) - require.NoError(t, err) + _, err = executor.Execute(context.Background(), "TestInsertSelect", session, query, nil) + require.NoError(t, err) - assertQueries(t, sbc1, wantQueries) - assertQueries(t, sbc2, nil) - assertQueries(t, sbclookup, wantlkpQueries) + assertQueries(t, sbc1, wantQueries) + assertQueries(t, sbc2, nil) + assertQueries(t, sbclookup, wantlkpQueries) - testQueryLog(t, logChan, "TestInsertSelect", "SET", wQuery, 0) - testQueryLog(t, logChan, "VindexCreate", "INSERT", "insert into name_user_map(`name`, user_id) values (:name_0, :user_id_0)", 1) - testQueryLog(t, logChan, "TestInsertSelect", "INSERT", "insert into `user`(id, v, `name`) select 1, 2, 'myname' from dual", 1) + testQueryLog(t, logChan, "TestInsertSelect", "SET", wQuery, 0) + testQueryLog(t, logChan, "VindexCreate", "INSERT", "insert into name_user_map(`name`, user_id) values (:name_0, :user_id_0)", 1) + testQueryLog(t, logChan, "TestInsertSelect", "INSERT", "insert into `user`(id, v, `name`) select 1, 2, 'myname' from dual", 2) + }) } } @@ -2787,7 +2794,7 @@ func TestInsertSelectFromTable(t *testing.T) { query := "insert into user(id, name) select c1, c2 from music" wantQueries := []*querypb.BoundQuery{{ - Sql: "select c1, c2 from music for update", + Sql: "select c1, c2 from music lock in share mode", BindVariables: map[string]*querypb.BindVariable{}, }, { Sql: "insert into `user`(id, `name`) values (:_c0_0, :_c0_1), (:_c1_0, :_c1_1), (:_c2_0, :_c2_1), (:_c3_0, :_c3_1), (:_c4_0, :_c4_1), (:_c5_0, :_c5_1), (:_c6_0, :_c6_1), (:_c7_0, :_c7_1)", @@ -2874,5 +2881,5 @@ func TestInsertReference(t *testing.T) { sbclookup.Queries = nil _, err = executorExec(executor, "insert into TestExecutor.zip_detail(id, status) values (1, 'CLOSED')", nil) - require.Error(t, err) + require.NoError(t, err) // Gen4 planner can redirect the query to correct source for update when reference table is involved. } diff --git a/go/vt/vtgate/executor_framework_test.go b/go/vt/vtgate/executor_framework_test.go index 0e4870095bd..53586b3b818 100644 --- a/go/vt/vtgate/executor_framework_test.go +++ b/go/vt/vtgate/executor_framework_test.go @@ -25,27 +25,23 @@ import ( "strings" "testing" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/sidecardb" - "vitess.io/vitess/go/vt/vtgate/logstats" - - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/cache" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/discovery" "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" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + "vitess.io/vitess/go/vt/sidecardb" "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vtgate/logstats" "vitess.io/vitess/go/vt/vtgate/vindexes" "vitess.io/vitess/go/vt/vttablet/sandboxconn" - - querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) //go:embed testdata/executorVSchema.json @@ -173,7 +169,7 @@ func createExecutorEnv() (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn bad.VSchema = badVSchema getSandbox(KsTestUnsharded).VSchema = unshardedVSchema - executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) key.AnyShardPicker = DestinationAnyShardPickerFirstShard{} // create a new session each time so that ShardSessions don't get re-used across tests @@ -197,7 +193,7 @@ func createCustomExecutor(vschema string) (executor *Executor, sbc1, sbc2, sbclo sbclookup = hc.AddTestTablet(cell, "0", 1, KsTestUnsharded, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) getSandbox(KsTestUnsharded).VSchema = unshardedVSchema - executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) // create a new session each time so that ShardSessions don't get re-used across tests primarySession = &vtgatepb.Session{ TargetString: "@primary", @@ -226,7 +222,7 @@ func createCustomExecutorSetValues(vschema string, values []*sqltypes.Result) (e sbclookup = hc.AddTestTablet(cell, "0", 1, KsTestUnsharded, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) getSandbox(KsTestUnsharded).VSchema = unshardedVSchema - executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + executor = NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) // create a new session each time so that ShardSessions don't get re-used across tests primarySession = &vtgatepb.Session{ TargetString: "@primary", diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index dddd40c9cb8..bd53845db6f 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -1037,7 +1037,7 @@ func TestLastInsertIDInVirtualTable(t *testing.T) { _, err := executorExec(executor, "select * from (select last_insert_id()) as t", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select * from (select :__lastInsertId as `last_insert_id()` from dual) as t", + Sql: "select t.`last_insert_id()` from (select :__lastInsertId as `last_insert_id()` from dual) as t", BindVariables: map[string]*querypb.BindVariable{"__lastInsertId": sqltypes.Uint64BindVariable(0)}, }} @@ -1139,9 +1139,7 @@ func TestSelectBindvars(t *testing.T) { }} utils.MustMatch(t, wantQueries, sbc1.Queries) sbc1.Queries = nil - testQueryLog(t, logChan, "VindexLookup", "SELECT", "select `name`, user_id from name_user_map where `name` in ::name", 1) - testQueryLog(t, logChan, "VindexLookup", "SELECT", "select `name`, user_id from name_user_map where `name` in ::name", 1) - testQueryLog(t, logChan, "TestExecute", "SELECT", "select id from `user` where `name` in (:name1, :name2)", 1) + testQueryLog(t, logChan, "TestExecute", "SELECT", "select id from `user` where `name` in (:name1, :name2)", 3) // Test with BytesBindVariable sql = "select id from `user` where `name` in (:name1, :name2)" @@ -1153,14 +1151,13 @@ func TestSelectBindvars(t *testing.T) { wantQueries = []*querypb.BoundQuery{{ Sql: "select id from `user` where 1 != 1", BindVariables: map[string]*querypb.BindVariable{ - "name1": sqltypes.BytesBindVariable([]byte("foo1")), - "name2": sqltypes.BytesBindVariable([]byte("foo2")), + "__vals": sqltypes.TestBindVariable([]any{[]byte("foo1"), []byte("foo2")}), + "name1": sqltypes.BytesBindVariable([]byte("foo1")), + "name2": sqltypes.BytesBindVariable([]byte("foo2")), }, }} utils.MustMatch(t, wantQueries, sbc1.Queries) - testQueryLog(t, logChan, "VindexLookup", "SELECT", "select `name`, user_id from name_user_map where `name` in ::name", 1) - testQueryLog(t, logChan, "VindexLookup", "SELECT", "select `name`, user_id from name_user_map where `name` in ::name", 1) - testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) + testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 3) // Test no match in the lookup vindex sbc1.Queries = nil @@ -1199,10 +1196,7 @@ func TestSelectBindvars(t *testing.T) { }} utils.MustMatch(t, wantLookupQueries, lookup.Queries) - - testQueryLog(t, logChan, "VindexLookup", "SELECT", "select `name`, user_id from name_user_map where `name` in ::name", 1) - testQueryLog(t, logChan, "TestExecute", "SELECT", "select id from `user` where `name` = :name", 1) - + testQueryLog(t, logChan, "TestExecute", "SELECT", "select id from `user` where `name` = :name", 2) } func TestSelectEqual(t *testing.T) { @@ -1420,10 +1414,8 @@ func TestSelectIN(t *testing.T) { _, err := executorExec(executor, "select id from user where id in (1)", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select id from `user` where id in ::__vals", - BindVariables: map[string]*querypb.BindVariable{ - "__vals": sqltypes.TestBindVariable([]any{int64(1)}), - }, + Sql: "select id from `user` where id in (1)", + BindVariables: map[string]*querypb.BindVariable{}, }} utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { @@ -1547,7 +1539,7 @@ func TestStreamSelectIN(t *testing.T) { } func createExecutor(serv *sandboxTopo, cell string, resolver *Resolver) *Executor { - return NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + return NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) } func TestSelectScatter(t *testing.T) { @@ -2716,25 +2708,18 @@ func TestCrossShardSubquery(t *testing.T) { result, err := executorExec(executor, "select id1 from (select u1.id id1, u2.id from user u1 join user u2 on u2.id = u1.col where u1.id = 1) as t", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select u1.id as id1, u1.col from `user` as u1 where u1.id = 1", + Sql: "select id1, t.`u1.col` from (select u1.id as id1, u1.col as `u1.col` from `user` as u1 where u1.id = 1) as t", BindVariables: map[string]*querypb.BindVariable{}, }} utils.MustMatch(t, wantQueries, sbc1.Queries) - // We have to use string representation because bindvars type is too complex. - got := fmt.Sprintf("%+v", sbc2.Queries) - want := `[sql:"select u2.id from ` + "`user`" + ` as u2 where u2.id = :u1_col" bind_variables:{key:"u1_col" value:{type:INT32 value:"3"}}]` - if got != want { - t.Errorf("sbc2.Queries: %s, want %s\n", got, want) - } - wantResult := &sqltypes.Result{ - Fields: []*querypb.Field{ - {Name: "id", Type: sqltypes.Int32}, - }, - Rows: [][]sqltypes.Value{{ - sqltypes.NewInt32(1), - }}, - } + wantQueries = []*querypb.BoundQuery{{ + Sql: "select 1 from (select u2.id from `user` as u2 where u2.id = :u1_col) as t", + BindVariables: map[string]*querypb.BindVariable{"u1_col": sqltypes.Int32BindVariable(3)}, + }} + utils.MustMatch(t, wantQueries, sbc2.Queries) + + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id", "int32"), "1") if !result.Equal(wantResult) { t.Errorf("result: %+v, want %+v", result, wantResult) } @@ -2799,28 +2784,18 @@ func TestCrossShardSubqueryStream(t *testing.T) { result, err := executorStream(executor, "select id1 from (select u1.id id1, u2.id from user u1 join user u2 on u2.id = u1.col where u1.id = 1) as t") require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select u1.id as id1, u1.col from `user` as u1 where u1.id = 1", + Sql: "select id1, t.`u1.col` from (select u1.id as id1, u1.col as `u1.col` from `user` as u1 where u1.id = 1) as t", BindVariables: map[string]*querypb.BindVariable{}, }} utils.MustMatch(t, wantQueries, sbc1.Queries) - // We have to use string representation because bindvars type is too complex. - got := fmt.Sprintf("%+v", sbc2.Queries) - want := `[sql:"select u2.id from ` + "`user`" + ` as u2 where u2.id = :u1_col" bind_variables:{key:"u1_col" value:{type:INT32 value:"3"}}]` - if got != want { - t.Errorf("sbc2.Queries:\n%s, want\n%s\n", got, want) - } + wantQueries = []*querypb.BoundQuery{{ + Sql: "select 1 from (select u2.id from `user` as u2 where u2.id = :u1_col) as t", + BindVariables: map[string]*querypb.BindVariable{"u1_col": sqltypes.Int32BindVariable(3)}, + }} + utils.MustMatch(t, wantQueries, sbc2.Queries) - wantResult := &sqltypes.Result{ - Fields: []*querypb.Field{ - {Name: "id", Type: sqltypes.Int32}, - }, - Rows: [][]sqltypes.Value{{ - sqltypes.NewInt32(1), - }}, - } - if !result.Equal(wantResult) { - t.Errorf("result: %+v, want %+v", result, wantResult) - } + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id", "int32"), "1") + utils.MustMatch(t, wantResult, result) } func TestCrossShardSubqueryGetFields(t *testing.T) { @@ -2840,10 +2815,10 @@ func TestCrossShardSubqueryGetFields(t *testing.T) { result, err := executorExec(executor, "select main1.col, t.id1 from main1 join (select u1.id id1, u2.id from user u1 join user u2 on u2.id = u1.col where u1.id = 1) as t", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select u1.id as id1, u1.col from `user` as u1 where 1 != 1", + Sql: "select t.id1, t.`u1.col` from (select u1.id as id1, u1.col as `u1.col` from `user` as u1 where 1 != 1) as t where 1 != 1", BindVariables: map[string]*querypb.BindVariable{}, }, { - Sql: "select u2.id from `user` as u2 where 1 != 1", + Sql: "select 1 from (select u2.id from `user` as u2 where 1 != 1) as t where 1 != 1", BindVariables: map[string]*querypb.BindVariable{ "u1_col": sqltypes.NullBindVariable, }, @@ -3044,14 +3019,16 @@ func TestSelectFromInformationSchema(t *testing.T) { session.TargetString = "TestExecutor" _, err = exec(executor, session, "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()") require.NoError(t, err) - assert.Equal(t, sbc1.StringQueries(), []string{"select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = database()"}) + assert.Equal(t, []string{"select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = database()"}, + sbc1.StringQueries()) // `USE TestXBadSharding` and then query info_schema about TestExecutor - should target TestExecutor and not use the default keyspace sbc1.Queries = nil session.TargetString = "TestXBadSharding" _, err = exec(executor, session, "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TestExecutor'") require.NoError(t, err) - assert.Equal(t, sbc1.StringQueries(), []string{"select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */"}) + assert.Equal(t, []string{"select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */"}, + sbc1.StringQueries()) } func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { @@ -3074,7 +3051,7 @@ func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { count++ } - executor := NewExecutor(context.Background(), serv, cell, resolver, true, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + executor := NewExecutor(context.Background(), serv, cell, resolver, true, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) before := runtime.NumGoroutine() query := "select id, col from user order by id limit 2" @@ -3998,7 +3975,7 @@ func TestSelectView(t *testing.T) { "select * from user_details_view", nil) require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{ - Sql: "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id) as user_details_view", + Sql: "select user_details_view.id, user_details_view.col from (select `user`.id, user_extra.col from `user`, user_extra where `user`.id = user_extra.user_id) as user_details_view", BindVariables: map[string]*querypb.BindVariable{}, }} utils.MustMatch(t, wantQueries, sbc.Queries) @@ -4008,7 +3985,7 @@ func TestSelectView(t *testing.T) { "select * from user_details_view where id = 2", nil) require.NoError(t, err) wantQueries = []*querypb.BoundQuery{{ - Sql: "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id) as user_details_view where id = :id /* INT64 */", + Sql: "select user_details_view.id, user_details_view.col from (select `user`.id, user_extra.col from `user`, user_extra where `user`.id = :id /* INT64 */ and `user`.id = user_extra.user_id) as user_details_view", BindVariables: map[string]*querypb.BindVariable{ "id": sqltypes.Int64BindVariable(2), }, @@ -4022,7 +3999,7 @@ func TestSelectView(t *testing.T) { bvtg1, _ := sqltypes.BuildBindVariable([]int64{1, 2, 3, 4, 5}) bvals, _ := sqltypes.BuildBindVariable([]int64{1, 2}) wantQueries = []*querypb.BoundQuery{{ - Sql: "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id) as user_details_view where id in ::__vals", + Sql: "select user_details_view.id, user_details_view.col from (select `user`.id, user_extra.col from `user`, user_extra where `user`.id in ::__vals and `user`.id = user_extra.user_id) as user_details_view", BindVariables: map[string]*querypb.BindVariable{ "vtg1": bvtg1, "__vals": bvals, diff --git a/go/vt/vtgate/executor_stream_test.go b/go/vt/vtgate/executor_stream_test.go index 8fea4ed985f..00c991065e9 100644 --- a/go/vt/vtgate/executor_stream_test.go +++ b/go/vt/vtgate/executor_stream_test.go @@ -61,7 +61,7 @@ func TestStreamSQLSharded(t *testing.T) { for _, shard := range shards { _ = hc.AddTestTablet(cell, shard, 1, "TestExecutor", shard, topodatapb.TabletType_PRIMARY, true, 1, nil) } - executor := NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_V3) + executor := NewExecutor(context.Background(), serv, cell, resolver, false, false, testBufferSize, cache.DefaultConfig, nil, false, querypb.ExecuteOptions_Gen4) sql := "stream * from sharded_user_msgs" result, err := executorStreamMessages(executor, sql) diff --git a/go/vt/vtgate/executor_vschema_ddl_test.go b/go/vt/vtgate/executor_vschema_ddl_test.go index 1383792051d..6124ae64476 100644 --- a/go/vt/vtgate/executor_vschema_ddl_test.go +++ b/go/vt/vtgate/executor_vschema_ddl_test.go @@ -17,6 +17,7 @@ limitations under the License. package vtgate import ( + "context" "reflect" "sort" "testing" @@ -28,8 +29,6 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "context" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/vtgate/vschemaacl" diff --git a/go/vt/vtgate/executor_vstream_test.go b/go/vt/vtgate/executor_vstream_test.go index 828cdea2d40..5b289b8f10f 100644 --- a/go/vt/vtgate/executor_vstream_test.go +++ b/go/vt/vtgate/executor_vstream_test.go @@ -17,6 +17,7 @@ limitations under the License. package vtgate import ( + "context" "testing" "time" @@ -28,8 +29,6 @@ import ( vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - "context" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" @@ -38,7 +37,7 @@ import ( // TestVStreamSQLUnsharded tests the experimental 'vstream * from' vtgate olap query func TestVStreamSQLUnsharded(t *testing.T) { - t.Skip("this test is failing due to races") //FIXME + t.Skip("this test is failing due to races") // FIXME executor, _, _, sbcLookup := createExecutorEnv() logChan := QueryLogger.Subscribe("Test") defer QueryLogger.Unsubscribe(logChan) diff --git a/go/vt/vtgate/mysql_protocol_test.go b/go/vt/vtgate/mysql_protocol_test.go index dcd12de4bb4..75afa04f5fe 100644 --- a/go/vt/vtgate/mysql_protocol_test.go +++ b/go/vt/vtgate/mysql_protocol_test.go @@ -17,6 +17,7 @@ limitations under the License. package vtgate import ( + "context" "net" "strconv" "testing" @@ -26,8 +27,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "context" - "google.golang.org/protobuf/proto" "vitess.io/vitess/go/mysql" diff --git a/go/vt/vtgate/planbuilder/aggregation_pushing.go b/go/vt/vtgate/planbuilder/aggregation_pushing.go index 56cd6a9f59a..677fabbac18 100644 --- a/go/vt/vtgate/planbuilder/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/aggregation_pushing.go @@ -44,12 +44,12 @@ func (hp *horizonPlanning) pushAggregation( err error) { pushed = true switch plan := plan.(type) { - case *routeGen4: + case *route: output = plan groupingOffsets, outputAggrsOffset, _, err = pushAggrOnRoute(ctx, plan, aggregations, grouping, ignoreOutputOrder) return - case *joinGen4: + case *join: output = plan groupingOffsets, outputAggrsOffset, err = hp.pushAggrOnJoin(ctx, plan, grouping, aggregations) return @@ -112,7 +112,7 @@ func (hp *horizonPlanning) pushAggregation( func pushAggrOnRoute( ctx *plancontext.PlanningContext, - plan *routeGen4, + plan *route, aggregations []operators.Aggr, grouping []operators.GroupBy, ignoreOutputOrder bool, @@ -184,7 +184,7 @@ func pushAggrOnRoute( func pushAggrsAndGroupingInOrder( ctx *plancontext.PlanningContext, - plan *routeGen4, + plan *route, it *sortedIterator, sel *sqlparser.Select, vtgateAggregation [][]offsets, @@ -246,7 +246,7 @@ vtgate level, we can offload most of the work to MySQL, and at the vtgate just s */ func (hp *horizonPlanning) pushAggrOnJoin( ctx *plancontext.PlanningContext, - join *joinGen4, + join *join, grouping []operators.GroupBy, aggregations []operators.Aggr, ) ([]offsets, [][]offsets, error) { @@ -432,7 +432,7 @@ func isAnyValue(in popcode.AggregateOpcode) bool { func splitAggregationsToLeftAndRight( ctx *plancontext.PlanningContext, aggregations []operators.Aggr, - join *joinGen4, + join *join, ) ([]*operators.Aggr, []*operators.Aggr, error) { var lhsAggrs, rhsAggrs []*operators.Aggr for _, aggr := range aggregations { @@ -464,7 +464,7 @@ func splitAggregationsToLeftAndRight( func splitGroupingsToLeftAndRight( ctx *plancontext.PlanningContext, - join *joinGen4, + join *join, grouping, lhsGrouping []operators.GroupBy, ) ([]operators.GroupBy, []operators.GroupBy, []int, error) { var rhsGrouping []operators.GroupBy diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 3ebe7bd95d7..a80a2f7eb86 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -21,41 +21,29 @@ import ( "fmt" "sort" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - querypb "vitess.io/vitess/go/vt/proto/query" - - "vitess.io/vitess/go/vt/vterrors" - "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" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/semantics" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) const ( - // V3 is also the default planner - V3 = querypb.ExecuteOptions_V3 // Gen4 uses the default Gen4 planner, which is the greedy planner Gen4 = querypb.ExecuteOptions_Gen4 // Gen4GreedyOnly uses only the faster greedy planner Gen4GreedyOnly = querypb.ExecuteOptions_Gen4Greedy - // Gen4Left2Right tries to emulate the V3 planner by only joining plans in the order they are listed in the FROM-clause + // Gen4Left2Right joins table in the order they are listed in the FROM-clause Gen4Left2Right = querypb.ExecuteOptions_Gen4Left2Right - // Gen4WithFallback first attempts to use the Gen4 planner, and if that fails, uses the V3 planner instead - Gen4WithFallback = querypb.ExecuteOptions_Gen4WithFallback - // Gen4CompareV3 executes queries on both Gen4 and V3 to compare their results. - Gen4CompareV3 = querypb.ExecuteOptions_Gen4CompareV3 - // V3Insert executes insert query on V3 and others on Gen4. - V3Insert = querypb.ExecuteOptions_V3Insert ) var ( - plannerVersions = []plancontext.PlannerVersion{V3, V3Insert, Gen4, Gen4GreedyOnly, Gen4Left2Right, Gen4WithFallback, Gen4CompareV3} + plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} ) type ( @@ -79,24 +67,6 @@ func singleTable(ks, tbl string) string { return fmt.Sprintf("%s.%s", ks, tbl) } -func tablesFromSemantics(semTable *semantics.SemTable) []string { - tables := make(map[string]any, len(semTable.Tables)) - for _, info := range semTable.Tables { - vindexTable := info.GetVindexTable() - if vindexTable == nil { - continue - } - tables[vindexTable.String()] = nil - } - - names := make([]string, 0, len(tables)) - for tbl := range tables { - names = append(names, tbl) - } - sort.Strings(names) - return names -} - // TestBuilder builds a plan for a query based on the specified vschema. // This method is only used from tests func TestBuilder(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error) { @@ -136,59 +106,20 @@ func BuildFromStmt(ctx context.Context, query string, stmt sqlparser.Statement, return plan, nil } -func getConfiguredPlanner(vschema plancontext.VSchema, v3planner func(string) stmtPlanner, stmt sqlparser.Statement, query string) (stmtPlanner, error) { - planner, ok := getPlannerFromQuery(stmt) - if !ok { +func getConfiguredPlanner(vschema plancontext.VSchema, stmt sqlparser.Statement, query string) (stmtPlanner, error) { + planner, found := getPlannerFromQueryHint(stmt) + if !found { // if the query doesn't specify the planner, we check what the configuration is planner = vschema.Planner() } switch planner { - case Gen4CompareV3: - return gen4CompareV3Planner(query), nil - case Gen4Left2Right, Gen4GreedyOnly: - return gen4Planner(query, planner), nil - case Gen4WithFallback: - fp := &fallbackPlanner{ - primary: gen4Planner(query, Gen4), - fallback: v3planner(query), - } - return fp.plan, nil - case V3Insert: - if _, isInsert := stmt.(*sqlparser.Insert); isInsert { - return v3planner(query), nil - } - return gen4Planner(query, Gen4), nil - case V3: - return v3planner(query), nil + case Gen4Left2Right, Gen4GreedyOnly, Gen4: default: // default is gen4 plan - return gen4Planner(query, Gen4), nil + log.Infof("Using Gen4 planner instead of %s", planner.String()) + planner = Gen4 } -} - -// getPlannerFromQuery chooses the planner to use based on the query -// The default planner can be overridden using /*vt+ PLANNER=gen4 */ -// We will also fall back on the gen4 planner if we encounter outer join, -// since there are known problems with the v3 planner and outer joins -func getPlannerFromQuery(stmt sqlparser.Statement) (version plancontext.PlannerVersion, found bool) { - version, found = getPlannerFromQueryHint(stmt) - if found { - return - } - - _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - join, ok := node.(*sqlparser.JoinTableExpr) - if ok { - if join.Join == sqlparser.LeftJoinType || join.Join == sqlparser.RightJoinType { - version = querypb.ExecuteOptions_Gen4 - found = true - return false, nil - } - } - return true, nil - }, stmt) - - return + return gen4Planner(query, planner), nil } func getPlannerFromQueryHint(stmt sqlparser.Statement) (plancontext.PlannerVersion, bool) { @@ -215,31 +146,31 @@ func buildRoutePlan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVa func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { switch stmt := stmt.(type) { case *sqlparser.Select: - configuredPlanner, err := getConfiguredPlanner(vschema, buildSelectPlan, stmt, query) + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err } return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case *sqlparser.Insert: - configuredPlanner, err := getConfiguredPlanner(vschema, buildInsertPlan, stmt, query) + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err } return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case *sqlparser.Update: - configuredPlanner, err := getConfiguredPlanner(vschema, buildUpdatePlan, stmt, query) + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err } return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case *sqlparser.Delete: - configuredPlanner, err := getConfiguredPlanner(vschema, buildDeletePlan, stmt, query) + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err } return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case *sqlparser.Union: - configuredPlanner, err := getConfiguredPlanner(vschema, buildUnionPlan, stmt, query) + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/concatenate.go b/go/vt/vtgate/planbuilder/concatenate.go index 70b867b1146..378c0049ed2 100644 --- a/go/vt/vtgate/planbuilder/concatenate.go +++ b/go/vt/vtgate/planbuilder/concatenate.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Vitess Authors. +Copyright 2021 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,69 +20,65 @@ 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/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" ) type concatenate struct { - v3Plan - lhs, rhs logicalPlan - order int -} - -var _ logicalPlan = (*concatenate)(nil) - -func (c *concatenate) Order() int { - return c.order -} + sources []logicalPlan -func (c *concatenate) ResultColumns() []*resultColumn { - return c.lhs.ResultColumns() + // These column offsets do not need to be typed checked - they usually contain weight_string() + // columns that are not going to be returned to the user + noNeedToTypeCheck []int } -func (c *concatenate) Reorder(order int) { - c.lhs.Reorder(order) - c.rhs.Reorder(c.lhs.Order()) - c.order = c.rhs.Order() + 1 -} +var _ logicalPlan = (*concatenate)(nil) -func (c *concatenate) Wireup(plan logicalPlan, jt *jointab) error { - // TODO systay should we do something different here? - err := c.lhs.Wireup(plan, jt) - if err != nil { - return err +// WireupGen4 implements the logicalPlan interface +func (c *concatenate) Wireup(ctx *plancontext.PlanningContext) error { + for _, source := range c.sources { + err := source.Wireup(ctx) + if err != nil { + return err + } } - return c.rhs.Wireup(plan, jt) -} - -func (c *concatenate) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - panic("implement me") -} - -func (c *concatenate) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - panic("implement me") -} - -func (c *concatenate) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - panic("implement me") + return nil } +// Primitive implements the logicalPlan interface func (c *concatenate) Primitive() engine.Primitive { - lhs := c.lhs.Primitive() - rhs := c.rhs.Primitive() + var sources []engine.Primitive + for _, source := range c.sources { + sources = append(sources, source.Primitive()) + } - return engine.NewConcatenate([]engine.Primitive{lhs, rhs}, nil) + return engine.NewConcatenate(sources, c.noNeedToTypeCheck) } // Rewrite implements the logicalPlan interface func (c *concatenate) Rewrite(inputs ...logicalPlan) error { - if len(inputs) != 2 { + if len(inputs) != len(c.sources) { return vterrors.VT13001("concatenate: wrong number of inputs") } - c.lhs = inputs[0] - c.rhs = inputs[1] + c.sources = inputs return nil } +// ContainsTables implements the logicalPlan interface +func (c *concatenate) ContainsTables() semantics.TableSet { + var tableSet semantics.TableSet + for _, source := range c.sources { + tableSet = tableSet.Merge(source.ContainsTables()) + } + return tableSet +} + // Inputs implements the logicalPlan interface func (c *concatenate) Inputs() []logicalPlan { - return []logicalPlan{c.lhs, c.rhs} + return c.sources +} + +// OutputColumns implements the logicalPlan interface +func (c *concatenate) OutputColumns() []sqlparser.SelectExpr { + return c.sources[0].OutputColumns() } diff --git a/go/vt/vtgate/planbuilder/concatenateGen4.go b/go/vt/vtgate/planbuilder/concatenateGen4.go deleted file mode 100644 index fa12d24cf73..00000000000 --- a/go/vt/vtgate/planbuilder/concatenateGen4.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - "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/plancontext" - "vitess.io/vitess/go/vt/vtgate/semantics" -) - -type concatenateGen4 struct { - sources []logicalPlan - - // These column offsets do not need to be typed checked - they usually contain weight_string() - // columns that are not going to be returned to the user - noNeedToTypeCheck []int -} - -var _ logicalPlan = (*concatenateGen4)(nil) - -// Order implements the logicalPlan interface -func (c *concatenateGen4) Order() int { - panic("implement me") -} - -// ResultColumns implements the logicalPlan interface -func (c *concatenateGen4) ResultColumns() []*resultColumn { - panic("implement me") -} - -// Reorder implements the logicalPlan interface -func (c *concatenateGen4) Reorder(order int) { - panic("implement me") -} - -// Wireup implements the logicalPlan interface -func (c *concatenateGen4) Wireup(plan logicalPlan, jt *jointab) error { - panic("implement me") -} - -// WireupGen4 implements the logicalPlan interface -func (c *concatenateGen4) WireupGen4(ctx *plancontext.PlanningContext) error { - for _, source := range c.sources { - err := source.WireupGen4(ctx) - if err != nil { - return err - } - } - return nil -} - -// SupplyVar implements the logicalPlan interface -func (c *concatenateGen4) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - panic("implement me") -} - -// SupplyCol implements the logicalPlan interface -func (c *concatenateGen4) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - panic("implement me") -} - -// SupplyWeightString implements the logicalPlan interface -func (c *concatenateGen4) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - panic("implement me") -} - -// Primitive implements the logicalPlan interface -func (c *concatenateGen4) Primitive() engine.Primitive { - var sources []engine.Primitive - for _, source := range c.sources { - sources = append(sources, source.Primitive()) - } - - return engine.NewConcatenate(sources, c.noNeedToTypeCheck) -} - -// Rewrite implements the logicalPlan interface -func (c *concatenateGen4) Rewrite(inputs ...logicalPlan) error { - if len(inputs) != len(c.sources) { - return vterrors.VT13001("concatenateGen4: wrong number of inputs") - } - c.sources = inputs - return nil -} - -// ContainsTables implements the logicalPlan interface -func (c *concatenateGen4) ContainsTables() semantics.TableSet { - var tableSet semantics.TableSet - for _, source := range c.sources { - tableSet = tableSet.Merge(source.ContainsTables()) - } - return tableSet -} - -// Inputs implements the logicalPlan interface -func (c *concatenateGen4) Inputs() []logicalPlan { - return c.sources -} - -// OutputColumns implements the logicalPlan interface -func (c *concatenateGen4) OutputColumns() []sqlparser.SelectExpr { - return c.sources[0].OutputColumns() -} diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 738595d7d6c..871b8adc38a 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -410,8 +410,6 @@ func tryToGetRoutePlan(selectPlan engine.Primitive) (valid bool, opCode engine.O switch plan := selectPlan.(type) { case *engine.Route: return true, plan.Opcode - case engine.Gen4Comparer: - return tryToGetRoutePlan(plan.GetGen4Primitive()) default: return false, engine.Opcode(0) } diff --git a/go/vt/vtgate/planbuilder/delete.go b/go/vt/vtgate/planbuilder/delete.go index 569bf455cce..f462df6ce76 100644 --- a/go/vt/vtgate/planbuilder/delete.go +++ b/go/vt/vtgate/planbuilder/delete.go @@ -17,63 +17,85 @@ limitations under the License. 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" + "vitess.io/vitess/go/vt/vtgate/semantics" + "vitess.io/vitess/go/vt/vtgate/vindexes" ) -// buildDeletePlan builds the instructions for a DELETE statement. -func buildDeletePlan(string) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - del := stmt.(*sqlparser.Delete) - if del.With != nil { - return nil, vterrors.VT12001("WITH expression in DELETE statement") - } - err := checkUnsupportedExpressions(del) - if err != nil { - return nil, err - } - if len(del.TableExprs) == 1 && len(del.Targets) == 1 { - del, err = rewriteSingleTbl(del) - if err != nil { - return nil, err - } - } - dml, tables, ksidVindex, err := buildDMLPlan(vschema, "delete", del, reservedVars, del.TableExprs, del.Where, del.OrderBy, del.Limit, del.Comments, del.Targets) +func gen4DeleteStmtPlanner( + version querypb.ExecuteOptions_PlannerVersion, + deleteStmt *sqlparser.Delete, + reservedVars *sqlparser.ReservedVars, + vschema plancontext.VSchema, +) (*planResult, error) { + if deleteStmt.With != nil { + return nil, vterrors.VT12001("WITH expression in DELETE statement") + } + + var err error + if len(deleteStmt.TableExprs) == 1 && len(deleteStmt.Targets) == 1 { + deleteStmt, err = rewriteSingleTbl(deleteStmt) if err != nil { return nil, err } - edel := &engine.Delete{DML: dml} - if dml.Opcode == engine.Unsharded { - return newPlanResult(edel, tables...), nil - } + } - if len(del.Targets) > 1 { - return nil, vterrors.VT12001("multi-table DELETE statement in a sharded keyspace") - } + ksName := "" + if ks, _ := vschema.DefaultKeyspace(); ks != nil { + ksName = ks.Name + } + semTable, err := semantics.Analyze(deleteStmt, ksName, vschema) + if err != nil { + return nil, err + } - edelTable, err := edel.GetSingleTable() - if err != nil { - return nil, err - } - if len(del.Targets) == 1 && del.Targets[0].Name != edelTable.Name { - return nil, vterrors.VT03003(del.Targets[0].Name.String()) - } + // record any warning as planner warning. + vschema.PlannerWarning(semTable.Warning) + err = rewriteRoutedTables(deleteStmt, vschema) + if err != nil { + return nil, err + } - if len(edelTable.Owned) > 0 { - aTblExpr, ok := del.TableExprs[0].(*sqlparser.AliasedTableExpr) - if !ok { - return nil, vterrors.VT12001("deleting from a complex table expression") - } - tblExpr := &sqlparser.AliasedTableExpr{Expr: sqlparser.TableName{Name: edelTable.Name}, As: aTblExpr.As} - edel.OwnedVindexQuery = generateDMLSubquery(tblExpr, del.Where, del.OrderBy, del.Limit, edelTable, ksidVindex.Columns) - edel.KsidVindex = ksidVindex.Vindex - edel.KsidLength = len(ksidVindex.Columns) - } + if ks, tables := semTable.SingleUnshardedKeyspace(); ks != nil { + plan := deleteUnshardedShortcut(deleteStmt, ks, tables) + plan = pushCommentDirectivesOnPlan(plan, deleteStmt) + return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil + } + + if err := checkIfDeleteSupported(deleteStmt, semTable); err != nil { + return nil, err + } - return newPlanResult(edel, tables...), nil + err = queryRewrite(semTable, reservedVars, deleteStmt) + if err != nil { + return nil, err } + + ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) + op, err := operators.PlanQuery(ctx, deleteStmt) + if err != nil { + return nil, err + } + + plan, err := transformToLogicalPlan(ctx, op, true) + if err != nil { + return nil, err + } + + plan = pushCommentDirectivesOnPlan(plan, deleteStmt) + + setLockOnAllSelect(plan) + + if err := plan.Wireup(ctx); err != nil { + return nil, err + } + + return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil } func rewriteSingleTbl(del *sqlparser.Delete) (*sqlparser.Delete, error) { @@ -112,3 +134,49 @@ func rewriteSingleTbl(del *sqlparser.Delete) (*sqlparser.Delete, error) { } return del, nil } + +func deleteUnshardedShortcut(stmt *sqlparser.Delete, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { + edml := engine.NewDML() + edml.Keyspace = ks + edml.Table = tables + edml.Opcode = engine.Unsharded + edml.Query = generateQuery(stmt) + return &primitiveWrapper{prim: &engine.Delete{DML: edml}} +} + +// checkIfDeleteSupported checks if the delete query is supported or we must return an error. +func checkIfDeleteSupported(del *sqlparser.Delete, semTable *semantics.SemTable) error { + if semTable.NotUnshardedErr != nil { + return semTable.NotUnshardedErr + } + + // Delete is only supported for a single TableExpr which is supposed to be an aliased expression + multiShardErr := vterrors.VT12001("multi-shard or vindex write statement") + if len(del.TableExprs) != 1 { + return multiShardErr + } + _, isAliasedExpr := del.TableExprs[0].(*sqlparser.AliasedTableExpr) + if !isAliasedExpr { + return multiShardErr + } + + if len(del.Targets) > 1 { + return vterrors.VT12001("multi-table DELETE statement in a sharded keyspace") + } + + err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + switch node.(type) { + case *sqlparser.Subquery, *sqlparser.DerivedTable: + // We have a subquery, so we must fail the planning. + // If this subquery and the table expression were all belonging to the same unsharded keyspace, + // we would have already created a plan for them before doing these checks. + return false, vterrors.VT12001("subqueries in DML") + } + return true, nil + }, del) + if err != nil { + return err + } + + return nil +} diff --git a/go/vt/vtgate/planbuilder/distinct.go b/go/vt/vtgate/planbuilder/distinct.go index dff6370078e..d9d8d4176dd 100644 --- a/go/vt/vtgate/planbuilder/distinct.go +++ b/go/vt/vtgate/planbuilder/distinct.go @@ -49,16 +49,7 @@ func newDistinctGen4Legacy(source logicalPlan, checkCols []engine.CheckCol, need } } -func newDistinctV3(source logicalPlan) logicalPlan { - return &distinct{logicalPlanCommon: newBuilderCommon(source)} -} - func (d *distinct) Primitive() engine.Primitive { - if d.checkCols == nil { - // If we are missing the checkCols information, we are on the V3 planner and should produce a V3 Distinct - return &engine.DistinctV3{Source: d.input.Primitive()} - } - truncate := d.truncateColumn if d.needToTruncate { wsColFound := false diff --git a/go/vt/vtgate/planbuilder/dml_planner.go b/go/vt/vtgate/planbuilder/dml_planner.go index 123349f6d1e..5467c035f32 100644 --- a/go/vt/vtgate/planbuilder/dml_planner.go +++ b/go/vt/vtgate/planbuilder/dml_planner.go @@ -17,378 +17,54 @@ limitations under the License. package planbuilder import ( - "fmt" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" "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/vindexes" -) - -type ( - // costDML is used to compare the cost of vindexOptionDML - costDML struct { - vindexCost int - isUnique bool - opCode engine.Opcode - } - - // vindexPlusPredicatesDML is a struct used to store all the predicates that the vindex can be used to query - vindexPlusPredicatesDML struct { - colVindex *vindexes.ColumnVindex - - // during planning, we store the alternatives found for this DML in this slice - options []*vindexOptionDML - } - - // vindexOptionDML stores the information needed to know if we have all the information needed to use a vindex - vindexOptionDML struct { - ready bool - values []evalengine.Expr - // columns that we have seen so far. Used only for multi-column vindexes so that we can track how many columns part of the vindex we have seen - colsSeen map[string]any - opcode engine.Opcode - foundVindex vindexes.Vindex - cost costDML - } ) -// getDMLRouting returns the vindex and values for the DML, -// If it cannot find a unique vindex match, it returns an error. -func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) ( - engine.Opcode, - *vindexes.ColumnVindex, - vindexes.Vindex, - []evalengine.Expr, - error, -) { - // Check that we have a primary vindex which is valid - if len(table.ColumnVindexes) == 0 || !table.ColumnVindexes[0].IsUnique() { - return engine.Scatter, nil, nil, nil, vterrors.VT09001(table.Name) - } - // ksidVindex is the primary vindex - ksidVindex := table.ColumnVindexes[0] - if where == nil { - return engine.Scatter, ksidVindex, nil, nil, nil - } - - filters := sqlparser.SplitAndExpression(nil, where.Expr) - // go over the vindexes in the order of increasing cost - for _, colVindex := range table.Ordered { - if lu, isLu := colVindex.Vindex.(vindexes.LookupBackfill); isLu && lu.IsBackfilling() { - // Checking if the Vindex is currently backfilling or not, if it isn't we can read from the vindex table - // and we will be able to do a delete equal. Otherwise, we continue to look for next best vindex. - continue - } - // get the best vindex option that can be used for this vindexes.ColumnVindex - if vindexOption := getBestVindexOption(filters, colVindex); vindexOption != nil { - return vindexOption.opcode, ksidVindex, colVindex.Vindex, vindexOption.values, nil +func rewriteRoutedTables(stmt sqlparser.Statement, vschema plancontext.VSchema) error { + // Rewrite routed tables + return sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) { + aliasTbl, isAlias := node.(*sqlparser.AliasedTableExpr) + if !isAlias { + return true, nil } - } - return engine.Scatter, ksidVindex, nil, nil, nil -} - -// getBestVindexOption returns the best vindex option that can be used for this vindexes.ColumnVindex -// It returns nil if there is no suitable way to use the ColumnVindex -func getBestVindexOption(exprs []sqlparser.Expr, index *vindexes.ColumnVindex) *vindexOptionDML { - vindexPlusPredicates := &vindexPlusPredicatesDML{ - colVindex: index, - } - for _, filter := range exprs { - comparison, ok := filter.(*sqlparser.ComparisonExpr) + tableName, ok := aliasTbl.Expr.(sqlparser.TableName) if !ok { - continue - } - var colName *sqlparser.ColName - var valExpr sqlparser.Expr - if col, ok := comparison.Left.(*sqlparser.ColName); ok { - colName = col - valExpr = comparison.Right - } else if col, ok := comparison.Right.(*sqlparser.ColName); ok { - colName = col - valExpr = comparison.Left - } else { - continue - } - - var opcode engine.Opcode - switch comparison.Operator { - case sqlparser.EqualOp: - if !sqlparser.IsValue(valExpr) { - continue - } - opcode = engine.Equal - case sqlparser.InOp: - if !sqlparser.IsSimpleTuple(valExpr) { - continue - } - opcode = engine.IN - default: - continue + return true, nil } - expr, err := evalengine.Translate(comparison.Right, nil) + vschemaTable, vindexTbl, _, _, _, err := vschema.FindTableOrVindex(tableName) if err != nil { - continue - } - addVindexOptions(colName, expr, opcode, vindexPlusPredicates) - } - return vindexPlusPredicates.bestOption() -} - -// bestOption returns the option which is ready and has the lowest associated cost -func (vpp *vindexPlusPredicatesDML) bestOption() *vindexOptionDML { - var best *vindexOptionDML - for _, option := range vpp.options { - if option.ready { - if best == nil || lessCostDML(option.cost, best.cost) { - best = option - } - } - } - return best -} - -// lessCostDML compares two costDML and returns true if the first cost is cheaper than the second -func lessCostDML(c1, c2 costDML) bool { - switch { - case c1.opCode != c2.opCode: - return c1.opCode < c2.opCode - case c1.isUnique == c2.isUnique: - return c1.vindexCost <= c2.vindexCost - default: - return c1.isUnique - } -} - -// addVindexOptions adds new vindexOptionDML if it matches any column of the vindexes.ColumnVindex -func addVindexOptions(column *sqlparser.ColName, value evalengine.Expr, opcode engine.Opcode, v *vindexPlusPredicatesDML) { - switch v.colVindex.Vindex.(type) { - case vindexes.SingleColumn: - col := v.colVindex.Columns[0] - if column.Name.Equal(col) { - // single column vindex - just add the option - vindex := v.colVindex - v.options = append(v.options, &vindexOptionDML{ - values: []evalengine.Expr{value}, - opcode: opcode, - foundVindex: vindex.Vindex, - cost: costForDML(v.colVindex, opcode), - ready: true, - }) + return false, err } - case vindexes.MultiColumn: - colLoweredName := "" - indexOfCol := -1 - for idx, col := range v.colVindex.Columns { - if column.Name.Equal(col) { - colLoweredName = column.Name.Lowered() - indexOfCol = idx - break - } - } - if colLoweredName == "" { - break + if vindexTbl != nil { + // vindex cannot be present in a dml statement. + return false, vterrors.VT09014() } - var newOption []*vindexOptionDML - for _, op := range v.options { - if op.ready { - continue - } - _, isPresent := op.colsSeen[colLoweredName] - if isPresent { - continue + if vschemaTable.Name.String() != tableName.Name.String() { + name := tableName.Name + if aliasTbl.As.IsEmpty() { + // if the user hasn't specified an alias, we'll insert one here so the old table name still works + aliasTbl.As = sqlparser.NewIdentifierCS(name.String()) } - option := copyOptionDML(op) - option.updateWithNewColumn(colLoweredName, indexOfCol, value, v.colVindex, opcode) - newOption = append(newOption, option) + tableName.Name = sqlparser.NewIdentifierCS(vschemaTable.Name.String()) + aliasTbl.Expr = tableName } - v.options = append(v.options, newOption...) - // multi column vindex - just always add as new option - option := createOptionDML(v.colVindex) - option.updateWithNewColumn(colLoweredName, indexOfCol, value, v.colVindex, opcode) - v.options = append(v.options, option) - } + return true, nil + }, stmt) } -// copyOptionDML is used to copy vindexOptionDML -func copyOptionDML(orig *vindexOptionDML) *vindexOptionDML { - colsSeen := make(map[string]any, len(orig.colsSeen)) - values := make([]evalengine.Expr, len(orig.values)) - - copy(values, orig.values) - for k, v := range orig.colsSeen { - colsSeen[k] = v - } - vo := &vindexOptionDML{ - values: values, - colsSeen: colsSeen, - opcode: orig.opcode, - foundVindex: orig.foundVindex, - cost: orig.cost, - } - return vo -} - -// updateWithNewColumn is used to update vindexOptionDML with a new column that matches one of its unseen columns -func (option *vindexOptionDML) updateWithNewColumn(colLoweredName string, indexOfCol int, value evalengine.Expr, colVindex *vindexes.ColumnVindex, opcode engine.Opcode) { - option.colsSeen[colLoweredName] = true - option.values[indexOfCol] = value - option.ready = len(option.colsSeen) == len(colVindex.Columns) - if option.opcode < opcode { - option.opcode = opcode - option.cost = costForDML(colVindex, opcode) - } -} - -// createOptionDML is used to create a vindexOptionDML -func createOptionDML( - colVindex *vindexes.ColumnVindex, -) *vindexOptionDML { - values := make([]evalengine.Expr, len(colVindex.Columns)) - vindex := colVindex.Vindex - - return &vindexOptionDML{ - values: values, - colsSeen: map[string]any{}, - foundVindex: vindex, - } -} - -// costForDML returns a cost struct to make route choices easier to compare -func costForDML(foundVindex *vindexes.ColumnVindex, opcode engine.Opcode) costDML { - switch opcode { - // For these opcodes, we should not have a vindex, so we just return the opcode as the cost - case engine.Unsharded, engine.Scatter: - return costDML{ - opCode: opcode, - } - } - - return costDML{ - vindexCost: foundVindex.Cost(), - isUnique: foundVindex.IsUnique(), - opCode: opcode, - } -} - -func buildDMLPlan( - vschema plancontext.VSchema, - dmlType string, - stmt sqlparser.Statement, - reservedVars *sqlparser.ReservedVars, - tableExprs sqlparser.TableExprs, - where *sqlparser.Where, - orderBy sqlparser.OrderBy, - limit *sqlparser.Limit, - comments *sqlparser.ParsedComments, - nodes ...sqlparser.SQLNode, -) (*engine.DML, []string, *vindexes.ColumnVindex, error) { - edml := engine.NewDML() - pb := newPrimitiveBuilder(vschema, newJointab(reservedVars)) - rb, err := pb.processDMLTable(tableExprs, reservedVars, nil) - if err != nil { - return nil, nil, nil, err - } - edml.Keyspace = rb.eroute.Keyspace - tc := &tableCollector{} - for _, tval := range pb.st.tables { - tc.addVindexTable(tval.vschemaTable) - } - - edml.Table, err = pb.st.AllVschemaTableNames() - if err != nil { - return nil, nil, nil, err - } - if !edml.Keyspace.Sharded { - // We only validate non-table subexpressions because the previous analysis has already validated them. - var subqueryArgs []sqlparser.SQLNode - subqueryArgs = append(subqueryArgs, nodes...) - subqueryArgs = append(subqueryArgs, where, orderBy, limit) - subqueryIsUnsharded, subqueryTables := pb.finalizeUnshardedDMLSubqueries(reservedVars, subqueryArgs...) - if subqueryIsUnsharded { - vschema.WarnUnshardedOnly("subqueries can't be sharded in DML") - } else { - return nil, nil, nil, vterrors.VT12001("sharded subqueries in DML") - } - edml.Opcode = engine.Unsharded - // Generate query after all the analysis. Otherwise table name substitutions for - // routed tables won't happen. - edml.Query = generateQuery(stmt) - edml.Table = append(edml.Table, subqueryTables...) - return edml, tc.getTables(), nil, nil - } - - if hasSubquery(stmt) { - return nil, nil, nil, vterrors.VT12001("sharded subqueries in DML") - } - - // Generate query after all the analysis. Otherwise table name substitutions for - // routed tables won't happen. - edml.Query = generateQuery(stmt) - - directives := comments.Directives() - if directives.IsSet(sqlparser.DirectiveMultiShardAutocommit) { - edml.MultiShardAutocommit = true - } - - edml.QueryTimeout = queryTimeout(directives) - - if len(pb.st.tables) != 1 { - return nil, nil, nil, vterrors.VT12001(fmt.Sprintf("multi-table %s statement in a sharded keyspace", dmlType)) - } - edmlTable, err := edml.GetSingleTable() - if err != nil { - return nil, nil, nil, err - } - routingType, ksidVindex, vindex, values, err := getDMLRouting(where, edmlTable) - if err != nil { - return nil, nil, nil, err - } - - if rb.eroute.TargetDestination != nil { - if rb.eroute.TargetTabletType != topodatapb.TabletType_PRIMARY { - return nil, nil, nil, vterrors.VT09002(dmlType) - } - edml.Opcode = engine.ByDestination - edml.TargetDestination = rb.eroute.TargetDestination - return edml, tc.getTables(), ksidVindex, nil - } - - edml.Opcode = routingType - if routingType == engine.Scatter { - if limit != nil { - return nil, nil, nil, vterrors.VT12001(fmt.Sprintf("multi-shard %s with LIMIT", dmlType)) +func setLockOnAllSelect(plan logicalPlan) { + _, _ = visit(plan, func(plan logicalPlan) (bool, logicalPlan, error) { + switch node := plan.(type) { + case *route: + node.Select.SetLock(sqlparser.ShareModeLock) + return true, node, nil } - } else { - edml.Vindex = vindex - edml.Values = values - } - - return edml, tc.getTables(), ksidVindex, nil -} - -func generateDMLSubquery(tblExpr sqlparser.TableExpr, where *sqlparser.Where, orderBy sqlparser.OrderBy, limit *sqlparser.Limit, table *vindexes.Table, ksidCols []sqlparser.IdentifierCI) string { - buf := sqlparser.NewTrackedBuffer(nil) - for idx, col := range ksidCols { - if idx == 0 { - buf.Myprintf("select %v", col) - } else { - buf.Myprintf(", %v", col) - } - } - for _, cv := range table.Owned { - for _, column := range cv.Columns { - buf.Myprintf(", %v", column) - } - } - buf.Myprintf(" from %v%v%v%v for update", tblExpr, where, orderBy, limit) - return buf.String() + return true, plan, nil + }) } func generateQuery(statement sqlparser.Statement) string { diff --git a/go/vt/vtgate/planbuilder/expr.go b/go/vt/vtgate/planbuilder/expr.go deleted file mode 100644 index fb92707b0ca..00000000000 --- a/go/vt/vtgate/planbuilder/expr.go +++ /dev/null @@ -1,337 +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 planbuilder - -import ( - "bytes" - "fmt" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" - popcode "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -type subqueryInfo struct { - ast *sqlparser.Subquery - plan logicalPlan - origin logicalPlan -} - -// findOrigin identifies the right-most origin referenced by expr. In situations where -// the expression references columns from multiple origins, the expression will be -// pushed to the right-most origin, and the executor will use the results of -// the previous origins to feed the necessary values to the primitives on the right. -// -// If the expression contains a subquery, the right-most origin identification -// also follows the same rules of a normal expression. This is achieved by -// looking at the Externs field of its symbol table that contains the list of -// external references. -// -// Once the target origin is identified, we have to verify that the subquery's -// route can be merged with it. If it cannot, we fail the query. This is because -// we don't have the ability to wire up subqueries through expression evaluation -// primitives. Consequently, if the plan for a subquery comes out as a Join, -// we can immediately error out. -// -// Since findOrigin can itself be called from within a subquery, it has to assume -// that some of the external references may actually be pointing to an outer -// query. The isLocal response from the symtab is used to make sure that we -// only analyze symbols that point to the current symtab. -// -// If an expression has no references to the current query, then the left-most -// origin is chosen as the default. -func (pb *primitiveBuilder) findOrigin(expr sqlparser.Expr, reservedVars *sqlparser.ReservedVars) (pullouts []*pulloutSubquery, origin logicalPlan, pushExpr sqlparser.Expr, err error) { - // highestOrigin tracks the highest origin referenced by the expression. - // Default is the first. - highestOrigin := first(pb.plan) - - // subqueries tracks the list of subqueries encountered. - var subqueries []subqueryInfo - - // constructsMap tracks the sub-construct in which a subquery - // occurred. The construct type decides on how the query gets - // pulled out. - constructsMap := make(map[*sqlparser.Subquery]sqlparser.Expr) - - err = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - switch node := node.(type) { - case *sqlparser.ColName: - newOrigin, isLocal, err := pb.st.Find(node) - if err != nil { - return false, err - } - if isLocal && newOrigin.Order() > highestOrigin.Order() { - highestOrigin = newOrigin - } - case *sqlparser.ComparisonExpr: - if node.Operator == sqlparser.InOp || node.Operator == sqlparser.NotInOp { - if sq, ok := node.Right.(*sqlparser.Subquery); ok { - constructsMap[sq] = node - } - } - case *sqlparser.ExistsExpr: - constructsMap[node.Subquery] = node - case *sqlparser.Subquery: - spb := newPrimitiveBuilder(pb.vschema, pb.jt) - switch stmt := node.Select.(type) { - case *sqlparser.Select: - if err := spb.processSelect(stmt, reservedVars, pb.st, ""); err != nil { - return false, err - } - case *sqlparser.Union: - if err := spb.processUnion(stmt, reservedVars, pb.st); err != nil { - return false, err - } - default: - return false, vterrors.VT13001(fmt.Sprintf("unexpected SELECT type: %T", node)) - } - sqi := subqueryInfo{ - ast: node, - plan: spb.plan, - } - for _, extern := range spb.st.Externs { - // No error expected. These are resolved externs. - newOrigin, isLocal, _ := pb.st.Find(extern) - if !isLocal { - continue - } - if highestOrigin.Order() < newOrigin.Order() { - highestOrigin = newOrigin - } - if sqi.origin == nil { - sqi.origin = newOrigin - } else if sqi.origin.Order() < newOrigin.Order() { - sqi.origin = newOrigin - } - } - subqueries = append(subqueries, sqi) - return false, nil - } - return true, nil - }, expr) - if err != nil { - return nil, nil, nil, err - } - - highestRoute, _ := highestOrigin.(*route) - for _, sqi := range subqueries { - subroute, _ := sqi.plan.(*route) - if highestRoute != nil && subroute != nil && highestRoute.MergeSubquery(pb, subroute) { - continue - } - if sqi.origin != nil { - return nil, nil, nil, vterrors.VT12001("cross-shard correlated subquery") - } - - sqName, hasValues := pb.jt.GenerateSubqueryVars() - construct, ok := constructsMap[sqi.ast] - if !ok { - // (subquery) -> :_sq - expr = sqlparser.ReplaceExpr(expr, sqi.ast, sqlparser.NewArgument(sqName)) - pullouts = append(pullouts, newPulloutSubquery(popcode.PulloutValue, sqName, hasValues, sqi.plan)) - continue - } - switch construct := construct.(type) { - case *sqlparser.ComparisonExpr: - if construct.Operator == sqlparser.InOp { - // a in (subquery) -> (:__sq_has_values = 1 and (a in ::__sq)) - right := &sqlparser.ComparisonExpr{ - Operator: construct.Operator, - Left: construct.Left, - Right: sqlparser.ListArg(sqName), - } - left := &sqlparser.ComparisonExpr{ - Left: sqlparser.NewArgument(hasValues), - Operator: sqlparser.EqualOp, - Right: sqlparser.NewIntLiteral("1"), - } - newExpr := &sqlparser.AndExpr{ - Left: left, - Right: right, - } - expr = sqlparser.ReplaceExpr(expr, construct, newExpr) - pullouts = append(pullouts, newPulloutSubquery(popcode.PulloutIn, sqName, hasValues, sqi.plan)) - } else { - // a not in (subquery) -> (:__sq_has_values = 0 or (a not in ::__sq)) - left := &sqlparser.ComparisonExpr{ - Left: sqlparser.NewArgument(hasValues), - Operator: sqlparser.EqualOp, - Right: sqlparser.NewIntLiteral("0"), - } - right := &sqlparser.ComparisonExpr{ - Operator: construct.Operator, - Left: construct.Left, - Right: sqlparser.ListArg(sqName), - } - newExpr := &sqlparser.OrExpr{ - Left: left, - Right: right, - } - expr = sqlparser.ReplaceExpr(expr, construct, newExpr) - pullouts = append(pullouts, newPulloutSubquery(popcode.PulloutNotIn, sqName, hasValues, sqi.plan)) - } - case *sqlparser.ExistsExpr: - // exists (subquery) -> :__sq_has_values - expr = sqlparser.ReplaceExpr(expr, construct, sqlparser.NewArgument(hasValues)) - pullouts = append(pullouts, newPulloutSubquery(popcode.PulloutExists, sqName, hasValues, sqi.plan)) - } - } - return pullouts, highestOrigin, expr, nil -} - -var dummyErr = vterrors.VT13001("dummy") - -func hasSubquery(node sqlparser.SQLNode) bool { - has := false - _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - switch node.(type) { - case *sqlparser.DerivedTable, *sqlparser.Subquery: - has = true - return false, dummyErr - } - return true, nil - }, node) - return has -} - -func (pb *primitiveBuilder) finalizeUnshardedDMLSubqueries(reservedVars *sqlparser.ReservedVars, nodes ...sqlparser.SQLNode) (bool, []*vindexes.Table) { - var keyspace string - var tables []*vindexes.Table - if rb, ok := pb.plan.(*route); ok { - keyspace = rb.eroute.Keyspace.Name - } else { - // This code is unreachable because the caller checks. - return false, nil - } - - for _, node := range nodes { - samePlan := true - inSubQuery := false - _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - switch nodeType := node.(type) { - case *sqlparser.Subquery, *sqlparser.Insert: - inSubQuery = true - return true, nil - case *sqlparser.Select: - if !inSubQuery { - return true, nil - } - spb := newPrimitiveBuilder(pb.vschema, pb.jt) - if err := spb.processSelect(nodeType, reservedVars, pb.st, ""); err != nil { - samePlan = false - return false, err - } - innerRoute, ok := spb.plan.(*route) - if !ok { - samePlan = false - return false, dummyErr - } - if innerRoute.eroute.Keyspace.Name != keyspace { - samePlan = false - return false, dummyErr - } - for _, sub := range innerRoute.substitutions { - *sub.oldExpr = *sub.newExpr - } - spbTables, err := spb.st.AllVschemaTableNames() - if err != nil { - return false, err - } - tables = append(tables, spbTables...) - case *sqlparser.Union: - if !inSubQuery { - return true, nil - } - spb := newPrimitiveBuilder(pb.vschema, pb.jt) - if err := spb.processUnion(nodeType, reservedVars, pb.st); err != nil { - samePlan = false - return false, err - } - innerRoute, ok := spb.plan.(*route) - if !ok { - samePlan = false - return false, dummyErr - } - if innerRoute.eroute.Keyspace.Name != keyspace { - samePlan = false - return false, dummyErr - } - } - - return true, nil - }, node) - if !samePlan { - return false, nil - } - } - return true, tables -} - -func valEqual(a, b sqlparser.Expr) bool { - switch a := a.(type) { - case *sqlparser.ColName: - if b, ok := b.(*sqlparser.ColName); ok { - return a.Metadata == b.Metadata - } - case *sqlparser.Argument: - b, ok := b.(*sqlparser.Argument) - if !ok { - return false - } - return a.Name == b.Name - case *sqlparser.Literal: - b, ok := b.(*sqlparser.Literal) - if !ok { - return false - } - switch a.Type { - case sqlparser.StrVal: - switch b.Type { - case sqlparser.StrVal: - return a.Val == b.Val - case sqlparser.HexVal: - return hexEqual(b, a) - } - case sqlparser.HexVal: - return hexEqual(a, b) - case sqlparser.IntVal: - if b.Type == (sqlparser.IntVal) { - return a.Val == b.Val - } - } - } - return false -} - -func hexEqual(a, b *sqlparser.Literal) bool { - v, err := a.HexDecode() - if err != nil { - return false - } - switch b.Type { - case sqlparser.StrVal: - return bytes.Equal(v, b.Bytes()) - case sqlparser.HexVal: - v2, err := b.HexDecode() - if err != nil { - return false - } - return bytes.Equal(v, v2) - } - return false -} diff --git a/go/vt/vtgate/planbuilder/expr_test.go b/go/vt/vtgate/planbuilder/expr_test.go deleted file mode 100644 index b59bd034810..00000000000 --- a/go/vt/vtgate/planbuilder/expr_test.go +++ /dev/null @@ -1,104 +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 planbuilder - -import ( - "testing" - - "vitess.io/vitess/go/vt/sqlparser" -) - -func TestValEqual(t *testing.T) { - c1 := &column{} - c2 := &column{} - testcases := []struct { - in1, in2 sqlparser.Expr - out bool - }{{ - in1: &sqlparser.ColName{Metadata: c1, Name: sqlparser.NewIdentifierCI("c1")}, - in2: &sqlparser.ColName{Metadata: c1, Name: sqlparser.NewIdentifierCI("c1")}, - out: true, - }, { - // Objects that have the same name need not be the same because - // they might have appeared in different scopes and could have - // resolved to different columns. - in1: &sqlparser.ColName{Metadata: c1, Name: sqlparser.NewIdentifierCI("c1")}, - in2: &sqlparser.ColName{Metadata: c2, Name: sqlparser.NewIdentifierCI("c1")}, - out: false, - }, { - in1: sqlparser.NewArgument("aa"), - in2: &sqlparser.ColName{Metadata: c1, Name: sqlparser.NewIdentifierCI("c1")}, - out: false, - }, { - in1: sqlparser.NewArgument("aa"), - in2: sqlparser.NewArgument("aa"), - out: true, - }, { - in1: sqlparser.NewArgument("aa"), - in2: sqlparser.NewArgument("bb"), - }, { - in1: sqlparser.NewStrLiteral("aa"), - in2: sqlparser.NewStrLiteral("aa"), - out: true, - }, { - in1: sqlparser.NewStrLiteral("11"), - in2: sqlparser.NewHexLiteral("3131"), - out: true, - }, { - in1: sqlparser.NewHexLiteral("3131"), - in2: sqlparser.NewStrLiteral("11"), - out: true, - }, { - in1: sqlparser.NewHexLiteral("3131"), - in2: sqlparser.NewHexLiteral("3131"), - out: true, - }, { - in1: sqlparser.NewHexLiteral("3131"), - in2: sqlparser.NewHexLiteral("3132"), - out: false, - }, { - in1: sqlparser.NewHexLiteral("313"), - in2: sqlparser.NewHexLiteral("3132"), - out: false, - }, { - in1: sqlparser.NewHexLiteral("3132"), - in2: sqlparser.NewHexLiteral("313"), - out: false, - }, { - in1: sqlparser.NewIntLiteral("313"), - in2: sqlparser.NewHexLiteral("3132"), - out: false, - }, { - in1: sqlparser.NewHexLiteral("3132"), - in2: sqlparser.NewIntLiteral("313"), - out: false, - }, { - in1: sqlparser.NewIntLiteral("313"), - in2: sqlparser.NewIntLiteral("313"), - out: true, - }, { - in1: sqlparser.NewIntLiteral("313"), - in2: sqlparser.NewIntLiteral("314"), - out: false, - }} - for _, tc := range testcases { - out := valEqual(tc.in1, tc.in2) - if out != tc.out { - t.Errorf("valEqual(%#v, %#v): %v, want %v", tc.in1, tc.in2, out, tc.out) - } - } -} diff --git a/go/vt/vtgate/planbuilder/fallback_planner.go b/go/vt/vtgate/planbuilder/fallback_planner.go deleted file mode 100644 index 8b76efb2a21..00000000000 --- a/go/vt/vtgate/planbuilder/fallback_planner.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - "fmt" - - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - "vitess.io/vitess/go/vt/sqlparser" -) - -type fallbackPlanner struct { - primary, fallback stmtPlanner -} - -var _ stmtPlanner = (*fallbackPlanner)(nil).plan - -func (fp *fallbackPlanner) safePrimary(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (res *planResult, err error) { - defer func() { - // if the primary planner panics, we want to catch it here so we can fall back - if r := recover(); r != nil { - err = fmt.Errorf("%v", r) // not using vterror since this will only be used for logging - } - }() - res, err = fp.primary(stmt, reservedVars, vschema) - return -} - -func (fp *fallbackPlanner) plan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - res, err := fp.safePrimary(sqlparser.CloneStatement(stmt), reservedVars, vschema) - if err != nil { - return fp.fallback(stmt, reservedVars, vschema) - } - return res, nil -} diff --git a/go/vt/vtgate/planbuilder/fallback_planner_test.go b/go/vt/vtgate/planbuilder/fallback_planner_test.go deleted file mode 100644 index d0110f72428..00000000000 --- a/go/vt/vtgate/planbuilder/fallback_planner_test.go +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - "fmt" - "testing" - - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - "github.com/stretchr/testify/assert" - - "vitess.io/vitess/go/vt/sqlparser" - - "vitess.io/vitess/go/vt/vtgate/engine" -) - -type testPlanner struct { - panic any - err error - res engine.Primitive - messWithAST func(sqlparser.Statement) - called bool -} - -var _ stmtPlanner = (*testPlanner)(nil).plan - -func (tp *testPlanner) plan(statement sqlparser.Statement, vars *sqlparser.ReservedVars, schema plancontext.VSchema) (*planResult, error) { - tp.called = true - if tp.panic != nil { - panic(tp.panic) - } - if tp.messWithAST != nil { - tp.messWithAST(statement) - } - return newPlanResult(tp.res), tp.err -} - -func TestFallbackPlanner(t *testing.T) { - a := &testPlanner{} - b := &testPlanner{} - fb := &fallbackPlanner{ - primary: a.plan, - fallback: b.plan, - } - - stmt := &sqlparser.Select{} - var vschema plancontext.VSchema - - // first planner succeeds - _, _ = fb.plan(stmt, nil, vschema) - assert.True(t, a.called) - assert.False(t, b.called) - a.called = false - - // first planner errors - a.err = fmt.Errorf("fail") - _, _ = fb.plan(stmt, nil, vschema) - assert.True(t, a.called) - assert.True(t, b.called) - - a.called = false - b.called = false - - // first planner panics - a.panic = "oh noes" - _, _ = fb.plan(stmt, nil, vschema) - assert.True(t, a.called) - assert.True(t, b.called) -} - -func TestFallbackClonesBeforePlanning(t *testing.T) { - a := &testPlanner{ - messWithAST: func(statement sqlparser.Statement) { - sel := statement.(*sqlparser.Select) - sel.SelectExprs = nil - }, - } - b := &testPlanner{} - fb := &fallbackPlanner{ - primary: a.plan, - fallback: b.plan, - } - - stmt := &sqlparser.Select{ - SelectExprs: sqlparser.SelectExprs{&sqlparser.StarExpr{}}, - } - var vschema plancontext.VSchema - - // first planner succeeds - _, _ = fb.plan(stmt, nil, vschema) - - assert.NotNilf(t, stmt.SelectExprs, "should not have changed") -} diff --git a/go/vt/vtgate/planbuilder/filtering.go b/go/vt/vtgate/planbuilder/filtering.go deleted file mode 100644 index 429bdf93cc2..00000000000 --- a/go/vt/vtgate/planbuilder/filtering.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -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 planbuilder - -import ( - "fmt" - - "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/operators" -) - -// planFilter solves this particular expression, either by pushing it down to a child or changing this logicalPlan -func planFilter(pb *primitiveBuilder, input logicalPlan, filter sqlparser.Expr, whereType string, origin logicalPlan) (logicalPlan, error) { - switch node := input.(type) { - case *join: - isLeft := true - var in logicalPlan - if node.isOnLeft(origin.Order()) { - in = node.Left - } else { - if node.ejoin.Opcode == engine.LeftJoin { - return nil, vterrors.VT12001("cross-shard LEFT JOIN and WHERE clause") - } - isLeft = false - in = node.Right - } - - filtered, err := planFilter(pb, in, filter, whereType, origin) - if err != nil { - return nil, err - } - if isLeft { - node.Left = filtered - } else { - node.Right = filtered - } - return node, nil - - case *route: - sel := node.Select.(*sqlparser.Select) - switch whereType { - case sqlparser.WhereStr: - sel.AddWhere(filter) - case sqlparser.HavingStr: - sel.AddHaving(filter) - } - node.UpdatePlan(pb, filter) - return node, nil - case *pulloutSubquery: - plan, err := planFilter(pb, node.underlying, filter, whereType, origin) - if err != nil { - return nil, err - } - node.underlying = plan - return node, nil - case *vindexFunc: - return filterVindexFunc(node, filter) - case *simpleProjection: - return nil, vterrors.VT12001("filtering on results of cross-shard subquery") - case *orderedAggregate: - return nil, vterrors.VT12001("filtering on results of aggregates") - } - - return nil, vterrors.VT13001(fmt.Sprintf("unreachable %T.filtering", input)) -} - -func filterVindexFunc(node *vindexFunc, filter sqlparser.Expr) (logicalPlan, error) { - if node.eVindexFunc.Opcode != engine.VindexNone { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (multiple filters)") - } - - // Check LHS. - comparison, ok := filter.(*sqlparser.ComparisonExpr) - if !ok { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (not a comparison)") - } - if comparison.Operator != sqlparser.EqualOp && comparison.Operator != sqlparser.InOp { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (not equality)") - } - colname, ok := comparison.Left.(*sqlparser.ColName) - if !ok { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (lhs is not a column)") - } - if !colname.Name.EqualString("id") { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (lhs is not id)") - } - - // Check RHS. - // We have to check before calling NewPlanValue because NewPlanValue allows lists also. - if !sqlparser.IsValue(comparison.Right) && !sqlparser.IsSimpleTuple(comparison.Right) { - return nil, vterrors.VT12001(operators.VindexUnsupported + " (rhs is not a value)") - } - var err error - node.eVindexFunc.Value, err = evalengine.Translate(comparison.Right, nil) - if err != nil { - return nil, vterrors.VT12001(fmt.Sprintf("%s: %v", operators.VindexUnsupported, err)) - } - - node.eVindexFunc.Opcode = engine.VindexMap - return node, nil -} diff --git a/go/vt/vtgate/planbuilder/from.go b/go/vt/vtgate/planbuilder/from.go deleted file mode 100644 index 669b92346e7..00000000000 --- a/go/vt/vtgate/planbuilder/from.go +++ /dev/null @@ -1,426 +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 planbuilder - -import ( - "fmt" - "sort" - "strings" - - "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/vt/vtgate/evalengine" - - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -// This file has functions to analyze the FROM clause. - -// processDMLTable analyzes the FROM clause for DMLs and returns a route. -func (pb *primitiveBuilder) processDMLTable(tableExprs sqlparser.TableExprs, reservedVars *sqlparser.ReservedVars, where sqlparser.Expr) (*route, error) { - if err := pb.processTableExprs(tableExprs, reservedVars, where); err != nil { - return nil, err - } - rb, ok := pb.plan.(*route) - if !ok { - return nil, vterrors.VT12001("multi-shard or vindex write statement") - } - for _, sub := range rb.substitutions { - *sub.oldExpr = *sub.newExpr - } - return rb, nil -} - -// processTableExprs analyzes the FROM clause. It produces a logicalPlan -// with all the routes identified. -func (pb *primitiveBuilder) processTableExprs(tableExprs sqlparser.TableExprs, reservedVars *sqlparser.ReservedVars, where sqlparser.Expr) error { - if len(tableExprs) == 1 { - return pb.processTableExpr(tableExprs[0], reservedVars, where) - } - - if err := pb.processTableExpr(tableExprs[0], reservedVars, where); err != nil { - return err - } - rpb := newPrimitiveBuilder(pb.vschema, pb.jt) - if err := rpb.processTableExprs(tableExprs[1:], reservedVars, where); err != nil { - return err - } - return pb.join(rpb, nil, reservedVars, where) -} - -// processTableExpr produces a logicalPlan subtree for the given TableExpr. -func (pb *primitiveBuilder) processTableExpr(tableExpr sqlparser.TableExpr, reservedVars *sqlparser.ReservedVars, where sqlparser.Expr) error { - switch tableExpr := tableExpr.(type) { - case *sqlparser.AliasedTableExpr: - return pb.processAliasedTable(tableExpr, reservedVars) - case *sqlparser.ParenTableExpr: - err := pb.processTableExprs(tableExpr.Exprs, reservedVars, where) - // If it's a route, preserve the parenthesis so things - // don't associate differently when more things are pushed - // into it. FROM a, (b, c) should not become FROM a, b, c. - if rb, ok := pb.plan.(*route); ok { - sel, ok := rb.Select.(*sqlparser.Select) - if !ok { - return vterrors.VT13002(sqlparser.String(rb.Select)) - } - - sel.From = sqlparser.TableExprs{&sqlparser.ParenTableExpr{Exprs: sel.From}} - } - return err - case *sqlparser.JoinTableExpr: - return pb.processJoin(tableExpr, reservedVars, where) - case *sqlparser.JSONTableExpr: - return vterrors.VT12001("JSON_TABLE expressions") - } - return vterrors.VT13001(fmt.Sprintf("unexpected table expression type: %T", tableExpr)) -} - -// processAliasedTable produces a logicalPlan subtree for the given AliasedTableExpr. -// If the expression is a subquery, then the primitive will create a table -// for it in the symtab. If the subquery is a route, then we build a route -// primitive with the subquery in the From clause, because a route is more -// versatile than a subquery. If a subquery becomes a route, then any result -// columns that represent underlying vindex columns are also exposed as -// vindex columns. -func (pb *primitiveBuilder) processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, reservedVars *sqlparser.ReservedVars) error { - if tableExpr.Columns != nil { - return vterrors.VT12001("column aliases in derived table") - } - switch expr := tableExpr.Expr.(type) { - case sqlparser.TableName: - return pb.buildTablePrimitive(tableExpr, expr) - case *sqlparser.DerivedTable: - if expr.Lateral { - return vterrors.VT12001("lateral derived tables") - } - spb := newPrimitiveBuilder(pb.vschema, pb.jt) - switch stmt := expr.Select.(type) { - case *sqlparser.Select: - if err := spb.processSelect(stmt, reservedVars, nil, ""); err != nil { - return err - } - case *sqlparser.Union: - if err := spb.processUnion(stmt, reservedVars, nil); err != nil { - return err - } - default: - return vterrors.VT13001(fmt.Sprintf("unexpected SELECT type: %T", stmt)) - } - - subroute, ok := spb.plan.(*route) - if !ok { - var err error - pb.plan, pb.st, err = newSimpleProjection(tableExpr.As, spb.plan) - if err != nil { - return err - } - pb.plan.Reorder(0) - return nil - } - - // Since a route is more versatile than a subquery, we - // build a route primitive that has the subquery in its - // FROM clause. This allows for other constructs to be - // later pushed into it. - rb, st := newRoute(&sqlparser.Select{From: []sqlparser.TableExpr{tableExpr}}) - rb.substitutions = subroute.substitutions - rb.condition = subroute.condition - rb.eroute = subroute.eroute - subroute.Redirect = rb - - // The subquery needs to be represented as a new logical table in the symtab. - // The new route will inherit the routeOptions of the underlying subquery. - // For this, we first build new vschema tables based on the columns returned - // by the subquery, and re-expose possible vindexes. When added to the symtab, - // a new set of column references will be generated against the new tables, - // and those vindex maps will be returned. They have to replace the old vindex - // maps of the inherited route options. - var tableNames []string - spbTables, err := spb.st.AllVschemaTableNames() - if err != nil { - return err - } - for _, table := range spbTables { - tableNames = append(tableNames, table.Name.String()) - } - sort.Strings(tableNames) - vschemaTable := &vindexes.Table{ - Keyspace: subroute.eroute.Keyspace, - Name: sqlparser.NewIdentifierCS(strings.Join(tableNames, ", ")), - } - for _, rc := range subroute.ResultColumns() { - if rc.column.vindex == nil { - continue - } - // Check if a colvindex of the same name already exists. - // Dups are not allowed in subqueries in this situation. - for _, colVindex := range vschemaTable.ColumnVindexes { - if colVindex.Columns[0].Equal(rc.alias) { - return vterrors.VT12001(fmt.Sprintf("duplicate column aliases: %v", rc.alias)) - } - } - vschemaTable.ColumnVindexes = append(vschemaTable.ColumnVindexes, &vindexes.ColumnVindex{ - Columns: []sqlparser.IdentifierCI{rc.alias}, - Vindex: rc.column.vindex, - }) - } - if err := st.AddVSchemaTable(sqlparser.TableName{Name: tableExpr.As}, vschemaTable, rb); err != nil { - return err - } - - pb.plan, pb.st = rb, st - return nil - } - return vterrors.VT13001(fmt.Sprintf("unexpected table expression type: %T", tableExpr.Expr)) -} - -// buildTablePrimitive builds a primitive based on the table name. -func (pb *primitiveBuilder) buildTablePrimitive(tableExpr *sqlparser.AliasedTableExpr, tableName sqlparser.TableName) error { - alias := tableName - if !tableExpr.As.IsEmpty() { - alias = sqlparser.TableName{Name: tableExpr.As} - } - sel := &sqlparser.Select{From: sqlparser.TableExprs([]sqlparser.TableExpr{tableExpr})} - - if sqlparser.SystemSchema(tableName.Qualifier.String()) { - ks, err := pb.vschema.AnyKeyspace() - if err != nil { - return err - } - rb, st := newRoute(sel) - rb.eroute = engine.NewSimpleRoute(engine.DBA, ks) - rb.eroute.TableName = sqlparser.String(tableName) - pb.plan, pb.st = rb, st - // Add the table to symtab - return st.AddTable(&table{ - alias: alias, - origin: rb, - }) - } - - vschemaTable, vindex, _, destTableType, destTarget, err := pb.vschema.FindTableOrVindex(tableName) - if err != nil { - return err - } - if vindex != nil { - single, ok := vindex.(vindexes.SingleColumn) - if !ok { - return vterrors.VT12001("multi-column vindexes") - } - pb.plan, pb.st = newVindexFunc(alias, single) - return nil - } - - sourceTable, err := pb.tryRedirectGen4InsertToSource(vschemaTable) - if err != nil { - return err - } - if sourceTable != nil { - vschemaTable = sourceTable - } - - rb, st := newRoute(sel) - pb.plan, pb.st = rb, st - if err := st.AddVSchemaTable(alias, vschemaTable, rb); err != nil { - return err - } - - sub := &tableSubstitution{ - oldExpr: tableExpr, - } - if tableExpr.As.IsEmpty() { - if tableName.Name != vschemaTable.Name { - // Table name does not match. Change and alias it to old name. - sub.newExpr = &sqlparser.AliasedTableExpr{ - Expr: sqlparser.TableName{Name: vschemaTable.Name}, - As: tableName.Name, - } - } - } else { - // Table is already aliased. - if tableName.Name != vschemaTable.Name { - // Table name does not match. Change it and reuse existing alias. - sub.newExpr = &sqlparser.AliasedTableExpr{ - Expr: sqlparser.TableName{Name: vschemaTable.Name}, - As: tableExpr.As, - } - } - } - if sub != nil && sub.newExpr != nil { - rb.substitutions = []*tableSubstitution{sub} - } - - var eroute *engine.Route - switch { - case vschemaTable.Type == vindexes.TypeSequence: - eroute = engine.NewSimpleRoute(engine.Next, vschemaTable.Keyspace) - case vschemaTable.Type == vindexes.TypeReference: - eroute = engine.NewSimpleRoute(engine.Reference, vschemaTable.Keyspace) - case !vschemaTable.Keyspace.Sharded: - eroute = engine.NewSimpleRoute(engine.Unsharded, vschemaTable.Keyspace) - case vschemaTable.Pinned == nil: - eroute = engine.NewSimpleRoute(engine.Scatter, vschemaTable.Keyspace) - eroute.TargetDestination = destTarget - eroute.TargetTabletType = destTableType - default: - // Pinned tables have their keyspace ids already assigned. - // Use the Binary vindex, which is the identity function - // for keyspace id. - eroute = engine.NewSimpleRoute(engine.EqualUnique, vschemaTable.Keyspace) - vindex, _ = vindexes.CreateVindex("binary", "binary", nil) - eroute.Vindex = vindex - lit := evalengine.NewLiteralString(vschemaTable.Pinned, collations.TypedCollation{}) - eroute.Values = []evalengine.Expr{lit} - } - eroute.TableName = sqlparser.String(vschemaTable.Name) - rb.eroute = eroute - - return nil -} - -// processJoin produces a logicalPlan subtree for the given Join. -// If the left and right nodes can be part of the same route, -// then it's a route. Otherwise, it's a join. -func (pb *primitiveBuilder) processJoin(ajoin *sqlparser.JoinTableExpr, reservedVars *sqlparser.ReservedVars, where sqlparser.Expr) error { - switch ajoin.Join { - case sqlparser.NormalJoinType, sqlparser.StraightJoinType, sqlparser.LeftJoinType: - case sqlparser.RightJoinType: - convertToLeftJoin(ajoin) - default: - return vterrors.VT12001(ajoin.Join.ToString()) - } - if err := pb.processTableExpr(ajoin.LeftExpr, reservedVars, where); err != nil { - return err - } - rpb := newPrimitiveBuilder(pb.vschema, pb.jt) - if err := rpb.processTableExpr(ajoin.RightExpr, reservedVars, where); err != nil { - return err - } - return pb.join(rpb, ajoin, reservedVars, where) -} - -// If the primitiveBuilder context is a Gen4 planner, the statement is an -// INSERT, and the vschema table is a reference with a valid source reference, -// then redirect the INSERT back to the source. -func (pb *primitiveBuilder) tryRedirectGen4InsertToSource(vschemaTable *vindexes.Table) (*vindexes.Table, error) { - if pb.stmt == nil { - return nil, nil - } - if _, ok := pb.stmt.(*sqlparser.Insert); !ok { - return nil, nil - } - if pb.vschema.Planner() == querypb.ExecuteOptions_V3 { - return nil, nil - } - if vschemaTable.Type != vindexes.TypeReference || vschemaTable.Source == nil { - return nil, nil - } - vschemaTable, _, _, _, _, err := pb.vschema.FindTableOrVindex(vschemaTable.Source.TableName) - return vschemaTable, err -} - -// convertToLeftJoin converts a right join into a left join. -func convertToLeftJoin(ajoin *sqlparser.JoinTableExpr) { - newRHS := ajoin.LeftExpr - // If the LHS is a join, we have to parenthesize it. - // Otherwise, it can be used as is. - if _, ok := newRHS.(*sqlparser.JoinTableExpr); ok { - newRHS = &sqlparser.ParenTableExpr{ - Exprs: sqlparser.TableExprs{newRHS}, - } - } - ajoin.LeftExpr, ajoin.RightExpr = ajoin.RightExpr, newRHS - ajoin.Join = sqlparser.LeftJoinType -} - -func (pb *primitiveBuilder) join(rpb *primitiveBuilder, ajoin *sqlparser.JoinTableExpr, reservedVars *sqlparser.ReservedVars, where sqlparser.Expr) error { - // Merge the symbol tables. In the case of a left join, we have to - // ideally create new symbols that originate from the join primitive. - // However, this is not worth it for now, because the Push functions - // verify that only valid constructs are passed through in case of left join. - err := pb.st.Merge(rpb.st) - if err != nil { - return err - } - - lRoute, leftIsRoute := pb.plan.(*route) - rRoute, rightIsRoute := rpb.plan.(*route) - if !leftIsRoute || !rightIsRoute { - return newJoin(pb, rpb, ajoin, reservedVars) - } - - // Try merging the routes. - if !lRoute.JoinCanMerge(pb, rRoute, ajoin, where) { - return newJoin(pb, rpb, ajoin, reservedVars) - } - - if lRoute.eroute.Opcode == engine.Reference { - // Swap the conditions & eroutes, and then merge. - lRoute.condition, rRoute.condition = rRoute.condition, lRoute.condition - lRoute.eroute, rRoute.eroute = rRoute.eroute, lRoute.eroute - } - lRoute.substitutions = append(lRoute.substitutions, rRoute.substitutions...) - rRoute.Redirect = lRoute - - // Merge the AST. - sel, ok := lRoute.Select.(*sqlparser.Select) - if !ok { - return vterrors.VT13002(sqlparser.String(lRoute.Select)) - } - if ajoin == nil { - rhsSel, ok := rRoute.Select.(*sqlparser.Select) - if !ok { - return vterrors.VT13002(sqlparser.String(rRoute.Select)) - } - sel.From = append(sel.From, rhsSel.From...) - } else { - sel.From = sqlparser.TableExprs{ajoin} - } - // join table name - if lRoute.eroute.TableName != rRoute.eroute.TableName { - lRoute.eroute.TableName = strings.Join([]string{lRoute.eroute.TableName, rRoute.eroute.TableName}, ", ") - } - - // join sysTableNames - for tableName, expr := range rRoute.eroute.SysTableTableName { - _, ok := lRoute.eroute.SysTableTableName[tableName] - if !ok { - lRoute.eroute.SysTableTableName[tableName] = expr - } - } - - // Since the routes have merged, set st.singleRoute to point at - // the merged route. - pb.st.singleRoute = lRoute - if ajoin == nil { - return nil - } - pullouts, _, expr, err := pb.findOrigin(ajoin.Condition.On, reservedVars) - if err != nil { - return err - } - ajoin.Condition.On = expr - pb.addPullouts(pullouts) - for _, filter := range sqlparser.SplitAndExpression(nil, ajoin.Condition.On) { - lRoute.UpdatePlan(pb, filter) - } - return nil -} diff --git a/go/vt/vtgate/planbuilder/gen4_compare_v3_planner.go b/go/vt/vtgate/planbuilder/gen4_compare_v3_planner.go deleted file mode 100644 index 3165225db78..00000000000 --- a/go/vt/vtgate/planbuilder/gen4_compare_v3_planner.go +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - "context" - - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/engine" -) - -func gen4CompareV3Planner(query string) func(sqlparser.Statement, *sqlparser.ReservedVars, plancontext.VSchema) (*planResult, error) { - return func(statement sqlparser.Statement, vars *sqlparser.ReservedVars, ctxVSchema plancontext.VSchema) (*planResult, error) { - // we will be switching the planner version to Gen4 and V3 in order to - // create instructions using them, thus we make sure to switch back to - // the Gen4CompareV3 planner before exiting this method. - defer ctxVSchema.SetPlannerVersion(Gen4CompareV3) - switch statement.(type) { - case *sqlparser.Select, *sqlparser.Union: - // These we can compare. Everything else we'll just use the Gen4 planner - default: - return planWithPlannerVersion(statement, vars, ctxVSchema, query, Gen4) - } - - // preliminary checks on the given statement - onlyGen4, hasOrderBy, err := preliminaryChecks(statement) - if err != nil { - return nil, err - } - - // plan statement using Gen4 - gen4Primitive, gen4Err := planWithPlannerVersion(statement, vars, ctxVSchema, query, Gen4) - - // if onlyGen4 is set to true or Gen4's instruction contain a lock primitive, - // we use only Gen4's primitive and exit early without using V3's. - // since lock primitives can imply the creation or deletion of locks, - // we want to execute them once using Gen4 to avoid the duplicated locks - // or double lock-releases. - if onlyGen4 || (gen4Primitive != nil && hasLockPrimitive(gen4Primitive.primitive)) { - return gen4Primitive, gen4Err - } - - // get V3's plan - v3Primitive, v3Err := planWithPlannerVersion(statement, vars, ctxVSchema, query, V3) - - // check potential errors from Gen4 and V3 - err = engine.CompareErrors(v3Err, gen4Err, "v3", "Gen4") - if err != nil { - return nil, err - } - - primitive := &engine.Gen4CompareV3{ - V3: v3Primitive.primitive, - Gen4: gen4Primitive.primitive, - HasOrderBy: hasOrderBy, - } - - return newPlanResult(primitive, gen4Primitive.tables...), nil - } -} - -func preliminaryChecks(statement sqlparser.Statement) (bool, bool, error) { - var onlyGen4, hasOrderBy bool - switch s := statement.(type) { - case *sqlparser.Union: - hasOrderBy = len(s.OrderBy) > 0 - - // walk through the union and search for select statements that have - // a next val select expression, in which case we need to only use - // the Gen4 planner instead of using both Gen4 and V3 to avoid unintended - // double-incrementation of sequence. - err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - if _, isNextVal := node.(*sqlparser.Nextval); isNextVal { - onlyGen4 = true - return false, nil - } - return true, nil - }, s) - if err != nil { - return false, false, err - } - case *sqlparser.Select: - hasOrderBy = len(s.OrderBy) > 0 - - for _, expr := range s.SelectExprs { - // we are not executing the plan a second time if the query is a select next val, - // since the first execution might increment the `next` value, results will almost - // always be different between v3 and Gen4. - if _, nextVal := expr.(*sqlparser.Nextval); nextVal { - onlyGen4 = true - break - } - } - } - return onlyGen4, hasOrderBy, nil -} - -func planWithPlannerVersion(statement sqlparser.Statement, vars *sqlparser.ReservedVars, ctxVSchema plancontext.VSchema, query string, version plancontext.PlannerVersion) (*planResult, error) { - ctxVSchema.SetPlannerVersion(version) - stmt := sqlparser.CloneStatement(statement) - return createInstructionFor(context.Background(), query, stmt, vars, ctxVSchema, false, false) -} - -// hasLockPrimitive recursively walks through the given primitive and its children -// to see if there are any engine.Lock primitive. -func hasLockPrimitive(primitive engine.Primitive) bool { - switch primitive.(type) { - case *engine.Lock: - return true - default: - for _, p := range primitive.Inputs() { - if hasLockPrimitive(p) { - return true - } - } - } - return false -} diff --git a/go/vt/vtgate/planbuilder/gen4_planner.go b/go/vt/vtgate/planbuilder/gen4_planner.go deleted file mode 100644 index de52b22b37a..00000000000 --- a/go/vt/vtgate/planbuilder/gen4_planner.go +++ /dev/null @@ -1,688 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - "fmt" - - 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" - "vitess.io/vitess/go/vt/vtgate/semantics" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -func gen4Planner(query string, plannerVersion querypb.ExecuteOptions_PlannerVersion) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - switch stmt := stmt.(type) { - case sqlparser.SelectStatement: - return gen4SelectStmtPlanner(query, plannerVersion, stmt, reservedVars, vschema) - case *sqlparser.Update: - return gen4UpdateStmtPlanner(plannerVersion, stmt, reservedVars, vschema) - case *sqlparser.Delete: - return gen4DeleteStmtPlanner(plannerVersion, stmt, reservedVars, vschema) - case *sqlparser.Insert: - return gen4InsertStmtPlanner(plannerVersion, stmt, reservedVars, vschema) - default: - return nil, vterrors.VT12001(fmt.Sprintf("%T", stmt)) - } - } -} - -func gen4SelectStmtPlanner( - query string, - plannerVersion querypb.ExecuteOptions_PlannerVersion, - stmt sqlparser.SelectStatement, - reservedVars *sqlparser.ReservedVars, - vschema plancontext.VSchema, -) (*planResult, error) { - switch node := stmt.(type) { - case *sqlparser.Select: - if node.With != nil { - return nil, vterrors.VT12001("WITH expression in SELECT statement") - } - case *sqlparser.Union: - if node.With != nil { - return nil, vterrors.VT12001("WITH expression in UNION statement") - } - } - - sel, isSel := stmt.(*sqlparser.Select) - if isSel { - // handle dual table for processing at vtgate. - p, err := handleDualSelects(sel, vschema) - if err != nil { - return nil, err - } - if p != nil { - used := "dual" - keyspace, ksErr := vschema.DefaultKeyspace() - if ksErr == nil { - // we are just getting the ks to log the correct table use. - // no need to fail this if we can't find the default keyspace - used = keyspace.Name + ".dual" - } - return newPlanResult(p, used), nil - } - - if sel.SQLCalcFoundRows && sel.Limit != nil { - return gen4planSQLCalcFoundRows(vschema, sel, query, reservedVars) - } - // if there was no limit, we can safely ignore the SQLCalcFoundRows directive - sel.SQLCalcFoundRows = false - } - - getPlan := func(selStatement sqlparser.SelectStatement) (logicalPlan, *semantics.SemTable, []string, error) { - return newBuildSelectPlan(selStatement, reservedVars, vschema, plannerVersion) - } - - plan, _, tablesUsed, err := getPlan(stmt) - if err != nil { - return nil, err - } - - if shouldRetryAfterPredicateRewriting(plan) { - // by transforming the predicates to CNF, the planner will sometimes find better plans - plan2, _, tablesUsed := gen4PredicateRewrite(stmt, getPlan) - if plan2 != nil { - return newPlanResult(plan2.Primitive(), tablesUsed...), nil - } - } - - primitive := plan.Primitive() - if !isSel { - return newPlanResult(primitive, tablesUsed...), nil - } - - // this is done because engine.Route doesn't handle the empty result well - // if it doesn't find a shard to send the query to. - // All other engine primitives can handle this, so we only need it when - // Route is the last (and only) instruction before the user sees a result - if isOnlyDual(sel) || (len(sel.GroupBy) == 0 && sel.SelectExprs.AllAggregation()) { - switch prim := primitive.(type) { - case *engine.Route: - prim.NoRoutesSpecialHandling = true - case *engine.VindexLookup: - prim.SendTo.NoRoutesSpecialHandling = true - } - } - return newPlanResult(primitive, tablesUsed...), nil -} - -func gen4planSQLCalcFoundRows(vschema plancontext.VSchema, sel *sqlparser.Select, query string, reservedVars *sqlparser.ReservedVars) (*planResult, error) { - ksName := "" - if ks, _ := vschema.DefaultKeyspace(); ks != nil { - ksName = ks.Name - } - semTable, err := semantics.Analyze(sel, ksName, vschema) - if err != nil { - return nil, err - } - // record any warning as planner warning. - vschema.PlannerWarning(semTable.Warning) - - plan, tablesUsed, err := buildSQLCalcFoundRowsPlan(query, sel, reservedVars, vschema, planSelectGen4) - if err != nil { - return nil, err - } - return newPlanResult(plan.Primitive(), tablesUsed...), nil -} - -func planSelectGen4(reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, sel *sqlparser.Select) (*jointab, logicalPlan, []string, error) { - plan, _, tablesUsed, err := newBuildSelectPlan(sel, reservedVars, vschema, 0) - if err != nil { - return nil, nil, nil, err - } - return nil, plan, tablesUsed, nil -} - -func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (logicalPlan, *semantics.SemTable, []string, error)) (logicalPlan, *semantics.SemTable, []string) { - rewritten, isSel := sqlparser.RewritePredicate(stmt).(sqlparser.SelectStatement) - if !isSel { - // Fail-safe code, should never happen - return nil, nil, nil - } - plan2, st, op, err := getPlan(rewritten) - if err == nil && !shouldRetryAfterPredicateRewriting(plan2) { - // we only use this new plan if it's better than the old one we got - return plan2, st, op - } - return nil, nil, nil -} - -func newBuildSelectPlan( - selStmt sqlparser.SelectStatement, - reservedVars *sqlparser.ReservedVars, - vschema plancontext.VSchema, - version querypb.ExecuteOptions_PlannerVersion, -) (plan logicalPlan, semTable *semantics.SemTable, tablesUsed []string, err error) { - ksName := "" - if ks, _ := vschema.DefaultKeyspace(); ks != nil { - ksName = ks.Name - } - semTable, err = semantics.Analyze(selStmt, ksName, vschema) - if err != nil { - return nil, nil, nil, err - } - // record any warning as planner warning. - vschema.PlannerWarning(semTable.Warning) - - ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) - - if ks, _ := semTable.SingleUnshardedKeyspace(); ks != nil { - plan, tablesUsed, err = selectUnshardedShortcut(ctx, selStmt, ks) - if err != nil { - return nil, nil, nil, err - } - plan = pushCommentDirectivesOnPlan(plan, selStmt) - return plan, semTable, tablesUsed, err - } - - // From this point on, we know it is not an unsharded query and return the NotUnshardedErr if there is any - if semTable.NotUnshardedErr != nil { - return nil, nil, nil, semTable.NotUnshardedErr - } - - err = queryRewrite(semTable, reservedVars, selStmt) - if err != nil { - return nil, nil, nil, err - } - - op, err := operators.PlanQuery(ctx, selStmt) - if err != nil { - return nil, nil, nil, err - } - - plan, err = transformToLogicalPlan(ctx, op, true) - if err != nil { - return nil, nil, nil, err - } - - optimizePlan(plan) - - sel, isSel := selStmt.(*sqlparser.Select) - if isSel { - if err = setMiscFunc(plan, sel); err != nil { - return nil, nil, nil, err - } - } - - if err = plan.WireupGen4(ctx); err != nil { - return nil, nil, nil, err - } - - plan = pushCommentDirectivesOnPlan(plan, selStmt) - - return plan, semTable, operators.TablesUsed(op), nil -} - -// optimizePlan removes unnecessary simpleProjections that have been created while planning -func optimizePlan(plan logicalPlan) { - for _, lp := range plan.Inputs() { - optimizePlan(lp) - } - - this, ok := plan.(*simpleProjection) - if !ok { - return - } - - input, ok := this.input.(*simpleProjection) - if !ok { - return - } - - for i, col := range this.eSimpleProj.Cols { - this.eSimpleProj.Cols[i] = input.eSimpleProj.Cols[col] - } - this.input = input.input -} - -func gen4UpdateStmtPlanner( - version querypb.ExecuteOptions_PlannerVersion, - updStmt *sqlparser.Update, - reservedVars *sqlparser.ReservedVars, - vschema plancontext.VSchema, -) (*planResult, error) { - if updStmt.With != nil { - return nil, vterrors.VT12001("WITH expression in UPDATE statement") - } - - ksName := "" - if ks, _ := vschema.DefaultKeyspace(); ks != nil { - ksName = ks.Name - } - semTable, err := semantics.Analyze(updStmt, ksName, vschema) - if err != nil { - return nil, err - } - // record any warning as planner warning. - vschema.PlannerWarning(semTable.Warning) - - err = rewriteRoutedTables(updStmt, vschema) - if err != nil { - return nil, err - } - - if ks, tables := semTable.SingleUnshardedKeyspace(); ks != nil { - plan := updateUnshardedShortcut(updStmt, ks, tables) - plan = pushCommentDirectivesOnPlan(plan, updStmt) - return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil - } - - if semTable.NotUnshardedErr != nil { - return nil, semTable.NotUnshardedErr - } - - err = queryRewrite(semTable, reservedVars, updStmt) - if err != nil { - return nil, err - } - - ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) - - op, err := operators.PlanQuery(ctx, updStmt) - if err != nil { - return nil, err - } - - plan, err := transformToLogicalPlan(ctx, op, true) - if err != nil { - return nil, err - } - - plan = pushCommentDirectivesOnPlan(plan, updStmt) - - setLockOnAllSelect(plan) - - if err := plan.WireupGen4(ctx); err != nil { - return nil, err - } - - return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil -} - -func updateUnshardedShortcut(stmt *sqlparser.Update, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { - edml := engine.NewDML() - edml.Keyspace = ks - edml.Table = tables - edml.Opcode = engine.Unsharded - edml.Query = generateQuery(stmt) - return &primitiveWrapper{prim: &engine.Update{DML: edml}} -} - -func gen4DeleteStmtPlanner( - version querypb.ExecuteOptions_PlannerVersion, - deleteStmt *sqlparser.Delete, - reservedVars *sqlparser.ReservedVars, - vschema plancontext.VSchema, -) (*planResult, error) { - if deleteStmt.With != nil { - return nil, vterrors.VT12001("WITH expression in DELETE statement") - } - - var err error - if len(deleteStmt.TableExprs) == 1 && len(deleteStmt.Targets) == 1 { - deleteStmt, err = rewriteSingleTbl(deleteStmt) - if err != nil { - return nil, err - } - } - - ksName := "" - if ks, _ := vschema.DefaultKeyspace(); ks != nil { - ksName = ks.Name - } - semTable, err := semantics.Analyze(deleteStmt, ksName, vschema) - if err != nil { - return nil, err - } - - // record any warning as planner warning. - vschema.PlannerWarning(semTable.Warning) - err = rewriteRoutedTables(deleteStmt, vschema) - if err != nil { - return nil, err - } - - if ks, tables := semTable.SingleUnshardedKeyspace(); ks != nil { - plan := deleteUnshardedShortcut(deleteStmt, ks, tables) - plan = pushCommentDirectivesOnPlan(plan, deleteStmt) - return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil - } - - if err := checkIfDeleteSupported(deleteStmt, semTable); err != nil { - return nil, err - } - - err = queryRewrite(semTable, reservedVars, deleteStmt) - if err != nil { - return nil, err - } - - ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) - op, err := operators.PlanQuery(ctx, deleteStmt) - if err != nil { - return nil, err - } - - plan, err := transformToLogicalPlan(ctx, op, true) - if err != nil { - return nil, err - } - - plan = pushCommentDirectivesOnPlan(plan, deleteStmt) - - setLockOnAllSelect(plan) - - if err := plan.WireupGen4(ctx); err != nil { - return nil, err - } - - return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil -} - -func deleteUnshardedShortcut(stmt *sqlparser.Delete, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { - edml := engine.NewDML() - edml.Keyspace = ks - edml.Table = tables - edml.Opcode = engine.Unsharded - edml.Query = generateQuery(stmt) - return &primitiveWrapper{prim: &engine.Delete{DML: edml}} -} - -func gen4InsertStmtPlanner(version querypb.ExecuteOptions_PlannerVersion, insStmt *sqlparser.Insert, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - ksName := "" - if ks, _ := vschema.DefaultKeyspace(); ks != nil { - ksName = ks.Name - } - semTable, err := semantics.Analyze(insStmt, ksName, vschema) - if err != nil { - return nil, err - } - // record any warning as planner warning. - vschema.PlannerWarning(semTable.Warning) - - err = rewriteRoutedTables(insStmt, vschema) - if err != nil { - return nil, err - } - // remove any alias added from routing table. - // insert query does not support table alias. - insStmt.Table.As = sqlparser.NewIdentifierCS("") - - // Check single unsharded. Even if the table is for single unsharded but sequence table is used. - // We cannot shortcut here as sequence column needs additional planning. - ks, tables := semTable.SingleUnshardedKeyspace() - if ks != nil && tables[0].AutoIncrement == nil { - plan := insertUnshardedShortcut(insStmt, ks, tables) - plan = pushCommentDirectivesOnPlan(plan, insStmt) - return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil - } - - tblInfo, err := semTable.TableInfoFor(semTable.TableSetFor(insStmt.Table)) - if err != nil { - return nil, err - } - if tblInfo.GetVindexTable().Keyspace.Sharded && semTable.NotUnshardedErr != nil { - return nil, semTable.NotUnshardedErr - } - - err = queryRewrite(semTable, reservedVars, insStmt) - if err != nil { - return nil, err - } - - ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) - - op, err := operators.PlanQuery(ctx, insStmt) - if err != nil { - return nil, err - } - - plan, err := transformToLogicalPlan(ctx, op, true) - if err != nil { - return nil, err - } - - plan = pushCommentDirectivesOnPlan(plan, insStmt) - - setLockOnAllSelect(plan) - - if err := plan.WireupGen4(ctx); err != nil { - return nil, err - } - - return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil -} - -func insertUnshardedShortcut(stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { - eIns := &engine.Insert{} - eIns.Keyspace = ks - eIns.Table = tables[0] - eIns.Opcode = engine.InsertUnsharded - eIns.Query = generateQuery(stmt) - return &insert{eInsert: eIns} -} - -func rewriteRoutedTables(stmt sqlparser.Statement, vschema plancontext.VSchema) error { - // Rewrite routed tables - return sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) { - aliasTbl, isAlias := node.(*sqlparser.AliasedTableExpr) - if !isAlias { - return true, nil - } - tableName, ok := aliasTbl.Expr.(sqlparser.TableName) - if !ok { - return true, nil - } - vschemaTable, vindexTbl, _, _, _, err := vschema.FindTableOrVindex(tableName) - if err != nil { - return false, err - } - if vindexTbl != nil { - // vindex cannot be present in a dml statement. - return false, vterrors.VT09014() - } - - if vschemaTable.Name.String() != tableName.Name.String() { - name := tableName.Name - if aliasTbl.As.IsEmpty() { - // if the user hasn't specified an alias, we'll insert one here so the old table name still works - aliasTbl.As = sqlparser.NewIdentifierCS(name.String()) - } - tableName.Name = sqlparser.NewIdentifierCS(vschemaTable.Name.String()) - aliasTbl.Expr = tableName - } - - return true, nil - }, stmt) -} - -func setLockOnAllSelect(plan logicalPlan) { - _, _ = visit(plan, func(plan logicalPlan) (bool, logicalPlan, error) { - switch node := plan.(type) { - case *routeGen4: - node.Select.SetLock(sqlparser.ShareModeLock) - return true, node, nil - } - return true, plan, nil - }) -} - -func planLimit(limit *sqlparser.Limit, plan logicalPlan) (logicalPlan, error) { - if limit == nil { - return plan, nil - } - rb, ok := plan.(*routeGen4) - if ok && rb.isSingleShard() { - rb.SetLimit(limit) - return plan, nil - } - - lPlan, err := createLimit(plan, limit) - if err != nil { - return nil, err - } - - // visit does not modify the plan. - _, err = visit(lPlan, setUpperLimit) - if err != nil { - return nil, err - } - return lPlan, nil -} - -func planHorizon(ctx *plancontext.PlanningContext, plan logicalPlan, in sqlparser.SelectStatement, truncateColumns bool) (logicalPlan, error) { - switch node := in.(type) { - case *sqlparser.Select: - hp := horizonPlanning{ - sel: node, - } - - replaceSubQuery(ctx, node) - var err error - plan, err = hp.planHorizon(ctx, plan, truncateColumns) - if err != nil { - return nil, err - } - plan, err = planLimit(node.Limit, plan) - if err != nil { - return nil, err - } - case *sqlparser.Union: - var err error - rb, isRoute := plan.(*routeGen4) - if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { - return nil, ctx.SemTable.NotSingleRouteErr - } - if isRoute && rb.isSingleShard() { - err = planSingleRoutePlan(node, rb) - } else { - plan, err = planOrderByOnUnion(ctx, plan, node) - } - if err != nil { - return nil, err - } - - plan, err = planLimit(node.Limit, plan) - if err != nil { - return nil, err - } - } - return plan, nil - -} - -func planOrderByOnUnion(ctx *plancontext.PlanningContext, plan logicalPlan, union *sqlparser.Union) (logicalPlan, error) { - qp, err := operators.CreateQPFromSelectStatement(ctx, union) - if err != nil { - return nil, err - } - hp := horizonPlanning{ - qp: qp, - } - if len(qp.OrderExprs) > 0 { - plan, err = hp.planOrderBy(ctx, qp.OrderExprs, plan) - if err != nil { - return nil, err - } - } - return plan, nil -} - -func pushCommentDirectivesOnPlan(plan logicalPlan, stmt sqlparser.Statement) logicalPlan { - var directives *sqlparser.CommentDirectives - cmt, ok := stmt.(sqlparser.Commented) - if ok { - directives = cmt.GetParsedComments().Directives() - scatterAsWarns := directives.IsSet(sqlparser.DirectiveScatterErrorsAsWarnings) - timeout := queryTimeout(directives) - multiShardAutoCommit := directives.IsSet(sqlparser.DirectiveMultiShardAutocommit) - - if scatterAsWarns || timeout > 0 || multiShardAutoCommit { - _, _ = visit(plan, func(logicalPlan logicalPlan) (bool, logicalPlan, error) { - switch plan := logicalPlan.(type) { - case *routeGen4: - plan.eroute.ScatterErrorsAsWarnings = scatterAsWarns - plan.eroute.QueryTimeout = timeout - case *primitiveWrapper: - setDirective(plan.prim, multiShardAutoCommit, timeout) - case *insert: - setDirective(plan.eInsert, multiShardAutoCommit, timeout) - } - return true, logicalPlan, nil - }) - } - } - - return plan -} - -func setDirective(prim engine.Primitive, msac bool, timeout int) { - switch edml := prim.(type) { - case *engine.Insert: - edml.MultiShardAutocommit = msac - edml.QueryTimeout = timeout - case *engine.Update: - edml.MultiShardAutocommit = msac - edml.QueryTimeout = timeout - case *engine.Delete: - edml.MultiShardAutocommit = msac - edml.QueryTimeout = timeout - } -} - -// checkIfDeleteSupported checks if the delete query is supported or we must return an error. -func checkIfDeleteSupported(del *sqlparser.Delete, semTable *semantics.SemTable) error { - if semTable.NotUnshardedErr != nil { - return semTable.NotUnshardedErr - } - - // Delete is only supported for a single TableExpr which is supposed to be an aliased expression - multiShardErr := vterrors.VT12001("multi-shard or vindex write statement") - if len(del.TableExprs) != 1 { - return multiShardErr - } - _, isAliasedExpr := del.TableExprs[0].(*sqlparser.AliasedTableExpr) - if !isAliasedExpr { - return multiShardErr - } - - if len(del.Targets) > 1 { - return vterrors.VT12001("multi-table DELETE statement in a sharded keyspace") - } - - err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - switch node.(type) { - case *sqlparser.Subquery, *sqlparser.DerivedTable: - // We have a subquery, so we must fail the planning. - // If this subquery and the table expression were all belonging to the same unsharded keyspace, - // we would have already created a plan for them before doing these checks. - return false, vterrors.VT12001("subqueries in DML") - } - return true, nil - }, del) - if err != nil { - return err - } - - return nil -} diff --git a/go/vt/vtgate/planbuilder/grouping.go b/go/vt/vtgate/planbuilder/grouping.go deleted file mode 100644 index 0bd10666029..00000000000 --- a/go/vt/vtgate/planbuilder/grouping.go +++ /dev/null @@ -1,128 +0,0 @@ -/* -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 planbuilder - -import ( - "fmt" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/engine" -) - -func planGroupBy(pb *primitiveBuilder, input logicalPlan, groupBy sqlparser.GroupBy) (logicalPlan, error) { - if len(groupBy) == 0 { - // if we have no grouping declared, we only want to visit orderedAggregate - _, isOrdered := input.(*orderedAggregate) - if !isOrdered { - return input, nil - } - } - - switch node := input.(type) { - case *mergeSort, *pulloutSubquery, *distinct: - inputs := node.Inputs() - input := inputs[0] - - newInput, err := planGroupBy(pb, input, groupBy) - if err != nil { - return nil, err - } - inputs[0] = newInput - err = node.Rewrite(inputs...) - if err != nil { - return nil, err - } - return node, nil - case *route: - node.Select.(*sqlparser.Select).GroupBy = groupBy - return node, nil - case *orderedAggregate: - for _, expr := range groupBy { - colNumber := -1 - switch e := expr.(type) { - case *sqlparser.ColName: - c := e.Metadata.(*column) - if c.Origin() == node { - return nil, vterrors.VT03005(sqlparser.String(e)) - } - for i, rc := range node.resultColumns { - if rc.column == c { - colNumber = i - break - } - } - if colNumber == -1 { - return nil, vterrors.VT12001("in scatter query: GROUP BY column must reference column in SELECT list") - } - case *sqlparser.Literal: - num, err := ResultFromNumber(node.resultColumns, e, "group statement") - if err != nil { - return nil, err - } - colNumber = num - default: - return nil, vterrors.VT12001("in scatter query: only simple references are allowed") - } - node.groupByKeys = append(node.groupByKeys, &engine.GroupByParams{KeyCol: colNumber, WeightStringCol: -1, FromGroupBy: true}) - } - // Append the distinct aggregate if any. - if node.extraDistinct != nil { - groupBy = append(groupBy, node.extraDistinct) - } - - newInput, err := planGroupBy(pb, node.input, groupBy) - if err != nil { - return nil, err - } - node.input = newInput - - return node, nil - } - return nil, vterrors.VT13001(fmt.Sprintf("unreachable %T.groupBy: ", input)) -} - -// planDistinct makes the output distinct -func planDistinct(input logicalPlan) (logicalPlan, error) { - switch node := input.(type) { - case *route: - node.Select.MakeDistinct() - return node, nil - case *orderedAggregate: - for i, rc := range node.resultColumns { - // If the column origin is oa (and not the underlying route), - // it means that it's an aggregate function supplied by oa. - // So, the distinct 'operator' cannot be pushed down into the - // route. - if rc.column.Origin() == node { - return newDistinctV3(node), nil - } - node.groupByKeys = append(node.groupByKeys, &engine.GroupByParams{KeyCol: i, WeightStringCol: -1, FromGroupBy: false}) - } - newInput, err := planDistinct(node.input) - if err != nil { - return nil, err - } - node.input = newInput - return node, nil - - case *distinct: - return input, nil - } - - return nil, vterrors.VT13001(fmt.Sprintf("unreachable %T.distinct", input)) -} diff --git a/go/vt/vtgate/planbuilder/hash_join.go b/go/vt/vtgate/planbuilder/hash_join.go index cef2f30bead..3b60d6a4efd 100644 --- a/go/vt/vtgate/planbuilder/hash_join.go +++ b/go/vt/vtgate/planbuilder/hash_join.go @@ -32,7 +32,6 @@ var _ logicalPlan = (*hashJoin)(nil) // hashJoin is used to build a HashJoin primitive. type hashJoin struct { - gen4Plan // Left and Right are the nodes for the join. Left, Right logicalPlan @@ -51,12 +50,12 @@ type hashJoin struct { } // WireupGen4 implements the logicalPlan interface -func (hj *hashJoin) WireupGen4(ctx *plancontext.PlanningContext) error { - err := hj.Left.WireupGen4(ctx) +func (hj *hashJoin) Wireup(ctx *plancontext.PlanningContext) error { + err := hj.Left.Wireup(ctx) if err != nil { return err } - return hj.Right.WireupGen4(ctx) + return hj.Right.Wireup(ctx) } // Primitive implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/horizon_planning.go b/go/vt/vtgate/planbuilder/horizon_planning.go index 8f78959d72d..39f88ef6278 100644 --- a/go/vt/vtgate/planbuilder/horizon_planning.go +++ b/go/vt/vtgate/planbuilder/horizon_planning.go @@ -36,7 +36,7 @@ type horizonPlanning struct { } func (hp *horizonPlanning) planHorizon(ctx *plancontext.PlanningContext, plan logicalPlan, truncateColumns bool) (logicalPlan, error) { - rb, isRoute := plan.(*routeGen4) + rb, isRoute := plan.(*route) if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { // If we got here, we don't have a single shard plan return nil, ctx.SemTable.NotSingleRouteErr @@ -163,9 +163,9 @@ func (hp *horizonPlanning) truncateColumnsIfNeeded(ctx *plancontext.PlanningCont return plan, nil } switch p := plan.(type) { - case *routeGen4: + case *route: p.eroute.SetTruncateColumnCount(hp.qp.GetColumnCount()) - case *joinGen4, *semiJoin, *hashJoin: + case *join, *semiJoin, *hashJoin: // since this is a join, we can safely add extra columns and not need to truncate them case *orderedAggregate: p.truncateColumnCount = hp.qp.GetColumnCount() @@ -323,7 +323,7 @@ func (hp *horizonPlanning) planAggrUsingOA( plan = newPlan - _, isRoute := plan.(*routeGen4) + _, isRoute := plan.(*route) needsProj := !isRoute var aggPlan = plan var proj *projection @@ -357,10 +357,7 @@ func (hp *horizonPlanning) planAggrUsingOA( return nil, err } - oa.resultsBuilder = resultsBuilder{ - logicalPlanCommon: newBuilderCommon(aggPlan), - weightStrings: make(map[*resultColumn]int), - } + oa.resultsBuilder = newResultsBuilder(aggPlan, nil) return hp.planHaving(ctx, oa) } @@ -593,9 +590,9 @@ func hasUniqueVindex(semTable *semantics.SemTable, groupByExprs []operators.Grou func (hp *horizonPlanning) planOrderBy(ctx *plancontext.PlanningContext, orderExprs []ops.OrderBy, plan logicalPlan) (logicalPlan, error) { switch plan := plan.(type) { - case *routeGen4: + case *route: return planOrderByForRoute(ctx, orderExprs, plan, hp.qp.HasStar) - case *joinGen4: + case *join: return hp.planOrderByForJoin(ctx, orderExprs, plan) case *hashJoin: return hp.planOrderByForHashJoin(ctx, orderExprs, plan) @@ -659,7 +656,7 @@ func isSpecialOrderBy(o ops.OrderBy) bool { return isFunction && f.Name.Lowered() == "rand" } -func planOrderByForRoute(ctx *plancontext.PlanningContext, orderExprs []ops.OrderBy, plan *routeGen4, hasStar bool) (logicalPlan, error) { +func planOrderByForRoute(ctx *plancontext.PlanningContext, orderExprs []ops.OrderBy, plan *route, hasStar bool) (logicalPlan, error) { for _, order := range orderExprs { err := checkOrderExprCanBePlannedInScatter(ctx, plan, order, hasStar) if err != nil { @@ -690,7 +687,7 @@ func planOrderByForRoute(ctx *plancontext.PlanningContext, orderExprs []ops.Orde // checkOrderExprCanBePlannedInScatter verifies that the given order by expression can be planned. // It checks if the expression exists in the plan's select list when the query is a scatter. -func checkOrderExprCanBePlannedInScatter(ctx *plancontext.PlanningContext, plan *routeGen4, order ops.OrderBy, hasStar bool) error { +func checkOrderExprCanBePlannedInScatter(ctx *plancontext.PlanningContext, plan *route, order ops.OrderBy, hasStar bool) error { if !hasStar { return nil } @@ -775,7 +772,7 @@ func (hp *horizonPlanning) planOrderByForHashJoin(ctx *plancontext.PlanningConte return sortPlan, nil } -func (hp *horizonPlanning) planOrderByForJoin(ctx *plancontext.PlanningContext, orderExprs []ops.OrderBy, plan *joinGen4) (logicalPlan, error) { +func (hp *horizonPlanning) planOrderByForJoin(ctx *plancontext.PlanningContext, orderExprs []ops.OrderBy, plan *join) (logicalPlan, error) { if len(orderExprs) == 1 && isSpecialOrderBy(orderExprs[0]) { lhs, err := hp.planOrderBy(ctx, orderExprs, plan.Left) if err != nil { @@ -809,12 +806,8 @@ func (hp *horizonPlanning) planOrderByForJoin(ctx *plancontext.PlanningContext, func createMemorySortPlanOnAggregation(ctx *plancontext.PlanningContext, plan *orderedAggregate, orderExprs []ops.OrderBy) (logicalPlan, error) { primitive := &engine.MemorySort{} ms := &memorySort{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(plan), - weightStrings: make(map[*resultColumn]int), - truncater: primitive, - }, - eMemorySort: primitive, + resultsBuilder: newResultsBuilder(plan, primitive), + eMemorySort: primitive, } for _, order := range orderExprs { @@ -854,12 +847,8 @@ func findExprInOrderedAggr(ctx *plancontext.PlanningContext, plan *orderedAggreg func (hp *horizonPlanning) createMemorySortPlan(ctx *plancontext.PlanningContext, plan logicalPlan, orderExprs []ops.OrderBy, useWeightStr bool) (logicalPlan, error) { primitive := &engine.MemorySort{} ms := &memorySort{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(plan), - weightStrings: make(map[*resultColumn]int), - truncater: primitive, - }, - eMemorySort: primitive, + resultsBuilder: newResultsBuilder(plan, primitive), + eMemorySort: primitive, } for _, order := range orderExprs { @@ -897,7 +886,7 @@ func (hp *horizonPlanning) planDistinct(ctx *plancontext.PlanningContext, plan l return plan, nil } switch p := plan.(type) { - case *routeGen4: + case *route: // we always make the underlying query distinct, // and then we might also add a distinct operator on top if it is needed p.Select.MakeDistinct() @@ -906,7 +895,7 @@ func (hp *horizonPlanning) planDistinct(ctx *plancontext.PlanningContext, plan l } return hp.addDistinct(ctx, plan) - case *joinGen4, *pulloutSubquery: + case *join, *pulloutSubquery: return hp.addDistinct(ctx, plan) case *orderedAggregate: return hp.planDistinctOA(ctx.SemTable, p) @@ -917,10 +906,7 @@ func (hp *horizonPlanning) planDistinct(ctx *plancontext.PlanningContext, plan l func (hp *horizonPlanning) planDistinctOA(semTable *semantics.SemTable, currPlan *orderedAggregate) (logicalPlan, error) { oa := &orderedAggregate{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(currPlan), - weightStrings: make(map[*resultColumn]int), - }, + resultsBuilder: newResultsBuilder(currPlan, nil), } for _, sExpr := range hp.qp.SelectExprs { expr, err := sExpr.GetExpr() @@ -991,11 +977,8 @@ func (hp *horizonPlanning) addDistinct(ctx *plancontext.PlanningContext, plan lo return nil, err } oa := &orderedAggregate{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(innerPlan), - weightStrings: make(map[*resultColumn]int), - }, - groupByKeys: groupByKeys, + resultsBuilder: newResultsBuilder(innerPlan, nil), + groupByKeys: groupByKeys, } return oa, nil } @@ -1049,7 +1032,7 @@ func (hp *horizonPlanning) planHaving(ctx *plancontext.PlanningContext, plan log func pushHaving(ctx *plancontext.PlanningContext, expr sqlparser.Expr, plan logicalPlan) (logicalPlan, error) { switch node := plan.(type) { - case *routeGen4: + case *route: sel := sqlparser.GetFirstSelect(node.Select) sel.AddHaving(expr) return plan, nil @@ -1065,7 +1048,7 @@ func pushHaving(ctx *plancontext.PlanningContext, expr sqlparser.Expr, plan logi func isJoin(plan logicalPlan) bool { switch plan.(type) { - case *joinGen4, *hashJoin: + case *join, *hashJoin: return true default: return false @@ -1098,7 +1081,7 @@ func exprHasVindex(semTable *semantics.SemTable, expr sqlparser.Expr, hasToBeUni return false } -func planSingleRoutePlan(sel sqlparser.SelectStatement, rb *routeGen4) error { +func planSingleRoutePlan(sel sqlparser.SelectStatement, rb *route) error { err := stripDownQuery(sel, rb.Select) if err != nil { return err @@ -1161,7 +1144,7 @@ func stripDownQuery(from, to sqlparser.SelectStatement) error { func planGroupByGen4(ctx *plancontext.PlanningContext, groupExpr operators.GroupBy, plan logicalPlan, wsAdded bool) error { switch node := plan.(type) { - case *routeGen4: + case *route: sel := node.Select.(*sqlparser.Select) sel.AddGroupBy(groupExpr.Inner) // If a weight_string function is added to the select list, diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 986d3d82d9c..c1c823d5def 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -17,441 +17,101 @@ limitations under the License. package planbuilder import ( - "fmt" - "strconv" - "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/vterrors" "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/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) -// buildInsertPlan builds the route for an INSERT statement. -func buildInsertPlan(string) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - pb := newStmtAwarePrimitiveBuilder(vschema, newJointab(reservedVars), stmt) - ins := stmt.(*sqlparser.Insert) - err := checkUnsupportedExpressions(ins) - if err != nil { - return nil, err - } - exprs := sqlparser.TableExprs{ins.Table} - rb, err := pb.processDMLTable(exprs, reservedVars, nil) - if err != nil { - return nil, err - } - // The table might have been routed to a different one. - ins.Table = exprs[0].(*sqlparser.AliasedTableExpr) - // remove any alias added from routing table. insert query does not support table alias. - ins.Table.As = sqlparser.NewIdentifierCS("") - if rb.eroute.TargetDestination != nil { - return nil, vterrors.VT12001("INSERT with a target destination") - } - - if len(pb.st.tables) != 1 { - // Unreachable. - return nil, vterrors.VT12001("multi-table INSERT statement in a sharded keyspace") - } - var vschemaTable *vindexes.Table - for _, tval := range pb.st.tables { - // There is only one table. - vschemaTable = tval.vschemaTable - } - if !rb.eroute.Keyspace.Sharded { - return buildInsertUnshardedPlan(ins, vschemaTable, reservedVars, vschema) - } - if ins.Action == sqlparser.ReplaceAct { - return nil, vterrors.VT12001("REPLACE INTO with sharded keyspace") - } - return buildInsertShardedPlan(ins, vschemaTable, reservedVars, vschema) - } -} - -func buildInsertUnshardedPlan(ins *sqlparser.Insert, table *vindexes.Table, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - eins := engine.NewSimpleInsert( - engine.InsertUnsharded, - table, - table.Keyspace, - ) - applyCommentDirectives(ins, eins) - - var rows sqlparser.Values - tc := &tableCollector{} - tc.addVindexTable(table) - switch insertValues := ins.Rows.(type) { - case *sqlparser.Select, *sqlparser.Union: - if eins.Table.AutoIncrement != nil { - return nil, vterrors.VT12001("auto-increment and SELECT in INSERT") - } - plan, err := subquerySelectPlan(ins, vschema, reservedVars, false) - if err != nil { - return nil, err - } - tc.addAllTables(plan.tables) - if route, ok := plan.primitive.(*engine.Route); ok && !route.Keyspace.Sharded && table.Keyspace.Name == route.Keyspace.Name { - eins.Query = generateQuery(ins) - } else { - eins.Input = plan.primitive - eins.Prefix, _, eins.Suffix = generateInsertShardedQuery(ins) - } - return newPlanResult(eins, tc.getTables()...), nil - case sqlparser.Values: - rows = insertValues - default: - return nil, vterrors.VT13001(fmt.Sprintf("unexpected construct in INSERT: %T", insertValues)) - } - if eins.Table.AutoIncrement == nil { - eins.Query = generateQuery(ins) - } else { - // Table has auto-inc and has a VALUES clause. - // If the column list is nil then add all the columns - // If the column list is empty then add only the auto-inc column and this happens on calling modifyForAutoinc - if ins.Columns == nil { - if table.ColumnListAuthoritative { - populateInsertColumnlist(ins, table) - } else { - return nil, vterrors.VT13001("column list required for tables with auto-inc columns") - } - } - for _, row := range rows { - if len(ins.Columns) != len(row) { - return nil, vterrors.VT13001("column list does not match values") - } - } - if err := modifyForAutoinc(ins, eins); err != nil { - return nil, err - } - eins.Query = generateQuery(ins) - } - - return newPlanResult(eins, tc.getTables()...), nil -} - -func buildInsertShardedPlan(ins *sqlparser.Insert, table *vindexes.Table, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - eins := &engine.Insert{ - Table: table, - Keyspace: table.Keyspace, - } - tc := &tableCollector{} - tc.addVindexTable(table) - eins.Ignore = bool(ins.Ignore) - if ins.OnDup != nil { - if isVindexChanging(sqlparser.UpdateExprs(ins.OnDup), eins.Table.ColumnVindexes) { - return nil, vterrors.VT12001("DML cannot update vindex column") - } - eins.Ignore = true +func gen4InsertStmtPlanner(version querypb.ExecuteOptions_PlannerVersion, insStmt *sqlparser.Insert, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { + ksName := "" + if ks, _ := vschema.DefaultKeyspace(); ks != nil { + ksName = ks.Name } - if ins.Columns == nil && table.ColumnListAuthoritative { - populateInsertColumnlist(ins, table) - } - - applyCommentDirectives(ins, eins) - eins.ColVindexes = getColVindexes(eins.Table.ColumnVindexes) - - // Till here common plan building done for insert by providing values or select query. - - rows, isRowValues := ins.Rows.(sqlparser.Values) - if !isRowValues { - return buildInsertSelectPlan(ins, table, reservedVars, vschema, eins) - } - eins.Opcode = engine.InsertSharded - - for _, value := range rows { - if len(ins.Columns) != len(value) { - return nil, vterrors.VT13001("column list does not match values") - } - } - - if err := modifyForAutoinc(ins, eins); err != nil { + semTable, err := semantics.Analyze(insStmt, ksName, vschema) + if err != nil { return nil, err } + // record any warning as planner warning. + vschema.PlannerWarning(semTable.Warning) - // Fill out the 3-d Values structure. Please see documentation of Insert.Values for details. - colVindexes := eins.ColVindexes - routeValues := make([][][]evalengine.Expr, len(colVindexes)) - for vIdx, colVindex := range colVindexes { - routeValues[vIdx] = make([][]evalengine.Expr, len(colVindex.Columns)) - for colIdx, col := range colVindex.Columns { - routeValues[vIdx][colIdx] = make([]evalengine.Expr, len(rows)) - colNum := findOrAddColumn(ins, col) - for rowNum, row := range rows { - innerpv, err := evalengine.Translate(row[colNum], nil) - if err != nil { - return nil, err - } - routeValues[vIdx][colIdx][rowNum] = innerpv - } - } - } - for _, colVindex := range colVindexes { - for _, col := range colVindex.Columns { - colNum := findOrAddColumn(ins, col) - for rowNum, row := range rows { - name := engine.InsertVarName(col, rowNum) - row[colNum] = sqlparser.NewArgument(name) - } - } - } - eins.VindexValues = routeValues - eins.Query = generateQuery(ins) - eins.Prefix, eins.Mid, eins.Suffix = generateInsertShardedQuery(ins) - return newPlanResult(eins, tc.getTables()...), nil -} - -// buildInsertSelectPlan builds an insert using select plan. -func buildInsertSelectPlan(ins *sqlparser.Insert, table *vindexes.Table, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, eins *engine.Insert) (*planResult, error) { - eins.Opcode = engine.InsertSelect - tc := &tableCollector{} - tc.addVindexTable(table) - - // check if column list is provided if not, then vschema should be able to provide the column list. - if len(ins.Columns) == 0 { - if !table.ColumnListAuthoritative { - return nil, vterrors.VT09004() - } - populateInsertColumnlist(ins, table) - } - - // select plan will be taken as input to insert rows into the table. - plan, err := subquerySelectPlan(ins, vschema, reservedVars, true) + err = rewriteRoutedTables(insStmt, vschema) if err != nil { return nil, err } - tc.addAllTables(plan.tables) - eins.Input = plan.primitive + // remove any alias added from routing table. + // insert query does not support table alias. + insStmt.Table.As = sqlparser.NewIdentifierCS("") - // When the table you are steaming data from and table you are inserting from are same. - // Then due to locking of the index range on the table we might not be able to insert into the table. - // Therefore, instead of streaming, this flag will ensure the records are first read and then inserted. - if strings.Contains(plan.primitive.GetTableName(), table.Name.String()) { - eins.ForceNonStreaming = true + // Check single unsharded. Even if the table is for single unsharded but sequence table is used. + // We cannot shortcut here as sequence column needs additional planning. + ks, tables := semTable.SingleUnshardedKeyspace() + if ks != nil && tables[0].AutoIncrement == nil { + plan := insertUnshardedShortcut(insStmt, ks, tables) + plan = pushCommentDirectivesOnPlan(plan, insStmt) + return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil } - // auto-increment column is added explicitly if not provided. - if err := modifyForAutoinc(ins, eins); err != nil { + tblInfo, err := semTable.TableInfoFor(semTable.TableSetFor(insStmt.Table)) + if err != nil { return nil, err } + if tblInfo.GetVindexTable().Keyspace.Sharded && semTable.NotUnshardedErr != nil { + return nil, semTable.NotUnshardedErr + } - // Fill out the 3-d Values structure - eins.VindexValueOffset, err = extractColVindexOffsets(ins, eins.ColVindexes) + err = queryRewrite(semTable, reservedVars, insStmt) if err != nil { return nil, err } - eins.Prefix, _, eins.Suffix = generateInsertShardedQuery(ins) - return newPlanResult(eins, tc.getTables()...), nil -} + ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) -func subquerySelectPlan(ins *sqlparser.Insert, vschema plancontext.VSchema, reservedVars *sqlparser.ReservedVars, sharded bool) (*planResult, error) { - selectStmt, queryPlanner, err := getStatementAndPlanner(ins, vschema) + op, err := operators.PlanQuery(ctx, insStmt) if err != nil { return nil, err } - // validate the columns to match on insert and select - // for sharded insert table only - if sharded { - if err := checkColumnCounts(ins, selectStmt); err != nil { - return nil, err - } - } - - // Override the locking with `for update` to lock the rows for inserting the data. - selectStmt.SetLock(sqlparser.ForUpdateLock) - - return queryPlanner(selectStmt, reservedVars, vschema) -} - -func getStatementAndPlanner( - ins *sqlparser.Insert, - vschema plancontext.VSchema, -) (selectStmt sqlparser.SelectStatement, configuredPlanner stmtPlanner, err error) { - switch stmt := ins.Rows.(type) { - case *sqlparser.Select: - configuredPlanner, err = getConfiguredPlanner(vschema, buildSelectPlan, stmt, "") - selectStmt = stmt - case *sqlparser.Union: - configuredPlanner, err = getConfiguredPlanner(vschema, buildUnionPlan, stmt, "") - selectStmt = stmt - default: - err = vterrors.VT12001(fmt.Sprintf("INSERT plan with %T", ins.Rows)) - } - + plan, err := transformToLogicalPlan(ctx, op, true) if err != nil { - return nil, nil, err - } - - return selectStmt, configuredPlanner, nil -} - -func checkColumnCounts(ins *sqlparser.Insert, selectStmt sqlparser.SelectStatement) error { - if len(ins.Columns) < selectStmt.GetColumnCount() { - return vterrors.VT03006() - } - if len(ins.Columns) > selectStmt.GetColumnCount() { - sel := sqlparser.GetFirstSelect(selectStmt) - var hasStarExpr bool - for _, sExpr := range sel.SelectExprs { - if _, hasStarExpr = sExpr.(*sqlparser.StarExpr); hasStarExpr { - break - } - } - if !hasStarExpr { - return vterrors.VT03006() - } - } - return nil -} - -func applyCommentDirectives(ins *sqlparser.Insert, eins *engine.Insert) { - directives := ins.Comments.Directives() - if directives.IsSet(sqlparser.DirectiveMultiShardAutocommit) { - eins.MultiShardAutocommit = true - } - eins.QueryTimeout = queryTimeout(directives) -} - -func getColVindexes(allColVindexes []*vindexes.ColumnVindex) (colVindexes []*vindexes.ColumnVindex) { - for _, colVindex := range allColVindexes { - if colVindex.IsPartialVindex() { - continue - } - colVindexes = append(colVindexes, colVindex) - } - return -} - -func extractColVindexOffsets(ins *sqlparser.Insert, colVindexes []*vindexes.ColumnVindex) ([][]int, error) { - vv := make([][]int, len(colVindexes)) - for idx, colVindex := range colVindexes { - for _, col := range colVindex.Columns { - colNum := findColumn(ins, col) - // sharding column values should be provided in the insert. - if colNum == -1 && idx == 0 { - return nil, vterrors.VT09003(col) - } - vv[idx] = append(vv[idx], colNum) - } - } - return vv, nil -} - -// findColumn returns the column index where it is placed on the insert column list. -// Otherwise, return -1 when not found. -func findColumn(ins *sqlparser.Insert, col sqlparser.IdentifierCI) int { - for i, column := range ins.Columns { - if col.Equal(column) { - return i - } + return nil, err } - return -1 -} -func populateInsertColumnlist(ins *sqlparser.Insert, table *vindexes.Table) { - cols := make(sqlparser.Columns, 0, len(table.Columns)) - for _, c := range table.Columns { - cols = append(cols, c.Name) - } - ins.Columns = cols -} + plan = pushCommentDirectivesOnPlan(plan, insStmt) -// 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(ins *sqlparser.Insert, eins *engine.Insert) error { - if eins.Table.AutoIncrement == nil { - return nil - } - colNum := findOrAddColumn(ins, eins.Table.AutoIncrement.Column) - selNext := &sqlparser.Select{ - From: []sqlparser.TableExpr{&sqlparser.AliasedTableExpr{Expr: &sqlparser.TableName{Name: eins.Table.AutoIncrement.Sequence.Name}}}, - SelectExprs: sqlparser.SelectExprs{&sqlparser.Nextval{Expr: &sqlparser.Argument{Name: "n", Type: sqltypes.Int64}}}, - } - eins.Generate = &engine.Generate{ - Keyspace: eins.Table.AutoIncrement.Sequence.Keyspace, - Query: sqlparser.String(selNext), - } - switch rows := ins.Rows.(type) { - case sqlparser.SelectStatement: - eins.Generate.Offset = colNum - return nil - case sqlparser.Values: - autoIncValues := make([]evalengine.Expr, 0, len(rows)) - for rowNum, row := range rows { - // Support the DEFAULT keyword by treating it as null - if _, ok := row[colNum].(*sqlparser.Default); ok { - row[colNum] = &sqlparser.NullVal{} - } + setLockOnAllSelect(plan) - pv, err := evalengine.Translate(row[colNum], nil) - if err != nil { - return err - } - autoIncValues = append(autoIncValues, pv) - row[colNum] = sqlparser.NewArgument(engine.SeqVarName + strconv.Itoa(rowNum)) - } - eins.Generate.Values = evalengine.NewTupleExpr(autoIncValues...) - return nil + if err := plan.Wireup(ctx); err != nil { + return nil, err } - return vterrors.VT13001(fmt.Sprintf("unexpected construct in INSERT: %T", ins.Rows)) -} -// findOrAddColumn finds the position of a column in the insert. If it's -// absent it appends it to the with NULL values and returns that position. -func findOrAddColumn(ins *sqlparser.Insert, col sqlparser.IdentifierCI) int { - colNum := findColumn(ins, col) - if colNum >= 0 { - return colNum - } - colOffset := len(ins.Columns) - ins.Columns = append(ins.Columns, col) - if rows, ok := ins.Rows.(sqlparser.Values); ok { - for i := range rows { - rows[i] = append(rows[i], &sqlparser.NullVal{}) - } - } - return colOffset + return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil } -// isVindexChanging returns true if any of the update -// expressions modify a vindex column. -func isVindexChanging(setClauses sqlparser.UpdateExprs, colVindexes []*vindexes.ColumnVindex) bool { - for _, assignment := range setClauses { - for _, vcol := range colVindexes { - for _, col := range vcol.Columns { - if col.Equal(assignment.Name.Name) { - valueExpr, isValuesFuncExpr := assignment.Expr.(*sqlparser.ValuesFuncExpr) - if !isValuesFuncExpr { - return true - } - // update on duplicate key is changing the vindex column, not supported. - if !valueExpr.Name.Name.Equal(assignment.Name.Name) { - return true - } - } - } - } - } - return false +func insertUnshardedShortcut(stmt *sqlparser.Insert, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { + eIns := &engine.Insert{} + eIns.Keyspace = ks + eIns.Table = tables[0] + eIns.Opcode = engine.InsertUnsharded + eIns.Query = generateQuery(stmt) + return &insert{eInsert: eIns} } type insert struct { eInsert *engine.Insert source logicalPlan - gen4Plan } var _ logicalPlan = (*insert)(nil) -func (i *insert) WireupGen4(ctx *plancontext.PlanningContext) error { +func (i *insert) Wireup(ctx *plancontext.PlanningContext) error { if i.source == nil { return nil } - return i.source.WireupGen4(ctx) + return i.source.Wireup(ctx) } func (i *insert) Primitive() engine.Primitive { diff --git a/go/vt/vtgate/planbuilder/join.go b/go/vt/vtgate/planbuilder/join.go index 0fc9b5f2ce3..f3929f9a8fd 100644 --- a/go/vt/vtgate/planbuilder/join.go +++ b/go/vt/vtgate/planbuilder/join.go @@ -19,230 +19,78 @@ package planbuilder import ( "fmt" - "vitess.io/vitess/go/vt/vterrors" - "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/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" ) var _ logicalPlan = (*join)(nil) // join is used to build a Join primitive. -// It's used to build a normal join or a left join -// operation. +// It's used to build an inner join and only used by the Gen4 planner type join struct { - v3Plan - order int - resultColumns []*resultColumn - weightStrings map[*resultColumn]int - - // leftOrder stores the order number of the left node. This is - // used for a b-tree style traversal towards the target route. - // Let us assume the following execution tree: - // J9 - // / \ - // / \ - // J3 J8 - // / \ / \ - // R1 R2 J6 R7 - // / \ - // R4 R5 - // - // In the above trees, the suffix numbers indicate the - // execution order. The leftOrder for the joins will then - // be as follows: - // J3: 1 - // J6: 4 - // J8: 6 - // J9: 3 - // - // The route to R4 would be: - // Go right from J9->J8 because Left(J9)==3, which is <4. - // Go left from J8->J6 because Left(J8)==6, which is >=4. - // Go left from J6->R4 because Left(J6)==4, the destination. - // Look for 'isOnLeft' to see how these numbers are used. - leftOrder int - // Left and Right are the nodes for the join. Left, Right logicalPlan - ejoin *engine.Join -} - -// newJoin makes a new join using the two planBuilder. ajoin can be nil -// if the join is on a ',' operator. lpb will contain the resulting join. -// rpb will be discarded. -func newJoin(lpb, rpb *primitiveBuilder, ajoin *sqlparser.JoinTableExpr, reservedVars *sqlparser.ReservedVars) error { - // This function converts ON clauses to WHERE clauses. The WHERE clause - // scope can see all tables, whereas the ON clause can only see the - // participants of the JOIN. However, since the ON clause doesn't allow - // external references, and the FROM clause doesn't allow duplicates, - // it's safe to perform this conversion and still expect the same behavior. - - opcode := engine.InnerJoin - if ajoin != nil { - switch { - case ajoin.Join == sqlparser.LeftJoinType: - opcode = engine.LeftJoin - - // For left joins, we have to push the ON clause into the RHS. - // We do this before creating the join primitive. - // However, variables of LHS need to be visible. To allow this, - // we mark the LHS symtab as outer scope to the RHS, just like - // a subquery. This make the RHS treat the LHS symbols as external. - // This will prevent constructs from escaping out of the rpb scope. - // At this point, the LHS symtab also contains symbols of the RHS. - // But the RHS will hide those, as intended. - rpb.st.Outer = lpb.st - if err := rpb.pushFilter(ajoin.Condition.On, sqlparser.WhereStr, reservedVars); err != nil { - return err - } - case ajoin.Condition.Using != nil: - return vterrors.VT12001("JOIN with USING(column_list) clause for complex queries") - } - } - lpb.plan = &join{ - weightStrings: make(map[*resultColumn]int), - Left: lpb.plan, - Right: rpb.plan, - ejoin: &engine.Join{ - Opcode: opcode, - Vars: make(map[string]int), - }, - } - lpb.plan.Reorder(0) - if ajoin == nil || opcode == engine.LeftJoin { - return nil - } - return lpb.pushFilter(ajoin.Condition.On, sqlparser.WhereStr, reservedVars) -} - -// Order implements the logicalPlan interface -func (jb *join) Order() int { - return jb.order -} + // The Opcode tells us if this is an inner or outer join + Opcode engine.JoinOpcode -// Reorder implements the logicalPlan interface -func (jb *join) Reorder(order int) { - jb.Left.Reorder(order) - jb.leftOrder = jb.Left.Order() - jb.Right.Reorder(jb.leftOrder) - jb.order = jb.Right.Order() + 1 -} + // These are the columns that will be produced by this plan. + // Negative offsets come from the LHS, and positive from the RHS + Cols []int -// Primitive implements the logicalPlan interface -func (jb *join) Primitive() engine.Primitive { - jb.ejoin.Left = jb.Left.Primitive() - jb.ejoin.Right = jb.Right.Primitive() - return jb.ejoin -} + // Vars are the columns that will be sent from the LHS to the RHS + // the number is the offset on the LHS result, and the string is the bind variable name used in the RHS + Vars map[string]int -// ResultColumns implements the logicalPlan interface -func (jb *join) ResultColumns() []*resultColumn { - return jb.resultColumns + // LHSColumns are the columns from the LHS used for the join. + // These are the same columns pushed on the LHS that are now used in the Vars field + LHSColumns []*sqlparser.ColName } -// Wireup implements the logicalPlan interface -func (jb *join) Wireup(plan logicalPlan, jt *jointab) error { - err := jb.Right.Wireup(plan, jt) +// WireupGen4 implements the logicalPlan interface +func (j *join) Wireup(ctx *plancontext.PlanningContext) error { + err := j.Left.Wireup(ctx) if err != nil { return err } - return jb.Left.Wireup(plan, jt) -} - -// SupplyVar implements the logicalPlan interface -func (jb *join) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - if !jb.isOnLeft(from) { - jb.Right.SupplyVar(from, to, col, varname) - return - } - if jb.isOnLeft(to) { - jb.Left.SupplyVar(from, to, col, varname) - return - } - if _, ok := jb.ejoin.Vars[varname]; ok { - // Looks like somebody else already requested this. - return - } - c := col.Metadata.(*column) - for i, rc := range jb.resultColumns { - if jb.ejoin.Cols[i] > 0 { - continue - } - if rc.column == c { - jb.ejoin.Vars[varname] = -jb.ejoin.Cols[i] - 1 - return - } - } - _, jb.ejoin.Vars[varname] = jb.Left.SupplyCol(col) + return j.Right.Wireup(ctx) } -// SupplyCol implements the logicalPlan interface -func (jb *join) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - c := col.Metadata.(*column) - for i, rc := range jb.resultColumns { - if rc.column == c { - return rc, i - } - } - - routeNumber := c.Origin().Order() - var sourceCol int - if jb.isOnLeft(routeNumber) { - rc, sourceCol = jb.Left.SupplyCol(col) - jb.ejoin.Cols = append(jb.ejoin.Cols, -sourceCol-1) - } else { - rc, sourceCol = jb.Right.SupplyCol(col) - jb.ejoin.Cols = append(jb.ejoin.Cols, sourceCol+1) +// Primitive implements the logicalPlan interface +func (j *join) Primitive() engine.Primitive { + return &engine.Join{ + Left: j.Left.Primitive(), + Right: j.Right.Primitive(), + Cols: j.Cols, + Vars: j.Vars, + Opcode: j.Opcode, } - jb.resultColumns = append(jb.resultColumns, rc) - return rc, len(jb.ejoin.Cols) - 1 } -// SupplyWeightString implements the logicalPlan interface -func (jb *join) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - rc := jb.resultColumns[colNumber] - if weightcolNumber, ok := jb.weightStrings[rc]; ok { - return weightcolNumber, nil - } - routeNumber := rc.column.Origin().Order() - if jb.isOnLeft(routeNumber) { - sourceCol, err := jb.Left.SupplyWeightString(-jb.ejoin.Cols[colNumber]-1, alsoAddToGroupBy) - if err != nil { - return 0, err - } - jb.ejoin.Cols = append(jb.ejoin.Cols, -sourceCol-1) - } else { - sourceCol, err := jb.Right.SupplyWeightString(jb.ejoin.Cols[colNumber]-1, alsoAddToGroupBy) - if err != nil { - return 0, err - } - jb.ejoin.Cols = append(jb.ejoin.Cols, sourceCol+1) - } - jb.resultColumns = append(jb.resultColumns, rc) - jb.weightStrings[rc] = len(jb.ejoin.Cols) - 1 - return len(jb.ejoin.Cols) - 1, nil +// Inputs implements the logicalPlan interface +func (j *join) Inputs() []logicalPlan { + return []logicalPlan{j.Left, j.Right} } // Rewrite implements the logicalPlan interface -func (jb *join) Rewrite(inputs ...logicalPlan) error { +func (j *join) Rewrite(inputs ...logicalPlan) error { if len(inputs) != 2 { - return vterrors.VT13001(fmt.Sprintf("join: wrong number of inputs, got: %d, expect: 2", len(inputs))) + return vterrors.VT13001(fmt.Sprintf("wrong number of children in join rewrite, got: %d, expect: 2", len(inputs))) } - jb.Left = inputs[0] - jb.Right = inputs[1] + j.Left = inputs[0] + j.Right = inputs[1] return nil } -// Inputs implements the logicalPlan interface -func (jb *join) Inputs() []logicalPlan { - return []logicalPlan{jb.Left, jb.Right} +// ContainsTables implements the logicalPlan interface +func (j *join) ContainsTables() semantics.TableSet { + return j.Left.ContainsTables().Merge(j.Right.ContainsTables()) } -// isOnLeft returns true if the specified route number -// is on the left side of the join. If false, it means -// the node is on the right. -func (jb *join) isOnLeft(nodeNum int) bool { - return nodeNum <= jb.leftOrder +// OutputColumns implements the logicalPlan interface +func (j *join) OutputColumns() []sqlparser.SelectExpr { + return getOutputColumnsFromJoin(j.Cols, j.Left.OutputColumns(), j.Right.OutputColumns()) } diff --git a/go/vt/vtgate/planbuilder/joinGen4.go b/go/vt/vtgate/planbuilder/joinGen4.go deleted file mode 100644 index 04a408b1fb4..00000000000 --- a/go/vt/vtgate/planbuilder/joinGen4.go +++ /dev/null @@ -1,98 +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 planbuilder - -import ( - "fmt" - - "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/plancontext" - "vitess.io/vitess/go/vt/vtgate/semantics" -) - -var _ logicalPlan = (*joinGen4)(nil) - -// joinGen4 is used to build a Join primitive. -// It's used to build an inner join and only used by the Gen4 planner -type joinGen4 struct { - // Left and Right are the nodes for the join. - Left, Right logicalPlan - - // The Opcode tells us if this is an inner or outer join - Opcode engine.JoinOpcode - - // These are the columns that will be produced by this plan. - // Negative offsets come from the LHS, and positive from the RHS - Cols []int - - // Vars are the columns that will be sent from the LHS to the RHS - // the number is the offset on the LHS result, and the string is the bind variable name used in the RHS - Vars map[string]int - - // LHSColumns are the columns from the LHS used for the join. - // These are the same columns pushed on the LHS that are now used in the Vars field - LHSColumns []*sqlparser.ColName - - gen4Plan -} - -// WireupGen4 implements the logicalPlan interface -func (j *joinGen4) WireupGen4(ctx *plancontext.PlanningContext) error { - err := j.Left.WireupGen4(ctx) - if err != nil { - return err - } - return j.Right.WireupGen4(ctx) -} - -// Primitive implements the logicalPlan interface -func (j *joinGen4) Primitive() engine.Primitive { - return &engine.Join{ - Left: j.Left.Primitive(), - Right: j.Right.Primitive(), - Cols: j.Cols, - Vars: j.Vars, - Opcode: j.Opcode, - } -} - -// Inputs implements the logicalPlan interface -func (j *joinGen4) Inputs() []logicalPlan { - return []logicalPlan{j.Left, j.Right} -} - -// Rewrite implements the logicalPlan interface -func (j *joinGen4) Rewrite(inputs ...logicalPlan) error { - if len(inputs) != 2 { - return vterrors.VT13001(fmt.Sprintf("wrong number of children in joinGen4 rewrite, got: %d, expect: 2", len(inputs))) - } - j.Left = inputs[0] - j.Right = inputs[1] - return nil -} - -// ContainsTables implements the logicalPlan interface -func (j *joinGen4) ContainsTables() semantics.TableSet { - return j.Left.ContainsTables().Merge(j.Right.ContainsTables()) -} - -// OutputColumns implements the logicalPlan interface -func (j *joinGen4) OutputColumns() []sqlparser.SelectExpr { - return getOutputColumnsFromJoin(j.Cols, j.Left.OutputColumns(), j.Right.OutputColumns()) -} diff --git a/go/vt/vtgate/planbuilder/jointab.go b/go/vt/vtgate/planbuilder/jointab.go deleted file mode 100644 index 956f7330bda..00000000000 --- a/go/vt/vtgate/planbuilder/jointab.go +++ /dev/null @@ -1,78 +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 planbuilder - -import ( - "fmt" - - "vitess.io/vitess/go/vt/sqlparser" -) - -// jointab manages procurement and naming of join -// variables across primitives. -type jointab struct { - refs map[*column]string - reserved *sqlparser.ReservedVars - varIndex int -} - -// newJointab creates a new jointab for the current plan -// being built. It also needs the current list of bind vars -// used in the original query to make sure that the names -// it generates don't collide with those already in use. -func newJointab(reserved *sqlparser.ReservedVars) *jointab { - return &jointab{ - refs: make(map[*column]string), - reserved: reserved, - } -} - -// Procure requests for the specified column from the plan -// and returns the join var name for it. -func (jt *jointab) Procure(plan logicalPlan, col *sqlparser.ColName, to int) string { - from, joinVar := jt.Lookup(col) - // If joinVar is empty, generate a unique name. - if joinVar == "" { - joinVar = jt.reserved.ReserveColName(col) - jt.refs[col.Metadata.(*column)] = joinVar - } - plan.SupplyVar(from, to, col, joinVar) - return joinVar -} - -// GenerateSubqueryVars generates substitution variable names for -// a subquery. It returns two names based on: __sq, __sq_has_values. -// The appropriate names can be used for substitution -// depending on the scenario. -func (jt *jointab) GenerateSubqueryVars() (sq, hasValues string) { - for { - jt.varIndex++ - var1 := fmt.Sprintf("__sq%d", jt.varIndex) - var2 := fmt.Sprintf("__sq_has_values%d", jt.varIndex) - if !jt.reserved.ReserveAll(var1, var2) { - continue - } - return var1, var2 - } -} - -// Lookup returns the order of the route that supplies the column and -// the join var name if one has already been assigned for it. -func (jt *jointab) Lookup(col *sqlparser.ColName) (order int, joinVar string) { - c := col.Metadata.(*column) - return c.Origin().Order(), jt.refs[c] -} diff --git a/go/vt/vtgate/planbuilder/jointab_test.go b/go/vt/vtgate/planbuilder/jointab_test.go deleted file mode 100644 index 6bfc23c155c..00000000000 --- a/go/vt/vtgate/planbuilder/jointab_test.go +++ /dev/null @@ -1,46 +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 planbuilder - -import ( - "reflect" - "testing" - - "vitess.io/vitess/go/vt/sqlparser" -) - -func TestGenerateSubqueryVars(t *testing.T) { - reserved := sqlparser.NewReservedVars("vtg", map[string]struct{}{ - "__sq1": {}, - "__sq_has_values3": {}, - }) - jt := newJointab(reserved) - - v1, v2 := jt.GenerateSubqueryVars() - combined := []string{v1, v2} - want := []string{"__sq2", "__sq_has_values2"} - if !reflect.DeepEqual(combined, want) { - t.Errorf("jt.GenerateSubqueryVars: %v, want %v", combined, want) - } - - v1, v2 = jt.GenerateSubqueryVars() - combined = []string{v1, v2} - want = []string{"__sq4", "__sq_has_values4"} - if !reflect.DeepEqual(combined, want) { - t.Errorf("jt.GenerateSubqueryVars: %v, want %v", combined, want) - } -} diff --git a/go/vt/vtgate/planbuilder/logical_plan.go b/go/vt/vtgate/planbuilder/logical_plan.go index 363c012daf8..51ed8e72b0e 100644 --- a/go/vt/vtgate/planbuilder/logical_plan.go +++ b/go/vt/vtgate/planbuilder/logical_plan.go @@ -29,50 +29,9 @@ import ( // logicalPlan defines the interface that a primitive must // satisfy. type logicalPlan interface { - // Order is the execution order of the primitive. If there are subprimitives, - // the order is one above the order of the subprimitives. - // This is because the primitive executes its subprimitives first and - // processes their results to generate its own values. - // Please copy code from an existing primitive to define this function. - Order() int - // ResultColumns returns the list of result columns the - // primitive returns. - // Please copy code from an existing primitive to define this function. - ResultColumns() []*resultColumn - - // Reorder reassigns order for the primitive and its sub-primitives. - // The input is the order of the previous primitive that should - // execute before this one. - Reorder(int) - - // Wireup performs the wire-up work. Nodes should be traversed - // from right to left because the rhs nodes can request vars from - // the lhs nodes. - Wireup(lp logicalPlan, jt *jointab) error - - // WireupGen4 does the wire up work for the Gen4 planner - WireupGen4(*plancontext.PlanningContext) error - - // SupplyVar finds the common root between from and to. If it's - // the common root, it supplies the requested var to the rhs tree. - // If the primitive already has the column in its list, it should - // just supply it to the 'to' node. Otherwise, it should request - // for it by calling SupplyCol on the 'from' sub-tree to request the - // column, and then supply it to the 'to' node. - SupplyVar(from, to int, col *sqlparser.ColName, varname string) - - // SupplyCol is meant to be used for the wire-up process. This function - // changes the primitive to supply the requested column and returns - // the resultColumn and column number of the result. SupplyCol - // is different from PushSelect because it may reuse an existing - // resultColumn, whereas PushSelect guarantees the addition of a new - // result column and returns a distinct symbol for it. - SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) - - // SupplyWeightString must supply a weight_string expression of the - // specified column. It returns an error if we cannot supply a weight column for it. - SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) + // Wireup does the wire up of primitive with the source. + Wireup(*plancontext.PlanningContext) error // Primitive returns the underlying primitive. // This function should only be called after Wireup is finished. @@ -92,59 +51,6 @@ type logicalPlan interface { OutputColumns() []sqlparser.SelectExpr } -// gen4Plan implements a few methods from logicalPlan that are unused by Gen4. -type gen4Plan struct{} - -// Order implements the logicalPlan interface -func (*gen4Plan) Order() int { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// ResultColumns implements the logicalPlan interface -func (*gen4Plan) ResultColumns() []*resultColumn { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// Reorder implements the logicalPlan interface -func (*gen4Plan) Reorder(int) { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// Wireup implements the logicalPlan interface -func (*gen4Plan) Wireup(logicalPlan, *jointab) error { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// SupplyVar implements the logicalPlan interface -func (*gen4Plan) SupplyVar(int, int, *sqlparser.ColName, string) { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// SupplyCol implements the logicalPlan interface -func (*gen4Plan) SupplyCol(*sqlparser.ColName) (rc *resultColumn, colNumber int) { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// SupplyWeightString implements the logicalPlan interface -func (*gen4Plan) SupplyWeightString(int, bool) (weightcolNumber int, err error) { - panic("[BUG]: should not be called. This is a Gen4 primitive") -} - -// v3Plan implements methods that are only used by gen4 -type v3Plan struct{} - -func (*v3Plan) WireupGen4(*plancontext.PlanningContext) error { - panic("[BUG]: should not be called. This is a V3 primitive") -} - -func (*v3Plan) ContainsTables() semantics.TableSet { - panic("[BUG]: should not be called. This is a V3 primitive") -} - -func (*v3Plan) OutputColumns() []sqlparser.SelectExpr { - panic("[BUG]: should not be called. This is a V3 primitive") -} - type planVisitor func(logicalPlan) (bool, logicalPlan, error) func visit(node logicalPlan, visitor planVisitor) (logicalPlan, error) { @@ -180,16 +86,6 @@ func visit(node logicalPlan, visitor planVisitor) (logicalPlan, error) { return node, nil } -// first returns the first logical plan of the tree, -// which is usually the left most leaf. -func first(input logicalPlan) logicalPlan { - inputs := input.Inputs() - if len(inputs) == 0 { - return input - } - return first(inputs[0]) -} - // ------------------------------------------------------------------------- // logicalPlanCommon implements some common functionality of builders. @@ -207,33 +103,8 @@ func (bc *logicalPlanCommon) Order() int { return bc.order } -func (bc *logicalPlanCommon) Reorder(order int) { - bc.input.Reorder(order) - bc.order = bc.input.Order() + 1 -} - -func (bc *logicalPlanCommon) ResultColumns() []*resultColumn { - return bc.input.ResultColumns() -} - -func (bc *logicalPlanCommon) Wireup(plan logicalPlan, jt *jointab) error { - return bc.input.Wireup(plan, jt) -} - -func (bc *logicalPlanCommon) WireupGen4(ctx *plancontext.PlanningContext) error { - return bc.input.WireupGen4(ctx) -} - -func (bc *logicalPlanCommon) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - bc.input.SupplyVar(from, to, col, varname) -} - -func (bc *logicalPlanCommon) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - return bc.input.SupplyCol(col) -} - -func (bc *logicalPlanCommon) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - return bc.input.SupplyWeightString(colNumber, alsoAddToGroupBy) +func (bc *logicalPlanCommon) Wireup(ctx *plancontext.PlanningContext) error { + return bc.input.Wireup(ctx) } // Rewrite implements the logicalPlan interface @@ -266,67 +137,12 @@ func (bc *logicalPlanCommon) OutputColumns() []sqlparser.SelectExpr { // resultsColumn functionality. type resultsBuilder struct { logicalPlanCommon - resultColumns []*resultColumn - weightStrings map[*resultColumn]int - truncater truncater + truncater truncater } func newResultsBuilder(input logicalPlan, truncater truncater) resultsBuilder { return resultsBuilder{ logicalPlanCommon: newBuilderCommon(input), - resultColumns: input.ResultColumns(), - weightStrings: make(map[*resultColumn]int), truncater: truncater, } } - -func (rsb *resultsBuilder) ResultColumns() []*resultColumn { - return rsb.resultColumns -} - -// SupplyCol is currently unreachable because the builders using resultsBuilder -// are currently above a join, which is the only logicalPlan that uses it for now. -// This can change if we start supporting correlated subqueries. -func (rsb *resultsBuilder) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - c := col.Metadata.(*column) - for i, rc := range rsb.resultColumns { - if rc.column == c { - return rc, i - } - } - rc, colNumber = rsb.input.SupplyCol(col) - if colNumber < len(rsb.resultColumns) { - return rc, colNumber - } - // Add result columns from input until colNumber is reached. - for colNumber >= len(rsb.resultColumns) { - rsb.resultColumns = append(rsb.resultColumns, rsb.input.ResultColumns()[len(rsb.resultColumns)]) - } - rsb.truncater.SetTruncateColumnCount(len(rsb.resultColumns)) - return rc, colNumber -} - -func (rsb *resultsBuilder) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - rc := rsb.resultColumns[colNumber] - var ok bool - weightcolNumber, ok = rsb.weightStrings[rc] - if !alsoAddToGroupBy && ok { - return weightcolNumber, nil - } - weightcolNumber, err = rsb.input.SupplyWeightString(colNumber, alsoAddToGroupBy) - if err != nil { - return 0, nil - } - rsb.weightStrings[rc] = weightcolNumber - if weightcolNumber < len(rsb.resultColumns) { - return weightcolNumber, nil - } - // Add result columns from input until weightcolNumber is reached. - for weightcolNumber >= len(rsb.resultColumns) { - rsb.resultColumns = append(rsb.resultColumns, rsb.input.ResultColumns()[len(rsb.resultColumns)]) - } - rsb.truncater.SetTruncateColumnCount(len(rsb.resultColumns)) - return weightcolNumber, nil -} - -// ------------------------------------------------------------------------- diff --git a/go/vt/vtgate/planbuilder/memory_sort.go b/go/vt/vtgate/planbuilder/memory_sort.go index 20dd125ecd0..d32777ac123 100644 --- a/go/vt/vtgate/planbuilder/memory_sort.go +++ b/go/vt/vtgate/planbuilder/memory_sort.go @@ -17,14 +17,10 @@ limitations under the License. package planbuilder import ( - "fmt" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" ) @@ -41,67 +37,6 @@ type memorySort struct { eMemorySort *engine.MemorySort } -func findColNumber(ms *memorySort, expr *sqlparser.ColName) int { - c := expr.Metadata.(*column) - for i, rc := range ms.ResultColumns() { - if rc.column == c { - return i - } - } - return -1 -} - -// newMemorySort builds a new memorySort. -func newMemorySort(plan logicalPlan, orderBy v3OrderBy) (*memorySort, error) { - eMemorySort := &engine.MemorySort{} - ms := &memorySort{ - resultsBuilder: newResultsBuilder(plan, eMemorySort), - eMemorySort: eMemorySort, - } - for _, order := range orderBy { - var colNumber int - switch expr := order.Expr.(type) { - case *sqlparser.Literal: - var err error - if colNumber, err = ResultFromNumber(ms.ResultColumns(), expr, "order clause"); err != nil { - return nil, err - } - case *sqlparser.ColName: - colNumber = findColNumber(ms, expr) - case *sqlparser.CastExpr: - colName, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, vterrors.VT12001(fmt.Sprintf("memory sort: complex ORDER BY expression: %s", sqlparser.String(expr))) - } - colNumber = findColNumber(ms, colName) - case *sqlparser.ConvertExpr: - colName, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, vterrors.VT12001(fmt.Sprintf("memory sort: complex ORDER BY expression: %s", sqlparser.String(expr))) - } - colNumber = findColNumber(ms, colName) - default: - return nil, vterrors.VT12001(fmt.Sprintf("memory sort: complex ORDER BY expression: %s", sqlparser.String(expr))) - } - // If column is not found, then the order by is referencing - // a column that's not on the select list. - if colNumber == -1 { - return nil, vterrors.VT12001(fmt.Sprintf("memory sort: ORDER BY must reference a column in the SELECT list: %s", sqlparser.String(order))) - } - // TODO(king-11) need to pass in collation here - ob := engine.OrderByParams{ - Col: colNumber, - WeightStringCol: -1, - Desc: order.Direction == sqlparser.DescOrder, - StarColFixedIndex: colNumber, - FromGroupBy: order.fromGroupBy, - CollationID: collations.Unknown, - } - ms.eMemorySort.OrderBy = append(ms.eMemorySort.OrderBy, ob) - } - return ms, nil -} - // Primitive implements the logicalPlan interface func (ms *memorySort) Primitive() engine.Primitive { ms.eMemorySort.Input = ms.input.Primitive() @@ -113,32 +48,6 @@ func (ms *memorySort) SetLimit(limit *sqlparser.Limit) error { return vterrors.VT13001("memorySort.Limit: unreachable") } -// Wireup implements the logicalPlan interface -// If text columns are detected in the keys, then the function modifies -// the primitive to pull a corresponding weight_string from mysql and -// compare those instead. This is because we currently don't have the -// ability to mimic mysql's collation behavior. -func (ms *memorySort) Wireup(plan logicalPlan, jt *jointab) error { - for i, orderby := range ms.eMemorySort.OrderBy { - rc := ms.resultColumns[orderby.Col] - // Add a weight_string column if we know that the column is a textual column or if its type is unknown - if sqltypes.IsText(rc.column.typ) || rc.column.typ == sqltypes.Null { - weightcolNumber, err := ms.input.SupplyWeightString(orderby.Col, orderby.FromGroupBy) - if err != nil { - _, isUnsupportedErr := err.(UnsupportedSupplyWeightString) - if isUnsupportedErr { - continue - } - return err - } - ms.weightStrings[rc] = weightcolNumber - ms.eMemorySort.OrderBy[i].WeightStringCol = weightcolNumber - ms.eMemorySort.TruncateColumnCount = len(ms.resultColumns) - } - } - return ms.input.Wireup(plan, jt) -} - -func (ms *memorySort) WireupGen4(ctx *plancontext.PlanningContext) error { - return ms.input.WireupGen4(ctx) +func (ms *memorySort) Wireup(ctx *plancontext.PlanningContext) error { + return ms.input.Wireup(ctx) } diff --git a/go/vt/vtgate/planbuilder/merge_sort.go b/go/vt/vtgate/planbuilder/merge_sort.go index 4e72d062241..0da5b5fc135 100644 --- a/go/vt/vtgate/planbuilder/merge_sort.go +++ b/go/vt/vtgate/planbuilder/merge_sort.go @@ -17,7 +17,6 @@ limitations under the License. package planbuilder import ( - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -37,15 +36,6 @@ type mergeSort struct { truncateColumnCount int } -// newMergeSort builds a new mergeSort. -func newMergeSort(rb *route) *mergeSort { - ms := &mergeSort{ - resultsBuilder: newResultsBuilder(rb, nil), - } - ms.truncater = ms - return ms -} - // SetTruncateColumnCount satisfies the truncater interface. // This function records the truncate column count and sets // it later on the eroute during wire-up phase. @@ -58,35 +48,8 @@ func (ms *mergeSort) Primitive() engine.Primitive { return ms.input.Primitive() } -// Wireup implements the logicalPlan interface -func (ms *mergeSort) Wireup(plan logicalPlan, jt *jointab) error { - // If the route has to do the ordering, and if any columns are Text, - // we have to request the corresponding weight_string from mysql - // and use that value instead. This is because we cannot mimic - // mysql's collation behavior yet. - rb := ms.input.(*route) - for i, orderby := range rb.eroute.OrderBy { - rc := ms.resultColumns[orderby.Col] - // Add a weight_string column if we know that the column is a textual column or if its type is unknown - if sqltypes.IsText(rc.column.typ) || rc.column.typ == sqltypes.Null { - var err error - rb.eroute.OrderBy[i].WeightStringCol, err = rb.SupplyWeightString(orderby.Col, orderby.FromGroupBy) - if err != nil { - _, isUnsupportedErr := err.(UnsupportedSupplyWeightString) - if isUnsupportedErr { - continue - } - return err - } - ms.truncateColumnCount = len(ms.resultColumns) - } - } - rb.eroute.TruncateColumnCount = ms.truncateColumnCount - return ms.input.Wireup(plan, jt) -} - -func (ms *mergeSort) WireupGen4(ctx *plancontext.PlanningContext) error { - return ms.input.WireupGen4(ctx) +func (ms *mergeSort) Wireup(ctx *plancontext.PlanningContext) error { + return ms.input.Wireup(ctx) } // OutputColumns implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 307936d3c08..2334edf21de 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -17,6 +17,7 @@ limitations under the License. package planbuilder import ( + "bytes" "fmt" "sort" "strconv" @@ -77,10 +78,7 @@ func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggrega } oa := &orderedAggregate{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(plan), - weightStrings: make(map[*resultColumn]int), - }, + resultsBuilder: newResultsBuilder(plan, nil), } for _, aggr := range op.Aggregations { @@ -133,12 +131,8 @@ func createMemorySort(ctx *plancontext.PlanningContext, src logicalPlan, orderin TruncateColumnCount: ordering.ResultColumns, } ms := &memorySort{ - resultsBuilder: resultsBuilder{ - logicalPlanCommon: newBuilderCommon(src), - weightStrings: make(map[*resultColumn]int), - truncater: primitive, - }, - eMemorySort: primitive, + resultsBuilder: newResultsBuilder(src, primitive), + eMemorySort: primitive, } for idx, order := range ordering.Order { @@ -290,7 +284,7 @@ func transformHorizon(ctx *plancontext.PlanningContext, op *operators.Horizon, i return planLimit(node.Limit, plan) case *sqlparser.Union: var err error - rb, isRoute := source.(*routeGen4) + rb, isRoute := source.(*route) if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { return nil, ctx.SemTable.NotSingleRouteErr } @@ -324,7 +318,7 @@ func transformApplyJoinPlan(ctx *plancontext.PlanningContext, n *operators.Apply opCode = engine.LeftJoin } - return &joinGen4{ + return &join{ Left: lhs, Right: rhs, Cols: n.Columns, @@ -394,7 +388,7 @@ func transformRoutePlan(ctx *plancontext.PlanningContext, op *operators.Route) ( if err != nil { return nil, err } - return &routeGen4{ + return &route{ eroute: eroute, Select: sel, tables: operators.TableID(op), @@ -663,7 +657,7 @@ func transformUnionPlan(ctx *plancontext.PlanningContext, op *operators.Union, i var result logicalPlan if len(sources) == 1 { src := sources[0] - if rb, isRoute := src.(*routeGen4); isRoute && rb.isSingleShard() { + if rb, isRoute := src.(*route); isRoute && rb.isSingleShard() { // if we have a single shard route, we don't need to do anything to make it distinct // TODO // rb.Select.SetLimit(op.limit) @@ -675,7 +669,7 @@ func transformUnionPlan(ctx *plancontext.PlanningContext, op *operators.Union, i if len(op.Ordering) > 0 { return nil, vterrors.VT12001("ORDER BY on top of UNION") } - result = &concatenateGen4{sources: sources} + result = &concatenate{sources: sources} } if op.Distinct { colls := getCollationsFor(ctx, op) @@ -721,7 +715,7 @@ func getCheckColsForUnion(ctx *plancontext.PlanningContext, result logicalPlan, // pushWeightStringForDistinct adds a weight_string projection func pushWeightStringForDistinct(ctx *plancontext.PlanningContext, plan logicalPlan, offset int) (newOffset int, err error) { switch node := plan.(type) { - case *routeGen4: + case *route: allSelects := sqlparser.GetAllSelects(node.Select) for _, sel := range allSelects { expr, err := getWeightStringForSelectExpr(sel.SelectExprs[offset]) @@ -736,7 +730,7 @@ func pushWeightStringForDistinct(ctx *plancontext.PlanningContext, plan logicalP } // we leave the responsibility of truncating to distinct node.eroute.TruncateColumnCount = 0 - case *concatenateGen4: + case *concatenate: for _, source := range node.sources { newOffset, err = pushWeightStringForDistinct(ctx, source, offset) if err != nil { @@ -744,7 +738,7 @@ func pushWeightStringForDistinct(ctx *plancontext.PlanningContext, plan logicalP } } node.noNeedToTypeCheck = append(node.noNeedToTypeCheck, newOffset) - case *joinGen4: + case *join: joinOffset := node.Cols[offset] switch { case joinOffset < 0: @@ -880,7 +874,7 @@ func transformDerivedPlan(ctx *plancontext.PlanningContext, op *operators.Horizo return nil, err } - rb, isRoute := plan.(*routeGen4) + rb, isRoute := plan.(*route) if !isRoute { return &simpleProjection{ logicalPlanCommon: newBuilderCommon(plan), @@ -941,9 +935,9 @@ func (sqr *subQReplacer) replacer(cursor *sqlparser.Cursor) bool { func pushDistinct(plan logicalPlan) { switch n := plan.(type) { - case *routeGen4: + case *route: n.Select.MakeDistinct() - case *concatenateGen4: + case *concatenate: for _, source := range n.sources { pushDistinct(source) } @@ -951,11 +945,11 @@ func pushDistinct(plan logicalPlan) { } func mergeUnionLogicalPlans(ctx *plancontext.PlanningContext, left logicalPlan, right logicalPlan) logicalPlan { - lroute, ok := left.(*routeGen4) + lroute, ok := left.(*route) if !ok { return nil } - rroute, ok := right.(*routeGen4) + rroute, ok := right.(*route) if !ok { return nil } @@ -967,7 +961,7 @@ func mergeUnionLogicalPlans(ctx *plancontext.PlanningContext, left logicalPlan, return nil } -func canMergeUnionPlans(ctx *plancontext.PlanningContext, a, b *routeGen4) bool { +func canMergeUnionPlans(ctx *plancontext.PlanningContext, a, b *route) bool { // this method should be close to tryMerge below. it does the same thing, but on logicalPlans instead of queryTrees if a.eroute.Keyspace.Name != b.eroute.Keyspace.Name { return false @@ -994,7 +988,7 @@ func canMergeUnionPlans(ctx *plancontext.PlanningContext, a, b *routeGen4) bool return false } -func canSelectDBAMerge(a, b *routeGen4) bool { +func canSelectDBAMerge(a, b *route) bool { if a.eroute.Opcode != engine.DBA { return false } @@ -1080,3 +1074,21 @@ func gen4ValEqual(ctx *plancontext.PlanningContext, a, b sqlparser.Expr) bool { } return false } + +func hexEqual(a, b *sqlparser.Literal) bool { + v, err := a.HexDecode() + if err != nil { + return false + } + switch b.Type { + case sqlparser.StrVal: + return bytes.Equal(v, b.Bytes()) + case sqlparser.HexVal: + v2, err := b.HexDecode() + if err != nil { + return false + } + return bytes.Equal(v, v2) + } + return false +} diff --git a/go/vt/vtgate/planbuilder/ordered_aggregate.go b/go/vt/vtgate/planbuilder/ordered_aggregate.go index 490935889f5..3bacc7d3b27 100644 --- a/go/vt/vtgate/planbuilder/ordered_aggregate.go +++ b/go/vt/vtgate/planbuilder/ordered_aggregate.go @@ -17,16 +17,8 @@ limitations under the License. package planbuilder import ( - "fmt" - "strconv" - "strings" - - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" - popcode "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -73,151 +65,6 @@ type orderedAggregate struct { truncateColumnCount int } -// checkAggregates analyzes the select expression for aggregates. If it determines -// that a primitive is needed to handle the aggregation, it builds an orderedAggregate -// primitive and returns it. It returns a groupByHandler if there is aggregation it -// can handle. -func (pb *primitiveBuilder) checkAggregates(sel *sqlparser.Select) error { - rb, isRoute := pb.plan.(*route) - if isRoute && rb.isSingleShard() { - // since we can push down all of the aggregation to the route, - // we don't need to do anything else here - return nil - } - - // Check if we can allow aggregates. - hasAggregates := sqlparser.ContainsAggregation(sel.SelectExprs) || len(sel.GroupBy) > 0 - if !hasAggregates && !sel.Distinct { - return nil - } - - // The query has aggregates. We can proceed only - // if the underlying primitive is a route because - // we need the ability to push down group by and - // order by clauses. - if !isRoute { - if hasAggregates { - return vterrors.VT12001("cross-shard query with aggregates") - } - pb.plan = newDistinctV3(pb.plan) - return nil - } - - // If there is a distinct clause, we can check the select list - // to see if it has a unique vindex reference. For example, - // if the query was 'select distinct id, col from t' (with id - // as a unique vindex), then the distinct operation can be - // safely pushed down because the unique vindex guarantees - // that each id can only be in a single shard. Without the - // unique vindex property, the id could come from multiple - // shards, which will require us to perform the grouping - // at the vtgate level. - if sel.Distinct { - for _, selectExpr := range sel.SelectExprs { - switch selectExpr := selectExpr.(type) { - case *sqlparser.AliasedExpr: - vindex := pb.st.Vindex(selectExpr.Expr, rb) - if vindex != nil && vindex.IsUnique() { - return nil - } - } - } - } - - // The group by clause could also reference a unique vindex. The above - // example could itself have been written as - // 'select id, col from t group by id, col', or a query could be like - // 'select id, count(*) from t group by id'. In the above cases, - // the grouping can be done at the shard level, which allows the entire query - // to be pushed down. In order to perform this analysis, we're going to look - // ahead at the group by clause to see if it references a unique vindex. - if pb.groupByHasUniqueVindex(sel, rb) { - return nil - } - - // We need an aggregator primitive. - oa := &orderedAggregate{} - oa.resultsBuilder = newResultsBuilder(rb, oa) - pb.plan = oa - pb.plan.Reorder(0) - return nil -} - -// groupbyHasUniqueVindex looks ahead at the group by expression to see if -// it references a unique vindex. -// -// The vitess group by rules are different from MySQL because it's not possible -// to match the MySQL behavior without knowing the schema. For example: -// 'select id as val from t group by val' will have different interpretations -// under MySQL depending on whether t has a val column or not. -// In vitess, we always assume that 'val' references 'id'. This is achieved -// by the symbol table resolving against the select list before searching -// the tables. -// -// In order to look ahead, we have to overcome the chicken-and-egg problem: -// group by needs the select aliases to be built. Select aliases are built -// on push-down. But push-down decision depends on whether group by expressions -// reference a vindex. -// To overcome this, the look-ahead has to perform a search that matches -// the group by analyzer. The flow is similar to oa.PushGroupBy, except that -// we don't search the ResultColumns because they're not created yet. Also, -// error conditions are treated as no match for simplicity; They will be -// subsequently caught downstream. -func (pb *primitiveBuilder) groupByHasUniqueVindex(sel *sqlparser.Select, rb *route) bool { - for _, expr := range sel.GroupBy { - var matchedExpr sqlparser.Expr - switch node := expr.(type) { - case *sqlparser.ColName: - if expr := findAlias(node, sel.SelectExprs); expr != nil { - matchedExpr = expr - } else { - matchedExpr = node - } - case *sqlparser.Literal: - if node.Type != sqlparser.IntVal { - continue - } - num, err := strconv.ParseInt(node.Val, 0, 64) - if err != nil { - continue - } - if num < 1 || num > int64(len(sel.SelectExprs)) { - continue - } - expr, ok := sel.SelectExprs[num-1].(*sqlparser.AliasedExpr) - if !ok { - continue - } - matchedExpr = expr.Expr - default: - continue - } - vindex := pb.st.Vindex(matchedExpr, rb) - if vindex != nil && vindex.IsUnique() { - return true - } - } - return false -} - -func findAlias(colname *sqlparser.ColName, selects sqlparser.SelectExprs) sqlparser.Expr { - // Qualified column names cannot match an (unqualified) alias. - if !colname.Qualifier.IsEmpty() { - return nil - } - // See if this references an alias. - for _, selectExpr := range selects { - selectExpr, ok := selectExpr.(*sqlparser.AliasedExpr) - if !ok { - continue - } - if colname.Name.Equal(selectExpr.As) { - return selectExpr.Expr - } - } - return nil -} - // Primitive implements the logicalPlan interface func (oa *orderedAggregate) Primitive() engine.Primitive { input := oa.input.Primitive() @@ -237,132 +84,8 @@ func (oa *orderedAggregate) Primitive() engine.Primitive { } } -func (oa *orderedAggregate) pushAggr(pb *primitiveBuilder, expr *sqlparser.AliasedExpr, origin logicalPlan) (rc *resultColumn, colNumber int, err error) { - aggrFunc, _ := expr.Expr.(sqlparser.AggrFunc) - origOpcode := popcode.SupportedAggregates[strings.ToLower(aggrFunc.AggrName())] - opcode := origOpcode - if aggrFunc.GetArgs() != nil && - len(aggrFunc.GetArgs()) != 1 { - return nil, 0, vterrors.VT12001(fmt.Sprintf("only one expression is allowed inside aggregates: %s", sqlparser.String(expr))) - } - - handleDistinct, innerAliased, err := oa.needDistinctHandling(pb, expr, opcode) - if err != nil { - return nil, 0, err - } - if handleDistinct { - if oa.extraDistinct != nil { - return nil, 0, vterrors.VT12001(fmt.Sprintf("only one DISTINCT aggregation allowed in a SELECT: %s", sqlparser.String(expr))) - } - // Push the expression that's inside the aggregate. - // The column will eventually get added to the group by and order by clauses. - newBuilder, _, innerCol, err := planProjection(pb, oa.input, innerAliased, origin) - if err != nil { - return nil, 0, err - } - pb.plan = newBuilder - col, err := BuildColName(oa.input.ResultColumns(), innerCol) - if err != nil { - return nil, 0, err - } - oa.extraDistinct = col - switch opcode { - case popcode.AggregateCount: - opcode = popcode.AggregateCountDistinct - case popcode.AggregateSum: - opcode = popcode.AggregateSumDistinct - } - aggr := engine.NewAggregateParam(opcode, innerCol, expr.ColumnName()) - aggr.OrigOpcode = origOpcode - oa.aggregates = append(oa.aggregates, aggr) - } else { - newBuilder, _, innerCol, err := planProjection(pb, oa.input, expr, origin) - if err != nil { - return nil, 0, err - } - pb.plan = newBuilder - aggr := engine.NewAggregateParam(opcode, innerCol, "") - aggr.OrigOpcode = origOpcode - oa.aggregates = append(oa.aggregates, aggr) - } - - // Build a new rc with oa as origin because it's semantically different - // from the expression we pushed down. - rc = newResultColumn(expr, oa) - oa.resultColumns = append(oa.resultColumns, rc) - return rc, len(oa.resultColumns) - 1, nil -} - -// needDistinctHandling returns true if oa needs to handle the distinct clause. -// If true, it will also return the aliased expression that needs to be pushed -// down into the underlying route. -func (oa *orderedAggregate) needDistinctHandling(pb *primitiveBuilder, expr *sqlparser.AliasedExpr, opcode popcode.AggregateOpcode) (bool, *sqlparser.AliasedExpr, error) { - var innerAliased *sqlparser.AliasedExpr - aggr, ok := expr.Expr.(sqlparser.AggrFunc) - - if !ok { - return false, nil, vterrors.VT03012(sqlparser.String(expr)) - } - - if !sqlparser.IsDistinct(aggr) { - return false, nil, nil - } - if opcode != popcode.AggregateCount && opcode != popcode.AggregateSum && opcode != popcode.AggregateCountStar { - return false, nil, nil - } - - innerAliased = &sqlparser.AliasedExpr{Expr: aggr.GetArg()} - - rb, ok := oa.input.(*route) - if !ok { - // Unreachable - return true, innerAliased, nil - } - vindex := pb.st.Vindex(innerAliased.Expr, rb) - if vindex != nil && vindex.IsUnique() { - return false, nil, nil - } - return true, innerAliased, nil -} - -// Wireup implements the logicalPlan interface -// If text columns are detected in the keys, then the function modifies -// the primitive to pull a corresponding weight_string from mysql and -// compare those instead. This is because we currently don't have the -// ability to mimic mysql's collation behavior. -func (oa *orderedAggregate) Wireup(plan logicalPlan, jt *jointab) error { - for i, gbk := range oa.groupByKeys { - rc := oa.resultColumns[gbk.KeyCol] - if sqltypes.IsText(rc.column.typ) { - weightcolNumber, err := oa.input.SupplyWeightString(gbk.KeyCol, gbk.FromGroupBy) - if err != nil { - _, isUnsupportedErr := err.(UnsupportedSupplyWeightString) - if isUnsupportedErr { - continue - } - return err - } - oa.weightStrings[rc] = weightcolNumber - oa.groupByKeys[i].WeightStringCol = weightcolNumber - oa.groupByKeys[i].KeyCol = weightcolNumber - oa.truncateColumnCount = len(oa.resultColumns) - } - } - for _, key := range oa.aggregates { - switch key.Opcode { - case popcode.AggregateCount: - if key.Alias == "" { - key.Alias = key.Opcode.String() - } - key.Opcode = popcode.AggregateSum - } - } - - return oa.input.Wireup(plan, jt) -} - -func (oa *orderedAggregate) WireupGen4(ctx *plancontext.PlanningContext) error { - return oa.input.WireupGen4(ctx) +func (oa *orderedAggregate) Wireup(ctx *plancontext.PlanningContext) error { + return oa.input.Wireup(ctx) } // OutputColumns implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/ordering.go b/go/vt/vtgate/planbuilder/ordering.go deleted file mode 100644 index 2a8613620e7..00000000000 --- a/go/vt/vtgate/planbuilder/ordering.go +++ /dev/null @@ -1,356 +0,0 @@ -/* -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 planbuilder - -import ( - "fmt" - - "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/engine" -) - -type v3Order struct { - *sqlparser.Order - fromGroupBy bool -} - -type v3OrderBy []*v3Order - -func planOrdering(pb *primitiveBuilder, input logicalPlan, orderBy v3OrderBy) (logicalPlan, error) { - switch node := input.(type) { - case *simpleProjection, *vindexFunc: - if len(orderBy) == 0 { - return node, nil - } - return newMemorySort(node, orderBy) - case *distinct: - // TODO: this is weird, but needed - newInput, err := planOrdering(pb, node.input, orderBy) - node.input = newInput - return node, err - case *pulloutSubquery: - plan, err := planOrdering(pb, node.underlying, orderBy) - if err != nil { - return nil, err - } - node.underlying = plan - return node, nil - case *route: - return planRouteOrdering(orderBy, node) - case *join: - return planJoinOrdering(pb, orderBy, node) - case *orderedAggregate: - return planOAOrdering(pb, orderBy, node) - case *mergeSort: - return nil, vterrors.VT12001("ORDER BY on top of ORDER BY") - case *concatenate: - if len(orderBy) == 0 { - return input, nil - } - return nil, vterrors.VT12001("ORDER BY on top of UNION") - } - return nil, vterrors.VT13001(fmt.Sprintf("unreachable %T.ordering", input)) -} - -func planOAOrdering(pb *primitiveBuilder, orderBy v3OrderBy, oa *orderedAggregate) (logicalPlan, error) { - // The requested order must be such that the ordering can be done - // before the group by, which will allow us to push it down to the - // route. This is actually true in most use cases, except for situations - // where ordering is requested on values of an aggregate result. - // Such constructs will need to be handled by a separate 'Sorter' - // primitive, after aggregation is done. For example, the following - // constructs are allowed: - // 'select a, b, count(*) from t group by a, b order by a desc, b asc' - // 'select a, b, count(*) from t group by a, b order by b' - // The following construct is not allowed: - // 'select a, count(*) from t group by a order by count(*)' - // Treat order by null as nil order by. - if len(orderBy) == 1 { - if _, ok := orderBy[0].Expr.(*sqlparser.NullVal); ok { - orderBy = nil - } - } - - // referenced tracks the keys referenced by the order by clause. - referenced := make([]bool, len(oa.groupByKeys)) - postSort := false - selOrderBy := make(v3OrderBy, 0, len(orderBy)) - for _, order := range orderBy { - // Identify the order by column. - var orderByCol *column - switch expr := order.Expr.(type) { - case *sqlparser.Literal: - num, err := ResultFromNumber(oa.resultColumns, expr, "order clause") - if err != nil { - return nil, err - } - orderByCol = oa.resultColumns[num].column - case *sqlparser.ColName: - orderByCol = expr.Metadata.(*column) - case *sqlparser.CastExpr: - col, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, complexOrderBy(sqlparser.String(expr)) - } - orderByCol = col.Metadata.(*column) - case *sqlparser.ConvertExpr: - col, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, complexOrderBy(sqlparser.String(expr)) - } - orderByCol = col.Metadata.(*column) - default: - return nil, complexOrderBy(sqlparser.String(expr)) - } - - // Match orderByCol against the group by columns. - found := false - for j, groupBy := range oa.groupByKeys { - if oa.resultColumns[groupBy.KeyCol].column != orderByCol { - continue - } - - found = true - referenced[j] = true - order.fromGroupBy = groupBy.FromGroupBy - selOrderBy = append(selOrderBy, order) - break - } - if !found { - postSort = true - } - } - - // Append any unreferenced keys at the end of the order by. - for i, groupByKey := range oa.groupByKeys { - if referenced[i] { - continue - } - // Build a brand new reference for the key. - col, err := BuildColName(oa.input.ResultColumns(), groupByKey.KeyCol) - if err != nil { - return nil, vterrors.Wrapf(err, "generating ORDER BY clause") - } - selOrderBy = append(selOrderBy, &v3Order{ - Order: &sqlparser.Order{Expr: col, Direction: sqlparser.AscOrder}, - fromGroupBy: groupByKey.FromGroupBy, - }) - } - - // Append the distinct aggregate if any. - if oa.extraDistinct != nil { - selOrderBy = append(selOrderBy, &v3Order{ - Order: &sqlparser.Order{Expr: oa.extraDistinct, Direction: sqlparser.AscOrder}, - fromGroupBy: true, - }) - } - - // Push down the order by. - // It's ok to push the original AST down because all references - // should point to the route. Only aggregate functions are originated - // by node, and we currently don't allow the ORDER BY to reference them. - plan, err := planOrdering(pb, oa.input, selOrderBy) - if err != nil { - return nil, err - } - oa.input = plan - if postSort { - return newMemorySort(oa, orderBy) - } - return oa, nil -} - -func planJoinOrdering(pb *primitiveBuilder, orderBy v3OrderBy, node *join) (logicalPlan, error) { - isSpecial := false - switch len(orderBy) { - case 0: - isSpecial = true - case 1: - if _, ok := orderBy[0].Expr.(*sqlparser.NullVal); ok { - isSpecial = true - } else if f, ok := orderBy[0].Expr.(*sqlparser.FuncExpr); ok { - if f.Name.Lowered() == "rand" { - isSpecial = true - } - } - } - if isSpecial { - l, err := planOrdering(pb, node.Left, orderBy) - if err != nil { - return nil, err - } - node.Left = l - r, err := planOrdering(pb, node.Right, orderBy) - if err != nil { - return nil, err - } - node.Right = r - return node, nil - } - - for _, order := range orderBy { - if e, ok := order.Expr.(*sqlparser.Literal); ok { - // This block handles constructs that use ordinals for 'ORDER BY'. For example: - // SELECT a, b, c FROM t1, t2 ORDER BY 1, 2, 3. - num, err := ResultFromNumber(node.ResultColumns(), e, "order clause") - if err != nil { - return nil, err - } - if node.ResultColumns()[num].column.Origin().Order() > node.Left.Order() { - return newMemorySort(node, orderBy) - } - } else { - // Analyze column references within the expression to make sure they all - // go to the left. - err := sqlparser.Walk(func(in sqlparser.SQLNode) (kontinue bool, err error) { - switch e := in.(type) { - case *sqlparser.ColName: - if e.Metadata.(*column).Origin().Order() > node.Left.Order() { - return false, vterrors.VT12001("ORDER BY spans across shards") - } - case *sqlparser.Subquery: - // Unreachable because ResolveSymbols perfoms this check up above. - return false, vterrors.VT12001("ORDER BY has subquery") - } - return true, nil - }, order.Expr) - if err != nil { - return newMemorySort(node, orderBy) - } - } - } - - // There were no errors. We can push the order by to the left-most route. - l, err := planOrdering(pb, node.Left, orderBy) - if err != nil { - return nil, err - } - node.Left = l - // Still need to push an empty order by to the right. - r, err := planOrdering(pb, node.Right, nil) - if err != nil { - return nil, err - } - node.Right = r - return node, nil -} - -func planRouteOrdering(orderBy v3OrderBy, node *route) (logicalPlan, error) { - switch len(orderBy) { - case 0: - return node, nil - case 1: - isSpecial := false - if _, ok := orderBy[0].Expr.(*sqlparser.NullVal); ok { - isSpecial = true - } else if f, ok := orderBy[0].Expr.(*sqlparser.FuncExpr); ok { - if f.Name.Lowered() == "rand" { - isSpecial = true - } - } - if isSpecial { - node.Select.AddOrder(orderBy[0].Order) - return node, nil - } - } - - if node.isSingleShard() { - for _, order := range orderBy { - node.Select.AddOrder(order.Order) - } - return node, nil - } - - // If it's a scatter, we have to populate the OrderBy field. - for _, order := range orderBy { - colNumber := -1 - switch expr := order.Expr.(type) { - case *sqlparser.Literal: - var err error - if colNumber, err = ResultFromNumber(node.resultColumns, expr, "order clause"); err != nil { - return nil, err - } - case *sqlparser.ColName: - c := expr.Metadata.(*column) - for i, rc := range node.resultColumns { - if rc.column == c { - colNumber = i - break - } - } - case *sqlparser.UnaryExpr: - col, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, complexOrderBy(sqlparser.String(expr)) - } - c := col.Metadata.(*column) - for i, rc := range node.resultColumns { - if rc.column == c { - colNumber = i - break - } - } - default: - return nil, complexOrderBy(sqlparser.String(expr)) - } - // If column is not found, then the order by is referencing - // a column that's not on the select list. - if colNumber == -1 { - return nil, vterrors.VT12001(fmt.Sprintf("in scatter query: ORDER BY must reference a column in the SELECT list: %s", sqlparser.String(order))) - } - starColFixedIndex := colNumber - if selectStatement, ok := node.Select.(*sqlparser.Select); ok { - for i, selectExpr := range selectStatement.SelectExprs { - if starExpr, ok := selectExpr.(*sqlparser.StarExpr); ok { - if i < colNumber { - tableName := starExpr.TableName - tableMap := node.resultColumns[i].column.st.tables - var tableMeta *table - if tableName.IsEmpty() && len(tableMap) == 1 { - for j := range tableMap { - tableMeta = tableMap[j] - } - } else { - tableMeta = tableMap[tableName] - } - if tableMeta == nil || !tableMeta.isAuthoritative { - return nil, vterrors.VT12001("in scatter query, cannot ORDER BY a column that comes after `*` expressions in the SELECT list") - } - starColFixedIndex += len(tableMeta.columnNames) - 1 - } - } - } - } - - // TODO(king-11) pass in collation here - ob := engine.OrderByParams{ - Col: colNumber, - WeightStringCol: -1, - Desc: order.Direction == sqlparser.DescOrder, - StarColFixedIndex: starColFixedIndex, - FromGroupBy: order.fromGroupBy, - CollationID: collations.Unknown, - } - node.eroute.OrderBy = append(node.eroute.OrderBy, ob) - - node.Select.AddOrder(order.Order) - } - return newMergeSort(node), nil -} - -func complexOrderBy(s string) error { - return vterrors.VT12001(fmt.Sprintf("in scatter query: complex ORDER BY expression: %s", s)) -} diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 1accbf89c2b..25e06df9b96 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -701,11 +701,9 @@ func (vw *vschemaWrapper) IsViewsEnabled() bool { type ( planTest struct { - Comment string `json:"comment,omitempty"` - Query string `json:"query,omitempty"` - Plan json.RawMessage `json:"plan,omitempty"` - V3Plan json.RawMessage `json:"v3-plan,omitempty"` - Gen4Plan json.RawMessage `json:"gen4-plan,omitempty"` + Comment string `json:"comment,omitempty"` + Query string `json:"query,omitempty"` + Plan json.RawMessage `json:"plan,omitempty"` } ) @@ -714,13 +712,7 @@ func testFile(t *testing.T, filename, tempDir string, vschema *vschemaWrapper, r t.Run(filename, func(t *testing.T) { var expected []planTest - var outFirstPlanner string for _, tcase := range readJSONTests(filename) { - if tcase.V3Plan == nil { - tcase.V3Plan = tcase.Plan - tcase.Gen4Plan = tcase.Plan - } - current := planTest{} testName := tcase.Comment if testName == "" { testName = tcase.Query @@ -728,52 +720,23 @@ func testFile(t *testing.T, filename, tempDir string, vschema *vschemaWrapper, r if tcase.Query == "" { continue } - t.Run(fmt.Sprintf("V3: %s", testName), func(t *testing.T) { - vschema.version = V3 - plan, err := TestBuilder(tcase.Query, vschema, vschema.currentDb()) - if render && plan != nil { - viz, err := engine.GraphViz(plan.Instructions) - if err == nil { - _ = viz.Render() - } - } - out := getPlanOrErrorOutput(err, plan) - - compare, s := jsondiff.Compare(tcase.V3Plan, []byte(out), &opts) - if compare != jsondiff.FullMatch { - t.Errorf("V3 - %s\nDiff:\n%s\n[%s] \n[%s]", filename, s, tcase.V3Plan, out) - } - - outFirstPlanner = out - current.Comment = testName - current.Query = tcase.Query - }) - - vschema.version = Gen4 - out, err := getPlanOutput(tcase, vschema, render) - if err != nil && len(tcase.Gen4Plan) == 0 && strings.HasPrefix(err.Error(), "gen4 does not yet support") { - continue + current := planTest{ + Comment: testName, + Query: tcase.Query, } - - // our expectation for the new planner on this query is one of three - // - it produces the same plan as V3 - this is shown using empty brackets: {\n} - // - it produces a different but accepted plan - this is shown using the accepted plan - // - or it produces a different plan that has not yet been accepted, or it fails to produce a plan - // this is shown by not having any info at all after the result for the V3 planner - // with this last expectation, it is an error if the Gen4 planner - // produces the same plan as the V3 planner does - t.Run(fmt.Sprintf("Gen4: %s", testName), func(t *testing.T) { - compare, s := jsondiff.Compare(tcase.Gen4Plan, []byte(out), &opts) + vschema.version = Gen4 + out := getPlanOutput(tcase, vschema, render) + + // our expectation for the planner on the query is one of three + // - produces same plan as expected + // - produces a different plan than expected + // - fails to produce a plan + t.Run(testName, func(t *testing.T) { + compare, s := jsondiff.Compare(tcase.Plan, []byte(out), &opts) if compare != jsondiff.FullMatch { - t.Errorf("Gen4 - %s\nDiff:\n%s\n[%s] \n[%s]", filename, s, tcase.Gen4Plan, out) - } - - if outFirstPlanner == out { - current.Plan = []byte(out) - } else { - current.V3Plan = []byte(outFirstPlanner) - current.Gen4Plan = []byte(out) + t.Errorf("%s\nDiff:\n%s\n[%s] \n[%s]", filename, s, tcase.Plan, out) } + current.Plan = []byte(out) }) expected = append(expected, current) } @@ -807,7 +770,7 @@ func readJSONTests(filename string) []planTest { return output } -func getPlanOutput(tcase planTest, vschema *vschemaWrapper, render bool) (out string, err error) { +func getPlanOutput(tcase planTest, vschema *vschemaWrapper, render bool) (out string) { defer func() { if r := recover(); r != nil { out = fmt.Sprintf("panicked: %v\n%s", r, string(debug.Stack())) @@ -820,8 +783,7 @@ func getPlanOutput(tcase planTest, vschema *vschemaWrapper, render bool) (out st _ = viz.Render() } } - out = getPlanOrErrorOutput(err, plan) - return out, err + return getPlanOrErrorOutput(err, plan) } func getPlanOrErrorOutput(err error, plan *engine.Plan) string { @@ -852,9 +814,6 @@ func BenchmarkPlanner(b *testing.B) { } for _, filename := range benchMarkFiles { testCases := readJSONTests(filename) - b.Run(filename+"-v3", func(b *testing.B) { - benchmarkPlanner(b, V3, testCases, vschema) - }) b.Run(filename+"-gen4", func(b *testing.B) { benchmarkPlanner(b, Gen4, testCases, vschema) }) @@ -901,7 +860,7 @@ func BenchmarkSelectVsDML(b *testing.B) { vschema := &vschemaWrapper{ v: loadSchema(b, "vschemas/schema.json", true), sysVarEnabled: true, - version: V3, + version: Gen4, } dmlCases := readJSONTests("dml_cases.json") @@ -916,11 +875,11 @@ func BenchmarkSelectVsDML(b *testing.B) { }) b.Run("DML (random sample, N=32)", func(b *testing.B) { - benchmarkPlanner(b, V3, dmlCases[:32], vschema) + benchmarkPlanner(b, Gen4, dmlCases[:32], vschema) }) b.Run("Select (random sample, N=32)", func(b *testing.B) { - benchmarkPlanner(b, V3, selectCases[:32], vschema) + benchmarkPlanner(b, Gen4, selectCases[:32], vschema) }) } @@ -928,7 +887,7 @@ func benchmarkPlanner(b *testing.B, version plancontext.PlannerVersion, testCase b.ReportAllocs() for n := 0; n < b.N; n++ { for _, tcase := range testCases { - if len(tcase.Gen4Plan) > 0 { + if len(tcase.Plan) > 0 { vschema.version = version _, _ = TestBuilder(tcase.Query, vschema, vschema.currentDb()) } diff --git a/go/vt/vtgate/planbuilder/plancontext/vschema.go b/go/vt/vtgate/planbuilder/plancontext/vschema.go index 489a9eafe8f..f288a9bd95c 100644 --- a/go/vt/vtgate/planbuilder/plancontext/vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/vschema.go @@ -4,7 +4,6 @@ import ( "context" "strings" - "vitess.io/vitess/go/vt/log" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" "vitess.io/vitess/go/vt/vtgate/engine" @@ -91,25 +90,13 @@ type VSchema interface { // PlannerNameToVersion returns the numerical representation of the planner func PlannerNameToVersion(s string) (PlannerVersion, bool) { - deprecationMessage := "The V3 planner is deprecated and will be removed in future release of Vitess" switch strings.ToLower(s) { - case "v3": - log.Warning(deprecationMessage) - return querypb.ExecuteOptions_V3, true case "gen4": return querypb.ExecuteOptions_Gen4, true case "gen4greedy", "greedy": return querypb.ExecuteOptions_Gen4Greedy, true case "left2right": return querypb.ExecuteOptions_Gen4Left2Right, true - case "gen4fallback": - return querypb.ExecuteOptions_Gen4WithFallback, true - case "gen4comparev3": - log.Warning(deprecationMessage) - return querypb.ExecuteOptions_Gen4CompareV3, true - case "v3insert": - log.Warning(deprecationMessage) - return querypb.ExecuteOptions_V3Insert, true } return 0, false } diff --git a/go/vt/vtgate/planbuilder/planner.go b/go/vt/vtgate/planbuilder/planner.go new file mode 100644 index 00000000000..ab965351ac5 --- /dev/null +++ b/go/vt/vtgate/planbuilder/planner.go @@ -0,0 +1,96 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package planbuilder + +import ( + "fmt" + "strconv" + + 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/plancontext" +) + +func gen4Planner(query string, plannerVersion querypb.ExecuteOptions_PlannerVersion) stmtPlanner { + return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { + switch stmt := stmt.(type) { + case sqlparser.SelectStatement: + return gen4SelectStmtPlanner(query, plannerVersion, stmt, reservedVars, vschema) + case *sqlparser.Update: + return gen4UpdateStmtPlanner(plannerVersion, stmt, reservedVars, vschema) + case *sqlparser.Delete: + return gen4DeleteStmtPlanner(plannerVersion, stmt, reservedVars, vschema) + case *sqlparser.Insert: + return gen4InsertStmtPlanner(plannerVersion, stmt, reservedVars, vschema) + default: + return nil, vterrors.VT12001(fmt.Sprintf("%T", stmt)) + } + } +} + +func pushCommentDirectivesOnPlan(plan logicalPlan, stmt sqlparser.Statement) logicalPlan { + var directives *sqlparser.CommentDirectives + cmt, ok := stmt.(sqlparser.Commented) + if ok { + directives = cmt.GetParsedComments().Directives() + scatterAsWarns := directives.IsSet(sqlparser.DirectiveScatterErrorsAsWarnings) + timeout := queryTimeout(directives) + multiShardAutoCommit := directives.IsSet(sqlparser.DirectiveMultiShardAutocommit) + + if scatterAsWarns || timeout > 0 || multiShardAutoCommit { + _, _ = visit(plan, func(logicalPlan logicalPlan) (bool, logicalPlan, error) { + switch plan := logicalPlan.(type) { + case *route: + plan.eroute.ScatterErrorsAsWarnings = scatterAsWarns + plan.eroute.QueryTimeout = timeout + case *primitiveWrapper: + setDirective(plan.prim, multiShardAutoCommit, timeout) + case *insert: + setDirective(plan.eInsert, multiShardAutoCommit, timeout) + } + return true, logicalPlan, nil + }) + } + } + + return plan +} + +func setDirective(prim engine.Primitive, msac bool, timeout int) { + switch edml := prim.(type) { + case *engine.Insert: + edml.MultiShardAutocommit = msac + edml.QueryTimeout = timeout + case *engine.Update: + edml.MultiShardAutocommit = msac + edml.QueryTimeout = timeout + case *engine.Delete: + edml.MultiShardAutocommit = msac + edml.QueryTimeout = timeout + } +} + +// queryTimeout returns DirectiveQueryTimeout value if set, otherwise returns 0. +func queryTimeout(d *sqlparser.CommentDirectives) int { + val, _ := d.GetString(sqlparser.DirectiveQueryTimeout, "0") + if intVal, err := strconv.Atoi(val); err == nil { + return intVal + } + return 0 +} diff --git a/go/vt/vtgate/planbuilder/gen4_planner_test.go b/go/vt/vtgate/planbuilder/planner_test.go similarity index 100% rename from go/vt/vtgate/planbuilder/gen4_planner_test.go rename to go/vt/vtgate/planbuilder/planner_test.go diff --git a/go/vt/vtgate/planbuilder/postprocess.go b/go/vt/vtgate/planbuilder/postprocess.go index c64ce9f493d..f7a508df4a6 100644 --- a/go/vt/vtgate/planbuilder/postprocess.go +++ b/go/vt/vtgate/planbuilder/postprocess.go @@ -25,74 +25,6 @@ import ( // This file has functions to analyze postprocessing // clauses like ORDER BY, etc. -// pushGroupBy processes the group by clause. It resolves all symbols -// and ensures that there are no subqueries. -func (pb *primitiveBuilder) pushGroupBy(sel *sqlparser.Select) error { - if sel.Distinct { - newBuilder, err := planDistinct(pb.plan) - if err != nil { - return err - } - pb.plan = newBuilder - } - - if err := pb.st.ResolveSymbols(sel.GroupBy); err != nil { - return err - } - - newInput, err := planGroupBy(pb, pb.plan, sel.GroupBy) - if err != nil { - return err - } - pb.plan = newInput - - return nil -} - -// pushOrderBy pushes the order by clause into the primitives. -// It resolves all symbols and ensures that there are no subqueries. -func (pb *primitiveBuilder) pushOrderBy(orderBy sqlparser.OrderBy) error { - if err := pb.st.ResolveSymbols(orderBy); err != nil { - return err - } - var v3OrderBylist v3OrderBy - for _, order := range orderBy { - v3OrderBylist = append(v3OrderBylist, &v3Order{Order: order}) - } - plan, err := planOrdering(pb, pb.plan, v3OrderBylist) - if err != nil { - return err - } - pb.plan = plan - pb.plan.Reorder(0) - return nil -} - -func (pb *primitiveBuilder) pushLimit(limit *sqlparser.Limit) error { - if limit == nil { - return nil - } - rb, ok := pb.plan.(*route) - if ok && rb.isSingleShard() { - rb.SetLimit(limit) - return nil - } - - lb, err := createLimit(pb.plan, limit) - if err != nil { - return err - } - - plan, err := visit(lb, setUpperLimit) - if err != nil { - return err - } - - pb.plan = plan - pb.plan.Reorder(0) - return nil -} - // make sure we have the right signature for this function var _ planVisitor = setUpperLimit @@ -101,7 +33,7 @@ var _ planVisitor = setUpperLimit // A primitive that cannot perform this can ignore the request. func setUpperLimit(plan logicalPlan) (bool, logicalPlan, error) { switch node := plan.(type) { - case *join, *joinGen4, *hashJoin: + case *join, *hashJoin: return false, node, nil case *memorySort: pv := evalengine.NewBindVar("__upper_limit") @@ -123,13 +55,6 @@ func setUpperLimit(plan logicalPlan) (bool, logicalPlan, error) { // If it's a scatter query, the rows returned will be // more than the upper limit, but enough for the limit node.Select.SetLimit(&sqlparser.Limit{Rowcount: sqlparser.NewArgument("__upper_limit")}) - case *routeGen4: - // The route pushes the limit regardless of the plan. - // If it's a scatter query, the rows returned will be - // more than the upper limit, but enough for the limit - node.Select.SetLimit(&sqlparser.Limit{Rowcount: sqlparser.NewArgument("__upper_limit")}) - case *concatenate: - return false, node, nil } return true, plan, nil } diff --git a/go/vt/vtgate/planbuilder/primitive_builder.go b/go/vt/vtgate/planbuilder/primitive_builder.go deleted file mode 100644 index b7c557518e5..00000000000 --- a/go/vt/vtgate/planbuilder/primitive_builder.go +++ /dev/null @@ -1,49 +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 planbuilder - -import ( - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" -) - -// primitiveBuilder is the top level type for building plans. -// It contains the current logicalPlan tree, the symtab and -// the jointab. It can create transient planBuilders due -// to the recursive nature of SQL. -type primitiveBuilder struct { - vschema plancontext.VSchema - jt *jointab - plan logicalPlan - st *symtab - stmt sqlparser.Statement -} - -func newStmtAwarePrimitiveBuilder(vschema plancontext.VSchema, jt *jointab, stmt sqlparser.Statement) *primitiveBuilder { - return &primitiveBuilder{ - vschema: vschema, - jt: jt, - stmt: stmt, - } -} - -func newPrimitiveBuilder(vschema plancontext.VSchema, jt *jointab) *primitiveBuilder { - return &primitiveBuilder{ - vschema: vschema, - jt: jt, - } -} diff --git a/go/vt/vtgate/planbuilder/primitive_wrapper.go b/go/vt/vtgate/planbuilder/primitive_wrapper.go index b4ed7c8aa39..cb6a65aba04 100644 --- a/go/vt/vtgate/planbuilder/primitive_wrapper.go +++ b/go/vt/vtgate/planbuilder/primitive_wrapper.go @@ -27,10 +27,9 @@ import ( // primitiveWrapper is used when only need a logical plan that supports plan.Primitive() and nothing else type primitiveWrapper struct { prim engine.Primitive - gen4Plan } -func (p *primitiveWrapper) WireupGen4(*plancontext.PlanningContext) error { +func (p *primitiveWrapper) Wireup(*plancontext.PlanningContext) error { return nil } diff --git a/go/vt/vtgate/planbuilder/project.go b/go/vt/vtgate/planbuilder/project.go deleted file mode 100644 index aa6faec524b..00000000000 --- a/go/vt/vtgate/planbuilder/project.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -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 planbuilder - -import ( - "fmt" - - 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" - popcode "vitess.io/vitess/go/vt/vtgate/engine/opcode" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" -) - -// planProjection pushes the select expression to the specified -// originator. If successful, the originator must create -// a resultColumn entry and return it. The top level caller -// must accumulate these result columns and set the symtab -// after analysis. -func planProjection(pb *primitiveBuilder, in logicalPlan, expr *sqlparser.AliasedExpr, origin logicalPlan) (logicalPlan, *resultColumn, int, error) { - switch node := in.(type) { - case *join: - var rc *resultColumn - if node.isOnLeft(origin.Order()) { - newLeft, col, colNumber, err := planProjection(pb, node.Left, expr, origin) - if err != nil { - return nil, nil, 0, err - } - node.ejoin.Cols = append(node.ejoin.Cols, -colNumber-1) - rc = col - node.Left = newLeft - } else { - // Pushing of non-trivial expressions not allowed for RHS of left joins. - if _, ok := expr.Expr.(*sqlparser.ColName); !ok && node.ejoin.Opcode == engine.LeftJoin { - return nil, nil, 0, vterrors.VT12001("cross-shard LEFT JOIN and column expressions") - } - - newRight, col, colNumber, err := planProjection(pb, node.Right, expr, origin) - if err != nil { - return nil, nil, 0, err - } - node.ejoin.Cols = append(node.ejoin.Cols, colNumber+1) - rc = col - node.Right = newRight - } - node.resultColumns = append(node.resultColumns, rc) - return in, rc, len(node.resultColumns) - 1, nil - - // orderedAggregate can accept expressions that are normal (a+b), or aggregate (MAX(v)). - // Normal expressions are pushed through to the underlying route. But aggregate - // expressions require post-processing. In such cases, oa shares the work with - // the underlying route: It asks the scatter route to perform the MAX operation - // also, and only performs the final aggregation with what the route returns. - // Since the results are expected to be ordered, this is something that can - // be performed 'as they come'. In this respect, oa is the originator for - // aggregate expressions like MAX, which will be added to symtab. The underlying - // MAX sent to the route will not be added to symtab and will not be reachable by - // others. This functionality depends on the PushOrderBy to request that - // the rows be correctly ordered. - case *orderedAggregate: - if aggrFunc, isAggregate := expr.Expr.(sqlparser.AggrFunc); isAggregate { - if _, ok := popcode.SupportedAggregates[aggrFunc.AggrName()]; ok { - rc, colNumber, err := node.pushAggr(pb, expr, origin) - if err != nil { - return nil, nil, 0, err - } - return node, rc, colNumber, nil - } - } - - // Ensure that there are no aggregates in the expression. - if sqlparser.ContainsAggregation(expr.Expr) { - return nil, nil, 0, vterrors.VT12001("in scatter query: complex aggregate expression") - } - - newInput, innerRC, _, err := planProjection(pb, node.input, expr, origin) - if err != nil { - return nil, nil, 0, err - } - node.input = newInput - node.resultColumns = append(node.resultColumns, innerRC) - return node, innerRC, len(node.resultColumns) - 1, nil - case *route: - sel := node.Select.(*sqlparser.Select) - sel.SelectExprs = append(sel.SelectExprs, expr) - - rc := newResultColumn(expr, node) - node.resultColumns = append(node.resultColumns, rc) - - return node, rc, len(node.resultColumns) - 1, nil - case *mergeSort: - projectedInput, rc, idx, err := planProjection(pb, node.input, expr, origin) - if err != nil { - return nil, nil, 0, err - } - err = node.Rewrite(projectedInput) - if err != nil { - return nil, nil, 0, err - } - return node, rc, idx, nil - case *distinct: - projectedInput, rc, idx, err := planProjection(pb, node.input, expr, origin) - if err != nil { - return nil, nil, 0, err - } - err = node.Rewrite(projectedInput) - if err != nil { - return nil, nil, 0, err - } - return node, rc, idx, nil - case *pulloutSubquery: - projectedInput, rc, idx, err := planProjection(pb, node.underlying, expr, origin) - if err != nil { - return nil, nil, 0, err - } - err = node.Rewrite(projectedInput, node.subquery) - if err != nil { - return nil, nil, 0, err - } - return node, rc, idx, nil - case *simpleProjection: - col, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, nil, 0, vterrors.VT12001("expression on results of a cross-shard subquery") - } - - // colNumber should already be set for subquery columns. - inner := col.Metadata.(*column).colNumber - node.eSimpleProj.Cols = append(node.eSimpleProj.Cols, inner) - - // Build a new column reference to represent the result column. - rc := newResultColumn(expr, node) - node.resultColumns = append(node.resultColumns, rc) - - return node, rc, len(node.resultColumns) - 1, nil - case *vindexFunc: - // Catch the case where no where clause was specified. If so, the opcode - // won't be set. - if node.eVindexFunc.Opcode == engine.VindexNone { - return nil, nil, 0, vterrors.VT12001(operators.VindexUnsupported + " (where clause missing)") - } - col, ok := expr.Expr.(*sqlparser.ColName) - if !ok { - return nil, nil, 0, vterrors.VT12001("expression on results of a vindex function") - } - rc := newResultColumn(expr, node) - node.resultColumns = append(node.resultColumns, rc) - node.eVindexFunc.Fields = append(node.eVindexFunc.Fields, &querypb.Field{ - Name: rc.alias.String(), - Type: querypb.Type_VARBINARY, - }) - node.eVindexFunc.Cols = append(node.eVindexFunc.Cols, col.Metadata.(*column).colNumber) - return node, rc, len(node.resultColumns) - 1, nil - - } - return nil, nil, 0, vterrors.VT13001(fmt.Sprintf("unreachable %T.projection", in)) -} diff --git a/go/vt/vtgate/planbuilder/projection.go b/go/vt/vtgate/planbuilder/projection.go index 2444b916d48..adf6975ce52 100644 --- a/go/vt/vtgate/planbuilder/projection.go +++ b/go/vt/vtgate/planbuilder/projection.go @@ -28,7 +28,6 @@ import ( ) type projection struct { - gen4Plan source logicalPlan columnNames []string columns []sqlparser.Expr @@ -41,12 +40,12 @@ type projection struct { var _ logicalPlan = (*projection)(nil) // WireupGen4 implements the logicalPlan interface -func (p *projection) WireupGen4(ctx *plancontext.PlanningContext) error { +func (p *projection) Wireup(ctx *plancontext.PlanningContext) error { if p.primitive != nil { // if primitive is not nil, it means that the horizon planning in the operator phase already // created all the needed evalengine expressions. // we don't need to do anything here, let's just shortcut out of this call - return p.source.WireupGen4(ctx) + return p.source.Wireup(ctx) } columns := make([]evalengine.Expr, 0, len(p.columns)) @@ -65,7 +64,7 @@ func (p *projection) WireupGen4(ctx *plancontext.PlanningContext) error { Exprs: columns, } - return p.source.WireupGen4(ctx) + return p.source.Wireup(ctx) } // Inputs implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/projection_pushing.go b/go/vt/vtgate/planbuilder/projection_pushing.go index 8772f882c78..e335c1c9ab5 100644 --- a/go/vt/vtgate/planbuilder/projection_pushing.go +++ b/go/vt/vtgate/planbuilder/projection_pushing.go @@ -40,11 +40,11 @@ func pushProjection( // All of these either push to the single source, or push to the LHS src := node.Inputs()[0] return pushProjection(ctx, expr, src, inner, reuseCol, hasAggregation) - case *routeGen4: + case *route: return addExpressionToRoute(ctx, node, expr, reuseCol) case *hashJoin: return pushProjectionIntoHashJoin(ctx, expr, node, reuseCol, inner, hasAggregation) - case *joinGen4: + case *join: return pushProjectionIntoJoin(ctx, expr, node, reuseCol, inner, hasAggregation) case *simpleProjection: return pushProjectionIntoSimpleProj(ctx, expr, node, inner, hasAggregation, reuseCol) @@ -54,7 +54,7 @@ func pushProjection( return pushProjectionIntoVindexFunc(node, expr, reuseCol) case *semiJoin: return pushProjectionIntoSemiJoin(ctx, expr, reuseCol, node, inner, hasAggregation) - case *concatenateGen4: + case *concatenate: return pushProjectionIntoConcatenate(ctx, expr, hasAggregation, node, inner, reuseCol) default: return 0, false, vterrors.VT13001(fmt.Sprintf("push projection does not yet support: %T", node)) @@ -70,7 +70,7 @@ func pushProjectionIntoVindexFunc(node *vindexFunc, expr *sqlparser.AliasedExpr, return i /* col added */, len(node.eVindexFunc.Cols) > colsBefore, nil } -func pushProjectionIntoConcatenate(ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, hasAggregation bool, node *concatenateGen4, inner bool, reuseCol bool) (int, bool, error) { +func pushProjectionIntoConcatenate(ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, hasAggregation bool, node *concatenate, inner bool, reuseCol bool) (int, bool, error) { if hasAggregation { return 0, false, vterrors.VT12001("aggregation on UNIONs") } @@ -169,7 +169,7 @@ func pushProjectionIntoSimpleProj( func pushProjectionIntoJoin( ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, - node *joinGen4, + node *join, reuseCol, inner, hasAggregation bool, ) (int, bool, error) { lhsSolves := node.Left.ContainsTables() @@ -292,7 +292,7 @@ func pushProjectionIntoHashJoin( return len(node.Cols) - 1, true, nil } -func addExpressionToRoute(ctx *plancontext.PlanningContext, rb *routeGen4, expr *sqlparser.AliasedExpr, reuseCol bool) (int, bool, error) { +func addExpressionToRoute(ctx *plancontext.PlanningContext, rb *route, expr *sqlparser.AliasedExpr, reuseCol bool) (int, bool, error) { if reuseCol { if i := checkIfAlreadyExists(expr, rb.Select, ctx.SemTable); i != -1 { return i, false, nil diff --git a/go/vt/vtgate/planbuilder/pullout_subquery.go b/go/vt/vtgate/planbuilder/pullout_subquery.go index 4e1008ff7ae..c276c86b426 100644 --- a/go/vt/vtgate/planbuilder/pullout_subquery.go +++ b/go/vt/vtgate/planbuilder/pullout_subquery.go @@ -49,25 +49,6 @@ func newPulloutSubquery(opcode popcode.PulloutOpcode, sqName, hasValues string, } } -// setUnderlying sets the underlying primitive. -func (ps *pulloutSubquery) setUnderlying(underlying logicalPlan) { - ps.underlying = underlying - ps.underlying.Reorder(ps.subquery.Order()) - ps.order = ps.underlying.Order() + 1 -} - -// Order implements the logicalPlan interface -func (ps *pulloutSubquery) Order() int { - return ps.order -} - -// Reorder implements the logicalPlan interface -func (ps *pulloutSubquery) Reorder(order int) { - ps.subquery.Reorder(order) - ps.underlying.Reorder(ps.subquery.Order()) - ps.order = ps.underlying.Order() + 1 -} - // Primitive implements the logicalPlan interface func (ps *pulloutSubquery) Primitive() engine.Primitive { ps.eSubquery.Subquery = ps.subquery.Primitive() @@ -75,44 +56,12 @@ func (ps *pulloutSubquery) Primitive() engine.Primitive { return ps.eSubquery } -// ResultColumns implements the logicalPlan interface -func (ps *pulloutSubquery) ResultColumns() []*resultColumn { - return ps.underlying.ResultColumns() -} - -// Wireup implements the logicalPlan interface -func (ps *pulloutSubquery) Wireup(plan logicalPlan, jt *jointab) error { - if err := ps.underlying.Wireup(plan, jt); err != nil { +// WireupGen4 implements the logicalPlan interface +func (ps *pulloutSubquery) Wireup(ctx *plancontext.PlanningContext) error { + if err := ps.underlying.Wireup(ctx); err != nil { return err } - return ps.subquery.Wireup(plan, jt) -} - -// Wireup2 implements the logicalPlan interface -func (ps *pulloutSubquery) WireupGen4(ctx *plancontext.PlanningContext) error { - if err := ps.underlying.WireupGen4(ctx); err != nil { - return err - } - return ps.subquery.WireupGen4(ctx) -} - -// SupplyVar implements the logicalPlan interface -func (ps *pulloutSubquery) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - if from <= ps.subquery.Order() { - ps.subquery.SupplyVar(from, to, col, varname) - return - } - ps.underlying.SupplyVar(from, to, col, varname) -} - -// SupplyCol implements the logicalPlan interface -func (ps *pulloutSubquery) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - return ps.underlying.SupplyCol(col) -} - -// SupplyWeightString implements the logicalPlan interface -func (ps *pulloutSubquery) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - return ps.underlying.SupplyWeightString(colNumber, alsoAddToGroupBy) + return ps.subquery.Wireup(ctx) } // Rewrite implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index 64f4f7cbc63..6a668b2c5c1 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors. +Copyright 2021 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,12 @@ limitations under the License. package planbuilder import ( - "fmt" - "strconv" - + 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/evalengine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -35,94 +34,28 @@ var _ logicalPlan = (*route)(nil) // are moved into this node, which will be used to build // the final SQL for this route. type route struct { - v3Plan - order int - - // Redirect may point to another route if this route - // was merged with it. The Resolve function chases - // this pointer till the last un-redirected route. - Redirect *route // Select is the AST for the query fragment that will be // executed by this route. Select sqlparser.SelectStatement - // resultColumns represent the columns returned by this route. - resultColumns []*resultColumn - - // weight_string keeps track of the weight_string expressions - // that were added additionally for each column. These expressions - // are added to be used for collation of text columns. - weightStrings map[*resultColumn]int - - // substitutions contain the list of table expressions that - // have to be substituted in the route's query. - substitutions []*tableSubstitution - // condition stores the AST condition that will be used // to resolve the ERoute Values field. condition sqlparser.Expr // eroute is the primitive being built. eroute *engine.Route -} - -type tableSubstitution struct { - newExpr, oldExpr *sqlparser.AliasedTableExpr -} -func newRoute(stmt sqlparser.SelectStatement) (*route, *symtab) { - rb := &route{ - Select: stmt, - order: 1, - weightStrings: make(map[*resultColumn]int), - } - return rb, newSymtabWithRoute(rb) -} - -// Resolve resolves redirects, and returns the last -// un-redirected route. -func (rb *route) Resolve() *route { - for rb.Redirect != nil { - rb = rb.Redirect - } - return rb -} - -// Order implements the logicalPlan interface -func (rb *route) Order() int { - return rb.order -} + // is the engine primitive we will return from the Primitive() method. Note that it could be different than eroute + enginePrimitive engine.Primitive -// Reorder implements the logicalPlan interface -func (rb *route) Reorder(order int) { - rb.order = order + 1 + // tables keeps track of which tables this route is covering + tables semantics.TableSet } // Primitive implements the logicalPlan interface func (rb *route) Primitive() engine.Primitive { - return rb.eroute -} - -// ResultColumns implements the logicalPlan interface -func (rb *route) ResultColumns() []*resultColumn { - return rb.resultColumns -} - -// PushAnonymous pushes an anonymous expression like '*' or NEXT VALUES -// into the select expression list of the route. This function is -// similar to PushSelect. -func (rb *route) PushAnonymous(expr sqlparser.SelectExpr) *resultColumn { - // TODO: we should not assume that the query is a SELECT - sel := rb.Select.(*sqlparser.Select) - sel.SelectExprs = append(sel.SelectExprs, expr) - - // We just create a place-holder resultColumn. It won't - // match anything. - rc := &resultColumn{column: &column{origin: rb}} - rb.resultColumns = append(rb.resultColumns, rc) - - return rc + return rb.enginePrimitive } // SetLimit adds a LIMIT clause to the route. @@ -130,82 +63,63 @@ func (rb *route) SetLimit(limit *sqlparser.Limit) { rb.Select.SetLimit(limit) } -// Wireup implements the logicalPlan interface -func (rb *route) Wireup(plan logicalPlan, jt *jointab) error { - // Precaution: update ERoute.Values only if it's not set already. - if rb.eroute.Values == nil { - // Resolve values stored in the logical plan. - switch vals := rb.condition.(type) { - case *sqlparser.ComparisonExpr: - pv, err := rb.procureValues(plan, jt, vals.Right) - if err != nil { - return err - } - rb.eroute.Values = []evalengine.Expr{pv} - vals.Right = sqlparser.ListArg(engine.ListVarName) - case nil: - // no-op. - default: - pv, err := rb.procureValues(plan, jt, vals) - if err != nil { - return err - } - rb.eroute.Values = []evalengine.Expr{pv} - } +// WireupGen4 implements the logicalPlan interface +func (rb *route) Wireup(ctx *plancontext.PlanningContext) error { + rb.prepareTheAST() + + // prepare the queries we will pass down + rb.eroute.Query = sqlparser.String(rb.Select) + buffer := sqlparser.NewTrackedBuffer(sqlparser.FormatImpossibleQuery) + node := buffer.WriteNode(rb.Select) + parsedQuery := node.ParsedQuery() + rb.eroute.FieldQuery = parsedQuery.Query + + // if we have a planable vindex lookup, let's extract it into its own primitive + planableVindex, ok := rb.eroute.RoutingParameters.Vindex.(vindexes.LookupPlanable) + if !ok { + rb.enginePrimitive = rb.eroute + return nil } - // Fix up the AST. - _ = sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) { - switch node := node.(type) { - case *sqlparser.Select: - if len(node.SelectExprs) == 0 { - node.SelectExprs = []sqlparser.SelectExpr{ - &sqlparser.AliasedExpr{ - Expr: sqlparser.NewIntLiteral("1"), - }, - } - } - case *sqlparser.ComparisonExpr: - if node.Operator == sqlparser.EqualOp { - if rb.exprIsValue(node.Left) && !rb.exprIsValue(node.Right) { - node.Left, node.Right = node.Right, node.Left - } - } - } - return true, nil - }, rb.Select) + query, args := planableVindex.Query() + stmt, reserved, err := sqlparser.Parse2(query) + if err != nil { + return err + } + reservedVars := sqlparser.NewReservedVars("vtg", reserved) - // Substitute table names - for _, sub := range rb.substitutions { - *sub.oldExpr = *sub.newExpr + lookupPrimitive, err := gen4SelectStmtPlanner(query, querypb.ExecuteOptions_Gen4, stmt.(sqlparser.SelectStatement), reservedVars, ctx.VSchema) + if err != nil { + return vterrors.Wrapf(err, "failed to plan the lookup query: [%s]", query) } - // Generate query while simultaneously resolving values. - varFormatter := func(buf *sqlparser.TrackedBuffer, node sqlparser.SQLNode) { - switch node := node.(type) { - case *sqlparser.ColName: - if !rb.isLocal(node) { - joinVar := jt.Procure(plan, node, rb.Order()) - buf.WriteArg(":", joinVar) - return - } - case sqlparser.TableName: - if !sqlparser.SystemSchema(node.Qualifier.String()) { - node.Name.Format(buf) - return - } - node.Format(buf) - return - } - node.Format(buf) + rb.enginePrimitive = &engine.VindexLookup{ + Opcode: rb.eroute.Opcode, + Vindex: planableVindex, + Keyspace: rb.eroute.Keyspace, + Values: rb.eroute.Values, + SendTo: rb.eroute, + Arguments: args, + Lookup: lookupPrimitive.primitive, } - buf := sqlparser.NewTrackedBuffer(varFormatter) - varFormatter(buf, rb.Select) - rb.eroute.Query = buf.ParsedQuery().Query - rb.eroute.FieldQuery = rb.generateFieldQuery(rb.Select, jt) + + rb.eroute.RoutingParameters.Opcode = engine.ByDestination + rb.eroute.RoutingParameters.Values = nil + rb.eroute.RoutingParameters.Vindex = nil + return nil } +// ContainsTables implements the logicalPlan interface +func (rb *route) ContainsTables() semantics.TableSet { + return rb.tables +} + +// OutputColumns implements the logicalPlan interface +func (rb *route) OutputColumns() []sqlparser.SelectExpr { + return sqlparser.GetFirstSelect(rb.Select).SelectExprs +} + // prepareTheAST does minor fixups of the SELECT struct before producing the query string func (rb *route) prepareTheAST() { _ = sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) { @@ -233,130 +147,6 @@ func (rb *route) prepareTheAST() { }, rb.Select) } -// procureValues procures and converts the input into -// the expected types for rb.Values. -func (rb *route) procureValues(plan logicalPlan, jt *jointab, val sqlparser.Expr) (evalengine.Expr, error) { - switch typedVal := val.(type) { - case sqlparser.ValTuple: - exprs := make([]evalengine.Expr, 0, len(typedVal)) - for _, item := range typedVal { - v, err := rb.procureValues(plan, jt, item) - if err != nil { - return nil, err - } - exprs = append(exprs, v) - } - return evalengine.NewTupleExpr(exprs...), nil - case *sqlparser.ColName: - joinVar := jt.Procure(plan, typedVal, rb.Order()) - return evalengine.NewBindVar(joinVar), nil - default: - return evalengine.Translate(typedVal, nil) - } -} - -func (rb *route) isLocal(col *sqlparser.ColName) bool { - return col.Metadata.(*column).Origin() == rb -} - -// generateFieldQuery generates a query with an impossible where. -// This will be used on the RHS node to fetch field info if the LHS -// returns no result. -func (rb *route) generateFieldQuery(sel sqlparser.SelectStatement, jt *jointab) string { - formatter := func(buf *sqlparser.TrackedBuffer, node sqlparser.SQLNode) { - switch node := node.(type) { - case *sqlparser.ColName: - if !rb.isLocal(node) { - _, joinVar := jt.Lookup(node) - buf.WriteArg(":", joinVar) - return - } - case sqlparser.TableName: - if !sqlparser.SystemSchema(node.Qualifier.String()) { - node.Name.Format(buf) - return - } - node.Format(buf) - return - } - sqlparser.FormatImpossibleQuery(buf, node) - } - - buffer := sqlparser.NewTrackedBuffer(formatter) - node := buffer.WriteNode(sel) - query := node.ParsedQuery() - return query.Query -} - -// SupplyVar implements the logicalPlan interface -func (rb *route) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - // route is an atomic primitive. So, SupplyVar cannot be - // called on it. - panic("BUG: route is an atomic node.") -} - -// SupplyCol implements the logicalPlan interface -func (rb *route) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - c := col.Metadata.(*column) - for i, rc := range rb.resultColumns { - if rc.column == c { - return rc, i - } - } - - // A new result has to be returned. - rc = &resultColumn{column: c} - rb.resultColumns = append(rb.resultColumns, rc) - // TODO: we should not assume that the query is a SELECT query - sel := rb.Select.(*sqlparser.Select) - sel.SelectExprs = append(sel.SelectExprs, &sqlparser.AliasedExpr{Expr: col}) - return rc, len(rb.resultColumns) - 1 -} - -// SupplyWeightString implements the logicalPlan interface -func (rb *route) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - rc := rb.resultColumns[colNumber] - s, ok := rb.Select.(*sqlparser.Select) - if !ok { - return 0, vterrors.VT13001("unexpected AST struct for query") - } - - aliasExpr, ok := s.SelectExprs[colNumber].(*sqlparser.AliasedExpr) - if !ok { - return 0, vterrors.VT13001(fmt.Sprintf("unexpected AST struct for query %T", s.SelectExprs[colNumber])) - } - weightStringExpr := &sqlparser.FuncExpr{ - Name: sqlparser.NewIdentifierCI("weight_string"), - Exprs: []sqlparser.SelectExpr{ - &sqlparser.AliasedExpr{ - Expr: aliasExpr.Expr, - }, - }, - } - expr := &sqlparser.AliasedExpr{ - Expr: weightStringExpr, - } - if alsoAddToGroupBy { - sel, isSelect := rb.Select.(*sqlparser.Select) - if !isSelect { - return 0, vterrors.VT13001(fmt.Sprintf("cannot add weight string in %T", rb.Select)) - } - sel.AddGroupBy(weightStringExpr) - } - - if weightcolNumber, ok := rb.weightStrings[rc]; ok { - return weightcolNumber, nil - } - // It's ok to pass nil for pb and logicalPlan because PushSelect doesn't use them. - // TODO: we are ignoring a potential error here. need to clean this up - _, _, weightcolNumber, err = planProjection(nil, rb, expr, nil) - if err != nil { - return 0, err - } - rb.weightStrings[rc] = weightcolNumber - return weightcolNumber, nil -} - // Rewrite implements the logicalPlan interface func (rb *route) Rewrite(inputs ...logicalPlan) error { if len(inputs) != 0 { @@ -370,487 +160,6 @@ func (rb *route) Inputs() []logicalPlan { return []logicalPlan{} } -// MergeSubquery returns true if the subquery route could successfully be merged -// with the outer route. -func (rb *route) MergeSubquery(pb *primitiveBuilder, inner *route) bool { - if rb.SubqueryCanMerge(pb, inner) { - if inner.eroute.Opcode == engine.DBA && (len(inner.eroute.SysTableTableName) > 0 || len(inner.eroute.SysTableTableSchema) > 0) { - switch rb.eroute.Opcode { - case engine.DBA, engine.Reference: - rb.eroute.SysTableTableSchema = append(rb.eroute.SysTableTableSchema, inner.eroute.SysTableTableSchema...) - for k, v := range inner.eroute.SysTableTableName { - if rb.eroute.SysTableTableName == nil { - rb.eroute.SysTableTableName = map[string]evalengine.Expr{} - } - rb.eroute.SysTableTableName[k] = v - } - rb.eroute.Opcode = engine.DBA - default: - return false - } - } else { - if rb.eroute.Opcode == engine.Reference { - rb.eroute.RoutingParameters = inner.eroute.RoutingParameters - rb.condition = inner.condition - } - } - - rb.substitutions = append(rb.substitutions, inner.substitutions...) - inner.Redirect = rb - return true - } - return false -} - -// MergeUnion returns true if the rhs route could successfully be merged -// with the rb route. -func (rb *route) MergeUnion(right *route, isDistinct bool) bool { - if rb.unionCanMerge(right, isDistinct) { - rb.substitutions = append(rb.substitutions, right.substitutions...) - right.Redirect = rb - return true - } - return false -} - func (rb *route) isSingleShard() bool { return rb.eroute.Opcode.IsSingleShard() } - -// JoinCanMerge, SubqueryCanMerge and unionCanMerge have subtly different behaviors. -// The difference in behavior is around SelectReference. -// It's not worth trying to reuse the code between them. -func (rb *route) JoinCanMerge(pb *primitiveBuilder, rrb *route, ajoin *sqlparser.JoinTableExpr, where sqlparser.Expr) bool { - if rb.eroute.Keyspace.Name != rrb.eroute.Keyspace.Name { - return false - } - if rrb.eroute.Opcode == engine.Reference { - // Any opcode can join with a reference table. - return true - } - switch rb.eroute.Opcode { - case engine.Unsharded: - return rb.eroute.Opcode == rrb.eroute.Opcode - case engine.EqualUnique: - // Check if they target the same shard. - if rrb.eroute.Opcode == engine.EqualUnique && rb.eroute.Vindex == rrb.eroute.Vindex && valEqual(rb.condition, rrb.condition) { - return true - } - case engine.Reference: - return true - case engine.Next: - return false - case engine.DBA: - if rrb.eroute.Opcode != engine.DBA { - return false - } - if where == nil { - return true - } - return ajoin != nil - } - if ajoin == nil { - return false - } - for _, filter := range sqlparser.SplitAndExpression(nil, ajoin.Condition.On) { - if rb.canMergeOnFilter(pb, rrb, filter) { - return true - } - } - return false -} - -func (rb *route) SubqueryCanMerge(pb *primitiveBuilder, inner *route) bool { - if rb.eroute.Keyspace.Name != inner.eroute.Keyspace.Name { - return false - } - - // if either side is a reference table, and we know the other side will only run once, - // we can just merge them and use the opcode of the other side - if rb.eroute.Opcode == engine.Reference || inner.eroute.Opcode == engine.Reference { - return rb.isSingleShard() && inner.isSingleShard() - } - - switch rb.eroute.Opcode { - case engine.Unsharded, engine.DBA: - return rb.eroute.Opcode == inner.eroute.Opcode - case engine.EqualUnique: - // Check if they target the same shard. - if inner.eroute.Opcode == engine.EqualUnique && rb.eroute.Vindex == inner.eroute.Vindex && valEqual(rb.condition, inner.condition) { - return true - } - case engine.Next: - return false - } - - switch vals := inner.condition.(type) { - case *sqlparser.ColName: - if pb.st.Vindex(vals, rb) == inner.eroute.Vindex { - return true - } - } - return false -} - -func (rb *route) unionCanMerge(other *route, distinct bool) bool { - if rb.eroute.Keyspace.Name != other.eroute.Keyspace.Name { - return false - } - switch rb.eroute.Opcode { - case engine.Unsharded, engine.Reference: - return rb.eroute.Opcode == other.eroute.Opcode - case engine.DBA: - return other.eroute.Opcode == engine.DBA && - len(rb.eroute.SysTableTableSchema) == 0 && - len(rb.eroute.SysTableTableName) == 0 && - len(other.eroute.SysTableTableSchema) == 0 && - len(other.eroute.SysTableTableName) == 0 - case engine.EqualUnique: - // Check if they target the same shard. - if other.eroute.Opcode == engine.EqualUnique && rb.eroute.Vindex == other.eroute.Vindex && valEqual(rb.condition, other.condition) { - return true - } - case engine.Scatter: - return other.eroute.Opcode == engine.Scatter && !distinct - case engine.Next: - return false - } - return false -} - -// canMergeOnFilter returns true if the join constraint makes the routes -// mergeable by unique vindex. The constraint has to be an equality -// like a.id = b.id where both columns have the same unique vindex. -func (rb *route) canMergeOnFilter(pb *primitiveBuilder, rrb *route, filter sqlparser.Expr) bool { - comparison, ok := filter.(*sqlparser.ComparisonExpr) - if !ok { - return false - } - if comparison.Operator != sqlparser.EqualOp { - return false - } - left := comparison.Left - right := comparison.Right - lVindex := pb.st.Vindex(left, rb) - if lVindex == nil { - left, right = right, left - lVindex = pb.st.Vindex(left, rb) - } - if lVindex == nil || !lVindex.IsUnique() { - return false - } - rVindex := pb.st.Vindex(right, rrb) - if rVindex == nil { - return false - } - return rVindex == lVindex -} - -// UpdatePlan evaluates the primitive against the specified -// filter. If it's an improvement, the primitive is updated. -// We assume that the filter has already been pushed into -// the route. -func (rb *route) UpdatePlan(pb *primitiveBuilder, filter sqlparser.Expr) { - switch rb.eroute.Opcode { - // For these opcodes, a new filter will not make any difference, so we can just exit early - case engine.Unsharded, engine.Next, engine.DBA, engine.Reference, engine.None: - return - } - opcode, vindex, values := rb.computePlan(pb, filter) - if opcode == engine.Scatter { - return - } - // If we get SelectNone in next filters, override the previous route plan. - if opcode == engine.None { - rb.updateRoute(opcode, vindex, values) - return - } - switch rb.eroute.Opcode { - case engine.EqualUnique: - if opcode == engine.EqualUnique && vindex.Cost() < rb.eroute.Vindex.Cost() { - rb.updateRoute(opcode, vindex, values) - } - case engine.Equal: - switch opcode { - case engine.EqualUnique: - rb.updateRoute(opcode, vindex, values) - case engine.Equal: - if vindex.Cost() < rb.eroute.Vindex.Cost() { - rb.updateRoute(opcode, vindex, values) - } - } - case engine.IN: - switch opcode { - case engine.EqualUnique, engine.Equal: - rb.updateRoute(opcode, vindex, values) - case engine.IN: - if vindex.Cost() < rb.eroute.Vindex.Cost() { - rb.updateRoute(opcode, vindex, values) - } - } - case engine.MultiEqual: - switch opcode { - case engine.EqualUnique, engine.Equal, engine.IN: - rb.updateRoute(opcode, vindex, values) - case engine.MultiEqual: - if vindex.Cost() < rb.eroute.Vindex.Cost() { - rb.updateRoute(opcode, vindex, values) - } - } - case engine.Scatter: - switch opcode { - case engine.EqualUnique, engine.Equal, engine.IN, engine.MultiEqual, engine.None: - rb.updateRoute(opcode, vindex, values) - } - } -} - -func (rb *route) updateRoute(opcode engine.Opcode, vindex vindexes.SingleColumn, condition sqlparser.Expr) { - rb.eroute.Opcode = opcode - rb.eroute.Vindex = vindex - rb.condition = condition -} - -// computePlan computes the plan for the specified filter. -func (rb *route) computePlan(pb *primitiveBuilder, filter sqlparser.Expr) (opcode engine.Opcode, vindex vindexes.SingleColumn, condition sqlparser.Expr) { - switch node := filter.(type) { - case *sqlparser.ComparisonExpr: - switch node.Operator { - case sqlparser.EqualOp: - return rb.computeEqualPlan(pb, node) - case sqlparser.InOp: - return rb.computeINPlan(pb, node) - case sqlparser.NotInOp: - return rb.computeNotInPlan(node.Right), nil, nil - case sqlparser.LikeOp: - return rb.computeLikePlan(pb, node) - } - case *sqlparser.IsExpr: - return rb.computeISPlan(pb, node) - } - return engine.Scatter, nil, nil -} - -// computeLikePlan computes the plan for 'LIKE' constraint -func (rb *route) computeLikePlan(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, condition sqlparser.Expr) { - - left := comparison.Left - right := comparison.Right - - if sqlparser.IsNull(right) { - return engine.None, nil, nil - } - if !rb.exprIsValue(right) { - return engine.Scatter, nil, nil - } - vindex = pb.st.Vindex(left, rb) - if vindex == nil { - // if there is no vindex defined, scatter - return engine.Scatter, nil, nil - } - if subsharding, ok := vindex.(vindexes.Prefixable); ok { - return engine.Equal, subsharding.PrefixVindex(), right - } - - return engine.Scatter, nil, nil -} - -// computeEqualPlan computes the plan for an equality constraint. -func (rb *route) computeEqualPlan(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, condition sqlparser.Expr) { - left := comparison.Left - right := comparison.Right - - if sqlparser.IsNull(right) { - return engine.None, nil, nil - } - - vindex = pb.st.Vindex(left, rb) - if vindex == nil { - left, right = right, left - vindex = pb.st.Vindex(left, rb) - if vindex == nil { - return engine.Scatter, nil, nil - } - } - if !rb.exprIsValue(right) { - return engine.Scatter, nil, nil - } - if vindex.IsUnique() { - return engine.EqualUnique, vindex, right - } - return engine.Equal, vindex, right -} - -// computeIS computes the plan for an equality constraint. -func (rb *route) computeISPlan(pb *primitiveBuilder, comparison *sqlparser.IsExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, expr sqlparser.Expr) { - // we only handle IS NULL correct. IsExpr can contain other expressions as well - if comparison.Right != sqlparser.IsNullOp { - return engine.Scatter, nil, nil - } - - vindex = pb.st.Vindex(comparison.Left, rb) - // fallback to scatter gather if there is no vindex - if vindex == nil { - return engine.Scatter, nil, nil - } - if _, isLookup := vindex.(vindexes.Lookup); isLookup { - // the lookup table is keyed by the lookup value, so it does not support nulls - return engine.Scatter, nil, nil - } - if vindex.IsUnique() { - return engine.EqualUnique, vindex, &sqlparser.NullVal{} - } - return engine.Equal, vindex, &sqlparser.NullVal{} -} - -// computeINPlan computes the plan for an IN constraint. -func (rb *route) computeINPlan(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, expr sqlparser.Expr) { - switch comparison.Left.(type) { - case *sqlparser.ColName: - return rb.computeSimpleINPlan(pb, comparison) - case sqlparser.ValTuple: - return rb.computeCompositeINPlan(pb, comparison) - } - return engine.Scatter, nil, nil -} - -// computeSimpleINPlan computes the plan for a simple IN constraint. -func (rb *route) computeSimpleINPlan(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, expr sqlparser.Expr) { - vindex = pb.st.Vindex(comparison.Left, rb) - if vindex == nil { - return engine.Scatter, nil, nil - } - switch node := comparison.Right.(type) { - case sqlparser.ValTuple: - if len(node) == 1 && sqlparser.IsNull(node[0]) { - return engine.None, nil, nil - } - - for _, n := range node { - if !rb.exprIsValue(n) { - return engine.Scatter, nil, nil - } - } - return engine.IN, vindex, comparison - case sqlparser.ListArg: - return engine.IN, vindex, comparison - } - return engine.Scatter, nil, nil -} - -// computeCompositeINPlan computes the plan for a composite IN constraint. -func (rb *route) computeCompositeINPlan(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr) (opcode engine.Opcode, vindex vindexes.SingleColumn, values sqlparser.Expr) { - leftTuple := comparison.Left.(sqlparser.ValTuple) - return rb.iterateCompositeIN(pb, comparison, nil, leftTuple) -} - -// iterateCompositeIN recursively walks the LHS tuple of the IN clause looking -// for column names. For those that match a vindex, it builds a multi-value plan -// using the corresponding values in the RHS. It returns the best of the plans built. -func (rb *route) iterateCompositeIN( - pb *primitiveBuilder, - comparison *sqlparser.ComparisonExpr, - coordinates []int, - tuple sqlparser.ValTuple, -) (opcode engine.Opcode, vindex vindexes.SingleColumn, values sqlparser.Expr) { - opcode = engine.Scatter - - cindex := len(coordinates) - coordinates = append(coordinates, 0) - for idx, expr := range tuple { - coordinates[cindex] = idx - switch expr := expr.(type) { - case sqlparser.ValTuple: - newOpcode, newVindex, newValues := rb.iterateCompositeIN(pb, comparison, coordinates, expr) - opcode, vindex, values = bestOfComposite(opcode, newOpcode, vindex, newVindex, values, newValues) - case *sqlparser.ColName: - newVindex := pb.st.Vindex(expr, rb) - if newVindex != nil { - newOpcode, newValues := rb.compositePlanForCol(pb, comparison, coordinates) - opcode, vindex, values = bestOfComposite(opcode, newOpcode, vindex, newVindex, values, newValues) - } - } - } - return opcode, vindex, values -} - -// compositePlanForCol builds a plan for a matched column in the LHS -// of a composite IN clause. -func (rb *route) compositePlanForCol(pb *primitiveBuilder, comparison *sqlparser.ComparisonExpr, coordinates []int) (opcode engine.Opcode, values sqlparser.Expr) { - rightTuple, ok := comparison.Right.(sqlparser.ValTuple) - if !ok { - return engine.Scatter, nil - } - retVal := make(sqlparser.ValTuple, len(rightTuple)) - for i, rval := range rightTuple { - val := tupleAccess(rval, coordinates) - if val == nil { - return engine.Scatter, nil - } - if !rb.exprIsValue(val) { - return engine.Scatter, nil - } - retVal[i] = val - } - return engine.MultiEqual, retVal -} - -// tupleAccess returns the value of the expression that corresponds -// to the specified coordinates. -func tupleAccess(expr sqlparser.Expr, coordinates []int) sqlparser.Expr { - tuple, _ := expr.(sqlparser.ValTuple) - for _, idx := range coordinates { - if idx >= len(tuple) { - return nil - } - expr = tuple[idx] - tuple, _ = expr.(sqlparser.ValTuple) - } - return expr -} - -// bestOfComposite returns the best of two composite IN clause plans. -func bestOfComposite(opcode1, opcode2 engine.Opcode, vindex1, vindex2 vindexes.SingleColumn, values1, values2 sqlparser.Expr) (opcode engine.Opcode, vindex vindexes.SingleColumn, values sqlparser.Expr) { - if opcode1 == engine.Scatter { - return opcode2, vindex2, values2 - } - if opcode2 == engine.Scatter { - return opcode1, vindex1, values1 - } - if vindex1.Cost() < vindex2.Cost() { - return opcode1, vindex1, values1 - } - return opcode2, vindex2, values2 -} - -// computeNotInPlan looks for null values to produce a SelectNone if found -func (rb *route) computeNotInPlan(right sqlparser.Expr) engine.Opcode { - switch node := right.(type) { - case sqlparser.ValTuple: - for _, n := range node { - if sqlparser.IsNull(n) { - return engine.None - } - } - } - - return engine.Scatter -} - -// exprIsValue returns true if the expression can be treated as a value -// for the routeOption. External references are treated as value. -func (rb *route) exprIsValue(expr sqlparser.Expr) bool { - if node, ok := expr.(*sqlparser.ColName); ok { - return node.Metadata.(*column).Origin() != rb - } - return sqlparser.IsValue(expr) -} - -// queryTimeout returns DirectiveQueryTimeout value if set, otherwise returns 0. -func queryTimeout(d *sqlparser.CommentDirectives) int { - val, _ := d.GetString(sqlparser.DirectiveQueryTimeout, "0") - if intVal, err := strconv.Atoi(val); err == nil { - return intVal - } - return 0 -} diff --git a/go/vt/vtgate/planbuilder/routeGen4.go b/go/vt/vtgate/planbuilder/routeGen4.go deleted file mode 100644 index a5b6982319e..00000000000 --- a/go/vt/vtgate/planbuilder/routeGen4.go +++ /dev/null @@ -1,255 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package planbuilder - -import ( - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/vt/vtgate/semantics" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -var _ logicalPlan = (*routeGen4)(nil) - -// routeGen4 is used to build a Route primitive. -// It's used to build one of the Select routes like -// SelectScatter, etc. Portions of the original Select AST -// are moved into this node, which will be used to build -// the final SQL for this route. -type routeGen4 struct { - gen4Plan - - // Select is the AST for the query fragment that will be - // executed by this route. - Select sqlparser.SelectStatement - - // condition stores the AST condition that will be used - // to resolve the ERoute Values field. - condition sqlparser.Expr - - // eroute is the primitive being built. - eroute *engine.Route - - // is the engine primitive we will return from the Primitive() method. Note that it could be different than eroute - enginePrimitive engine.Primitive - - // tables keeps track of which tables this route is covering - tables semantics.TableSet -} - -// Primitive implements the logicalPlan interface -func (rb *routeGen4) Primitive() engine.Primitive { - return rb.enginePrimitive -} - -// SetLimit adds a LIMIT clause to the route. -func (rb *routeGen4) SetLimit(limit *sqlparser.Limit) { - rb.Select.SetLimit(limit) -} - -// WireupGen4 implements the logicalPlan interface -func (rb *routeGen4) WireupGen4(ctx *plancontext.PlanningContext) error { - rb.prepareTheAST() - - // prepare the queries we will pass down - rb.eroute.Query = sqlparser.String(rb.Select) - buffer := sqlparser.NewTrackedBuffer(sqlparser.FormatImpossibleQuery) - node := buffer.WriteNode(rb.Select) - parsedQuery := node.ParsedQuery() - rb.eroute.FieldQuery = parsedQuery.Query - - // if we have a planable vindex lookup, let's extract it into its own primitive - planableVindex, ok := rb.eroute.RoutingParameters.Vindex.(vindexes.LookupPlanable) - if !ok { - rb.enginePrimitive = rb.eroute - return nil - } - - query, args := planableVindex.Query() - stmt, reserved, err := sqlparser.Parse2(query) - if err != nil { - return err - } - reservedVars := sqlparser.NewReservedVars("vtg", reserved) - - lookupPrimitive, err := gen4SelectStmtPlanner(query, querypb.ExecuteOptions_Gen4, stmt.(sqlparser.SelectStatement), reservedVars, ctx.VSchema) - if err != nil { - return vterrors.Wrapf(err, "failed to plan the lookup query: [%s]", query) - } - - rb.enginePrimitive = &engine.VindexLookup{ - Opcode: rb.eroute.Opcode, - Vindex: planableVindex, - Keyspace: rb.eroute.Keyspace, - Values: rb.eroute.Values, - SendTo: rb.eroute, - Arguments: args, - Lookup: lookupPrimitive.primitive, - } - - rb.eroute.RoutingParameters.Opcode = engine.ByDestination - rb.eroute.RoutingParameters.Values = nil - rb.eroute.RoutingParameters.Vindex = nil - - return nil -} - -// ContainsTables implements the logicalPlan interface -func (rb *routeGen4) ContainsTables() semantics.TableSet { - return rb.tables -} - -// OutputColumns implements the logicalPlan interface -func (rb *routeGen4) OutputColumns() []sqlparser.SelectExpr { - return sqlparser.GetFirstSelect(rb.Select).SelectExprs -} - -// prepareTheAST does minor fixups of the SELECT struct before producing the query string -func (rb *routeGen4) prepareTheAST() { - _ = sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) { - switch node := node.(type) { - case *sqlparser.Select: - if len(node.SelectExprs) == 0 { - node.SelectExprs = []sqlparser.SelectExpr{ - &sqlparser.AliasedExpr{ - Expr: sqlparser.NewIntLiteral("1"), - }, - } - } - case *sqlparser.ComparisonExpr: - // 42 = colName -> colName = 42 - b := node.Operator == sqlparser.EqualOp - value := sqlparser.IsValue(node.Left) - name := sqlparser.IsColName(node.Right) - if b && - value && - name { - node.Left, node.Right = node.Right, node.Left - } - } - return true, nil - }, rb.Select) -} - -func (rb *routeGen4) isLocal(col *sqlparser.ColName) bool { - return col.Metadata.(*column).Origin() == rb -} - -// generateFieldQuery generates a query with an impossible where. -// This will be used on the RHS node to fetch field info if the LHS -// returns no result. -func (rb *routeGen4) generateFieldQuery(sel sqlparser.SelectStatement, jt *jointab) string { - formatter := func(buf *sqlparser.TrackedBuffer, node sqlparser.SQLNode) { - switch node := node.(type) { - case *sqlparser.ColName: - if !rb.isLocal(node) { - _, joinVar := jt.Lookup(node) - buf.WriteArg(":", joinVar) - return - } - case sqlparser.TableName: - if !sqlparser.SystemSchema(node.Qualifier.String()) { - node.Name.Format(buf) - return - } - node.Format(buf) - return - } - sqlparser.FormatImpossibleQuery(buf, node) - } - - buffer := sqlparser.NewTrackedBuffer(formatter) - node := buffer.WriteNode(sel) - query := node.ParsedQuery() - return query.Query -} - -// Rewrite implements the logicalPlan interface -func (rb *routeGen4) Rewrite(inputs ...logicalPlan) error { - if len(inputs) != 0 { - return vterrors.VT13001("route: wrong number of inputs") - } - return nil -} - -// Inputs implements the logicalPlan interface -func (rb *routeGen4) Inputs() []logicalPlan { - return []logicalPlan{} -} - -func (rb *routeGen4) isSingleShard() bool { - return rb.eroute.Opcode.IsSingleShard() -} - -func (rb *routeGen4) unionCanMerge(other *routeGen4, distinct bool) bool { - if rb.eroute.Keyspace.Name != other.eroute.Keyspace.Name { - return false - } - switch rb.eroute.Opcode { - case engine.Unsharded, engine.Reference: - return rb.eroute.Opcode == other.eroute.Opcode - case engine.DBA: - return other.eroute.Opcode == engine.DBA && - len(rb.eroute.SysTableTableSchema) == 0 && - len(rb.eroute.SysTableTableName) == 0 && - len(other.eroute.SysTableTableSchema) == 0 && - len(other.eroute.SysTableTableName) == 0 - case engine.EqualUnique: - // Check if they target the same shard. - if other.eroute.Opcode == engine.EqualUnique && rb.eroute.Vindex == other.eroute.Vindex && valEqual(rb.condition, other.condition) { - return true - } - case engine.Scatter: - return other.eroute.Opcode == engine.Scatter && !distinct - case engine.Next: - return false - } - return false -} - -func (rb *routeGen4) updateRoute(opcode engine.Opcode, vindex vindexes.SingleColumn, condition sqlparser.Expr) { - rb.eroute.Opcode = opcode - rb.eroute.Vindex = vindex - rb.condition = condition -} - -// computeNotInPlan looks for null values to produce a SelectNone if found -func (rb *routeGen4) computeNotInPlan(right sqlparser.Expr) engine.Opcode { - switch node := right.(type) { - case sqlparser.ValTuple: - for _, n := range node { - if sqlparser.IsNull(n) { - return engine.None - } - } - } - - return engine.Scatter -} - -// exprIsValue returns true if the expression can be treated as a value -// for the routeOption. External references are treated as value. -func (rb *routeGen4) exprIsValue(expr sqlparser.Expr) bool { - if node, ok := expr.(*sqlparser.ColName); ok { - return node.Metadata.(*column).Origin() != rb - } - return sqlparser.IsValue(expr) -} diff --git a/go/vt/vtgate/planbuilder/route_test.go b/go/vt/vtgate/planbuilder/route_test.go deleted file mode 100644 index 9f4c8fa3b97..00000000000 --- a/go/vt/vtgate/planbuilder/route_test.go +++ /dev/null @@ -1,168 +0,0 @@ -/* -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 planbuilder - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -/* - -This test file only tests the V3 planner. It does not test the Subshard opcode - -For easy reference, opcodes are: - Unsharded 0 - EqualUnique 1 - Equal 2 - IN 3 - MultiEqual 4 - Scatter 5 - Next 6 - DBA 7 - Reference 8 - None 9 -*/ - -func TestJoinCanMerge(t *testing.T) { - testcases := [][]bool{ - {true, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, true, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - - {false, false, false, false, false, false, false, false, false, false, false, false}, // this whole line is not tested - - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, true, true, false, false}, - {true, true, true, true, true /*not tested*/, false, true, true, true, true, true, true}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - } - - ks := &vindexes.Keyspace{} - for left, vals := range testcases { - for right, val := range vals { - name := fmt.Sprintf("%s:%s", engine.Opcode(left).String(), engine.Opcode(right).String()) - if left == int(engine.SubShard) || right == int(engine.SubShard) { - continue // not used by v3 - } - - t.Run(name, func(t *testing.T) { - lRoute := &route{ - // Setting condition will make SelectEqualUnique match itself. - condition: &sqlparser.ColName{}, - } - pb := &primitiveBuilder{ - plan: lRoute, - } - rRoute := &route{ - condition: &sqlparser.ColName{}, - } - lRoute.eroute = engine.NewSimpleRoute(engine.Opcode(left), ks) - rRoute.eroute = engine.NewSimpleRoute(engine.Opcode(right), ks) - assert.Equal(t, val, lRoute.JoinCanMerge(pb, rRoute, nil, nil), fmt.Sprintf("%v:%v", lRoute.eroute.RouteType(), rRoute.eroute.RouteType())) - }) - } - } -} - -func TestSubqueryCanMerge(t *testing.T) { - testcases := [][]bool{ - // US EU E IN ME subShard scatter nxt dba ref none byD - {true, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, // unsharded - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, // equalUnique - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // equal - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // in - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // multiEqual - - {false, false, false, false, false, false, false, false, false, false, false, false, false}, // subshard - this whole line is not tested - - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // scatter - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, // next - {false, false, false, false, false /*not tested*/, false, false, false, true, true, false, false}, // dba - {true, true, false, false, false /*not tested*/, false, false, true, true, true, false, false}, // reference - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // none - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, // byDestination - } - - ks := &vindexes.Keyspace{} - lRoute := &route{} - pb := &primitiveBuilder{ - plan: lRoute, - } - rRoute := &route{} - for left, vals := range testcases { - lRoute.eroute = engine.NewSimpleRoute(engine.Opcode(left), ks) - for right, val := range vals { - name := fmt.Sprintf("%s:%s", engine.Opcode(left).String(), engine.Opcode(right).String()) - t.Run(name, func(t *testing.T) { - if left == int(engine.SubShard) || right == int(engine.SubShard) { - t.Skip("not used by v3") - } - - rRoute.eroute = engine.NewSimpleRoute(engine.Opcode(right), ks) - assert.Equal(t, val, lRoute.SubqueryCanMerge(pb, rRoute), fmt.Sprintf("%v:%v", lRoute.eroute.RouteType(), rRoute.eroute.RouteType())) - }) - } - } -} - -func TestUnionCanMerge(t *testing.T) { - testcases := [][]bool{ - {true, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - - {false, false, false, false, false, false, false, false, false, false, false, false, false}, // this whole line is not tested - - {false, false, false, false, false /*not tested*/, false, true, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, true, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, true, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - {false, false, false, false, false /*not tested*/, false, false, false, false, false, false, false}, - } - - ks := &vindexes.Keyspace{} - lRoute := &route{} - rRoute := &route{} - for left, vals := range testcases { - lRoute.eroute = engine.NewSimpleRoute(engine.Opcode(left), ks) - for right, val := range vals { - name := fmt.Sprintf("%s:%s", engine.Opcode(left).String(), engine.Opcode(right).String()) - t.Run(name, func(t *testing.T) { - if left == int(engine.SubShard) || right == int(engine.SubShard) { - t.Skip("not used by v3") - } - - rRoute.eroute = engine.NewSimpleRoute(engine.Opcode(right), ks) - assert.Equal(t, val, lRoute.unionCanMerge(rRoute, false), fmt.Sprintf("can't create a single route from these two inputs %v:%v", lRoute.eroute.RouteType(), rRoute.eroute.RouteType())) - }) - } - } -} diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index f6de8264d85..df4e34e8308 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -19,242 +19,396 @@ package planbuilder import ( "fmt" - "vitess.io/vitess/go/vt/log" - - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/vt/key" - - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/vt/vtgate/evalengine" - + 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/evalengine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" ) -func buildSelectPlan(query string) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - sel := stmt.(*sqlparser.Select) - if sel.With != nil { +func gen4SelectStmtPlanner( + query string, + plannerVersion querypb.ExecuteOptions_PlannerVersion, + stmt sqlparser.SelectStatement, + reservedVars *sqlparser.ReservedVars, + vschema plancontext.VSchema, +) (*planResult, error) { + switch node := stmt.(type) { + case *sqlparser.Select: + if node.With != nil { return nil, vterrors.VT12001("WITH expression in SELECT statement") } - err := checkUnsupportedExpressions(sel) - if err != nil { - return nil, err + case *sqlparser.Union: + if node.With != nil { + return nil, vterrors.VT12001("WITH expression in UNION statement") } + } + sel, isSel := stmt.(*sqlparser.Select) + if isSel { + // handle dual table for processing at vtgate. p, err := handleDualSelects(sel, vschema) if err != nil { return nil, err } if p != nil { - return newPlanResult(p), nil - } - - getPlan := func(sel *sqlparser.Select) (logicalPlan, error) { - pb := newPrimitiveBuilder(vschema, newJointab(reservedVars)) - if err := pb.processSelect(sel, reservedVars, nil, query); err != nil { - return nil, err + used := "dual" + keyspace, ksErr := vschema.DefaultKeyspace() + if ksErr == nil { + // we are just getting the ks to log the correct table use. + // no need to fail this if we can't find the default keyspace + used = keyspace.Name + ".dual" } - if err := pb.plan.Wireup(pb.plan, pb.jt); err != nil { - return nil, err - } - return pb.plan, nil + return newPlanResult(p, used), nil } - plan, err := getPlan(sel) - if err != nil { - return nil, err + if sel.SQLCalcFoundRows && sel.Limit != nil { + return gen4planSQLCalcFoundRows(vschema, sel, query, reservedVars) } + // if there was no limit, we can safely ignore the SQLCalcFoundRows directive + sel.SQLCalcFoundRows = false + } - if shouldRetryAfterPredicateRewriting(plan) { - // by transforming the predicates to CNF, the planner will sometimes find better plans - primitive := rewriteToCNFAndReplan(stmt, getPlan) - if primitive != nil { - return newPlanResult(primitive), nil - } + getPlan := func(selStatement sqlparser.SelectStatement) (logicalPlan, *semantics.SemTable, []string, error) { + return newBuildSelectPlan(selStatement, reservedVars, vschema, plannerVersion) + } + + plan, _, tablesUsed, err := getPlan(stmt) + if err != nil { + return nil, err + } + + if shouldRetryAfterPredicateRewriting(plan) { + // by transforming the predicates to CNF, the planner will sometimes find better plans + plan2, _, tablesUsed := gen4PredicateRewrite(stmt, getPlan) + if plan2 != nil { + return newPlanResult(plan2.Primitive(), tablesUsed...), nil } - primitive := plan.Primitive() - if rb, ok := primitive.(*engine.Route); ok { - // this is done because engine.Route doesn't handle the empty result well - // if it doesn't find a shard to send the query to. - // All other engine primitives can handle this, so we only need it when - // Route is the last (and only) instruction before the user sees a result - if isOnlyDual(sel) || (len(sel.GroupBy) == 0 && sel.SelectExprs.AllAggregation()) { - rb.NoRoutesSpecialHandling = true - } + } + + primitive := plan.Primitive() + if !isSel { + return newPlanResult(primitive, tablesUsed...), nil + } + + // this is done because engine.Route doesn't handle the empty result well + // if it doesn't find a shard to send the query to. + // All other engine primitives can handle this, so we only need it when + // Route is the last (and only) instruction before the user sees a result + if isOnlyDual(sel) || (len(sel.GroupBy) == 0 && sel.SelectExprs.AllAggregation()) { + switch prim := primitive.(type) { + case *engine.Route: + prim.NoRoutesSpecialHandling = true + case *engine.VindexLookup: + prim.SendTo.NoRoutesSpecialHandling = true } + } + return newPlanResult(primitive, tablesUsed...), nil +} - return newPlanResult(primitive), nil +func gen4planSQLCalcFoundRows(vschema plancontext.VSchema, sel *sqlparser.Select, query string, reservedVars *sqlparser.ReservedVars) (*planResult, error) { + ksName := "" + if ks, _ := vschema.DefaultKeyspace(); ks != nil { + ksName = ks.Name + } + semTable, err := semantics.Analyze(sel, ksName, vschema) + if err != nil { + return nil, err } + // record any warning as planner warning. + vschema.PlannerWarning(semTable.Warning) + + plan, tablesUsed, err := buildSQLCalcFoundRowsPlan(query, sel, reservedVars, vschema) + if err != nil { + return nil, err + } + return newPlanResult(plan.Primitive(), tablesUsed...), nil } -// checkUnsupportedExpressions checks for unsupported expressions. -func checkUnsupportedExpressions(sel sqlparser.SQLNode) error { - var unsupportedErr error - sqlparser.Rewrite(sel, func(cursor *sqlparser.Cursor) bool { - switch cursor.Node().(type) { - case *sqlparser.AssignmentExpr: - unsupportedErr = vterrors.VT12001("Assignment expression") - return false - default: - return true +func buildSQLCalcFoundRowsPlan( + originalQuery string, + sel *sqlparser.Select, + reservedVars *sqlparser.ReservedVars, + vschema plancontext.VSchema, +) (logicalPlan, []string, error) { + limitPlan, _, err := planSelectGen4(reservedVars, vschema, sel) + if err != nil { + return nil, nil, err + } + + statement2, reserved2, err := sqlparser.Parse2(originalQuery) + if err != nil { + return nil, nil, err + } + sel2 := statement2.(*sqlparser.Select) + + sel2.SQLCalcFoundRows = false + sel2.OrderBy = nil + sel2.Limit = nil + + countStartExpr := []sqlparser.SelectExpr{&sqlparser.AliasedExpr{ + Expr: &sqlparser.CountStar{}, + }} + if sel2.GroupBy == nil && sel2.Having == nil { + // if there is no grouping, we can use the same query and + // just replace the SELECT sub-clause to have a single count(*) + sel2.SelectExprs = countStartExpr + } else { + // when there is grouping, we have to move the original query into a derived table. + // select id, sum(12) from user group by id => + // select count(*) from (select id, sum(12) from user group by id) t + sel3 := &sqlparser.Select{ + SelectExprs: countStartExpr, + From: []sqlparser.TableExpr{ + &sqlparser.AliasedTableExpr{ + Expr: &sqlparser.DerivedTable{Select: sel2}, + As: sqlparser.NewIdentifierCS("t"), + }, + }, } - }, nil) - if unsupportedErr != nil { - return unsupportedErr + sel2 = sel3 } - return nil + + reservedVars2 := sqlparser.NewReservedVars("vtg", reserved2) + + countPlan, tablesUsed, err := planSelectGen4(reservedVars2, vschema, sel2) + if err != nil { + return nil, nil, err + } + return &sqlCalcFoundRows{LimitQuery: limitPlan, CountQuery: countPlan}, tablesUsed, nil } -func rewriteToCNFAndReplan(stmt sqlparser.Statement, getPlan func(sel *sqlparser.Select) (logicalPlan, error)) engine.Primitive { - rewritten := sqlparser.RewritePredicate(stmt) - sel2, isSelect := rewritten.(*sqlparser.Select) - if isSelect { - log.Infof("retrying plan after cnf: %s", sqlparser.String(sel2)) - plan2, err := getPlan(sel2) - if err == nil && !shouldRetryAfterPredicateRewriting(plan2) { - // we only use this new plan if it's better than the old one we got - return plan2.Primitive() - } +func planSelectGen4(reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, sel *sqlparser.Select) (logicalPlan, []string, error) { + plan, _, tablesUsed, err := newBuildSelectPlan(sel, reservedVars, vschema, 0) + if err != nil { + return nil, nil, err } - return nil + return plan, tablesUsed, nil } -func shouldRetryAfterPredicateRewriting(plan logicalPlan) bool { - // if we have a I_S query, but have not found table_schema or table_name, let's try CNF - var opcode engine.Opcode - var sysTableTableName map[string]evalengine.Expr - var sysTableTableSchema []evalengine.Expr +func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (logicalPlan, *semantics.SemTable, []string, error)) (logicalPlan, *semantics.SemTable, []string) { + rewritten, isSel := sqlparser.RewritePredicate(stmt).(sqlparser.SelectStatement) + if !isSel { + // Fail-safe code, should never happen + return nil, nil, nil + } + plan2, st, op, err := getPlan(rewritten) + if err == nil && !shouldRetryAfterPredicateRewriting(plan2) { + // we only use this new plan if it's better than the old one we got + return plan2, st, op + } + return nil, nil, nil +} - switch routePlan := plan.(type) { - case *routeGen4: - opcode = routePlan.eroute.Opcode - sysTableTableName = routePlan.eroute.SysTableTableName - sysTableTableSchema = routePlan.eroute.SysTableTableSchema - case *route: - opcode = routePlan.eroute.Opcode - sysTableTableName = routePlan.eroute.SysTableTableName - sysTableTableSchema = routePlan.eroute.SysTableTableSchema - default: - return false +func newBuildSelectPlan( + selStmt sqlparser.SelectStatement, + reservedVars *sqlparser.ReservedVars, + vschema plancontext.VSchema, + version querypb.ExecuteOptions_PlannerVersion, +) (plan logicalPlan, semTable *semantics.SemTable, tablesUsed []string, err error) { + ksName := "" + if ks, _ := vschema.DefaultKeyspace(); ks != nil { + ksName = ks.Name + } + semTable, err = semantics.Analyze(selStmt, ksName, vschema) + if err != nil { + return nil, nil, nil, err } + // record any warning as planner warning. + vschema.PlannerWarning(semTable.Warning) - return opcode == engine.DBA && - len(sysTableTableName) == 0 && - len(sysTableTableSchema) == 0 -} + ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) -// processSelect builds a primitive tree for the given query or subquery. -// The tree built by this function has the following general structure: -// -// The leaf nodes can be a route, vindexFunc or subquery. In the symtab, -// the tables map has columns that point to these leaf nodes. A subquery -// itself contains a logicalPlan tree, but it's opaque and is made to look -// like a table for the analysis of the current tree. -// -// The leaf nodes are usually tied together by join nodes. While the join -// nodes are built, they have ON clauses. Those are analyzed and pushed -// down into the leaf nodes as the tree is formed. Join nodes are formed -// during analysis of the FROM clause. -// -// During the WHERE clause analysis, the target leaf node is identified -// for each part, and the PushFilter function is used to push the condition -// down. The same strategy is used for the other clauses. -// -// So, a typical plan would either be a simple leaf node, or may consist -// of leaf nodes tied together by join nodes. -// -// If a query has aggregates that cannot be pushed down, an aggregator -// primitive is built. The current orderedAggregate primitive can only -// be built on top of a route. The orderedAggregate expects the rows -// to be ordered as they are returned. This work is performed by the -// underlying route. This means that a compatible ORDER BY clause -// can also be handled by this combination of primitives. In this case, -// the tree would consist of an orderedAggregate whose input is a route. -// -// If a query has an ORDER BY, but the route is a scatter, then the -// ordering is pushed down into the route itself. This results in a simple -// route primitive. -// -// The LIMIT clause is the last construct of a query. If it cannot be -// pushed into a route, then a primitive is created on top of any -// of the above trees to make it discard unwanted rows. -func (pb *primitiveBuilder) processSelect(sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars, outer *symtab, query string) error { - // Check and error if there is any locking function present in select expression. - for _, expr := range sel.SelectExprs { - if aExpr, ok := expr.(*sqlparser.AliasedExpr); ok && sqlparser.IsLockingFunc(aExpr.Expr) { - return vterrors.VT12001(fmt.Sprintf("%v is allowed only with dual", sqlparser.String(aExpr))) + if ks, _ := semTable.SingleUnshardedKeyspace(); ks != nil { + plan, tablesUsed, err = selectUnshardedShortcut(ctx, selStmt, ks) + if err != nil { + return nil, nil, nil, err } + plan = pushCommentDirectivesOnPlan(plan, selStmt) + return plan, semTable, tablesUsed, err } - if sel.SQLCalcFoundRows { - if outer != nil || query == "" { - return vterrors.VT03008("SQL_CALC_FOUND_ROWS") - } - sel.SQLCalcFoundRows = false - if sel.Limit != nil { - plan, _, err := buildSQLCalcFoundRowsPlan(query, sel, reservedVars, pb.vschema, planSelectV3) - if err != nil { - return err - } - pb.plan = plan - return nil + + // From this point on, we know it is not an unsharded query and return the NotUnshardedErr if there is any + if semTable.NotUnshardedErr != nil { + return nil, nil, nil, semTable.NotUnshardedErr + } + + err = queryRewrite(semTable, reservedVars, selStmt) + if err != nil { + return nil, nil, nil, err + } + + op, err := operators.PlanQuery(ctx, selStmt) + if err != nil { + return nil, nil, nil, err + } + + plan, err = transformToLogicalPlan(ctx, op, true) + if err != nil { + return nil, nil, nil, err + } + + optimizePlan(plan) + + sel, isSel := selStmt.(*sqlparser.Select) + if isSel { + if err = setMiscFunc(plan, sel); err != nil { + return nil, nil, nil, err } } - // Into is not supported in subquery. - if sel.Into != nil && (outer != nil || query == "") { - return vterrors.VT03008("INTO") + if err = plan.Wireup(ctx); err != nil { + return nil, nil, nil, err } - var where sqlparser.Expr - if sel.Where != nil { - where = sel.Where.Expr + plan = pushCommentDirectivesOnPlan(plan, selStmt) + + return plan, semTable, operators.TablesUsed(op), nil +} + +// optimizePlan removes unnecessary simpleProjections that have been created while planning +func optimizePlan(plan logicalPlan) { + for _, lp := range plan.Inputs() { + optimizePlan(lp) } - if err := pb.processTableExprs(sel.From, reservedVars, where); err != nil { - return err + + this, ok := plan.(*simpleProjection) + if !ok { + return + } + + input, ok := this.input.(*simpleProjection) + if !ok { + return } - if rb, ok := pb.plan.(*route); ok { - // TODO(sougou): this can probably be improved. - directives := sel.Comments.Directives() - rb.eroute.QueryTimeout = queryTimeout(directives) - if rb.eroute.TargetDestination != nil { - return vterrors.VT12001("SELECT with a target destination") + for i, col := range this.eSimpleProj.Cols { + this.eSimpleProj.Cols[i] = input.eSimpleProj.Cols[col] + } + this.input = input.input +} + +func planLimit(limit *sqlparser.Limit, plan logicalPlan) (logicalPlan, error) { + if limit == nil { + return plan, nil + } + rb, ok := plan.(*route) + if ok && rb.isSingleShard() { + rb.SetLimit(limit) + return plan, nil + } + + lPlan, err := createLimit(plan, limit) + if err != nil { + return nil, err + } + + // visit does not modify the plan. + _, err = visit(lPlan, setUpperLimit) + if err != nil { + return nil, err + } + return lPlan, nil +} + +func planHorizon(ctx *plancontext.PlanningContext, plan logicalPlan, in sqlparser.SelectStatement, truncateColumns bool) (logicalPlan, error) { + switch node := in.(type) { + case *sqlparser.Select: + hp := horizonPlanning{ + sel: node, } - if directives.IsSet(sqlparser.DirectiveScatterErrorsAsWarnings) { - rb.eroute.ScatterErrorsAsWarnings = true + + replaceSubQuery(ctx, node) + var err error + plan, err = hp.planHorizon(ctx, plan, truncateColumns) + if err != nil { + return nil, err + } + plan, err = planLimit(node.Limit, plan) + if err != nil { + return nil, err + } + case *sqlparser.Union: + var err error + rb, isRoute := plan.(*route) + if !isRoute && ctx.SemTable.NotSingleRouteErr != nil { + return nil, ctx.SemTable.NotSingleRouteErr + } + if isRoute && rb.isSingleShard() { + err = planSingleRoutePlan(node, rb) + } else { + plan, err = planOrderByOnUnion(ctx, plan, node) + } + if err != nil { + return nil, err } - } - // Set the outer symtab after processing of FROM clause. - // This is because correlation is not allowed there. - pb.st.Outer = outer - if sel.Where != nil { - if err := pb.pushFilter(sel.Where.Expr, sqlparser.WhereStr, reservedVars); err != nil { - return err + plan, err = planLimit(node.Limit, plan) + if err != nil { + return nil, err } } - if err := pb.checkAggregates(sel); err != nil { - return err + return plan, nil + +} + +func planOrderByOnUnion(ctx *plancontext.PlanningContext, plan logicalPlan, union *sqlparser.Union) (logicalPlan, error) { + qp, err := operators.CreateQPFromSelectStatement(ctx, union) + if err != nil { + return nil, err } - if err := pb.pushSelectExprs(sel, reservedVars); err != nil { - return err + hp := horizonPlanning{ + qp: qp, } - if sel.Having != nil { - if err := pb.pushFilter(sel.Having.Expr, sqlparser.HavingStr, reservedVars); err != nil { - return err + if len(qp.OrderExprs) > 0 { + plan, err = hp.planOrderBy(ctx, qp.OrderExprs, plan) + if err != nil { + return nil, err } } - if err := pb.pushOrderBy(sel.OrderBy); err != nil { - return err + return plan, nil +} + +func isOnlyDual(sel *sqlparser.Select) bool { + if sel.Where != nil || sel.GroupBy != nil || sel.Having != nil || sel.Limit != nil || sel.OrderBy != nil { + // we can only deal with queries without any other subclauses - just SELECT and FROM, nothing else is allowed + return false } - if err := pb.pushLimit(sel.Limit); err != nil { - return err + + if len(sel.From) > 1 { + return false + } + table, ok := sel.From[0].(*sqlparser.AliasedTableExpr) + if !ok { + return false + } + tableName, ok := table.Expr.(sqlparser.TableName) + + return ok && tableName.Name.String() == "dual" && tableName.Qualifier.IsEmpty() +} + +func shouldRetryAfterPredicateRewriting(plan logicalPlan) bool { + // if we have a I_S query, but have not found table_schema or table_name, let's try CNF + var opcode engine.Opcode + var sysTableTableName map[string]evalengine.Expr + var sysTableTableSchema []evalengine.Expr + + switch routePlan := plan.(type) { + case *route: + opcode = routePlan.eroute.Opcode + sysTableTableName = routePlan.eroute.SysTableTableName + sysTableTableSchema = routePlan.eroute.SysTableTableSchema + default: + return false } - return setMiscFunc(pb.plan, sel) + return opcode == engine.DBA && + len(sysTableTableName) == 0 && + len(sysTableTableSchema) == 0 } func setMiscFunc(in logicalPlan, sel *sqlparser.Select) error { @@ -266,12 +420,6 @@ func setMiscFunc(in logicalPlan, sel *sqlparser.Select) error { return false, nil, err } return true, node, nil - case *routeGen4: - err := copyCommentsAndLocks(node.Select, sel, node.eroute.Opcode) - if err != nil { - return false, nil, err - } - return true, node, nil } return true, plan, nil }) @@ -295,67 +443,6 @@ func copyCommentsAndLocks(statement sqlparser.SelectStatement, sel *sqlparser.Se return nil } -func buildSQLCalcFoundRowsPlan( - originalQuery string, - sel *sqlparser.Select, - reservedVars *sqlparser.ReservedVars, - vschema plancontext.VSchema, - planSelect func(reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, sel *sqlparser.Select) (*jointab, logicalPlan, []string, error), -) (logicalPlan, []string, error) { - ljt, limitPlan, _, err := planSelect(reservedVars, vschema, sel) - if err != nil { - return nil, nil, err - } - - statement2, reserved2, err := sqlparser.Parse2(originalQuery) - if err != nil { - return nil, nil, err - } - sel2 := statement2.(*sqlparser.Select) - - sel2.SQLCalcFoundRows = false - sel2.OrderBy = nil - sel2.Limit = nil - - countStartExpr := []sqlparser.SelectExpr{&sqlparser.AliasedExpr{ - Expr: &sqlparser.CountStar{}, - }} - if sel2.GroupBy == nil && sel2.Having == nil { - // if there is no grouping, we can use the same query and - // just replace the SELECT sub-clause to have a single count(*) - sel2.SelectExprs = countStartExpr - } else { - // when there is grouping, we have to move the original query into a derived table. - // select id, sum(12) from user group by id => - // select count(*) from (select id, sum(12) from user group by id) t - sel3 := &sqlparser.Select{ - SelectExprs: countStartExpr, - From: []sqlparser.TableExpr{ - &sqlparser.AliasedTableExpr{ - Expr: &sqlparser.DerivedTable{Select: sel2}, - As: sqlparser.NewIdentifierCS("t"), - }, - }, - } - sel2 = sel3 - } - - reservedVars2 := sqlparser.NewReservedVars("vtg", reserved2) - - cjt, countPlan, tablesUsed, err := planSelect(reservedVars2, vschema, sel2) - if err != nil { - return nil, nil, err - } - return &sqlCalcFoundRows{LimitQuery: limitPlan, CountQuery: countPlan, ljt: ljt, cjt: cjt}, tablesUsed, nil -} - -func planSelectV3(reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, sel *sqlparser.Select) (*jointab, logicalPlan, []string, error) { - ljt := newJointab(reservedVars) - frpb := newPrimitiveBuilder(vschema, ljt) - err := frpb.processSelect(sel, reservedVars, nil, "") - return ljt, frpb.plan, nil, err -} - func handleDualSelects(sel *sqlparser.Select, vschema plancontext.VSchema) (engine.Primitive, error) { if !isOnlyDual(sel) { return nil, nil @@ -418,236 +505,3 @@ func buildLockingPrimitive(sel *sqlparser.Select, vschema plancontext.VSchema, l LockFunctions: lockFunctions, }, nil } - -func isOnlyDual(sel *sqlparser.Select) bool { - if sel.Where != nil || sel.GroupBy != nil || sel.Having != nil || sel.Limit != nil || sel.OrderBy != nil { - // we can only deal with queries without any other subclauses - just SELECT and FROM, nothing else is allowed - return false - } - - if len(sel.From) > 1 { - return false - } - table, ok := sel.From[0].(*sqlparser.AliasedTableExpr) - if !ok { - return false - } - tableName, ok := table.Expr.(sqlparser.TableName) - - return ok && tableName.Name.String() == "dual" && tableName.Qualifier.IsEmpty() -} - -// pushFilter identifies the target route for the specified bool expr, -// pushes it down, and updates the route info if the new constraint improves -// the primitive. This function can push to a WHERE or HAVING clause. -func (pb *primitiveBuilder) pushFilter(in sqlparser.Expr, whereType string, reservedVars *sqlparser.ReservedVars) error { - filters := sqlparser.SplitAndExpression(nil, in) - reorderBySubquery(filters) - for _, filter := range filters { - pullouts, origin, expr, err := pb.findOrigin(filter, reservedVars) - if err != nil { - return err - } - rut, isRoute := origin.(*route) - if isRoute && rut.eroute.Opcode == engine.DBA { - err := pb.findSysInfoRoutingPredicates(expr, rut, reservedVars) - if err != nil { - return err - } - } - // The returned expression may be complex. Resplit before pushing. - for _, subexpr := range sqlparser.SplitAndExpression(nil, expr) { - pb.plan, err = planFilter(pb, pb.plan, subexpr, whereType, origin) - if err != nil { - return err - } - } - pb.addPullouts(pullouts) - } - return nil -} - -// reorderBySubquery reorders the filters by pushing subqueries -// to the end. This allows the non-subquery filters to be -// pushed first because they can potentially improve the routing -// plan, which can later allow a filter containing a subquery -// to successfully merge with the corresponding route. -func reorderBySubquery(filters []sqlparser.Expr) { - max := len(filters) - for i := 0; i < max; i++ { - if !hasSubquery(filters[i]) { - continue - } - saved := filters[i] - for j := i; j < len(filters)-1; j++ { - filters[j] = filters[j+1] - } - filters[len(filters)-1] = saved - max-- - } -} - -// addPullouts adds the pullout subqueries to the primitiveBuilder. -func (pb *primitiveBuilder) addPullouts(pullouts []*pulloutSubquery) { - for _, pullout := range pullouts { - pullout.setUnderlying(pb.plan) - pb.plan = pullout - pb.plan.Reorder(0) - } -} - -// pushSelectExprs identifies the target route for the -// select expressions and pushes them down. -func (pb *primitiveBuilder) pushSelectExprs(sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars) error { - resultColumns, err := pb.pushSelectRoutes(sel.SelectExprs, reservedVars) - if err != nil { - return err - } - pb.st.SetResultColumns(resultColumns) - return pb.pushGroupBy(sel) -} - -// pushSelectRoutes is a convenience function that pushes all the select -// expressions and returns the list of resultColumns generated for it. -func (pb *primitiveBuilder) pushSelectRoutes(selectExprs sqlparser.SelectExprs, reservedVars *sqlparser.ReservedVars) ([]*resultColumn, error) { - resultColumns := make([]*resultColumn, 0, len(selectExprs)) - for _, node := range selectExprs { - switch node := node.(type) { - case *sqlparser.AliasedExpr: - pullouts, origin, expr, err := pb.findOrigin(node.Expr, reservedVars) - if err != nil { - return nil, err - } - node.Expr = expr - newBuilder, rc, _, err := planProjection(pb, pb.plan, node, origin) - if err != nil { - return nil, err - } - pb.plan = newBuilder - resultColumns = append(resultColumns, rc) - pb.addPullouts(pullouts) - case *sqlparser.StarExpr: - var expanded bool - var err error - resultColumns, expanded, err = pb.expandStar(resultColumns, node) - if err != nil { - return nil, err - } - if expanded { - continue - } - // We'll allow select * for simple routes. - rb, ok := pb.plan.(*route) - if !ok { - return nil, vterrors.VT12001("'*' expression in cross-shard query") - } - // Validate keyspace reference if any. - if !node.TableName.IsEmpty() { - if _, err := pb.st.FindTable(node.TableName); err != nil { - return nil, err - } - } - resultColumns = append(resultColumns, rb.PushAnonymous(node)) - case *sqlparser.Nextval: - rb, ok := pb.plan.(*route) - if !ok { - // This code is unreachable because the parser doesn't allow joins for next val statements. - return nil, vterrors.VT12001("SELECT NEXT query in cross-shard query") - } - if rb.eroute.Opcode != engine.Next { - return nil, vterrors.VT03018() - } - rb.eroute.Opcode = engine.Next - resultColumns = append(resultColumns, rb.PushAnonymous(node)) - default: - return nil, vterrors.VT13001(fmt.Sprintf("unexpected SELECT expression type: %T", node)) - } - } - return resultColumns, nil -} - -// expandStar expands a StarExpr and pushes the expanded -// expressions down if the tables have authoritative column lists. -// If not, it returns false. -// This function breaks the abstraction a bit: it directly sets the -// the Metadata for newly created expressions. In all other cases, -// the Metadata is set through a symtab Find. -func (pb *primitiveBuilder) expandStar(inrcs []*resultColumn, expr *sqlparser.StarExpr) (outrcs []*resultColumn, expanded bool, err error) { - tables := pb.st.AllTables() - if tables == nil { - // no table metadata available. - return inrcs, false, nil - } - if expr.TableName.IsEmpty() { - for _, t := range tables { - // All tables must have authoritative column lists. - if !t.isAuthoritative { - return inrcs, false, nil - } - } - singleTable := false - if len(tables) == 1 { - singleTable = true - } - for _, t := range tables { - for _, col := range t.columnNames { - var expr *sqlparser.AliasedExpr - if singleTable { - // If there's only one table, we use unqualified column names. - expr = &sqlparser.AliasedExpr{ - Expr: &sqlparser.ColName{ - Metadata: t.columns[col.Lowered()], - Name: col, - }, - } - } else { - // If a and b have id as their column, then - // select * from a join b should result in - // select a.id as id, b.id as id from a join b. - expr = &sqlparser.AliasedExpr{ - Expr: &sqlparser.ColName{ - Metadata: t.columns[col.Lowered()], - Name: col, - Qualifier: t.alias, - }, - As: col, - } - } - newBuilder, rc, _, err := planProjection(pb, pb.plan, expr, t.Origin()) - if err != nil { - // Unreachable because PushSelect won't fail on ColName. - return inrcs, false, err - } - pb.plan = newBuilder - inrcs = append(inrcs, rc) - } - } - return inrcs, true, nil - } - - // Expression qualified with table name. - t, err := pb.st.FindTable(expr.TableName) - if err != nil { - return inrcs, false, err - } - if !t.isAuthoritative { - return inrcs, false, nil - } - for _, col := range t.columnNames { - expr := &sqlparser.AliasedExpr{ - Expr: &sqlparser.ColName{ - Metadata: t.columns[col.Lowered()], - Name: col, - Qualifier: expr.TableName, - }, - } - newBuilder, rc, _, err := planProjection(pb, pb.plan, expr, t.Origin()) - if err != nil { - // Unreachable because PushSelect won't fail on ColName. - return inrcs, false, err - } - pb.plan = newBuilder - inrcs = append(inrcs, rc) - } - return inrcs, true, nil -} diff --git a/go/vt/vtgate/planbuilder/semi_join.go b/go/vt/vtgate/planbuilder/semi_join.go index 44d99942fe4..5d530c7bce4 100644 --- a/go/vt/vtgate/planbuilder/semi_join.go +++ b/go/vt/vtgate/planbuilder/semi_join.go @@ -30,7 +30,6 @@ var _ logicalPlan = (*semiJoin)(nil) // This gets built if a rhs is correlated and can // be pulled out but requires some variables to be supplied from outside. type semiJoin struct { - gen4Plan rhs logicalPlan lhs logicalPlan cols []int @@ -63,11 +62,11 @@ func (ps *semiJoin) Primitive() engine.Primitive { } // WireupGen4 implements the logicalPlan interface -func (ps *semiJoin) WireupGen4(ctx *plancontext.PlanningContext) error { - if err := ps.lhs.WireupGen4(ctx); err != nil { +func (ps *semiJoin) Wireup(ctx *plancontext.PlanningContext) error { + if err := ps.lhs.Wireup(ctx); err != nil { return err } - return ps.rhs.WireupGen4(ctx) + return ps.rhs.Wireup(ctx) } // Rewrite implements the logicalPlan interface diff --git a/go/vt/vtgate/planbuilder/simple_projection.go b/go/vt/vtgate/planbuilder/simple_projection.go index c413630f386..e9e8a146b59 100644 --- a/go/vt/vtgate/planbuilder/simple_projection.go +++ b/go/vt/vtgate/planbuilder/simple_projection.go @@ -17,10 +17,7 @@ limitations under the License. package planbuilder import ( - "fmt" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" ) @@ -37,35 +34,7 @@ var _ logicalPlan = (*simpleProjection)(nil) // a simpleProjection. type simpleProjection struct { logicalPlanCommon - resultColumns []*resultColumn - eSimpleProj *engine.SimpleProjection -} - -// newSimpleProjection builds a new simpleProjection. -func newSimpleProjection(alias sqlparser.IdentifierCS, plan logicalPlan) (*simpleProjection, *symtab, error) { - sq := &simpleProjection{ - logicalPlanCommon: newBuilderCommon(plan), - eSimpleProj: &engine.SimpleProjection{}, - } - - // Create a 'table' that represents the derived table. - t := &table{ - alias: sqlparser.TableName{Name: alias}, - origin: sq, - } - - // Create column symbols based on the result column names. - for _, rc := range plan.ResultColumns() { - if _, ok := t.columns[rc.alias.Lowered()]; ok { - return nil, nil, vterrors.VT12001(fmt.Sprintf("duplicate column names in subquery: %s", sqlparser.String(rc.alias))) - } - t.addColumn(rc.alias, &column{origin: sq}) - } - t.isAuthoritative = true - st := newSymtab() - // AddTable will not fail because symtab is empty. - _ = st.AddTable(t) - return sq, st, nil + eSimpleProj *engine.SimpleProjection } // Primitive implements the logicalPlan interface @@ -74,27 +43,6 @@ func (sq *simpleProjection) Primitive() engine.Primitive { return sq.eSimpleProj } -// ResultColumns implements the logicalPlan interface -func (sq *simpleProjection) ResultColumns() []*resultColumn { - return sq.resultColumns -} - -// SupplyCol implements the logicalPlan interface -func (sq *simpleProjection) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - c := col.Metadata.(*column) - for i, rc := range sq.resultColumns { - if rc.column == c { - return rc, i - } - } - - // columns that reference subqueries will have their colNumber set. - // Let's use it here. - sq.eSimpleProj.Cols = append(sq.eSimpleProj.Cols, c.colNumber) - sq.resultColumns = append(sq.resultColumns, &resultColumn{column: c}) - return rc, len(sq.resultColumns) - 1 -} - // OutputColumns implements the logicalPlan interface func (sq *simpleProjection) OutputColumns() []sqlparser.SelectExpr { exprs := make([]sqlparser.SelectExpr, 0, len(sq.eSimpleProj.Cols)) diff --git a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go index 56326c8b96f..3c763ab7060 100644 --- a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go +++ b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go @@ -47,7 +47,7 @@ func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.Se if err != nil { return nil, nil, err } - plan := &routeGen4{ + plan := &route{ eroute: &engine.Route{ RoutingParameters: &engine.RoutingParameters{ Opcode: engine.Unsharded, @@ -58,7 +58,7 @@ func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.Se Select: stmt, } - if err := plan.WireupGen4(ctx); err != nil { + if err := plan.Wireup(ctx); err != nil { return nil, nil, err } return plan, operators.QualifiedTableNames(ks, tableNames), nil diff --git a/go/vt/vtgate/planbuilder/sql_calc_found_rows.go b/go/vt/vtgate/planbuilder/sql_calc_found_rows.go index 72850361a9e..b67b6a0db3e 100644 --- a/go/vt/vtgate/planbuilder/sql_calc_found_rows.go +++ b/go/vt/vtgate/planbuilder/sql_calc_found_rows.go @@ -30,27 +30,15 @@ var _ logicalPlan = (*sqlCalcFoundRows)(nil) type sqlCalcFoundRows struct { LimitQuery, CountQuery logicalPlan - - // only used by WireUp for V3 - ljt, cjt *jointab -} - -// Wireup implements the logicalPlan interface -func (s *sqlCalcFoundRows) Wireup(logicalPlan, *jointab) error { - err := s.LimitQuery.Wireup(s.LimitQuery, s.ljt) - if err != nil { - return err - } - return s.CountQuery.Wireup(s.CountQuery, s.cjt) } // WireupGen4 implements the logicalPlan interface -func (s *sqlCalcFoundRows) WireupGen4(ctx *plancontext.PlanningContext) error { - err := s.LimitQuery.WireupGen4(ctx) +func (s *sqlCalcFoundRows) Wireup(ctx *plancontext.PlanningContext) error { + err := s.LimitQuery.Wireup(ctx) if err != nil { return err } - return s.CountQuery.WireupGen4(ctx) + return s.CountQuery.Wireup(ctx) } // ContainsTables implements the logicalPlan interface @@ -72,38 +60,6 @@ func (s *sqlCalcFoundRows) Primitive() engine.Primitive { } } -// All the methods below are not implemented. They should not be called on a sqlCalcFoundRows plan - -// Order implements the logicalPlan interface -func (s *sqlCalcFoundRows) Order() int { - return s.LimitQuery.Order() -} - -// ResultColumns implements the logicalPlan interface -func (s *sqlCalcFoundRows) ResultColumns() []*resultColumn { - return s.LimitQuery.ResultColumns() -} - -// Reorder implements the logicalPlan interface -func (s *sqlCalcFoundRows) Reorder(order int) { - s.LimitQuery.Reorder(order) -} - -// SupplyVar implements the logicalPlan interface -func (s *sqlCalcFoundRows) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - s.LimitQuery.SupplyVar(from, to, col, varname) -} - -// SupplyCol implements the logicalPlan interface -func (s *sqlCalcFoundRows) SupplyCol(col *sqlparser.ColName) (*resultColumn, int) { - return s.LimitQuery.SupplyCol(col) -} - -// SupplyWeightString implements the logicalPlan interface -func (s *sqlCalcFoundRows) SupplyWeightString(int, bool) (weightcolNumber int, err error) { - return 0, UnsupportedSupplyWeightString{Type: "sqlCalcFoundRows"} -} - // Rewrite implements the logicalPlan interface func (s *sqlCalcFoundRows) Rewrite(inputs ...logicalPlan) error { if len(inputs) != 2 { diff --git a/go/vt/vtgate/planbuilder/subquery_op.go b/go/vt/vtgate/planbuilder/subquery_op.go index ed945cbc6ad..d2fd30c05c3 100644 --- a/go/vt/vtgate/planbuilder/subquery_op.go +++ b/go/vt/vtgate/planbuilder/subquery_op.go @@ -63,11 +63,11 @@ func transformCorrelatedSubQueryPlan(ctx *plancontext.PlanningContext, op *opera } func mergeSubQueryOpPlan(ctx *plancontext.PlanningContext, inner, outer logicalPlan, n *operators.SubQueryOp) logicalPlan { - iroute, ok := inner.(*routeGen4) + iroute, ok := inner.(*route) if !ok { return nil } - oroute, ok := outer.(*routeGen4) + oroute, ok := outer.(*route) if !ok { return nil } @@ -83,7 +83,7 @@ func mergeSubQueryOpPlan(ctx *plancontext.PlanningContext, inner, outer logicalP } // mergeSystemTableInformation copies over information from the second route to the first and appends to it -func mergeSystemTableInformation(a *routeGen4, b *routeGen4) logicalPlan { +func mergeSystemTableInformation(a *route, b *route) logicalPlan { // safe to append system table schema and system table names, since either the routing will match or either side would be throwing an error // during run-time which we want to preserve. For example outer side has User in sys table schema and inner side has User and Main in sys table schema // Inner might end up throwing an error at runtime, but if it doesn't then it is safe to merge. @@ -94,7 +94,7 @@ func mergeSystemTableInformation(a *routeGen4, b *routeGen4) logicalPlan { return a } -func canMergeSubqueryPlans(ctx *plancontext.PlanningContext, a, b *routeGen4) bool { +func canMergeSubqueryPlans(ctx *plancontext.PlanningContext, a, b *route) bool { // this method should be close to tryMerge below. it does the same thing, but on logicalPlans instead of queryTrees if a.eroute.Keyspace.Name != b.eroute.Keyspace.Name { return false diff --git a/go/vt/vtgate/planbuilder/symtab.go b/go/vt/vtgate/planbuilder/symtab.go deleted file mode 100644 index 7853899b4f6..00000000000 --- a/go/vt/vtgate/planbuilder/symtab.go +++ /dev/null @@ -1,617 +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 planbuilder - -import ( - "fmt" - "strconv" - "strings" - - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/vindexes" - - querypb "vitess.io/vitess/go/vt/proto/query" -) - -// symtab represents the symbol table for a SELECT statement -// or a subquery. The symtab evolves over time. -// As a query is analyzed, multiple independent -// symtabs are created, and they are later merged as each -// sub-expression of a FROM clause is merged. -// -// A symtab maintains uniqueColumns, which is a list of unique -// vindex column names. These names can be resolved without the -// need to qualify them by their table names. If there are -// duplicates during a merge, those columns are removed from -// the unique list, thereby disallowing unqualified references -// to such columns. -// -// After a select expression is analyzed, the -// ResultColumns field is set. In the case of a subquery, the -// Outer field points to the outer symtab. Any symbols that -// are not resolved locally are added to the Externs field, -// which is later used to determine if the subquery can be -// merged with an outer route. -type symtab struct { - tables map[sqlparser.TableName]*table - tableNames []sqlparser.TableName - - // uniqueColumns has the column name as key - // and points at the columns that tables contains. - uniqueColumns map[string]*column - - // singleRoute is set only if all the symbols in - // the symbol table are part of the same route. - singleRoute *route - - ResultColumns []*resultColumn - Outer *symtab - Externs []*sqlparser.ColName -} - -// newSymtab creates a new symtab. -func newSymtab() *symtab { - return &symtab{ - tables: make(map[sqlparser.TableName]*table), - uniqueColumns: make(map[string]*column), - } -} - -// newSymtab creates a new symtab initialized -// to contain just one route. -func newSymtabWithRoute(rb *route) *symtab { - return &symtab{ - tables: make(map[sqlparser.TableName]*table), - uniqueColumns: make(map[string]*column), - singleRoute: rb, - } -} - -// AddVSchemaTable adds a vschema table to symtab. -func (st *symtab) AddVSchemaTable(alias sqlparser.TableName, vschemaTable *vindexes.Table, rb *route) error { - t := &table{ - alias: alias, - origin: rb, - vschemaTable: vschemaTable, - } - - for _, col := range vschemaTable.Columns { - if _, err := t.mergeColumn(col.Name, &column{ - origin: rb, - st: st, - typ: col.Type, - }); err != nil { - return err - } - } - if vschemaTable.ColumnListAuthoritative { - // This will prevent new columns from being added. - t.isAuthoritative = true - } - - for _, cv := range vschemaTable.ColumnVindexes { - single, ok := cv.Vindex.(vindexes.SingleColumn) - if !ok { - continue - } - for i, cvcol := range cv.Columns { - col, err := t.mergeColumn(cvcol, &column{ - origin: rb, - st: st, - }) - if err != nil { - return err - } - if i == 0 { - if col.vindex == nil || col.vindex.Cost() > single.Cost() { - col.vindex = single - } - } - } - } - - if ai := vschemaTable.AutoIncrement; ai != nil { - if _, ok := t.columns[ai.Column.Lowered()]; !ok { - if _, err := t.mergeColumn(ai.Column, &column{ - origin: rb, - st: st, - }); err != nil { - return err - } - } - } - if err := st.AddTable(t); err != nil { - return err - } - return nil -} - -// Merge merges the new symtab into the current one. -// Duplicate table aliases return an error. -// uniqueColumns is updated, but duplicates are removed. -// Merges are only performed during the FROM clause analysis. -// At this point, only tables and uniqueColumns are set. -// All other fields are ignored. -func (st *symtab) Merge(newsyms *symtab) error { - if st.tableNames == nil || newsyms.tableNames == nil { - // If any side of symtab has anonymous tables, - // we treat the merged symtab as having anonymous tables. - return nil - } - for _, t := range newsyms.tables { - if err := st.AddTable(t); err != nil { - return err - } - } - return nil -} - -// AddTable adds a table to symtab. -func (st *symtab) AddTable(t *table) error { - if rb, ok := t.origin.(*route); !ok || rb.Resolve() != st.singleRoute { - st.singleRoute = nil - } - if _, ok := st.tables[t.alias]; ok { - return vterrors.VT03013(t.alias.Name.String()) - } - st.tables[t.alias] = t - st.tableNames = append(st.tableNames, t.alias) - - // update the uniqueColumns list, and eliminate - // duplicate symbols if found. - for colname, c := range t.columns { - c.st = st - if _, ok := st.uniqueColumns[colname]; ok { - // Keep the entry, but make it nil. This will - // ensure that yet another column of the same name - // doesn't get added back in. - st.uniqueColumns[colname] = nil - continue - } - st.uniqueColumns[colname] = c - } - return nil -} - -// AllTables returns an ordered list of all current tables. -func (st *symtab) AllTables() []*table { - if len(st.tableNames) == 0 { - return nil - } - tables := make([]*table, 0, len(st.tableNames)) - for _, tname := range st.tableNames { - tables = append(tables, st.tables[tname]) - } - return tables -} - -// AllVschemaTableNames returns an ordered list of all current vschema tables. -func (st *symtab) AllVschemaTableNames() ([]*vindexes.Table, error) { - if len(st.tableNames) == 0 { - return nil, nil - } - tables := make([]*vindexes.Table, 0, len(st.tableNames)) - for _, tname := range st.tableNames { - t, ok := st.tables[tname] - if !ok { - return nil, vterrors.VT05004(sqlparser.String(tname)) - } - if t.vschemaTable != nil { - tables = append(tables, t.vschemaTable) - } - } - return tables, nil -} - -// FindTable finds a table in symtab. This function is specifically used -// for expanding 'select a.*' constructs. If you're in a subquery, -// you're most likely referring to a table in the local 'from' clause. -// For this reason, the search is only performed in the current scope. -// This may be a deviation from the formal definition of SQL, but there -// are currently no use cases that require the full support. -func (st *symtab) FindTable(tname sqlparser.TableName) (*table, error) { - if st.tableNames == nil { - // Unreachable because current code path checks for this condition - // before invoking this function. - return nil, vterrors.VT05007() - } - t, ok := st.tables[tname] - if !ok { - return nil, vterrors.VT05004(sqlparser.String(tname)) - } - return t, nil -} - -// SetResultColumns sets the result columns. -func (st *symtab) SetResultColumns(rcs []*resultColumn) { - for _, rc := range rcs { - rc.column.st = st - } - st.ResultColumns = rcs -} - -// Find returns the logicalPlan for the symbol referenced by col. -// If a reference is found, col.Metadata is set to point -// to it. Subsequent searches will reuse this metadata. -// -// Unqualified columns are searched in the following order: -// 1. ResultColumns -// 2. uniqueColumns -// 3. symtab has only one table. The column is presumed to -// belong to that table. -// 4. symtab has more than one table, but all tables belong -// to the same route. An anonymous column is created against -// the current route. -// If all the above fail, an error is returned. This means -// that an unqualified reference can only be locally resolved. -// -// For qualified columns, we first look for the table. If one -// is found, we look for a column in the pre-existing list. -// If one is not found, we optimistically create an entry -// presuming that the table has such a column. If this is -// not the case, the query will fail when sent to vttablet. -// If the table is not found in the local scope, the search -// is continued in the outer scope, but only if ResultColumns -// is not set (this is MySQL behavior). -// -// For symbols that were found locally, isLocal is returned -// as true. Otherwise, it's returned as false and the symbol -// gets added to the Externs list, which can later be used -// to decide where to push-down the subquery. -func (st *symtab) Find(col *sqlparser.ColName) (origin logicalPlan, isLocal bool, err error) { - // Return previously cached info if present. - if column, ok := col.Metadata.(*column); ok { - return column.Origin(), column.st == st, nil - } - - // Unqualified column case. - if col.Qualifier.IsEmpty() { - // Step 1. Search ResultColumns. - c, err := st.searchResultColumn(col) - if err != nil { - return nil, false, err - } - if c != nil { - col.Metadata = c - return c.Origin(), true, nil - } - } - - // Steps 2-4 performed by searchTables. - c, err := st.searchTables(col) - if err != nil { - return nil, false, err - } - if c != nil { - col.Metadata = c - return c.Origin(), true, nil - } - - if st.Outer == nil { - return nil, false, vterrors.VT03019(sqlparser.String(col)) - } - // Search is not continued if ResultColumns already has values: - // select a ... having ... (select b ... having a...). In this case, - // a (in having) should not match the outer-most 'a'. This is to - // match MySQL's behavior. - if len(st.ResultColumns) != 0 { - return nil, false, vterrors.VT03020(sqlparser.String(col)) - } - - if origin, _, err = st.Outer.Find(col); err != nil { - return nil, false, err - } - st.Externs = append(st.Externs, col) - return origin, false, nil -} - -// searchResultColumn looks for col in the results columns. -func (st *symtab) searchResultColumn(col *sqlparser.ColName) (c *column, err error) { - var cursym *resultColumn - for _, rc := range st.ResultColumns { - if rc.alias.Equal(col.Name) { - if cursym != nil { - return nil, vterrors.VT03021(sqlparser.String(col)) - } - cursym = rc - } - } - if cursym != nil { - return cursym.column, nil - } - return nil, nil -} - -// searchTables looks for the column in the tables. The search order -// is as described in Find. -func (st *symtab) searchTables(col *sqlparser.ColName) (*column, error) { - var t *table - // @@ syntax is only allowed for dual tables, in which case there should be - // only one in the symtab. So, such expressions will be implicitly matched. - if col.Qualifier.IsEmpty() || strings.HasPrefix(col.Qualifier.Name.String(), "@@") { - // Search uniqueColumns first. If found, our job is done. - // Check for nil because there can be nil entries if there - // are duplicate columns across multiple tables. - if c := st.uniqueColumns[col.Name.Lowered()]; c != nil { - return c, nil - } - - switch { - case len(st.tables) == 1: - // If there's only one table match against it. - // Loop executes once to match the only table. - for _, v := range st.tables { - t = v - } - // No return: break out. - case st.singleRoute != nil: - // If there's only one route, create an anonymous symbol. - return &column{origin: st.singleRoute, st: st}, nil - default: - // If none of the above, the symbol is unresolvable. - return nil, vterrors.VT03019(sqlparser.String(col)) - } - } else { - var ok bool - t, ok = st.tables[col.Qualifier] - if !ok { - return nil, nil - } - } - - // At this point, t should be set. - c, ok := t.columns[col.Name.Lowered()] - if !ok { - // We know all the column names of a subquery. Might as well return an error if it's not found. - if t.isAuthoritative { - return nil, vterrors.VT03019(sqlparser.String(col)) - } - c = &column{ - origin: t.Origin(), - st: st, - } - t.addColumn(col.Name, c) - } - return c, nil -} - -// ResultFromNumber returns the result column index based on the column -// order expression. -func ResultFromNumber(rcs []*resultColumn, val *sqlparser.Literal, caller string) (int, error) { - if val.Type != sqlparser.IntVal { - return 0, vterrors.VT13001("column number is not an INT") - } - num, err := strconv.ParseInt(val.Val, 0, 64) - if err != nil { - return 0, vterrors.VT13001(fmt.Sprintf("error parsing column number: %s", sqlparser.String(val))) - } - if num < 1 || num > int64(len(rcs)) { - return 0, vterrors.VT03014(num, caller) - } - return int(num - 1), nil -} - -// Vindex returns the vindex if the expression is a plain column reference -// that is part of the specified route, and has an associated vindex. -func (st *symtab) Vindex(expr sqlparser.Expr, scope *route) vindexes.SingleColumn { - col, ok := expr.(*sqlparser.ColName) - if !ok { - return nil - } - if col.Metadata == nil { - // Find will set the Metadata. - if _, _, err := st.Find(col); err != nil { - return nil - } - } - c := col.Metadata.(*column) - if c.Origin() != scope { - return nil - } - return c.vindex -} - -// BuildColName builds a *sqlparser.ColName for the resultColumn specified -// by the index. The built ColName will correctly reference the resultColumn -// it was built from. -func BuildColName(rcs []*resultColumn, index int) (*sqlparser.ColName, error) { - alias := rcs[index].alias - if alias.IsEmpty() { - return nil, vterrors.VT12001("reference a complex expression") - } - for i, rc := range rcs { - if i == index { - continue - } - if rc.alias.Equal(alias) { - return nil, vterrors.VT03021(alias) - } - } - return &sqlparser.ColName{ - Metadata: rcs[index].column, - Name: alias, - }, nil -} - -// ResolveSymbols resolves all column references against symtab. -// This makes sure that they all have their Metadata initialized. -// If a symbol cannot be resolved or if the expression contains -// a subquery, an error is returned. -func (st *symtab) ResolveSymbols(node sqlparser.SQLNode) error { - return sqlparser.Walk(func(currNode sqlparser.SQLNode) (kontinue bool, err error) { - switch currNode := currNode.(type) { - case *sqlparser.ColName: - if _, _, err := st.Find(currNode); err != nil { - return false, err - } - case *sqlparser.Subquery: - return false, vterrors.VT12001(fmt.Sprintf("subqueries disallowed in %T", node)) - } - return true, nil - }, node) -} - -// table is part of symtab. -// It represents a table alias in a FROM clause. It points -// to the logicalPlan that represents it. -type table struct { - alias sqlparser.TableName - columns map[string]*column - columnNames []sqlparser.IdentifierCI - isAuthoritative bool - origin logicalPlan - vschemaTable *vindexes.Table -} - -func (t *table) addColumn(alias sqlparser.IdentifierCI, c *column) { - if t.columns == nil { - t.columns = make(map[string]*column) - } - lowered := alias.Lowered() - // Dups are allowed, but first one wins if referenced. - if _, ok := t.columns[lowered]; !ok { - c.colNumber = len(t.columnNames) - t.columns[lowered] = c - } - t.columnNames = append(t.columnNames, alias) -} - -// mergeColumn merges or creates a new column for the table. -// If the table is authoritative and the column doesn't already -// exist, it returns an error. If the table is not authoritative, -// the column is added if not already present. -func (t *table) mergeColumn(alias sqlparser.IdentifierCI, c *column) (*column, error) { - if t.columns == nil { - t.columns = make(map[string]*column) - } - lowered := alias.Lowered() - if col, ok := t.columns[lowered]; ok { - return col, nil - } - if t.isAuthoritative { - return nil, vterrors.VT03022(sqlparser.String(alias), sqlparser.String(t.alias)) - } - c.colNumber = len(t.columnNames) - t.columns[lowered] = c - t.columnNames = append(t.columnNames, alias) - return c, nil -} - -// Origin returns the route that originates the table. -func (t *table) Origin() logicalPlan { - // If it's a route, we have to resolve it. - if rb, ok := t.origin.(*route); ok { - return rb.Resolve() - } - return t.origin -} - -// column represents a unique symbol in the query that other -// parts can refer to. -// Every column contains the logicalPlan it originates from. -// If a column has associated vindexes, then the one with the -// lowest cost is set. -// -// Two columns are equal if their pointer values match. -// -// For subquery and vindexFunc, the colNumber is also set because -// the column order is known and unchangeable. -type column struct { - origin logicalPlan - st *symtab - vindex vindexes.SingleColumn - typ querypb.Type - colNumber int -} - -// Origin returns the route that originates the column. -func (c *column) Origin() logicalPlan { - // If it's a route, we have to resolve it. - if rb, ok := c.origin.(*route); ok { - return rb.Resolve() - } - return c.origin -} - -// resultColumn contains symbol info about a select expression. If the -// expression represents an underlying column, then it points to it. -// Otherwise, an anonymous column is created as place-holder. -type resultColumn struct { - // alias will represent the unqualified symbol name for that expression. - // If the statement provides an explicit alias, that name will be used. - // If the expression is a simple column, then the base name of the - // column will be used as the alias. If the expression is non-trivial, - // alias will be empty, and cannot be referenced from other parts of - // the query. - alias sqlparser.IdentifierCI - column *column -} - -// NewResultColumn creates a new resultColumn based on the supplied expression. -// The created symbol is not remembered until it is later set as ResultColumns -// after all select expressions are analyzed. -func newResultColumn(expr *sqlparser.AliasedExpr, origin logicalPlan) *resultColumn { - rc := &resultColumn{ - alias: expr.As, - } - if col, ok := expr.Expr.(*sqlparser.ColName); ok { - // If no alias was specified, then the base name - // of the column becomes the alias. - if rc.alias.IsEmpty() { - rc.alias = col.Name - } - // If it's a col it should already have metadata. - rc.column = col.Metadata.(*column) - } else { - // We don't generate an alias if the expression is non-trivial. - // Just to be safe, generate an anonymous column for the expression. - typ, err := GetReturnType(expr.Expr) - rc.column = &column{ - origin: origin, - } - if err == nil { - rc.column.typ = typ - } - } - return rc -} - -// GetReturnType returns the type of the select expression that MySQL will return -func GetReturnType(input sqlparser.Expr) (querypb.Type, error) { - switch node := input.(type) { - case *sqlparser.FuncExpr: - functionName := strings.ToUpper(node.Name.String()) - switch functionName { - case "ABS": - // Returned value depends on the return type of the input - if len(node.Exprs) == 1 { - expr, isAliasedExpr := node.Exprs[0].(*sqlparser.AliasedExpr) - if isAliasedExpr { - return GetReturnType(expr.Expr) - } - } - } - case *sqlparser.ColName: - col := node.Metadata.(*column) - return col.typ, nil - case *sqlparser.Count, *sqlparser.CountStar: - return querypb.Type_INT64, nil - } - return 0, vterrors.VT12001(fmt.Sprintf("evaluate return type for %T", input)) -} diff --git a/go/vt/vtgate/planbuilder/symtab_test.go b/go/vt/vtgate/planbuilder/symtab_test.go deleted file mode 100644 index 725eeaa541a..00000000000 --- a/go/vt/vtgate/planbuilder/symtab_test.go +++ /dev/null @@ -1,227 +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 planbuilder - -import ( - "testing" - - "github.com/stretchr/testify/require" - - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/sqlparser" -) - -/* -func TestSymtabAddVSchemaTable(t *testing.T) { - tname := sqlparser.TableName{Name: sqlparser.NewIdentifierCS("t")} - rb := &route{} - - null, _ := vindexes.CreateVindex("null", "null", nil) - - tcases := []struct { - in *vindexes.Table - authoritative bool - vindex []string - err string - }{{ - // Single table. - in: &vindexes.Table{ - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C1"), - }, { - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{}, - }, { - // Column vindex specified. - in: &vindexes.Table{ - ColumnVindexes: []*vindexes.ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("C1")}, - Vindex: null, - }}, - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C1"), - }, { - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{"c1"}, - }, { - // Multi-column vindex. - in: &vindexes.Table{ - ColumnVindexes: []*vindexes.ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{ - sqlparser.NewIdentifierCI("C1"), - sqlparser.NewIdentifierCI("C2"), - }, - Vindex: null, - }}, - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C1"), - }, { - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{"c1"}, - }, { - // AutoIncrement. - in: &vindexes.Table{ - AutoIncrement: &vindexes.AutoIncrement{ - Column: sqlparser.NewIdentifierCI("C1"), - }, - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C1"), - }, { - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{}, - }, { - // Column vindex specifies a column not in list. - in: &vindexes.Table{ - ColumnVindexes: []*vindexes.ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("C1")}, - Vindex: null, - }}, - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{"c1"}, - }, { - // Column vindex specifies columns with none in list. - in: &vindexes.Table{ - ColumnVindexes: []*vindexes.ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{ - sqlparser.NewIdentifierCI("C1"), - sqlparser.NewIdentifierCI("C2"), - }, - Vindex: null, - }}, - }, - authoritative: false, - vindex: []string{"c1"}, - }, { - // AutoIncrement specifies a column not in list. - in: &vindexes.Table{ - AutoIncrement: &vindexes.AutoIncrement{ - Column: sqlparser.NewIdentifierCI("C1"), - }, - Columns: []vindexes.Column{{ - Name: sqlparser.NewIdentifierCI("C2"), - }}, - }, - authoritative: false, - vindex: []string{}, - }, { - // Two column vindexes. - in: &vindexes.Table{ - ColumnVindexes: []*vindexes.ColumnVindex{{ - Columns: []sqlparser.IdentifierCI{ - sqlparser.NewIdentifierCI("C1"), - }, - Vindex: null, - }, { - Columns: []sqlparser.IdentifierCI{ - sqlparser.NewIdentifierCI("C2"), - }, - Vindex: null, - }}, - }, - authoritative: false, - vindex: []string{"c1", "c2"}, - }} - - out := []string{"c1", "c2"} - for _, tcase := range tcases { - st := newSymtab() - vindexMap, err := st.AddVSchemaTable(tname, tcase.in, rb) - tcasein, _ := json.Marshal(tcase.in) - if err != nil { - if err.Error() != tcase.err { - t.Errorf("st.AddVSchemaTable(%s) err: %v, want %s", tcasein, err, tcase.err) - } - continue - } else if tcase.err != "" { - t.Errorf("st.AddVSchemaTable(%s) succeeded, want error: %s", tcasein, tcase.err) - continue - } - tab := st.tables[tname] - for _, col := range out { - if tab.columns[col] == nil { - t.Errorf("st.AddVSchemaTable(%s): column %s not found", tcasein, col) - } - } - for _, col := range tcase.vindex { - c := tab.columns[col] - if c == nil { - t.Errorf("st.AddVSchemaTable(%s): column %s not found", tcasein, col) - } - if _, ok := vindexMap[c]; !ok { - t.Errorf("st.AddVSchemaTable(%s).vindexMap: column %s not found", tcasein, col) - } - } - if tab.isAuthoritative != tcase.authoritative { - t.Errorf("st.AddVSchemaTable(%s).authoritative: %v want %v", tcasein, tab.isAuthoritative, tcase.authoritative) - } - } -} -*/ - -func TestGetReturnType(t *testing.T) { - tests := []struct { - input sqlparser.Expr - output querypb.Type - expectedErr error - }{{ - input: &sqlparser.FuncExpr{Name: sqlparser.NewIdentifierCI("Abs"), Exprs: sqlparser.SelectExprs{ - &sqlparser.AliasedExpr{ - Expr: &sqlparser.ColName{ - Name: sqlparser.NewIdentifierCI("A"), - Metadata: &column{ - typ: querypb.Type_DECIMAL, - }, - }, - }, - }}, - output: querypb.Type_DECIMAL, - }, { - input: &sqlparser.Count{}, - output: querypb.Type_INT64, - }, { - input: &sqlparser.CountStar{}, - output: querypb.Type_INT64, - }} - - for _, test := range tests { - t.Run(sqlparser.String(test.input), func(t *testing.T) { - got, err := GetReturnType(test.input) - if test.expectedErr != nil { - require.EqualError(t, err, test.expectedErr.Error()) - } else { - require.NoError(t, err) - require.Equal(t, test.output, got) - } - }) - } -} diff --git a/go/vt/vtgate/planbuilder/system_tables.go b/go/vt/vtgate/planbuilder/system_tables.go deleted file mode 100644 index d8c429af6e9..00000000000 --- a/go/vt/vtgate/planbuilder/system_tables.go +++ /dev/null @@ -1,136 +0,0 @@ -/* -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 planbuilder - -import ( - "strings" - - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" -) - -func (pb *primitiveBuilder) findSysInfoRoutingPredicates(expr sqlparser.Expr, rut *route, reservedVars *sqlparser.ReservedVars) error { - isTableSchema, bvName, out, err := extractInfoSchemaRoutingPredicate(expr, reservedVars) - if err != nil { - return err - } - if out == nil { - // we didn't find a predicate to use for routing, so we just exit early - return nil - } - - if isTableSchema { - rut.eroute.SysTableTableSchema = append(rut.eroute.SysTableTableSchema, out) - } else { - if rut.eroute.SysTableTableName == nil { - rut.eroute.SysTableTableName = map[string]evalengine.Expr{} - } - rut.eroute.SysTableTableName[bvName] = out - } - - return nil -} - -func findOtherComparator(cmp *sqlparser.ComparisonExpr) (bool, sqlparser.Expr, sqlparser.Expr, func(arg *sqlparser.Argument)) { - if schema, table := isTableSchemaOrName(cmp.Left); schema || table { - return schema, cmp.Left, cmp.Right, func(arg *sqlparser.Argument) { - cmp.Right = arg - } - } - if schema, table := isTableSchemaOrName(cmp.Right); schema || table { - return schema, cmp.Right, cmp.Left, func(arg *sqlparser.Argument) { - cmp.Left = arg - } - } - - return false, nil, nil, nil -} - -func isTableSchemaOrName(e sqlparser.Expr) (isTableSchema bool, isTableName bool) { - col, ok := e.(*sqlparser.ColName) - if !ok { - return false, false - } - return isDbNameCol(col), isTableNameCol(col) -} - -var schemaColumns = map[string]any{ - "table_schema": nil, - "constraint_schema": nil, - "schema_name": nil, - "routine_schema": nil, - "specific_schema": nil, - "event_schema": nil, - "referenced_table_schema": nil, - "index_schema": nil, - "trigger_schema": nil, - "event_object_schema": nil, -} - -func isDbNameCol(col *sqlparser.ColName) bool { - _, found := schemaColumns[col.Name.Lowered()] - return found -} - -func isTableNameCol(col *sqlparser.ColName) bool { - return col.Name.EqualString("table_name") || col.Name.EqualString("referenced_table_name") -} - -func extractInfoSchemaRoutingPredicate( - in sqlparser.Expr, - reservedVars *sqlparser.ReservedVars, -) (isSchemaName bool, name string, evalExpr evalengine.Expr, err error) { - cmp, ok := in.(*sqlparser.ComparisonExpr) - if !ok || cmp.Operator != sqlparser.EqualOp { - return - } - - isSchemaName, col, other, replaceOther := findOtherComparator(cmp) - if col == nil || !shouldRewrite(other) { - return - } - - evalExpr, err = evalengine.Translate(other, &evalengine.Config{ResolveColumn: operators.NotImplementedSchemaInfoResolver}) - if err != nil { - if strings.Contains(err.Error(), evalengine.ErrTranslateExprNotSupported) { - // This just means we can't rewrite this particular expression, - // not that we have to exit altogether - err = nil - return - } - return false, "", nil, err - } - - if isSchemaName { - name = sqltypes.BvSchemaName - } else { - name = reservedVars.ReserveColName(col.(*sqlparser.ColName)) - } - replaceOther(sqlparser.NewTypedArgument(name, sqltypes.VarChar)) - return isSchemaName, name, evalExpr, nil -} - -func shouldRewrite(e sqlparser.Expr) bool { - switch node := e.(type) { - case *sqlparser.FuncExpr: - // we should not rewrite database() calls against information_schema - return !(node.Name.EqualString("database") || node.Name.EqualString("schema")) - } - return true -} diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index f5501e9f06b..6f84d838f34 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -2,8 +2,7 @@ { "comment": "count(*) spread across join", "query": "select count(*) from user join user_extra on user.foo = user_extra.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user join user_extra on user.foo = user_extra.bar", "Instructions": { @@ -63,8 +62,7 @@ { "comment": "sum spread across join", "query": "select sum(user.col) from user join user_extra on user.foo = user_extra.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(user.col) from user join user_extra on user.foo = user_extra.bar", "Instructions": { @@ -124,8 +122,7 @@ { "comment": "count spread across join", "query": "select count(user.col) from user join user_extra on user.foo = user_extra.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(user.col) from user join user_extra on user.foo = user_extra.bar", "Instructions": { @@ -185,8 +182,7 @@ { "comment": "max spread across join", "query": "select max(user.col) from user join user_extra on user.foo = user_extra.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select max(user.col) from user join user_extra on user.foo = user_extra.bar", "Instructions": { @@ -238,8 +234,7 @@ { "comment": "min spread across join RHS", "query": "select min(user_extra.col) from user join user_extra on user.foo = user_extra.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select min(user_extra.col) from user join user_extra on user.foo = user_extra.bar", "Instructions": { @@ -291,22 +286,7 @@ { "comment": "group by a unique vindex should revert to simple route, and having clause should find the correct symbols.", "query": "select id, count(*) c from user group by id having max(col) > 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, count(*) c from user group by id having max(col) > 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, count(*) as c from `user` where 1 != 1 group by id", - "Query": "select id, count(*) as c from `user` group by id having max(col) > 10", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, count(*) c from user group by id having max(col) > 10", "Instructions": { @@ -328,37 +308,7 @@ { "comment": "scatter aggregate in a subquery", "query": "select a from (select count(*) as a from user) t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a from (select count(*) as a from user) t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) as a from `user` where 1 != 1", - "Query": "select count(*) as a from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a from (select count(*) as a from user) t", "Instructions": { @@ -387,29 +337,7 @@ { "comment": "scatter aggregate with non-aggregate expressions.", "query": "select id, count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, count(*) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(1) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, count(*) from `user` where 1 != 1", - "Query": "select id, count(*) from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, count(*) from user", "Instructions": { @@ -438,30 +366,7 @@ { "comment": "scatter aggregate using distinctdistinct", "query": "select distinct col from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct col from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "OrderBy": "0 ASC", - "Query": "select distinct col from `user` order by col asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct col from user", "Instructions": { @@ -491,30 +396,7 @@ { "comment": "scatter aggregate group by select col", "query": "select col from user group by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user group by col", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1 group by col", - "OrderBy": "0 ASC", - "Query": "select col from `user` group by col order by col asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user group by col", "Instructions": { @@ -544,22 +426,7 @@ { "comment": "count with distinct group by unique vindex", "query": "select id, count(distinct col) from user group by id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, count(distinct col) from user group by id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, count(distinct col) from `user` where 1 != 1 group by id", - "Query": "select id, count(distinct col) from `user` group by id", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, count(distinct col) from user group by id", "Instructions": { @@ -579,33 +446,9 @@ } }, { - "comment": "count and sum with distinct unique vindex", + "comment": "count with distinct unique vindex", "query": "select col, count(distinct id), sum(distinct id) from user group by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col, count(distinct id), sum(distinct id) from user group by col", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count, sum(2)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, count(distinct id), sum(distinct id) from `user` where 1 != 1 group by col", - "OrderBy": "0 ASC", - "Query": "select col, count(distinct id), sum(distinct id) from `user` group by col order by col asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(distinct id), sum(distinct id) from user group by col", "Instructions": { @@ -636,32 +479,7 @@ { "comment": "count with distinct no unique vindex", "query": "select col1, count(distinct col2) from user group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, count(distinct col2) from user group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "count_distinct_count(1) AS count(distinct col2)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2, weight_string(col1), weight_string(col2)", - "OrderBy": "(0|2) ASC, (1|3) ASC", - "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2, weight_string(col1), weight_string(col2) order by col1 asc, col2 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, count(distinct col2) from user group by col1", "Instructions": { @@ -693,31 +511,7 @@ { "comment": "count with distinct no unique vindex and no group by", "query": "select count(distinct col2) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(distinct col2) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "count_distinct_count(0) AS count(distinct col2)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col2, weight_string(col2) from `user` where 1 != 1 group by col2, weight_string(col2)", - "OrderBy": "(0|1) ASC", - "Query": "select col2, weight_string(col2) from `user` group by col2, weight_string(col2) order by col2 asc", - "ResultColumns": 1, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(distinct col2) from user", "Instructions": { @@ -748,32 +542,7 @@ { "comment": "count with distinct no unique vindex, count expression aliased", "query": "select col1, count(distinct col2) c2 from user group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, count(distinct col2) c2 from user group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "count_distinct_count(1) AS c2", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2, weight_string(col1), weight_string(col2)", - "OrderBy": "(0|2) ASC, (1|3) ASC", - "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2, weight_string(col1), weight_string(col2) order by col1 asc, col2 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, count(distinct col2) c2 from user group by col1", "Instructions": { @@ -805,32 +574,7 @@ { "comment": "sum with distinct no unique vindex", "query": "select col1, sum(distinct col2) from user group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, sum(distinct col2) from user group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_distinct_sum(1) AS sum(distinct col2)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2, weight_string(col1), weight_string(col2)", - "OrderBy": "(0|2) ASC, (1|3) ASC", - "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2, weight_string(col1), weight_string(col2) order by col1 asc, col2 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, sum(distinct col2) from user group by col1", "Instructions": { @@ -862,32 +606,7 @@ { "comment": "min with distinct no unique vindex. distinct is ignored.", "query": "select col1, min(distinct col2) from user group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, min(distinct col2) from user group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "min(1)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, min(col2) as `min(distinct col2)`, weight_string(col1) from `user` where 1 != 1 group by col1, weight_string(col1)", - "OrderBy": "(0|2) ASC", - "Query": "select col1, min(col2) as `min(distinct col2)`, weight_string(col1) from `user` group by col1, weight_string(col1) order by col1 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, min(distinct col2) from user group by col1", "Instructions": { @@ -919,52 +638,20 @@ { "comment": "order by count distinct", "query": "select col1, count(distinct col2) k from user group by col1 order by k", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, count(distinct col2) k from user group by col1 order by k", "Instructions": { "OperatorType": "Sort", "Variant": "Memory", "OrderBy": "1 ASC", + "ResultColumns": 2, "Inputs": [ { "OperatorType": "Aggregate", "Variant": "Ordered", - "Aggregates": "count_distinct_count(1) AS k", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2, weight_string(col1), weight_string(col2)", - "OrderBy": "(0|2) ASC, (1|3) ASC", - "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2, weight_string(col1), weight_string(col2) order by col1 asc, col2 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select col1, count(distinct col2) k from user group by col1 order by k", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "1 ASC", - "ResultColumns": 2, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "count_distinct(1|3) AS k", - "GroupBy": "(0|2)", + "Aggregates": "count_distinct(1|3) AS k", + "GroupBy": "(0|2)", "Inputs": [ { "OperatorType": "Route", @@ -990,38 +677,12 @@ { "comment": "scatter aggregate group by aggregate function", "query": "select count(*) b from user group by b", - "v3-plan": "VT03005: cannot group on 'b'", - "gen4-plan": "VT03005: cannot group on 'count(*)'" + "plan": "VT03005: cannot group on 'count(*)'" }, { "comment": "scatter aggregate multiple group by (columns)", "query": "select a, b, count(*) from user group by a, b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) from user group by a, b", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0, 1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*), weight_string(a), weight_string(b) from `user` where 1 != 1 group by a, b, weight_string(a), weight_string(b)", - "OrderBy": "(0|3) ASC, (1|4) ASC", - "Query": "select a, b, count(*), weight_string(a), weight_string(b) from `user` group by a, b, weight_string(a), weight_string(b) order by a asc, b asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) from user group by a, b", "Instructions": { @@ -1053,32 +714,7 @@ { "comment": "scatter aggregate multiple group by (numbers)", "query": "select a, b, count(*) from user group by 2, 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) from user group by 2, 1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "1, 0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by 2, 1, weight_string(b), weight_string(a)", - "OrderBy": "(1|3) ASC, (0|4) ASC", - "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by 2, 1, weight_string(b), weight_string(a) order by b asc, a asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) from user group by 2, 1", "Instructions": { @@ -1110,32 +746,7 @@ { "comment": "scatter aggregate multiple group by columns inverse order", "query": "select a, b, count(*) from user group by b, a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) from user group by b, a", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "1, 0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by b, a, weight_string(b), weight_string(a)", - "OrderBy": "(1|3) ASC, (0|4) ASC", - "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by b, a, weight_string(b), weight_string(a) order by b asc, a asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) from user group by b, a", "Instructions": { @@ -1167,30 +778,7 @@ { "comment": "scatter aggregate group by column number", "query": "select col from user group by 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user group by 1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1 group by 1", - "OrderBy": "0 ASC", - "Query": "select col from `user` group by 1 order by col asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user group by 1", "Instructions": { @@ -1220,35 +808,12 @@ { "comment": "scatter aggregate group by invalid column number", "query": "select col from user group by 2", - "v3-plan": "VT03014: unknown column '2' in 'group statement'", - "gen4-plan": "Unknown column '2' in 'group statement'" + "plan": "Unknown column '2' in 'group statement'" }, { "comment": "scatter aggregate order by null", "query": "select count(*) from user order by null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(*) from user order by null", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select count(*) from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user order by null", "Instructions": { @@ -1277,32 +842,7 @@ { "comment": "scatter aggregate with numbered order by columns", "query": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by 1, 2, 3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by 1, 2, 3", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(4) AS count", - "GroupBy": "0, 1, 2", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3, weight_string(a), weight_string(b), weight_string(c)", - "OrderBy": "(0|5) ASC, (1|6) ASC, (2|7) ASC", - "Query": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` group by 1, 2, 3, weight_string(a), weight_string(b), weight_string(c) order by 1 asc, 2 asc, 3 asc", - "ResultColumns": 5, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by 1, 2, 3", "Instructions": { @@ -1334,32 +874,7 @@ { "comment": "scatter aggregate with named order by columns", "query": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by a, b, c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by a, b, c", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(4) AS count", - "GroupBy": "0, 1, 2", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3, weight_string(a), weight_string(b), weight_string(c)", - "OrderBy": "(0|5) ASC, (1|6) ASC, (2|7) ASC", - "Query": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` group by 1, 2, 3, weight_string(a), weight_string(b), weight_string(c) order by a asc, b asc, c asc", - "ResultColumns": 5, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3 order by a, b, c", "Instructions": { @@ -1391,32 +906,7 @@ { "comment": "scatter aggregate with jumbled order by columns", "query": "select a, b, c, d, count(*) from user group by 1, 2, 3, 4 order by d, b, a, c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3, 4 order by d, b, a, c", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(4) AS count", - "GroupBy": "0, 1, 2, 3", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3, 4, weight_string(d), weight_string(b), weight_string(a), weight_string(c)", - "OrderBy": "(3|5) ASC, (1|6) ASC, (0|7) ASC, (2|8) ASC", - "Query": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` group by 1, 2, 3, 4, weight_string(d), weight_string(b), weight_string(a), weight_string(c) order by d asc, b asc, a asc, c asc", - "ResultColumns": 5, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, c, d, count(*) from user group by 1, 2, 3, 4 order by d, b, a, c", "Instructions": { @@ -1448,32 +938,7 @@ { "comment": "scatter aggregate with jumbled group by and order by columns", "query": "select a, b, c, d, count(*) from user group by 3, 2, 1, 4 order by d, b, a, c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, c, d, count(*) from user group by 3, 2, 1, 4 order by d, b, a, c", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(4) AS count", - "GroupBy": "2, 1, 0, 3", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` where 1 != 1 group by 3, 2, 1, 4, weight_string(d), weight_string(b), weight_string(a), weight_string(c)", - "OrderBy": "(3|5) ASC, (1|6) ASC, (0|7) ASC, (2|8) ASC", - "Query": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` group by 3, 2, 1, 4, weight_string(d), weight_string(b), weight_string(a), weight_string(c) order by d asc, b asc, a asc, c asc", - "ResultColumns": 5, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, c, d, count(*) from user group by 3, 2, 1, 4 order by d, b, a, c", "Instructions": { @@ -1505,32 +970,7 @@ { "comment": "scatter aggregate with some descending order by cols", "query": "select a, b, c, count(*) from user group by 3, 2, 1 order by 1 desc, 3 desc, b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, c, count(*) from user group by 3, 2, 1 order by 1 desc, 3 desc, b", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(3) AS count", - "GroupBy": "2, 1, 0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, c, count(*), weight_string(a), weight_string(c), weight_string(b) from `user` where 1 != 1 group by 3, 2, 1, weight_string(a), weight_string(c), weight_string(b)", - "OrderBy": "(0|4) DESC, (2|5) DESC, (1|6) ASC", - "Query": "select a, b, c, count(*), weight_string(a), weight_string(c), weight_string(b) from `user` group by 3, 2, 1, weight_string(a), weight_string(c), weight_string(b) order by 1 desc, 3 desc, b asc", - "ResultColumns": 4, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, c, count(*) from user group by 3, 2, 1 order by 1 desc, 3 desc, b", "Instructions": { @@ -1562,43 +1002,12 @@ { "comment": "invalid order by column numner for scatter", "query": "select col, count(*) from user group by col order by 5 limit 10", - "v3-plan": "VT03014: unknown column '5' in 'order clause'", - "gen4-plan": "Unknown column '5' in 'order clause'" + "plan": "Unknown column '5' in 'order clause'" }, { "comment": "aggregate with limit", "query": "select col, count(*) from user group by col limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col, count(*) from user group by col limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, count(*) from `user` where 1 != 1 group by col", - "OrderBy": "0 ASC", - "Query": "select col, count(*) from `user` group by col order by col asc limit :__upper_limit", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) from user group by col limit 10", "Instructions": { @@ -1635,26 +1044,7 @@ { "comment": "Group by with collate operator", "query": "select user.col1 as a from user where user.id = 5 group by a collate utf8_general_ci", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a from user where user.id = 5 group by a collate utf8_general_ci", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a from `user` where 1 != 1 group by a collate utf8_general_ci", - "Query": "select `user`.col1 as a from `user` where `user`.id = 5 group by a collate utf8_general_ci", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a from user where user.id = 5 group by a collate utf8_general_ci", "Instructions": { @@ -1680,22 +1070,7 @@ { "comment": "routing rules for aggregates", "query": "select id, count(*) from route2 group by id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, count(*) from route2 group by id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id, count(*) from unsharded as route2 where 1 != 1 group by id", - "Query": "select id, count(*) from unsharded as route2 group by id", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, count(*) from route2 group by id", "Instructions": { @@ -1717,22 +1092,7 @@ { "comment": "order by on a reference table", "query": "select col from ref order by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from ref order by col", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from ref where 1 != 1", - "Query": "select col from ref order by col asc", - "Table": "ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from ref order by col", "Instructions": { @@ -1740,51 +1100,21 @@ "Variant": "Reference", "Keyspace": { "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from ref where 1 != 1", - "Query": "select col from ref order by col asc", - "Table": "ref" - }, - "TablesUsed": [ - "user.ref" - ] - } - }, - { - "comment": "distinct and aggregate functions missing group by", - "query": "select distinct a, count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct a, count(*) from user", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, count(*), weight_string(a) from `user` where 1 != 1", - "OrderBy": "(0|2) ASC", - "Query": "select a, count(*), weight_string(a) from `user` order by a asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "Sharded": true + }, + "FieldQuery": "select col from ref where 1 != 1", + "Query": "select col from ref order by col asc", + "Table": "ref" + }, + "TablesUsed": [ + "user.ref" + ] + } + }, + { + "comment": "distinct and aggregate functions missing group by", + "query": "select distinct a, count(*) from user", + "plan": { "QueryType": "SELECT", "Original": "select distinct a, count(*) from user", "Instructions": { @@ -1813,37 +1143,7 @@ { "comment": "distinct and aggregate functions", "query": "select distinct a, count(*) from user group by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct a, count(*) from user group by a", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0, 0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, count(*), weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|2) ASC, (0|2) ASC", - "Query": "select a, count(*), weight_string(a) from `user` group by a, weight_string(a) order by a asc, a asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct a, count(*) from user group by a", "Instructions": { @@ -1875,8 +1175,7 @@ { "comment": "Group by invalid column number (code is duplicated from symab).", "query": "select id from user group by 1.1", - "v3-plan": "VT13001: [BUG] column number is not an INT", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user group by 1.1", "Instructions": { @@ -1908,14 +1207,12 @@ { "comment": "Group by out of range column number (code is duplicated from symab).", "query": "select id from user group by 2", - "v3-plan": "VT03014: unknown column '2' in 'group statement'", - "gen4-plan": "Unknown column '2' in 'group statement'" + "plan": "Unknown column '2' in 'group statement'" }, { "comment": "here it is safe to remove the order by on the derived table since it will not influence the output of the count(*)", "query": "select count(*) from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a", "Instructions": { @@ -1945,32 +1242,7 @@ { "comment": "order by inside derived tables can be ignored", "query": "select col from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col, user_extra.extra, weight_string(user_extra.extra) from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "OrderBy": "(1|2) ASC", - "Query": "select `user`.col, user_extra.extra, weight_string(user_extra.extra) from `user` join user_extra on `user`.id = user_extra.user_id order by user_extra.extra asc", - "ResultColumns": 2, - "Table": "`user`, user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a", "Instructions": { @@ -1993,8 +1265,7 @@ { "comment": "here we keep the order since the column is visible on the outside, and used by the orderedAggregate", "query": "select col, count(*) from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a group by col", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) from (select user.col, user_extra.extra from user join user_extra on user.id = user_extra.user_id order by user_extra.extra) a group by col", "Instructions": { @@ -2026,31 +1297,7 @@ { "comment": "optimize group by when using distinct with no aggregation", "query": "select distinct col1, col2 from user group by col1, col2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct col1, col2 from user group by col1, col2", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "0, 1, 0, 1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2, weight_string(col1), weight_string(col2)", - "OrderBy": "(0|2) ASC, (1|3) ASC, (0|2) ASC, (1|3) ASC", - "Query": "select distinct col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2, weight_string(col1), weight_string(col2) order by col1 asc, col2 asc, col1 asc, col2 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct col1, col2 from user group by col1, col2", "Instructions": { @@ -2081,34 +1328,7 @@ { "comment": "do not use distinct when using only aggregates and no group by", "query": "select distinct count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct count(*) from user", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select count(*) from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct count(*) from user", "Instructions": { @@ -2137,8 +1357,7 @@ { "comment": "Grouping on join", "query": "select user.a from user join user_extra group by user.a", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.a from user join user_extra group by user.a", "Instructions": { @@ -2189,14 +1408,12 @@ { "comment": "Cannot have more than one aggr(distinct...", "query": "select count(distinct a), count(distinct b) from user", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: count(distinct b)", - "gen4-plan": "VT12001: unsupported: only one DISTINCT aggregation is allowed in a SELECT: count(distinct b)" + "plan": "VT12001: unsupported: only one DISTINCT aggregation is allowed in a SELECT: count(distinct b)" }, { "comment": "multiple distinct functions with grouping.", "query": "select col1, count(distinct col2), sum(distinct col2) from user group by col1", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: sum(distinct col2)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, count(distinct col2), sum(distinct col2) from user group by col1", "Instructions": { @@ -2228,8 +1445,7 @@ { "comment": "aggregate query with order by aggregate column along with NULL", "query": "select col, count(*) k from user group by col order by null, k", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: null", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) k from user group by col order by null, k", "Instructions": { @@ -2267,31 +1483,7 @@ { "comment": "aggregate query with order by NULL", "query": "select col, count(*) k from user group by col order by null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col, count(*) k from user group by col order by null", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, count(*) as k from `user` where 1 != 1 group by col", - "OrderBy": "0 ASC", - "Query": "select col, count(*) as k from `user` group by col order by col asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) k from user group by col order by null", "Instructions": { @@ -2322,8 +1514,7 @@ { "comment": "join query on sharding key with group by a unique vindex with having clause.", "query": "select user.id, count(*) c from user, user_extra where user.id = user_extra.user_id group by user.id having max(user.col) > 10", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id, count(*) c from user, user_extra where user.id = user_extra.user_id group by user.id having max(user.col) > 10", "Instructions": { @@ -2346,29 +1537,7 @@ { "comment": "correlated subquery on sharding key with group by a unique vindex with having clause.", "query": "select count(*) from user where exists (select 1 from user_extra where user_id = user.id group by user_id having max(col) > 10)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(*) from user where exists (select 1 from user_extra where user_id = user.id group by user_id having max(col) > 10)", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select count(*) from `user` where exists (select 1 from user_extra where user_id = `user`.id group by user_id having max(col) > 10 limit 1)", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user where exists (select 1 from user_extra where user_id = user.id group by user_id having max(col) > 10)", "Instructions": { @@ -2398,22 +1567,7 @@ { "comment": "aggregation filtering by having on a route", "query": "select id from user group by id having count(id) = 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user group by id having count(id) = 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1 group by id", - "Query": "select id from `user` group by id having count(id) = 10", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user group by id having count(id) = 10", "Instructions": { @@ -2435,32 +1589,7 @@ { "comment": "weight_string addition to group by", "query": "select lower(textcol1) as v, count(*) from user group by v", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select lower(textcol1) as v, count(*) from user group by v", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select lower(textcol1) as v, count(*), weight_string(lower(textcol1)) from `user` where 1 != 1 group by v, weight_string(lower(textcol1))", - "OrderBy": "(0|2) ASC", - "Query": "select lower(textcol1) as v, count(*), weight_string(lower(textcol1)) from `user` group by v, weight_string(lower(textcol1)) order by v asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select lower(textcol1) as v, count(*) from user group by v", "Instructions": { @@ -2492,32 +1621,7 @@ { "comment": "weight_string addition to group by when also there in order by", "query": "select char_length(texcol1) as a, count(*) from user group by a order by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select char_length(texcol1) as a, count(*) from user group by a order by a", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select char_length(texcol1) as a, count(*), weight_string(char_length(texcol1)) from `user` where 1 != 1 group by a, weight_string(char_length(texcol1))", - "OrderBy": "(0|2) ASC", - "Query": "select char_length(texcol1) as a, count(*), weight_string(char_length(texcol1)) from `user` group by a, weight_string(char_length(texcol1)) order by a asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select char_length(texcol1) as a, count(*) from user group by a order by a", "Instructions": { @@ -2549,30 +1653,7 @@ { "comment": "order by inside and outside parenthesis select", "query": "(select id from user order by 1 desc) order by 1 asc limit 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from user order by 1 desc) order by 1 asc limit 2", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(2)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id, weight_string(id) from `user` order by 1 asc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from user order by 1 desc) order by 1 asc limit 2", "Instructions": { @@ -2602,8 +1683,7 @@ { "comment": "correlated subquery in exists clause with an ordering", "query": "select col, id from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id) order by id", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, id from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id) order by id", "Instructions": { @@ -2652,8 +1732,7 @@ { "comment": "Column and Literal equality filter on scatter aggregates", "query": "select count(*) a from user having a = 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a = 10", "Instructions": { @@ -2688,8 +1767,7 @@ { "comment": "Equality filtering with column and string literal on scatter aggregates", "query": "select count(*) a from user having a = '1'", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a = '1'", "Instructions": { @@ -2724,8 +1802,7 @@ { "comment": "Column and Literal not equal filter on scatter aggregates", "query": "select count(*) a from user having a != 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a != 10", "Instructions": { @@ -2760,8 +1837,7 @@ { "comment": "Not equal filter with column and string literal on scatter aggregates", "query": "select count(*) a from user having a != '1'", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a != '1'", "Instructions": { @@ -2796,8 +1872,7 @@ { "comment": "Greater than filter on scatter aggregates", "query": "select count(*) a from user having a > 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a > 10", "Instructions": { @@ -2832,8 +1907,7 @@ { "comment": "Greater Equal filter on scatter aggregates", "query": "select count(*) a from user having a >= 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a >= 10", "Instructions": { @@ -2868,8 +1942,7 @@ { "comment": "Less than filter on scatter aggregates", "query": "select count(*) a from user having a < 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a < 10", "Instructions": { @@ -2904,8 +1977,7 @@ { "comment": "Less Equal filter on scatter aggregates", "query": "select count(*) a from user having a <= 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a <= 10", "Instructions": { @@ -2940,8 +2012,7 @@ { "comment": "Less Equal filter on scatter with grouping", "query": "select col, count(*) a from user group by col having a <= 10", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) a from user group by col having a <= 10", "Instructions": { @@ -2978,8 +2049,7 @@ { "comment": "We should be able to find grouping keys on ordered aggregates", "query": "select count(*) as a, val1 from user group by val1 having a = 1.00", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) as a, val1 from user group by val1 having a = 1.00", "Instructions": { @@ -3016,41 +2086,16 @@ ] } ] - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "distinct on text column with collation", - "query": "select col, count(distinct textcol1) from user group by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col, count(distinct textcol1) from user group by col", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "count_distinct_count(1) AS count(distinct textcol1)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, textcol1, weight_string(textcol1) from `user` where 1 != 1 group by col, textcol1, weight_string(textcol1)", - "OrderBy": "0 ASC, (1|2) ASC", - "Query": "select col, textcol1, weight_string(textcol1) from `user` group by col, textcol1, weight_string(textcol1) order by col asc, textcol1 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "distinct on text column with collation", + "query": "select col, count(distinct textcol1) from user group by col", + "plan": { "QueryType": "SELECT", "Original": "select col, count(distinct textcol1) from user group by col", "Instructions": { @@ -3081,26 +2126,7 @@ { "comment": "aggregation filtering by having on a route with no group by with non-unique vindex filter", "query": "select 1 from user having count(id) = 10 and name = 'a'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user having count(id) = 10 and name = 'a'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` having count(id) = 10 and `name` = 'a'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"a\")" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user having count(id) = 10 and name = 'a'", "Instructions": { @@ -3172,8 +2198,7 @@ { "comment": "Aggregates and joins", "query": "select count(*) from user join user_extra", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user join user_extra", "Instructions": { @@ -3230,22 +2255,7 @@ { "comment": "aggregation filtering by having on a route with no group by", "query": "select 1 from user having count(id) = 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user having count(id) = 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` having count(id) = 10", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user having count(id) = 10", "Instructions": { @@ -3288,8 +2298,7 @@ { "comment": "Aggregate on join", "query": "select user.a, count(*) from user join user_extra group by user.a", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.a, count(*) from user join user_extra group by user.a", "Instructions": { @@ -3351,8 +2360,7 @@ { "comment": "Aggregate on other table in join", "query": "select user.a, count(user_extra.a) from user join user_extra group by user.a", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.a, count(user_extra.a) from user join user_extra group by user.a", "Instructions": { @@ -3414,8 +2422,7 @@ { "comment": "aggregation spread out across three routes", "query": "select count(u.textcol1), count(ue.foo), us.bar from user u join user_extra ue on u.foo = ue.bar join unsharded us on ue.bar = us.baz group by us.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(u.textcol1), count(ue.foo), us.bar from user u join user_extra ue on u.foo = ue.bar join unsharded us on ue.bar = us.baz group by us.bar", "Instructions": { @@ -3521,32 +2528,7 @@ { "comment": "using two distinct columns - min with distinct vindex, sum with distinct without vindex", "query": "select col1, min(distinct id), sum(distinct col3) from user group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, min(distinct id), sum(distinct col3) from user group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "min(1), sum_distinct_sum(2) AS sum(distinct col3)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, min(id) as `min(distinct id)`, col3, weight_string(col1), weight_string(col3) from `user` where 1 != 1 group by col1, col3, weight_string(col1), weight_string(col3)", - "OrderBy": "(0|3) ASC, (2|4) ASC", - "Query": "select col1, min(id) as `min(distinct id)`, col3, weight_string(col1), weight_string(col3) from `user` group by col1, col3, weight_string(col1), weight_string(col3) order by col1 asc, col3 asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, min(distinct id), sum(distinct col3) from user group by col1", "Instructions": { @@ -3578,8 +2560,7 @@ { "comment": "aggregation on top of semijoin", "query": "select count(*) from user where exists (select 0 from user_extra where user.apa = user_extra.bar)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user where exists (select 0 from user_extra where user.apa = user_extra.bar)", "Instructions": { @@ -3637,32 +2618,7 @@ { "comment": "we have to track the order of distinct aggregation expressions", "query": "select val2, count(distinct val1), count(*) from user group by val2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select val2, count(distinct val1), count(*) from user group by val2", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "count_distinct_count(1) AS count(distinct val1), sum_count(2) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select val2, val1, count(*), weight_string(val2), weight_string(val1) from `user` where 1 != 1 group by val2, val1, weight_string(val2), weight_string(val1)", - "OrderBy": "(0|3) ASC, (1|4) ASC", - "Query": "select val2, val1, count(*), weight_string(val2), weight_string(val1) from `user` group by val2, val1, weight_string(val2), weight_string(val1) order by val2 asc, val1 asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select val2, count(distinct val1), count(*) from user group by val2", "Instructions": { @@ -3694,32 +2650,7 @@ { "comment": "group by column alias", "query": "select ascii(val1) as a, count(*) from user group by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ascii(val1) as a, count(*) from user group by a", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ascii(val1) as a, count(*), weight_string(ascii(val1)) from `user` where 1 != 1 group by a, weight_string(ascii(val1))", - "OrderBy": "(0|2) ASC", - "Query": "select ascii(val1) as a, count(*), weight_string(ascii(val1)) from `user` group by a, weight_string(ascii(val1)) order by a asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ascii(val1) as a, count(*) from user group by a", "Instructions": { @@ -3751,8 +2682,7 @@ { "comment": "multiple distinct aggregations on the same column is allowed", "query": "select tcol1, count(distinct tcol2), sum(distinct tcol2) from user group by tcol1", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: sum(distinct tcol2)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select tcol1, count(distinct tcol2), sum(distinct tcol2) from user group by tcol1", "Instructions": { @@ -3784,8 +2714,7 @@ { "comment": "multiple distinct aggregations on the same column in different positions", "query": "select count(distinct tcol2), tcol1, count(*), sum(distinct tcol2) from user group by tcol1", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: sum(distinct tcol2)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(distinct tcol2), tcol1, count(*), sum(distinct tcol2) from user group by tcol1", "Instructions": { @@ -3817,8 +2746,7 @@ { "comment": "distinct aggregation will 3 table join query", "query": "select u.textcol1, count(distinct u.val2) from user u join user u2 on u.val2 = u2.id join music m on u2.val2 = m.id group by u.textcol1", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.textcol1, count(distinct u.val2) from user u join user u2 on u.val2 = u2.id join music m on u2.val2 = m.id group by u.textcol1", "Instructions": { @@ -3903,22 +2831,7 @@ { "comment": "group_concat on single shards", "query": "select group_concat(user_id order by name), id from user group by id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select group_concat(user_id order by name), id from user group by id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select group_concat(user_id order by `name` asc), id from `user` where 1 != 1 group by id", - "Query": "select group_concat(user_id order by `name` asc), id from `user` group by id", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select group_concat(user_id order by name), id from user group by id", "Instructions": { @@ -3940,22 +2853,7 @@ { "comment": "select count(distinct user_id, name) from unsharded", "query": "select count(distinct user_id, name) from unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(distinct user_id, name) from unsharded", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select count(distinct user_id, `name`) from unsharded where 1 != 1", - "Query": "select count(distinct user_id, `name`) from unsharded", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(distinct user_id, name) from unsharded", "Instructions": { @@ -3977,14 +2875,12 @@ { "comment": "select count(distinct user_id, name) from user", "query": "select count(distinct user_id, name) from user", - "v3-plan": "VT12001: unsupported: only one expression is allowed inside aggregates: count(distinct user_id, `name`)", - "gen4-plan": "VT03001: aggregate functions take a single argument 'count(distinct user_id, `name`)'" + "plan": "VT03001: aggregate functions take a single argument 'count(distinct user_id, `name`)'" }, { "comment": "select sum(col) from (select user.col as col, 32 from user join user_extra) t", "query": "select sum(col) from (select user.col as col, 32 from user join user_extra) t", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(col) from (select user.col as col, 32 from user join user_extra) t", "Instructions": { @@ -4041,8 +2937,7 @@ { "comment": "find aggregation expression and use column offset in filter", "query": "select foo, count(*) from user group by foo having count(*) = 3", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select foo, count(*) from user group by foo having count(*) = 3", "Instructions": { @@ -4088,8 +2983,7 @@ { "comment": "find aggregation expression and use column offset in filter times two", "query": "select foo, sum(foo), sum(bar) from user group by foo having sum(foo)+sum(bar) = 42", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select foo, sum(foo), sum(bar) from user group by foo having sum(foo)+sum(bar) = 42", "Instructions": { @@ -4136,8 +3030,7 @@ { "comment": "find aggregation expression and use column offset in filter times three", "query": "select foo, sum(foo) as fooSum, sum(bar) as barSum from user group by foo having fooSum+sum(bar) = 42", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select foo, sum(foo) as fooSum, sum(bar) as barSum from user group by foo having fooSum+sum(bar) = 42", "Instructions": { @@ -4184,8 +3077,7 @@ { "comment": "having should be able to add new aggregation expressions in having", "query": "select foo from user group by foo having count(*) = 3", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select foo from user group by foo having count(*) = 3", "Instructions": { @@ -4230,8 +3122,7 @@ { "comment": "select u.id from user u join user_extra ue on ue.id = u.id group by u.id having count(u.name) = 3", "query": "select u.id from user u join user_extra ue on ue.id = u.id group by u.id having count(u.name) = 3", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user u join user_extra ue on ue.id = u.id group by u.id having count(u.name) = 3", "Instructions": { @@ -4319,22 +3210,7 @@ { "comment": "select u.id from user u join user_extra ue on ue.user_id = u.id group by u.id having count(u.name) = 3", "query": "select u.id from user u join user_extra ue on ue.user_id = u.id group by u.id having count(u.name) = 3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id from user u join user_extra ue on ue.user_id = u.id group by u.id having count(u.name) = 3", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id from `user` as u join user_extra as ue on ue.user_id = u.id where 1 != 1 group by u.id", - "Query": "select u.id from `user` as u join user_extra as ue on ue.user_id = u.id group by u.id having count(u.`name`) = 3", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user u join user_extra ue on ue.user_id = u.id group by u.id having count(u.name) = 3", "Instructions": { @@ -4357,8 +3233,7 @@ { "comment": "only extract the aggregation once, even if used twice", "query": "select u.id from user u join user_extra ue on ue.id = u.id group by u.id having count(*) < 3 and count(*) > 5", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user u join user_extra ue on ue.id = u.id group by u.id having count(*) < 3 and count(*) > 5", "Instructions": { @@ -4446,8 +3321,7 @@ { "comment": "select (select 1 from user u having count(ue.col) > 10) from user_extra ue", "query": "select (select 1 from user u having count(ue.col) > 10) from user_extra ue", - "v3-plan": "VT03020: column ue.col not found in subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select (select 1 from user u having count(ue.col) > 10) from user_extra ue", "Instructions": { @@ -4511,8 +3385,7 @@ { "comment": "group by and ',' joins with condition", "query": "select user.col from user join user_extra on user_extra.col = user.col group by user.id", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user_extra.col = user.col group by user.id", "Instructions": { @@ -4567,8 +3440,7 @@ { "comment": "scatter aggregate symtab lookup error", "query": "select id, b as id, count(*) from user order by id", - "v3-plan": "VT03021: ambiguous column reference: id", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, b as id, count(*) from user order by id", "Instructions": { @@ -4605,29 +3477,7 @@ { "comment": "aggr and non-aggr without group by (with query does not give useful result out)", "query": "select id, count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, count(*) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(1) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, count(*) from `user` where 1 != 1", - "Query": "select id, count(*) from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, count(*) from user", "Instructions": { @@ -4656,8 +3506,7 @@ { "comment": "group by and ',' joins", "query": "select user.id from user, user_extra group by id", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id from user, user_extra group by id", "Instructions": { @@ -4708,8 +3557,7 @@ { "comment": "count on column from LIMIT", "query": "select count(city) from (select phone, id, city from user where id > 12 limit 10) as x", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(city) from (select phone, id, city from user where id > 12 limit 10) as x", "Instructions": { @@ -4744,8 +3592,7 @@ { "comment": "count(*) on column from LIMIT", "query": "select count(*) from (select phone, id, city from user where id > 12 limit 10) as x", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from (select phone, id, city from user where id > 12 limit 10) as x", "Instructions": { @@ -4838,8 +3685,7 @@ { "comment": "grouping on data from derived table", "query": "select val1, count(*) from (select id, val1 from user where val2 < 4 order by val1 limit 2) as x group by val1", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select val1, count(*) from (select id, val1 from user where val2 < 4 order by val1 limit 2) as x group by val1", "Instructions": { @@ -4884,22 +3730,7 @@ { "comment": "Can't inline derived table when it has HAVING with aggregation function", "query": "select * from (select id from user having count(*) = 1) s", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select id from user having count(*) = 1) s", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select id from `user` where 1 != 1) as s where 1 != 1", - "Query": "select * from (select id from `user` having count(*) = 1) as s", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select id from user having count(*) = 1) s", "Instructions": { @@ -4942,8 +3773,7 @@ { "comment": "Group By X Order By X", "query": "SELECT user.intcol FROM user GROUP BY user.intcol ORDER BY COUNT(user.intcol)", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: count(`user`.intcol)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT user.intcol FROM user GROUP BY user.intcol ORDER BY COUNT(user.intcol)", "Instructions": { @@ -4982,8 +3812,7 @@ { "comment": "AggregateAnyValue in non full group by query", "query": "select u.id, u.name, count(m.predef1) from user.user as u join user.user_extra as m on u.id = m.order group by u.id", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id, u.name, count(m.predef1) from user.user as u join user.user_extra as m on u.id = m.order group by u.id", "Instructions": { @@ -5179,8 +4008,7 @@ { "comment": "Aggregations from derived table used in arithmetic outside derived table", "query": "select A.a, A.b, (A.a / A.b) as d from (select sum(a) as a, sum(b) as b from user) A", - "v3-plan": "VT12001: unsupported: expression on results of a cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select A.a, A.b, (A.a / A.b) as d from (select sum(a) as a, sum(b) as b from user) A", "Instructions": { @@ -5219,22 +4047,7 @@ { "comment": "when pushing predicates into derived tables, make sure to put them in HAVING when they contain aggregations", "query": "select t1.portalId, t1.flowId from (select portalId, flowId, count(*) as count from user_extra where localDate > :v1 group by user_id, flowId order by null) as t1 where count >= :v2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t1.portalId, t1.flowId from (select portalId, flowId, count(*) as count from user_extra where localDate > :v1 group by user_id, flowId order by null) as t1 where count >= :v2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t1.portalId, t1.flowId from (select portalId, flowId, count(*) as `count` from user_extra where 1 != 1 group by user_id, flowId) as t1 where 1 != 1", - "Query": "select t1.portalId, t1.flowId from (select portalId, flowId, count(*) as `count` from user_extra where localDate > :v1 group by user_id, flowId order by null) as t1 where `count` >= :v2", - "Table": "user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t1.portalId, t1.flowId from (select portalId, flowId, count(*) as count from user_extra where localDate > :v1 group by user_id, flowId order by null) as t1 where count >= :v2", "Instructions": { @@ -5256,8 +4069,7 @@ { "comment": "aggregation, where and derived tables - we can push extremums", "query": "SELECT foo FROM (SELECT foo, max(baz) as bazo FROM (SELECT foo, baz FROM user) f GROUP BY foo) tt WHERE bazo BETWEEN 100 AND 200", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT foo FROM (SELECT foo, max(baz) as bazo FROM (SELECT foo, baz FROM user) f GROUP BY foo) tt WHERE bazo BETWEEN 100 AND 200", "Instructions": { @@ -5302,8 +4114,7 @@ { "comment": "aggregation, where and derived tables - we can't push aggregations that might need a second layer of aggregation", "query": "SELECT foo FROM (SELECT foo, count(baz) as bazo FROM (SELECT foo, baz FROM user) f GROUP BY foo) tt WHERE bazo BETWEEN 100 AND 200", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT foo FROM (SELECT foo, count(baz) as bazo FROM (SELECT foo, baz FROM user) f GROUP BY foo) tt WHERE bazo BETWEEN 100 AND 200", "Instructions": { @@ -5348,8 +4159,7 @@ { "comment": "Scatter order by is complex with aggregates in select", "query": "select col, count(*) from user group by col order by col+1", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: col + 1", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) from user group by col order by col+1", "Instructions": { @@ -5388,8 +4198,7 @@ { "comment": "scatter aggregate complex order by", "query": "select id from user group by id order by id+1", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: id + 1", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user group by id order by id+1", "Instructions": { @@ -5413,8 +4222,7 @@ { "comment": "select expression does not directly depend on grouping expression", "query": "select a from user group by a+1", - "v3-plan": "VT12001: unsupported: in scatter query: only simple references are allowed", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a from user group by a+1", "Instructions": { @@ -5446,8 +4254,7 @@ { "comment": "inner join with scalar aggregation", "query": "select count(*) from user join music on user.foo = music.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user join music on user.foo = music.bar", "Instructions": { @@ -5837,8 +4644,7 @@ { "comment": "3 table inner join with scalar aggregation", "query": "select count(*) from user join music on user.foo = music.bar join user_extra on user.foo = user_extra.baz", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user join music on user.foo = music.bar join user_extra on user.foo = user_extra.baz", "Instructions": { @@ -6021,8 +4827,7 @@ { "comment": "ordering have less column than grouping columns, grouping gets rearranged as order by and missing columns gets added to ordering", "query": "select u.col, u.intcol, count(*) from user u join music group by 1,2 order by 2", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.col, u.intcol, count(*) from user u join music group by 1,2 order by 2", "Instructions": { @@ -6083,22 +4888,7 @@ { "comment": "redundant group by columns are not added", "query": "select col, val, id from user group by col, val, id, id, val, col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col, val, id from user group by col, val, id, id, val, col", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col, val, id from `user` where 1 != 1 group by col, val, id, id, val, col", - "Query": "select col, val, id from `user` group by col, val, id, id, val, col", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, val, id from user group by col, val, id, id, val, col", "Instructions": { @@ -6120,8 +4910,7 @@ { "comment": "scatter aggregate with ambiguous aliases", "query": "select distinct a, b as a from user", - "v3-plan": "generating ORDER BY clause: VT03021: ambiguous column reference: a", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct a, b as a from user", "Instructions": { @@ -6152,8 +4941,7 @@ { "comment": "scatter aggregate with complex select list (can't build order by)", "query": "select distinct a+1 from user", - "v3-plan": "generating ORDER BY clause: VT12001: unsupported: reference a complex expression", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct a+1 from user", "Instructions": { @@ -6184,8 +4972,7 @@ { "comment": "distinct on top of aggregation", "query": "select distinct count(*) from user group by col", - "v3-plan": "VT12001: unsupported: in scatter query: GROUP BY column must reference column in SELECT list", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct count(*) from user group by col", "Instructions": { @@ -6225,8 +5012,7 @@ { "comment": "scalar aggregates with min, max, sum distinct and count distinct using collations", "query": "select min(textcol1), max(textcol2), sum(distinct textcol1), count(distinct textcol1) from user", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: count(distinct textcol1)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select min(textcol1), max(textcol2), sum(distinct textcol1), count(distinct textcol1) from user", "Instructions": { @@ -6256,8 +5042,7 @@ { "comment": "grouping aggregates with mi, max, sum distinct and count distinct using collations", "query": "select col, min(textcol1), max(textcol2), sum(distinct textcol1), count(distinct textcol1) from user group by col", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: count(distinct textcol1)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, min(textcol1), max(textcol2), sum(distinct textcol1), count(distinct textcol1) from user group by col", "Instructions": { @@ -6288,8 +5073,7 @@ { "comment": "using a grouping column multiple times should be OK", "query": "select col, col, count(*) from user group by col", - "v3-plan": "generating ORDER BY clause: VT03021: ambiguous column reference: col", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, col, count(*) from user group by col", "Instructions": { @@ -6320,8 +5104,7 @@ { "comment": "multiple count star and a count with 3 table join", "query": "select count(*), count(*), count(u.col) from user u, user u2, user_extra ue", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*), count(*), count(u.col) from user u, user u2, user_extra ue", "Instructions": { @@ -6408,8 +5191,7 @@ { "comment": "interleaving grouping, aggregation and join with min, max columns", "query": "select user.col, min(user_extra.foo), user.bar, max(user_extra.bar) from user join user_extra on user.col = user_extra.bar group by user.col, user.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col, min(user_extra.foo), user.bar, max(user_extra.bar) from user join user_extra on user.col = user_extra.bar group by user.col, user.bar", "Instructions": { @@ -6464,8 +5246,7 @@ { "comment": "extremum on input from both sides", "query": "select max(u.foo*ue.bar) from user u join user_extra ue", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select max(u.foo*ue.bar) from user u join user_extra ue", "Instructions": { @@ -6518,8 +5299,7 @@ { "comment": "aggregate on input from both sides - TODO optimize more", "query": "select sum(user.foo+user_extra.bar) from user, user_extra", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(user.foo+user_extra.bar) from user, user_extra", "Instructions": { @@ -6571,8 +5351,7 @@ { "comment": "grouping column could be coming from multiple sides", "query": "select count(*) from user, user_extra group by user.id+user_extra.id", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) from user, user_extra group by user.id+user_extra.id", "Instructions": { @@ -6643,8 +5422,7 @@ { "comment": "Complex aggregate expression on scatter", "query": "select 1+count(*) from user", - "v3-plan": "VT12001: unsupported: in scatter query: complex aggregate expression", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1+count(*) from user", "Instructions": { @@ -6681,8 +5459,7 @@ { "comment": "combine the output of two aggregations in the final result", "query": "select greatest(sum(user.foo), sum(user_extra.bar)) from user join user_extra on user.col = user_extra.col", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select greatest(sum(user.foo), sum(user_extra.bar)) from user join user_extra on user.col = user_extra.col", "Instructions": { @@ -6751,8 +5528,7 @@ { "comment": "Aggregate detection (group_concat)", "query": "select group_concat(user.a) from user join user_extra", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select group_concat(user.a) from user join user_extra", "Instructions": { @@ -6801,8 +5577,7 @@ { "comment": "plan a query with any_value()", "query": "select count(*), any_value(u.name), any_value(ue.title) from user u join user_extra ue on u.bar = ue.foo ", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*), any_value(u.name), any_value(ue.title) from user u join user_extra ue on u.bar = ue.foo ", "Instructions": { @@ -6864,8 +5639,7 @@ { "comment": "group_concat with group by without in select list", "query": "select group_concat(user.id) from user, music where user.id = music.foo group by user.bar", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select group_concat(user.id) from user, music where user.id = music.foo group by user.bar", "Instructions": { @@ -6930,31 +5704,7 @@ { "comment": "group_concat aggregation on top of route", "query": "select intcol, group_concat(foo) from user group by intcol", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select intcol, group_concat(foo) from user group by intcol", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "group_concat(1)", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select intcol, group_concat(foo) from `user` where 1 != 1 group by intcol", - "OrderBy": "0 ASC", - "Query": "select intcol, group_concat(foo) from `user` group by intcol order by intcol asc", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select intcol, group_concat(foo) from user group by intcol", "Instructions": { @@ -6985,8 +5735,7 @@ { "comment": "ordering on top of aggregator without pushing the column down during the horizon phase", "query": "select u.foo, group_concat(u.bar) from user u, music m where u.col = m.col group by u.foo order by u.baz", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.foo, group_concat(u.bar) from user u, music m where u.col = m.col group by u.foo order by u.baz", "Instructions": { @@ -7048,8 +5797,7 @@ { "comment": "count distinct and sum distinct on join query pushed down - unique vindex", "query": "select u.col1, count(distinct m.user_id), sum(distinct m.user_id) from user u join music m group by u.col1", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.col1, count(distinct m.user_id), sum(distinct m.user_id) from user u join music m group by u.col1", "Instructions": { @@ -7101,8 +5849,7 @@ { "comment": "count and sum distinct with min distinct on different expressions", "query": "select foo, min(distinct bar), count(distinct baz), sum(distinct baz), max(distinct toto) from user group by foo", - "v3-plan": "VT12001: unsupported: only one DISTINCT aggregation allowed in a SELECT: sum(distinct baz)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select foo, min(distinct bar), count(distinct baz), sum(distinct baz), max(distinct toto) from user group by foo", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases.json b/go/vt/vtgate/planbuilder/testdata/ddl_cases.json index 8326922225c..eec1a0ce101 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases.json @@ -251,22 +251,7 @@ { "comment": "create view with subquery in unsharded keyspace", "query": "create view view_a as select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view view_a as select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "Query": "create view view_a as select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) as a" - }, - "TablesUsed": [ - "main.view_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view view_a as select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", "Instructions": { @@ -380,22 +365,7 @@ { "comment": "Create View with authoritative column", "query": "create view user.tmp_view as select * from user.authoritative", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.tmp_view as select * from user.authoritative", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view tmp_view as select * from authoritative" - }, - "TablesUsed": [ - "user.tmp_view" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.tmp_view as select * from user.authoritative", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases_no_default_keyspace.json b/go/vt/vtgate/planbuilder/testdata/ddl_cases_no_default_keyspace.json index 30547db61c4..9df66921fd5 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases_no_default_keyspace.json +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases_no_default_keyspace.json @@ -116,22 +116,7 @@ { "comment": "create view with select * from authoritative table", "query": "create view user.view_a as select * from authoritative", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.view_a as select * from authoritative", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view view_a as select * from authoritative" - }, - "TablesUsed": [ - "user.view_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.view_a as select * from authoritative", "Instructions": { @@ -150,22 +135,7 @@ { "comment": "create view with select * from join of authoritative tables", "query": "create view user.view_a as select * from authoritative a join authoritative b on a.user_id=b.user_id", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.view_a as select * from authoritative a join authoritative b on a.user_id=b.user_id", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view view_a as select * from authoritative as a join authoritative as b on a.user_id = b.user_id" - }, - "TablesUsed": [ - "user.view_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.view_a as select * from authoritative a join authoritative b on a.user_id=b.user_id", "Instructions": { @@ -184,22 +154,7 @@ { "comment": "create view with select * from qualified authoritative table", "query": "create view user.view_a as select a.* from authoritative a", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.view_a as select a.* from authoritative a", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view view_a as select a.* from authoritative as a" - }, - "TablesUsed": [ - "user.view_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.view_a as select a.* from authoritative a", "Instructions": { @@ -237,22 +192,7 @@ { "comment": "create view with select authoritative.* with intermixing still expands", "query": "create view user.view_a as select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.view_a as select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view view_a as select `user`.id, a.*, `user`.col1 from authoritative as a join `user` on a.user_id = `user`.id" - }, - "TablesUsed": [ - "user.view_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.view_a as select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index 8b92ffe9336..c52807fed79 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -144,29 +144,7 @@ { "comment": "routing rules: updated of a routed table", "query": "update route1 set a=1 where id=1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update route1 set a=1 where id=1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` as route1 set a = 1 where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update route1 set a=1 where id=1", "Instructions": { @@ -192,25 +170,7 @@ { "comment": "update: routing rules for subquery.", "query": "update unsharded_a set a=(select a from route2)", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update unsharded_a set a=(select a from route2)", - "Instructions": { - "OperatorType": "Update", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "update unsharded_a set a = (select a from unsharded as route2)", - "Table": "unsharded, unsharded_a" - }, - "TablesUsed": [ - "main.unsharded_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update unsharded_a set a=(select a from route2)", "Instructions": { @@ -299,29 +259,7 @@ { "comment": "update by primary keyspace id", "query": "update user set val = 1 where id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set val = 1 where id = 1", "Instructions": { @@ -347,29 +285,7 @@ { "comment": "update by primary keyspace id with alias", "query": "update user as user_alias set val = 1 where user_alias.id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user as user_alias set val = 1 where user_alias.id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` as user_alias set val = 1 where user_alias.id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user as user_alias set val = 1 where user_alias.id = 1", "Instructions": { @@ -395,29 +311,7 @@ { "comment": "update by primary keyspace id with parenthesized expression", "query": "update user set val = 1 where (id = 1)", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where (id = 1)", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set val = 1 where (id = 1)", "Instructions": { @@ -443,29 +337,7 @@ { "comment": "update by primary keyspace id with multi-part where clause with parens", "query": "update user set val = 1 where (name = 'foo' and id = 1)", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where (name = 'foo' and id = 1)", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where `name` = 'foo' and id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set val = 1 where (name = 'foo' and id = 1)", "Instructions": { @@ -491,35 +363,7 @@ { "comment": "update by primary keyspace id, changing one vindex column", "query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user_metadata set email = 'juan@vitess.io' where user_id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "email_user_map:4" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, email, address, non_planable, email = 'juan@vitess.io' from user_metadata where user_id = 1 for update", - "Query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1", - "Table": "user_metadata", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user_metadata" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user_metadata set email = 'juan@vitess.io' where user_id = 1", "Instructions": { @@ -556,36 +400,7 @@ { "comment": "update by primary keyspace id, changing multiple vindex columns", "query": "update user_metadata set email = 'juan@vitess.io', address = '155 5th street' where user_id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user_metadata set email = 'juan@vitess.io', address = '155 5th street' where user_id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "address_user_map:5", - "email_user_map:4" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, email, address, non_planable, email = 'juan@vitess.io', address = '155 5th street' from user_metadata where user_id = 1 for update", - "Query": "update user_metadata set email = 'juan@vitess.io', address = '155 5th street' where user_id = 1", - "Table": "user_metadata", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user_metadata" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user_metadata set email = 'juan@vitess.io', address = '155 5th street' where user_id = 1", "Instructions": { @@ -618,35 +433,7 @@ { "comment": "update by primary keyspace id, changing one vindex column, using order by and limit", "query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 order by user_id asc limit 10", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 order by user_id asc limit 10", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "email_user_map:4" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, email, address, non_planable, email = 'juan@vitess.io' from user_metadata where user_id = 1 order by user_id asc limit 10 for update", - "Query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 order by user_id asc limit 10", - "Table": "user_metadata", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user_metadata" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 order by user_id asc limit 10", "Instructions": { @@ -678,12 +465,12 @@ { "comment": "update changes non owned vindex column", "query": "update music_extra set music_id = 1 where user_id = 1", - "v3-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update music_extra set music_id = 1 where user_id = 1", "Instructions": { "OperatorType": "Update", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true @@ -705,10 +492,14 @@ "TablesUsed": [ "user.music_extra" ] - }, - "gen4-plan": { + } + }, + { + "comment": "update by primary keyspace id, stray where clause", + "query": "update user set val = 1 where id = id2 and id = 1", + "plan": { "QueryType": "UPDATE", - "Original": "update music_extra set music_id = 1 where user_id = 1", + "Original": "update user set val = 1 where id = id2 and id = 1", "Instructions": { "OperatorType": "Update", "Variant": "EqualUnique", @@ -717,39 +508,33 @@ "Sharded": true }, "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "music_user_map:1" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, music_id = 1 from music_extra where user_id = 1 for update", - "Query": "update music_extra set music_id = 1 where user_id = 1", - "Table": "music_extra", + "Query": "update `user` set val = 1 where id = id2 and id = 1", + "Table": "user", "Values": [ "INT64(1)" ], "Vindex": "user_index" }, "TablesUsed": [ - "user.music_extra" + "user.user" ] } }, { - "comment": "update by primary keyspace id, stray where clause", - "query": "update user set val = 1 where id = id2 and id = 1", - "v3-plan": { + "comment": "update by primary keyspace id, stray where clause with conversion error", + "query": "update user set val = 1 where id = 18446744073709551616 and id = 1", + "plan": { "QueryType": "UPDATE", - "Original": "update user set val = 1 where id = id2 and id = 1", + "Original": "update user set val = 1 where id = 18446744073709551616 and id = 1", "Instructions": { "OperatorType": "Update", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = id2 and id = 1", + "Query": "update `user` set val = 1 where id = 18446744073709551616 and id = 1", "Table": "user", "Values": [ "INT64(1)" @@ -759,121 +544,26 @@ "TablesUsed": [ "user.user" ] - }, - "gen4-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where id = id2 and id = 1", + } + }, + { + "comment": "delete from by primary keyspace id", + "query": "delete from user where id = 1", + "plan": { + "QueryType": "DELETE", + "Original": "delete from user where id = 1", "Instructions": { - "OperatorType": "Update", + "OperatorType": "Delete", "Variant": "EqualUnique", "Keyspace": { "Name": "user", "Sharded": true }, "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = id2 and id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "update by primary keyspace id, stray where clause with conversion error", - "query": "update user set val = 1 where id = 18446744073709551616 and id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where id = 18446744073709551616 and id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = 18446744073709551616 and id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { - "QueryType": "UPDATE", - "Original": "update user set val = 1 where id = 18446744073709551616 and id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set val = 1 where id = 18446744073709551616 and id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "delete from by primary keyspace id", - "query": "delete from user where id = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from user where id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where id = 1 for update", - "Query": "delete from `user` where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { - "QueryType": "DELETE", - "Original": "delete from user where id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where id = 1 for update", - "Query": "delete from `user` where id = 1", + "KsidLength": 1, + "KsidVindex": "user_index", + "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where id = 1 for update", + "Query": "delete from `user` where id = 1", "Table": "user", "Values": [ "INT64(1)" @@ -956,32 +646,7 @@ { "comment": "routing rules: deleted from a routed table", "query": "delete from route1 where id = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from route1 where id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly from `user` as route1 where id = 1 for update", - "Query": "delete from `user` as route1 where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from route1 where id = 1", "Instructions": { @@ -1010,25 +675,7 @@ { "comment": "delete: routing rules for subquery", "query": "delete from unsharded_a where a=(select a from route2)", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from unsharded_a where a=(select a from route2)", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from unsharded_a where a = (select a from unsharded as route2)", - "Table": "unsharded, unsharded_a" - }, - "TablesUsed": [ - "main.unsharded_a" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from unsharded_a where a=(select a from route2)", "Instructions": { @@ -1051,29 +698,7 @@ { "comment": "update by lookup", "query": "update music set val = 1 where id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update music set val = 1 where id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update music set val = 1 where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "music_user_map" - }, - "TablesUsed": [ - "user.music" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update music set val = 1 where id = 1", "Instructions": { @@ -1145,32 +770,7 @@ { "comment": "delete from by lookup", "query": "delete from music where id = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from music where id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, id from music where id = 1 for update", - "Query": "delete from music where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "music_user_map" - }, - "TablesUsed": [ - "user.music" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from music where id = 1", "Instructions": { @@ -1199,29 +799,7 @@ { "comment": "delete from, no owned vindexes", "query": "delete from music_extra where user_id = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from music_extra where user_id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from music_extra where user_id = 1", - "Table": "music_extra", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.music_extra" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from music_extra where user_id = 1", "Instructions": { @@ -1390,25 +968,7 @@ { "comment": "insert unsharded with select", "query": "insert into unsharded select id from unsharded_auto", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded select id from unsharded_auto", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into unsharded select id from unsharded_auto for update", - "TableName": "unsharded" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded select id from unsharded_auto", "Instructions": { @@ -1431,25 +991,7 @@ { "comment": "insert unsharded with select with join", "query": "insert into unsharded select id from unsharded join unsharded_auto", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded select id from unsharded join unsharded_auto", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into unsharded select id from unsharded join unsharded_auto for update", - "TableName": "unsharded" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded select id from unsharded join unsharded_auto", "Instructions": { @@ -1665,8 +1207,7 @@ { "comment": "insert with mimatched column list", "query": "insert into user(id) values (1, 2)", - "v3-plan": "VT13001: [BUG] column list does not match values", - "gen4-plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count at row 1" }, { "comment": "insert no column list for sharded authoritative table", @@ -2001,25 +1542,7 @@ { "comment": "unsharded insert from union", "query": "insert into unsharded select 1 from dual union select 1 from dual", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded select 1 from dual union select 1 from dual", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into unsharded select 1 from dual union select 1 from dual for update", - "TableName": "unsharded" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded select 1 from dual union select 1 from dual", "Instructions": { @@ -2190,8 +1713,7 @@ { "comment": "insert into a vindex not allowed", "query": "insert into user_index(id) values(1)", - "v3-plan": "VT12001: unsupported: multi-shard or vindex write statement", - "gen4-plan": "VT09014: vindex cannot be modified" + "plan": "VT09014: vindex cannot be modified" }, { "comment": "simple replace unsharded", @@ -2218,7 +1740,7 @@ { "comment": "replace unsharded with select", "query": "replace into unsharded select id from unsharded_auto", - "v3-plan": { + "plan": { "QueryType": "INSERT", "Original": "replace into unsharded select id from unsharded_auto", "Instructions": { @@ -2229,30 +1751,12 @@ "Sharded": false }, "TargetTabletType": "PRIMARY", - "Query": "replace into unsharded select id from unsharded_auto for update", + "Query": "replace into unsharded select id from unsharded_auto", "TableName": "unsharded" }, "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { - "QueryType": "INSERT", - "Original": "replace into unsharded select id from unsharded_auto", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "replace into unsharded select id from unsharded_auto", - "TableName": "unsharded" - }, - "TablesUsed": [ - "main.unsharded", - "main.unsharded_auto" + "main.unsharded", + "main.unsharded_auto" ] } }, @@ -2436,32 +1940,7 @@ { "comment": "delete row in a multi column vindex table", "query": "delete from multicolvin where kid=1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from multicolvin where kid=1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "kid_index", - "OwnedVindexQuery": "select kid, column_a, column_b, column_c from multicolvin where kid = 1 for update", - "Query": "delete from multicolvin where kid = 1", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "kid_index" - }, - "TablesUsed": [ - "user.multicolvin" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from multicolvin where kid=1", "Instructions": { @@ -2490,35 +1969,7 @@ { "comment": "update columns of multi column vindex", "query": "update multicolvin set column_b = 1, column_c = 2 where kid = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicolvin set column_b = 1, column_c = 2 where kid = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "colb_colc_map:4" - ], - "KsidLength": 1, - "KsidVindex": "kid_index", - "OwnedVindexQuery": "select kid, column_a, column_b, column_c, column_b = 1 and column_c = 2 from multicolvin where kid = 1 for update", - "Query": "update multicolvin set column_b = 1, column_c = 2 where kid = 1", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "kid_index" - }, - "TablesUsed": [ - "user.multicolvin" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicolvin set column_b = 1, column_c = 2 where kid = 1", "Instructions": { @@ -2550,36 +2001,7 @@ { "comment": "update multiple vindexes, with multi column vindex", "query": "update multicolvin set column_a = 0, column_b = 1, column_c = 2 where kid = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicolvin set column_a = 0, column_b = 1, column_c = 2 where kid = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "cola_map:4", - "colb_colc_map:5" - ], - "KsidLength": 1, - "KsidVindex": "kid_index", - "OwnedVindexQuery": "select kid, column_a, column_b, column_c, column_a = 0, column_b = 1 and column_c = 2 from multicolvin where kid = 1 for update", - "Query": "update multicolvin set column_a = 0, column_b = 1, column_c = 2 where kid = 1", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "kid_index" - }, - "TablesUsed": [ - "user.multicolvin" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicolvin set column_a = 0, column_b = 1, column_c = 2 where kid = 1", "Instructions": { @@ -2976,25 +2398,7 @@ { "comment": "unsharded update where inner query references outer query", "query": "update unsharded set col = (select id from unsharded_a where id = unsharded.col) where col = (select id from unsharded_b)", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update unsharded set col = (select id from unsharded_a where id = unsharded.col) where col = (select id from unsharded_b)", - "Instructions": { - "OperatorType": "Update", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "update unsharded set col = (select id from unsharded_a where id = unsharded.col) where col = (select id from unsharded_b)", - "Table": "unsharded, unsharded_a, unsharded_b" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update unsharded set col = (select id from unsharded_a where id = unsharded.col) where col = (select id from unsharded_b)", "Instructions": { @@ -3018,25 +2422,7 @@ { "comment": "unsharded delete where inner query references outer query", "query": "delete from unsharded where col = (select id from unsharded_a where id = unsharded.col)", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from unsharded where col = (select id from unsharded_a where id = unsharded.col)", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from unsharded where col = (select id from unsharded_a where id = unsharded.col)", - "Table": "unsharded, unsharded_a" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from unsharded where col = (select id from unsharded_a where id = unsharded.col)", "Instructions": { @@ -3059,35 +2445,7 @@ { "comment": "update vindex value to null", "query": "update user set name = null where id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set name = null where id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "name_user_map:3" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly, `name` = null from `user` where id = 1 for update", - "Query": "update `user` set `name` = null where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set name = null where id = 1", "Instructions": { @@ -3308,32 +2666,7 @@ { "comment": "delete with single table targets", "query": "delete music from music where id = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete music from music where id = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select user_id, id from music where id = 1 for update", - "Query": "delete from music where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "music_user_map" - }, - "TablesUsed": [ - "user.music" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete music from music where id = 1", "Instructions": { @@ -3409,35 +2742,7 @@ { "comment": "update multi column vindex, without values for all the vindex columns", "query": "update multicolvin set column_c = 2 where kid = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicolvin set column_c = 2 where kid = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "colb_colc_map:4" - ], - "KsidLength": 1, - "KsidVindex": "kid_index", - "OwnedVindexQuery": "select kid, column_a, column_b, column_c, column_c = 2 from multicolvin where kid = 1 for update", - "Query": "update multicolvin set column_c = 2 where kid = 1", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "kid_index" - }, - "TablesUsed": [ - "user.multicolvin" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicolvin set column_c = 2 where kid = 1", "Instructions": { @@ -3469,35 +2774,7 @@ { "comment": "update with binary value", "query": "update user set name = _binary 'abc' where id = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set name = _binary 'abc' where id = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "name_user_map:3" - ], - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly, `name` = _binary 'abc' from `user` where id = 1 for update", - "Query": "update `user` set `name` = _binary 'abc' where id = 1", - "Table": "user", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set name = _binary 'abc' where id = 1", "Instructions": { @@ -3529,28 +2806,7 @@ { "comment": "delete with binary value", "query": "delete from user where name = _binary 'abc'", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from user where name = _binary 'abc'", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where `name` = _binary 'abc' for update", - "Query": "delete from `user` where `name` = _binary 'abc'", - "Table": "user" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from user where name = _binary 'abc'", "Instructions": { @@ -3694,25 +2950,7 @@ { "comment": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", "query": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", - "v3-plan": { - "QueryType": "INSERT", - "Original": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into user_privacy_consents(user_id, accepted_at) select user_id, accepted_at from (select 1 as user_id, 1629194864 as accepted_at from dual) as tmp where not exists (select 1 from user_privacy_consents where user_id = 1 limit 1) for update", - "TableName": "user_privacy_consents" - }, - "TablesUsed": [ - "main.user_privacy_consents" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", "Instructions": { @@ -3788,32 +3026,7 @@ { "comment": "Delete on backfilling and non-backfilling unique lookup vindexes should be a delete equal", "query": "delete from zlookup_unique.t1 where c2 = 10 and c3 = 20", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from zlookup_unique.t1 where c2 = 10 and c3 = 20", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "zlookup_unique", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "xxhash", - "OwnedVindexQuery": "select c1, c2, c3 from t1 where c2 = 10 and c3 = 20 for update", - "Query": "delete from t1 where c2 = 10 and c3 = 20", - "Table": "t1", - "Values": [ - "INT64(20)" - ], - "Vindex": "lookup_t1_2" - }, - "TablesUsed": [ - "zlookup_unique.t1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from zlookup_unique.t1 where c2 = 10 and c3 = 20", "Instructions": { @@ -3842,35 +3055,7 @@ { "comment": "Update on backfilling and non-backfilling unique lookup vindexes should be an equal", "query": "update zlookup_unique.t1 set c2 = 1 where c2 = 10 and c3 = 20", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update zlookup_unique.t1 set c2 = 1 where c2 = 10 and c3 = 20", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "zlookup_unique", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "lookup_t1:3" - ], - "KsidLength": 1, - "KsidVindex": "xxhash", - "OwnedVindexQuery": "select c1, c2, c3, c2 = 1 from t1 where c2 = 10 and c3 = 20 for update", - "Query": "update t1 set c2 = 1 where c2 = 10 and c3 = 20", - "Table": "t1", - "Values": [ - "INT64(20)" - ], - "Vindex": "lookup_t1_2" - }, - "TablesUsed": [ - "zlookup_unique.t1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update zlookup_unique.t1 set c2 = 1 where c2 = 10 and c3 = 20", "Instructions": { @@ -4016,30 +3201,7 @@ { "comment": "update with a multicol vindex", "query": "update multicol_tbl set x = 1 where cola = 1 and colb = 2", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set x = 1 where cola = 1 and colb = 2", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update multicol_tbl set x = 1 where cola = 1 and colb = 2", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)", - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set x = 1 where cola = 1 and colb = 2", "Instructions": { @@ -4066,30 +3228,7 @@ { "comment": "update with a multicol vindex - reverse order", "query": "update multicol_tbl set x = 1 where colb = 2 and cola = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set x = 1 where colb = 2 and cola = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update multicol_tbl set x = 1 where colb = 2 and cola = 1", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)", - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set x = 1 where colb = 2 and cola = 1", "Instructions": { @@ -4170,33 +3309,7 @@ { "comment": "delete with a multicol vindex", "query": "delete from multicol_tbl where cola = 1 and colb = 2", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from multicol_tbl where cola = 1 and colb = 2", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where cola = 1 and colb = 2 for update", - "Query": "delete from multicol_tbl where cola = 1 and colb = 2", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)", - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from multicol_tbl where cola = 1 and colb = 2", "Instructions": { @@ -4226,33 +3339,7 @@ { "comment": "delete with a multicol vindex - reverse order", "query": "delete from multicol_tbl where colb = 2 and cola = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from multicol_tbl where colb = 2 and cola = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where colb = 2 and cola = 1 for update", - "Query": "delete from multicol_tbl where colb = 2 and cola = 1", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)", - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from multicol_tbl where colb = 2 and cola = 1", "Instructions": { @@ -4342,36 +3429,7 @@ { "comment": "update with multicol and an owned vindex which changes", "query": "update multicol_tbl set colc = 1 where cola = 1 and colb = 2", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set colc = 1 where cola = 1 and colb = 2", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "colc_map:4" - ], - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name`, colc = 1 from multicol_tbl where cola = 1 and colb = 2 for update", - "Query": "update multicol_tbl set colc = 1 where cola = 1 and colb = 2", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)", - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set colc = 1 where cola = 1 and colb = 2", "Instructions": { @@ -4430,29 +3488,7 @@ { "comment": "update with routing using subsharding column", "query": "update multicol_tbl set x = 42 where cola = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set x = 42 where cola = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update multicol_tbl set x = 42 where cola = 1", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set x = 42 where cola = 1", "Instructions": { @@ -4478,35 +3514,7 @@ { "comment": "update with routing using subsharding column on lookup vindex", "query": "update multicol_tbl set name = 'bar' where cola = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set name = 'bar' where cola = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "ChangedVindexValues": [ - "name_muticoltbl_map:4" - ], - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name`, `name` = 'bar' from multicol_tbl where cola = 1 for update", - "Query": "update multicol_tbl set `name` = 'bar' where cola = 1", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set name = 'bar' where cola = 1", "Instructions": { @@ -4570,7 +3578,7 @@ { "comment": "update with routing using subsharding column with in query as lower cost over lookup vindex", "query": "update multicol_tbl set x = 1 where name = 'foo' and cola = 2", - "v3-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update multicol_tbl set x = 1 where name = 'foo' and cola = 2", "Instructions": { @@ -4584,45 +3592,23 @@ "Query": "update multicol_tbl set x = 1 where `name` = 'foo' and cola = 2", "Table": "multicol_tbl", "Values": [ - "INT64(2)" + "VARCHAR(\"foo\")" ], - "Vindex": "multicolIdx" + "Vindex": "name_muticoltbl_map" }, "TablesUsed": [ "user.multicol_tbl" ] - }, - "gen4-plan": { - "QueryType": "UPDATE", - "Original": "update multicol_tbl set x = 1 where name = 'foo' and cola = 2", + } + }, + { + "comment": "delete with routing using non-unique lookup vindex", + "query": "delete from multicol_tbl where name = 'foo'", + "plan": { + "QueryType": "DELETE", + "Original": "delete from multicol_tbl where name = 'foo'", "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update multicol_tbl set x = 1 where `name` = 'foo' and cola = 2", - "Table": "multicol_tbl", - "Values": [ - "VARCHAR(\"foo\")" - ], - "Vindex": "name_muticoltbl_map" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - } - }, - { - "comment": "delete with routing using non-unique lookup vindex", - "query": "delete from multicol_tbl where name = 'foo'", - "plan": { - "QueryType": "DELETE", - "Original": "delete from multicol_tbl where name = 'foo'", - "Instructions": { - "OperatorType": "Delete", + "OperatorType": "Delete", "Variant": "Equal", "Keyspace": { "Name": "user", @@ -4647,32 +3633,7 @@ { "comment": "delete with routing using subsharding column", "query": "delete from multicol_tbl where cola = 1", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from multicol_tbl where cola = 1", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where cola = 1 for update", - "Query": "delete from multicol_tbl where cola = 1", - "Table": "multicol_tbl", - "Values": [ - "INT64(1)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from multicol_tbl where cola = 1", "Instructions": { @@ -4730,32 +3691,7 @@ { "comment": "delete with routing using subsharding column with in query as lower cost over lookup vindex", "query": "delete from multicol_tbl where name = 'foo' and cola = 2", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from multicol_tbl where name = 'foo' and cola = 2", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 2, - "KsidVindex": "multicolIdx", - "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where `name` = 'foo' and cola = 2 for update", - "Query": "delete from multicol_tbl where `name` = 'foo' and cola = 2", - "Table": "multicol_tbl", - "Values": [ - "INT64(2)" - ], - "Vindex": "multicolIdx" - }, - "TablesUsed": [ - "user.multicol_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from multicol_tbl where name = 'foo' and cola = 2", "Instructions": { @@ -4784,41 +3720,7 @@ { "comment": "insert using select with simple table.", "query": "insert into music(id, user_id) select * from user", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into music(id, user_id) select * from user", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "TableName": "music", - "VindexOffsetFromSelect": { - "music_user_map": "[0]", - "user_index": "[1]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` for update", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.music" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into music(id, user_id) select * from user", "Instructions": { @@ -4872,41 +3774,7 @@ { "comment": "insert using select with auto-inc column using vitess sequence, sequence column not present", "query": "insert into user_extra(user_id) select id from user", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user_extra(user_id) select id from user", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(1)", - "TableName": "user_extra", - "VindexOffsetFromSelect": { - "user_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` for update", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user_extra" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user_extra(user_id) select id from user", "Instructions": { @@ -4945,41 +3813,7 @@ { "comment": "insert using select with auto-inc column using vitess sequence, sequence column present", "query": "insert into user_extra(id, user_id) select null, id from user", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user_extra(id, user_id) select null, id from user", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(2)", - "TableName": "user_extra", - "VindexOffsetFromSelect": { - "user_index": "[1]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select null, id from `user` where 1 != 1", - "Query": "select null, id from `user` for update", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user_extra" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user_extra(id, user_id) select null, id from user", "Instructions": { @@ -5018,43 +3852,7 @@ { "comment": "sharded insert from select", "query": "insert into user(id) select 1 from dual", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user(id) select 1 from dual", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(0)", - "TableName": "user", - "VindexOffsetFromSelect": { - "costly_map": "[-1]", - "name_user_map": "[-1]", - "user_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Projection", - "Expressions": [ - "INT64(1) as 1" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - ] - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user(id) select 1 from dual", "Instructions": { @@ -5095,43 +3893,7 @@ { "comment": "insert using select with sharding column is autoinc and not present in the insert column query", "query": "insert into user(pattern) SELECT 1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user(pattern) SELECT 1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(1)", - "TableName": "user", - "VindexOffsetFromSelect": { - "costly_map": "[-1]", - "name_user_map": "[-1]", - "user_index": "[1]" - }, - "Inputs": [ - { - "OperatorType": "Projection", - "Expressions": [ - "INT64(1) as 1" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - ] - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user(pattern) SELECT 1", "Instructions": { @@ -5177,41 +3939,7 @@ { "comment": "sharded same keyspace", "query": "insert into user_extra(user_id, col) select col1, col2 from user", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user_extra(user_id, col) select col1, col2 from user", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(2)", - "TableName": "user_extra", - "VindexOffsetFromSelect": { - "user_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2 from `user` where 1 != 1", - "Query": "select col1, col2 from `user` for update", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user_extra" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user_extra(user_id, col) select col1, col2 from user", "Instructions": { @@ -5250,25 +3978,7 @@ { "comment": "unsharded same keyspace", "query": "insert into unsharded(col) select col from unsharded_auto", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded(col) select col from unsharded_auto", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into unsharded(col) select col from unsharded_auto for update", - "TableName": "unsharded" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded(col) select col from unsharded_auto", "Instructions": { @@ -5291,41 +4001,7 @@ { "comment": "sharded different keyspace", "query": "insert into user_extra(user_id, col) select col1, col2 from t1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user_extra(user_id, col) select col1, col2 from t1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(2)", - "TableName": "user_extra", - "VindexOffsetFromSelect": { - "user_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "zlookup_unique", - "Sharded": true - }, - "FieldQuery": "select col1, col2 from t1 where 1 != 1", - "Query": "select col1, col2 from t1 for update", - "Table": "t1" - } - ] - }, - "TablesUsed": [ - "user.user_extra" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user_extra(user_id, col) select col1, col2 from t1", "Instructions": { @@ -5351,54 +4027,20 @@ }, "FieldQuery": "select col1, col2 from t1 where 1 != 1", "Query": "select col1, col2 from t1 lock in share mode", - "Table": "t1" - } - ] - }, - "TablesUsed": [ - "user.user_extra", - "zlookup_unique.t1" - ] - } - }, - { - "comment": "sharded insert table, unsharded select table", - "query": "insert into user_extra(user_id, col) select col1, col2 from unsharded_tab", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user_extra(user_id, col) select col1, col2 from unsharded_tab", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(2)", - "TableName": "user_extra", - "VindexOffsetFromSelect": { - "user_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main_2", - "Sharded": false - }, - "FieldQuery": "select col1, col2 from unsharded_tab where 1 != 1", - "Query": "select col1, col2 from unsharded_tab for update", - "Table": "unsharded_tab" + "Table": "t1" } ] }, "TablesUsed": [ - "user.user_extra" + "user.user_extra", + "zlookup_unique.t1" ] - }, - "gen4-plan": { + } + }, + { + "comment": "sharded insert table, unsharded select table", + "query": "insert into user_extra(user_id, col) select col1, col2 from unsharded_tab", + "plan": { "QueryType": "INSERT", "Original": "insert into user_extra(user_id, col) select col1, col2 from unsharded_tab", "Instructions": { @@ -5437,37 +4079,7 @@ { "comment": "unsharded different keyspace", "query": "insert into unsharded(col) select col from unsharded_tab", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded(col) select col from unsharded_tab", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "TableName": "unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main_2", - "Sharded": false - }, - "FieldQuery": "select col from unsharded_tab where 1 != 1", - "Query": "select col from unsharded_tab for update", - "Table": "unsharded_tab" - } - ] - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded(col) select col from unsharded_tab", "Instructions": { @@ -5502,37 +4114,7 @@ { "comment": "unsharded insert table, sharded select table", "query": "insert into unsharded(col) select col from t1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into unsharded(col) select col from t1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "TableName": "unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "zlookup_unique", - "Sharded": true - }, - "FieldQuery": "select col from t1 where 1 != 1", - "Query": "select col from t1 for update", - "Table": "t1" - } - ] - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into unsharded(col) select col from t1", "Instructions": { @@ -5567,8 +4149,7 @@ { "comment": "unsharded subquery in sharded update, not the same keyspace between outer and inner", "query": "update user set col = (select id from unsharded)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set col = (select id from unsharded)", "Instructions": { @@ -5611,8 +4192,7 @@ { "comment": "sharded subquery in unsharded update, not the same keyspace", "query": "update unsharded set col = (select id from user)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update unsharded set col = (select id from user)", "Instructions": { @@ -5655,8 +4235,7 @@ { "comment": "sharded join unsharded subqueries in unsharded update", "query": "update unsharded set col = (select id from unsharded join user on unsharded.id = user.id)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update unsharded set col = (select id from unsharded join user on unsharded.id = user.id)", "Instructions": { @@ -5725,8 +4304,7 @@ { "comment": "sharded update with sub query where the sources can be merged into a single query", "query": "update user set col = (select count(*) from user_extra where user_extra.user_id = 5) where id = 5", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set col = (select count(*) from user_extra where user_extra.user_id = 5) where id = 5", "Instructions": { @@ -5753,8 +4331,7 @@ { "comment": "merge through correlated subquery", "query": "update user set col = (select count(*) from user_extra where user_extra.user_id = user.id) where id = 5", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set col = (select count(*) from user_extra where user_extra.user_id = user.id) where id = 5", "Instructions": { @@ -5781,8 +4358,7 @@ { "comment": "merge through correlated subquery #2", "query": "update user set col = (select count(*) from user_extra where user_extra.user_id = user.id) where id > 5", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set col = (select count(*) from user_extra where user_extra.user_id = user.id) where id > 5", "Instructions": { @@ -5895,28 +4471,9 @@ } }, { - "comment": "Here V3 populates the TablesUsed incorrectly\n# delete with join from multi table join subquery.", + "comment": "delete with join from multi table join subquery", "query": "delete foo from unsharded as foo join (select id from unsharded a join unsharded_b b on a.user_id = b.user_id) as keepers on foo.id = keepers.id where keepers.id is null and foo.col is not null and foo.col < 1000", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete foo from unsharded as foo join (select id from unsharded a join unsharded_b b on a.user_id = b.user_id) as keepers on foo.id = keepers.id where keepers.id is null and foo.col is not null and foo.col < 1000", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "delete foo from unsharded as foo join (select id from unsharded as a join unsharded_b as b on a.user_id = b.user_id) as keepers on foo.id = keepers.id where keepers.id is null and foo.col is not null and foo.col < 1000", - "Table": "unsharded, unsharded, unsharded_b" - }, - "TablesUsed": [ - "main.unsharded", - "main.unsharded, unsharded_b" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete foo from unsharded as foo join (select id from unsharded a join unsharded_b b on a.user_id = b.user_id) as keepers on foo.id = keepers.id where keepers.id is null and foo.col is not null and foo.col < 1000", "Instructions": { @@ -5939,25 +4496,7 @@ { "comment": "update with routing using multi column vindex", "query": "update user set col = 1 where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update user set col = 1 where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Update", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update `user` set col = 1 where (`name`, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "user" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user set col = 1 where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -5983,28 +4522,7 @@ { "comment": "delete with routing using multi column vindex", "query": "delete from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "DELETE", - "Original": "delete from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "KsidLength": 1, - "KsidVindex": "user_index", - "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where (`name`, col) in (('aa', 'bb'), ('cc', 'dd')) for update", - "Query": "delete from `user` where (`name`, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "user" - }, - "TablesUsed": [ - "user.user" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -6077,25 +4595,7 @@ { "comment": "unsharded update query with comment directive", "query": "update /*vt+ QUERY_TIMEOUT_MS=1 */ unsharded set val = 1", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "update /*vt+ QUERY_TIMEOUT_MS=1 */ unsharded set val = 1", - "Instructions": { - "OperatorType": "Update", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetTabletType": "PRIMARY", - "Query": "update /*vt+ QUERY_TIMEOUT_MS=1 */ unsharded set val = 1", - "Table": "unsharded" - }, - "TablesUsed": [ - "main.unsharded" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update /*vt+ QUERY_TIMEOUT_MS=1 */ unsharded set val = 1", "Instructions": { @@ -6141,46 +4641,7 @@ { "comment": "insert with select using same tables, cannot stream parallel", "query": "insert into music(id, user_id) select id, user_id from music where user_id = 1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into music(id, user_id) select id, user_id from music where user_id = 1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "InputAsNonStreaming": true, - "TableName": "music", - "VindexOffsetFromSelect": { - "music_user_map": "[0]", - "user_index": "[1]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, user_id from music where 1 != 1", - "Query": "select id, user_id from music where user_id = 1 for update", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "user.music" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into music(id, user_id) select id, user_id from music where user_id = 1", "Instructions": { @@ -6277,46 +4738,7 @@ { "comment": "insert + lookup vindex + auto increment on lookup column + select - not provided", "query": "insert into mixed_tbl(shard_key) select foo from user where id = 1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into mixed_tbl(shard_key) select foo from user where id = 1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(1)", - "TableName": "mixed_tbl", - "VindexOffsetFromSelect": { - "lkp_shard_map": "[1]", - "shard_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select foo from `user` where 1 != 1", - "Query": "select foo from `user` where id = 1 for update", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "user.mixed_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into mixed_tbl(shard_key) select foo from user where id = 1", "Instructions": { @@ -6360,46 +4782,7 @@ { "comment": "insert + lookup vindex + auto increment on lookup column + select - provided", "query": "insert into mixed_tbl(shard_key, lkp_key) select foo, bar from user where id = 1", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into mixed_tbl(shard_key, lkp_key) select foo, bar from user where id = 1", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Select", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "AutoIncrement": "select next :n /* INT64 */ values from seq:Offset(1)", - "TableName": "mixed_tbl", - "VindexOffsetFromSelect": { - "lkp_shard_map": "[1]", - "shard_index": "[0]" - }, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select foo, bar from `user` where 1 != 1", - "Query": "select foo, bar from `user` where id = 1 for update", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "user.mixed_tbl" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into mixed_tbl(shard_key, lkp_key) select foo, bar from user where id = 1", "Instructions": { @@ -6441,16 +4824,16 @@ } }, { - "comment": "insert into a vindex not allowed - gen4 produces different error - forcing a v3 plan here will have same output", - "query": "insert /*vt+ planner=v3insert */ into user_index(id) values(1)", - "plan": "VT12001: unsupported: multi-shard or vindex write statement" + "comment": "insert into a vindex not allowed", + "query": "insert into user_index(id) values(1)", + "plan": "VT09014: vindex cannot be modified" }, { - "comment": "insert with select takes shared lock in gen4 and for update in v3, as forcing v3 plan the output will remain same", - "query": "insert /*vt+ planner=v3insert */ into user(id) select id from user", + "comment": "insert with select takes shared lock", + "query": "insert into user(id) select id from user", "plan": { "QueryType": "INSERT", - "Original": "insert /*vt+ planner=v3insert */ into user(id) select id from user", + "Original": "insert into user(id) select id from user", "Instructions": { "OperatorType": "Insert", "Variant": "Select", @@ -6476,7 +4859,7 @@ "Sharded": true }, "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` for update", + "Query": "select id from `user` lock in share mode", "Table": "`user`" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json index 3fecffc3316..d388fb1fbe3 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json @@ -2,22 +2,7 @@ { "comment": "No where clause", "query": "select id from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user", "Instructions": { @@ -39,22 +24,7 @@ { "comment": "Query that always return empty", "query": "select id from user where someColumn = null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where someColumn = null", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where someColumn = null", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where someColumn = null", "Instructions": { @@ -76,22 +46,7 @@ { "comment": "Null Safe Equality Operator is handled correctly", "query": "SELECT id from user where someColumn <=> null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT id from user where someColumn <=> null", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where someColumn <=> null", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT id from user where someColumn <=> null", "Instructions": { @@ -113,26 +68,7 @@ { "comment": "Single table unique vindex route", "query": "select id from user where user.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id = 5", "Instructions": { @@ -158,22 +94,7 @@ { "comment": "Single table unique vindex route, but complex expr", "query": "select id from user where user.id = 5+5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id = 5+5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id = 5 + 5", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id = 5+5", "Instructions": { @@ -199,26 +120,7 @@ { "comment": "Single table multiple unique vindex match", "query": "select id from music where id = 5 and user_id = 4", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id = 5 and user_id = 4", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id = 5 and user_id = 4", - "Table": "music", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id = 5 and user_id = 4", "Instructions": { @@ -244,26 +146,7 @@ { "comment": "Single table multiple non-unique vindex match", "query": "select id from user where costly = 'aa' and name = 'bb'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where costly = 'aa' and name = 'bb'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where costly = 'aa' and `name` = 'bb'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"bb\")" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where costly = 'aa' and name = 'bb'", "Instructions": { @@ -314,26 +197,7 @@ { "comment": "Single table multiple non-unique vindex match for IN clause", "query": "select id from user where costly in ('aa', 'bb') and name in ('aa', 'bb')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where costly in ('aa', 'bb') and name in ('aa', 'bb')", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where costly in ('aa', 'bb') and `name` in ::__vals", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"aa\"), VARCHAR(\"bb\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where costly in ('aa', 'bb') and name in ('aa', 'bb')", "Instructions": { @@ -384,26 +248,7 @@ { "comment": "Composite IN clause", "query": "select id from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (`name`, col) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"aa\"), VARCHAR(\"cc\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (name, col) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -454,26 +299,7 @@ { "comment": "Composite IN clause, swapped columns", "query": "select id from user where (col, name) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (col, name) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (col, `name`) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"bb\"), VARCHAR(\"dd\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (col, name) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -524,26 +350,7 @@ { "comment": "Composite IN clause, choose cost within tuple", "query": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (costly, `name`) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"bb\"), VARCHAR(\"dd\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -594,26 +401,7 @@ { "comment": "Composite IN clause, choose cost within tuple, swapped", "query": "select id from user where (name, costly) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (name, costly) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (`name`, costly) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"aa\"), VARCHAR(\"cc\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (name, costly) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -664,26 +452,7 @@ { "comment": "Composite IN clause, choose cost", "query": "select id from user where (col, costly) in (('aa', 'bb')) and (col, name) in (('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (col, costly) in (('aa', 'bb')) and (col, name) in (('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (col, costly) in (('aa', 'bb')) and (col, `name`) in (('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"dd\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (col, costly) in (('aa', 'bb')) and (col, name) in (('cc', 'dd'))", "Instructions": { @@ -734,26 +503,7 @@ { "comment": "Composite IN clause vs equality", "query": "select id from user where (col, name) in (('aa', 'bb')) and id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (col, name) in (('aa', 'bb')) and id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (col, `name`) in (('aa', 'bb')) and id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (col, name) in (('aa', 'bb')) and id = 5", "Instructions": { @@ -779,26 +529,7 @@ { "comment": "Composite IN: multiple vindex matches", "query": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (costly, `name`) in (('aa', 'bb'), ('cc', 'dd'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"bb\"), VARCHAR(\"dd\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (costly, name) in (('aa', 'bb'), ('cc', 'dd'))", "Instructions": { @@ -849,26 +580,7 @@ { "comment": "Composite IN: tuple inside tuple", "query": "select id from user where ((col1, name), col2) in ((('aa', 'bb'), 'cc'), (('dd', 'ee'), 'ff'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where ((col1, name), col2) in ((('aa', 'bb'), 'cc'), (('dd', 'ee'), 'ff'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where ((col1, `name`), col2) in ((('aa', 'bb'), 'cc'), (('dd', 'ee'), 'ff'))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"bb\"), VARCHAR(\"ee\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where ((col1, name), col2) in ((('aa', 'bb'), 'cc'), (('dd', 'ee'), 'ff'))", "Instructions": { @@ -919,26 +631,7 @@ { "comment": "Composite IN: tuple inside tuple, but no match in tuple", "query": "select id from user where (name, (col1, col2)) in (('aa', ('bb', 'cc')), ('dd', ('ee', 'ff')))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (name, (col1, col2)) in (('aa', ('bb', 'cc')), ('dd', ('ee', 'ff')))", - "Instructions": { - "OperatorType": "Route", - "Variant": "MultiEqual", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (`name`, (col1, col2)) in (('aa', ('bb', 'cc')), ('dd', ('ee', 'ff')))", - "Table": "`user`", - "Values": [ - "(VARCHAR(\"aa\"), VARCHAR(\"dd\"))" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (name, (col1, col2)) in (('aa', ('bb', 'cc')), ('dd', ('ee', 'ff')))", "Instructions": { @@ -989,22 +682,7 @@ { "comment": "Composite IN: tuple inside tuple, mismiatched values", "query": "select id from user where ((col1, name), col2) in (('aa', 'bb', 'cc'), (('dd', 'ee'), 'ff'))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where ((col1, name), col2) in (('aa', 'bb', 'cc'), (('dd', 'ee'), 'ff'))", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where ((col1, `name`), col2) in (('aa', 'bb', 'cc'), (('dd', 'ee'), 'ff'))", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where ((col1, name), col2) in (('aa', 'bb', 'cc'), (('dd', 'ee'), 'ff'))", "Instructions": { @@ -1026,22 +704,7 @@ { "comment": "Composite IN: RHS not tuple", "query": "select id from user where (col1, name) in (select * from music where music.user_id=user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (col1, name) in (select * from music where music.user_id=user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (col1, `name`) in (select * from music where music.user_id = `user`.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (col1, name) in (select * from music where music.user_id=user.id)", "Instructions": { @@ -1064,22 +727,7 @@ { "comment": "Composite IN: RHS has no simple values", "query": "select id from user where (col1, name) in (('aa', 1+1))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (col1, name) in (('aa', 1+1))", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (col1, `name`) in (('aa', 1 + 1))", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (col1, name) in (('aa', 1+1))", "Instructions": { @@ -1130,22 +778,7 @@ { "comment": "IN clause: LHS is neither column nor composite tuple", "query": "select Id from user where 1 in ('aa', 'bb')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select Id from user where 1 in ('aa', 'bb')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select Id from `user` where 1 != 1", - "Query": "select Id from `user` where 1 in ('aa', 'bb')", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select Id from user where 1 in ('aa', 'bb')", "Instructions": { @@ -1167,22 +800,7 @@ { "comment": "Single table complex in clause", "query": "select id from user where name in (col, 'bb')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where name in (col, 'bb')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `name` in (col, 'bb')", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where name in (col, 'bb')", "Instructions": { @@ -1204,26 +822,7 @@ { "comment": "Single table equality route with val arg", "query": "select id from user where name = :a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where name = :a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `name` = :a", - "Table": "`user`", - "Values": [ - ":a" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where name = :a", "Instructions": { @@ -1274,26 +873,7 @@ { "comment": "Single table equality route with unsigned value", "query": "select id from user where name = 18446744073709551615", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where name = 18446744073709551615", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `name` = 18446744073709551615", - "Table": "`user`", - "Values": [ - "UINT64(18446744073709551615)" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where name = 18446744073709551615", "Instructions": { @@ -1344,26 +924,7 @@ { "comment": "Single table in clause list arg", "query": "select id from user where name in ::list", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where name in ::list", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `name` in ::__vals", - "Table": "`user`", - "Values": [ - "::list" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where name in ::list", "Instructions": { @@ -1414,26 +975,7 @@ { "comment": "Multi-table unique vindex constraint", "query": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user.id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "Query": "select user_extra.id from `user` join user_extra on `user`.id = user_extra.user_id where `user`.id = 5", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user.id = 5", "Instructions": { @@ -1460,26 +1002,7 @@ { "comment": "Multi-table unique vindex constraint on right table", "query": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user_extra.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user_extra.user_id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "Query": "select user_extra.id from `user` join user_extra on `user`.id = user_extra.user_id where user_extra.user_id = 5", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.id = user_extra.user_id where user_extra.user_id = 5", "Instructions": { @@ -1560,48 +1083,7 @@ { "comment": "Multi-route unique vindex constraint", "query": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "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 `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 user_extra.id from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5", "Instructions": { @@ -1650,52 +1132,7 @@ { "comment": "Multi-route unique vindex route on both routes", "query": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5 and user_extra.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5 and user_extra.user_id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "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 `user`.col from `user` where `user`.id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra where user_extra.col = :user_col and user_extra.user_id = 5", - "Table": "user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user.id = 5 and user_extra.user_id = 5", "Instructions": { @@ -1722,7 +1159,7 @@ { "comment": "Multi-route with cross-route constraint", "query": "select user_extra.id from user join user_extra on user.col = user_extra.col where user_extra.user_id = user.col", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user_extra.user_id = user.col", "Instructions": { @@ -1753,48 +1190,7 @@ "Sharded": true }, "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra where user_extra.col = :user_col and user_extra.user_id = :user_col", - "Table": "user_extra", - "Values": [ - ":user_col" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where user_extra.user_id = user.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "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 `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra where user_extra.user_id = :user_col and user_extra.col = :user_col", + "Query": "select user_extra.id from user_extra where user_extra.user_id = :user_col and user_extra.col = :user_col", "Table": "user_extra", "Values": [ ":user_col" @@ -1812,44 +1208,7 @@ { "comment": "Multi-route with non-route constraint, should use first route.", "query": "select user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "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 `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 user_extra.id from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra on user.col = user_extra.col where 1 = 1", "Instructions": { @@ -1894,26 +1253,7 @@ { "comment": "Route with multiple route constraints, SelectIN is the best constraint.", "query": "select id from user where user.col = 5 and user.id in (1, 2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.col = 5 and user.id in (1, 2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.col = 5 and `user`.id in ::__vals", - "Table": "`user`", - "Values": [ - "(INT64(1), INT64(2))" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.col = 5 and user.id in (1, 2)", "Instructions": { @@ -1939,26 +1279,7 @@ { "comment": "Route with multiple route constraints and boolean, SelectIN is the best constraint.", "query": "select id from user where user.col = case user.col when 'foo' then true else false end and user.id in (1, 2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.col = case user.col when 'foo' then true else false end and user.id in (1, 2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.col = case `user`.col when 'foo' then true else false end and `user`.id in ::__vals", - "Table": "`user`", - "Values": [ - "(INT64(1), INT64(2))" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.col = case user.col when 'foo' then true else false end and user.id in (1, 2)", "Instructions": { @@ -1984,26 +1305,7 @@ { "comment": "Route with multiple route constraints and boolean, SelectEqual is the best constraint.", "query": "select (id or col) as val from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select (id or col) as val from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id or col as val from `user` where 1 != 1", - "Query": "select id or col as val from `user` where `user`.col = 5 and `user`.id in (1, 2) and `user`.`name` = 'aa'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"aa\")" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select (id or col) as val from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa'", "Instructions": { @@ -2054,26 +1356,7 @@ { "comment": "Route with multiple route constraints, SelectEqual is the best constraint.", "query": "select id from user where user.col = false and user.id in (1, 2) and user.name = 'aa'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.col = false and user.id in (1, 2) and user.name = 'aa'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.col = false and `user`.id in (1, 2) and `user`.`name` = 'aa'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"aa\")" - ], - "Vindex": "name_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.col = false and user.id in (1, 2) and user.name = 'aa'", "Instructions": { @@ -2124,26 +1407,7 @@ { "comment": "Route with multiple route constraints, SelectEqualUnique is the best constraint.", "query": "select id from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa' and user.id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa' and user.id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.col = 5 and `user`.id in (1, 2) and `user`.`name` = 'aa' and `user`.id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.col = 5 and user.id in (1, 2) and user.name = 'aa' and user.id = 1", "Instructions": { @@ -2169,26 +1433,7 @@ { "comment": "Route with multiple route constraints, SelectEqualUnique is the best constraint, order reversed.", "query": "select id from user where user.id = 1 and user.name = 'aa' and user.id in (1, 2) and user.col = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id = 1 and user.name = 'aa' and user.id in (1, 2) and user.col = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id = 1 and `user`.`name` = 'aa' and `user`.id in (1, 2) and `user`.col = 5", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id = 1 and user.name = 'aa' and user.id in (1, 2) and user.col = 5", "Instructions": { @@ -2214,22 +1459,7 @@ { "comment": "Route with OR and AND clause, must parenthesize correctly.", "query": "select id from user where user.id = 1 or user.name = 'aa' and user.id in (1, 2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id = 1 or user.name = 'aa' and user.id in (1, 2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id = 1 or `user`.`name` = 'aa' and `user`.id in (1, 2)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id = 1 or user.name = 'aa' and user.id in (1, 2)", "Instructions": { @@ -2255,44 +1485,7 @@ { "comment": "Unsharded route", "query": "select unsharded.id from user join unsharded where unsharded.id = user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.id from user join unsharded where unsharded.id = user.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.id = :user_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.id from user join unsharded where unsharded.id = user.id", "Instructions": { @@ -2341,26 +1534,7 @@ { "comment": "routing rules: choose the redirected table", "query": "select col from route1 where id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from route1 where id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` as route1 where 1 != 1", - "Query": "select col from `user` as route1 where id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from route1 where id = 1", "Instructions": { @@ -2386,7 +1560,7 @@ { "comment": "subquery", "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col) and u.id in (user_extra.col, 1)", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col) and u.id in (user_extra.col, 1)", "Instructions": { @@ -2417,7 +1591,7 @@ "Sharded": true }, "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id in ::__vals and u.id in (select m2 from `user` where `user`.id = u.id and `user`.col = :user_extra_col)", + "Query": "select u.m from `user` as u where u.id in (select m2 from `user` where `user`.id = u.id and `user`.col = :user_extra_col /* INT16 */) and u.id in ::__vals", "Table": "`user`", "Values": [ "(:user_extra_col, INT64(1))" @@ -2425,11 +1599,19 @@ "Vindex": "user_index" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "correlated subquery merge-able into a route of a join tree", + "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id) and u.id in (user_extra.col, 1)", + "plan": { "QueryType": "SELECT", - "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col) and u.id in (user_extra.col, 1)", + "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id) and u.id in (user_extra.col, 1)", "Instructions": { "OperatorType": "Join", "Variant": "Join", @@ -2458,7 +1640,7 @@ "Sharded": true }, "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id in (select m2 from `user` where `user`.id = u.id and `user`.col = :user_extra_col /* INT16 */) and u.id in ::__vals", + "Query": "select u.m from `user` as u where u.id in (select m2 from `user` where `user`.id = u.id) and u.id in ::__vals", "Table": "`user`", "Values": [ "(:user_extra_col, INT64(1))" @@ -2474,137 +1656,9 @@ } }, { - "comment": "correlated subquery merge-able into a route of a join tree", - "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id) and u.id in (user_extra.col, 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id) and u.id in (user_extra.col, 1)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_extra_col": 0 - }, - "TableName": "user_extra_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id in ::__vals and u.id in (select m2 from `user` where `user`.id = u.id)", - "Table": "`user`", - "Values": [ - "(:user_extra_col, INT64(1))" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id) and u.id in (user_extra.col, 1)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_extra_col": 0 - }, - "TableName": "user_extra_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id in (select m2 from `user` where `user`.id = u.id) and u.id in ::__vals", - "Table": "`user`", - "Values": [ - "(:user_extra_col, INT64(1))" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "ensure subquery reordering gets us a better plan", - "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = 5) and u.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = 5) and u.id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "TableName": "user_extra_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id = 5 and u.id in (select m2 from `user` where `user`.id = 5)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "comment": "ensure subquery reordering gets us a better plan", + "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = 5) and u.id = 5", + "plan": { "QueryType": "SELECT", "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = 5) and u.id = 5", "Instructions": { @@ -2650,48 +1704,7 @@ { "comment": "nested subquery", "query": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col and user.id in (select m3 from user_extra where user_extra.user_id = user.id)) and u.id in (user_extra.col, 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col and user.id in (select m3 from user_extra where user_extra.user_id = user.id)) and u.id in (user_extra.col, 1)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_extra_col": 0 - }, - "TableName": "user_extra_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.m from `user` as u where 1 != 1", - "Query": "select u.m from `user` as u where u.id in ::__vals and u.id in (select m2 from `user` where `user`.id = u.id and `user`.col = :user_extra_col and `user`.id in (select m3 from user_extra where user_extra.user_id = `user`.id))", - "Table": "`user`", - "Values": [ - "(:user_extra_col, INT64(1))" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.m from user_extra join user u where u.id in (select m2 from user where user.id = u.id and user_extra.col = user.col and user.id in (select m3 from user_extra where user_extra.user_id = user.id)) and u.id in (user_extra.col, 1)", "Instructions": { @@ -2740,22 +1753,7 @@ { "comment": "Correlated subquery in where clause", "query": "select id from user where user.col in (select user_extra.col from user_extra where user_extra.user_id = user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.col in (select user_extra.col from user_extra where user_extra.user_id = user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.col in (select user_extra.col from user_extra where user_extra.user_id = `user`.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.col in (select user_extra.col from user_extra where user_extra.user_id = user.id)", "Instructions": { @@ -2778,26 +1776,7 @@ { "comment": "outer and inner subquery route by same int val", "query": "select id from user where id = 5 and user.col in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 5 and user.col in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5 and `user`.col in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 5 and user.col in (select user_extra.col from user_extra where user_extra.user_id = 5)", "Instructions": { @@ -2824,26 +1803,7 @@ { "comment": "outer and inner subquery route by same str val", "query": "select id from user where id = 'aa' and user.col in (select user_extra.col from user_extra where user_extra.user_id = 'aa')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 'aa' and user.col in (select user_extra.col from user_extra where user_extra.user_id = 'aa')", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 'aa' and `user`.col in (select user_extra.col from user_extra where user_extra.user_id = 'aa')", - "Table": "`user`", - "Values": [ - "VARCHAR(\"aa\")" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 'aa' and user.col in (select user_extra.col from user_extra where user_extra.user_id = 'aa')", "Instructions": { @@ -2870,26 +1830,7 @@ { "comment": "outer and inner subquery route by same val arg", "query": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = :a and `user`.col in (select user_extra.col from user_extra where user_extra.user_id = :a)", - "Table": "`user`", - "Values": [ - ":a" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a)", "Instructions": { @@ -2916,28 +1857,12 @@ { "comment": "unresolved symbol in inner subquery.", "query": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a and foo.id = 1)", - "v3-plan": "VT03019: column foo.id not found", - "gen4-plan": "column 'foo.id' not found" + "plan": "column 'foo.id' not found" }, { "comment": "outer and inner subquery route by same outermost column value", "query": "select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select user_extra.col from user_extra where user_extra.user_id = uu.id))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select user_extra.col from user_extra where user_extra.user_id = uu.id))", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id2 from `user` as uu where 1 != 1", - "Query": "select id2 from `user` as uu where id in (select id from `user` where id = uu.id and `user`.col in (select user_extra.col from user_extra where user_extra.user_id = uu.id))", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select user_extra.col from user_extra where user_extra.user_id = uu.id))", "Instructions": { @@ -2960,7 +1885,7 @@ { "comment": "cross-shard subquery in IN clause.\n# Note the improved Underlying plan as SelectIN.", "query": "select id from user where id in (select col from user)", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id in (select col from user)", "Instructions": { @@ -2998,94 +1923,18 @@ "Vindex": "user_index" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "cross-shard subquery in NOT IN clause.", + "query": "select id from user where id not in (select col from user)", + "plan": { "QueryType": "SELECT", - "Original": "select id from user where id in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where :__sq_has_values1 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "cross-shard subquery in NOT IN clause.", - "query": "select id from user where id not in (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id not in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutNotIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where :__sq_has_values1 = 0 or id not in ::__sq1", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id not in (select col from user)", + "Original": "select id from user where id not in (select col from user)", "Instructions": { "OperatorType": "Subquery", "Variant": "PulloutNotIn", @@ -3126,49 +1975,7 @@ { "comment": "cross-shard subquery in EXISTS clause.", "query": "select id from user where exists (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where exists (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where :__sq_has_values1", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where exists (select col from user)", "Instructions": { @@ -3216,47 +2023,7 @@ { "comment": "cross-shard subquery as expression", "query": "select id from user where id = (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = :__sq1", - "Table": "`user`", - "Values": [ - ":__sq1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = (select col from user)", "Instructions": { @@ -3303,68 +2070,7 @@ { "comment": "multi-level pullout", "query": "select id1 from user where id = (select id2 from user where id2 in (select id3 from user))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id1 from user where id = (select id2 from user where id2 in (select id3 from user))", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values2", - "__sq2" - ], - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id3 from `user` where 1 != 1", - "Query": "select id3 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id2 from `user` where 1 != 1", - "Query": "select id2 from `user` where :__sq_has_values1 = 1 and id2 in ::__sq1", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id1 from `user` where 1 != 1", - "Query": "select id1 from `user` where id = :__sq2", - "Table": "`user`", - "Values": [ - ":__sq2" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id1 from user where id = (select id2 from user where id2 in (select id3 from user))", "Instructions": { @@ -3432,22 +2138,7 @@ { "comment": "routing rules subquery merge", "query": "select col from user where id = (select id from route1 where route1.id = user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = (select id from route1 where route1.id = user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = (select id from `user` as route1 where route1.id = `user`.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = (select id from route1 where route1.id = user.id)", "Instructions": { @@ -3469,7 +2160,7 @@ { "comment": "routing rules subquery pullout", "query": "select col from user where id = (select id from route2)", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = (select id from route2)", "Instructions": { @@ -3507,78 +2198,19 @@ "Vindex": "user_index" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "main.unsharded", + "user.user" + ] + } + }, + { + "comment": "Case preservation test", + "query": "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5", + "plan": { "QueryType": "SELECT", - "Original": "select col from user where id = (select id from route2)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id from unsharded as route2 where 1 != 1", - "Query": "select id from unsharded as route2", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = :__sq1", - "Table": "`user`", - "Values": [ - ":__sq1" - ], - "Vindex": "user_index" - } - ] - }, - "TablesUsed": [ - "main.unsharded", - "user.user" - ] - } - }, - { - "comment": "Case preservation test", - "query": "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.Id from `user` join user_extra on `user`.iD = user_extra.User_Id where 1 != 1", - "Query": "select user_extra.Id from `user` join user_extra on `user`.iD = user_extra.User_Id where `user`.Id = 5", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5", + "Original": "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5", "Instructions": { "OperatorType": "Route", "Variant": "EqualUnique", @@ -3603,22 +2235,7 @@ { "comment": "database() call in where clause.", "query": "select id from user where database()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where database()", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where database()", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where database()", "Instructions": { @@ -3640,22 +2257,7 @@ { "comment": "Select with equals null", "query": "select id from music where id = null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id = null", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id = null", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id = null", "Instructions": { @@ -3677,22 +2279,7 @@ { "comment": "SELECT with IS NULL", "query": "select id from music where id is null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id is null", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id is null", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id is null", "Instructions": { @@ -3714,22 +2301,7 @@ { "comment": "SELECT with IS NOT NULL", "query": "select id from music where id is not null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id is not null", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id is not null", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id is not null", "Instructions": { @@ -3751,22 +2323,7 @@ { "comment": "Single table with unique vindex match and null match", "query": "select id from music where user_id = 4 and id = null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where user_id = 4 and id = null", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where user_id = 4 and id = null", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where user_id = 4 and id = null", "Instructions": { @@ -3788,22 +2345,7 @@ { "comment": "Single table with unique vindex match and IN (null)", "query": "select id from music where user_id = 4 and id IN (null)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where user_id = 4 and id IN (null)", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where user_id = 4 and id in (null)", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where user_id = 4 and id IN (null)", "Instructions": { @@ -3825,26 +2367,7 @@ { "comment": "Single table with unique vindex match and IN (null, 1, 2)", "query": "select id from music where user_id = 4 and id IN (null, 1, 2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where user_id = 4 and id IN (null, 1, 2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where user_id = 4 and id in (null, 1, 2)", - "Table": "music", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where user_id = 4 and id IN (null, 1, 2)", "Instructions": { @@ -3870,22 +2393,7 @@ { "comment": "Single table with unique vindex match and NOT IN (null, 1, 2)", "query": "select id from music where user_id = 4 and id NOT IN (null, 1, 2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where user_id = 4 and id NOT IN (null, 1, 2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where user_id = 4 and id not in (null, 1, 2)", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where user_id = 4 and id NOT IN (null, 1, 2)", "Instructions": { @@ -3907,22 +2415,7 @@ { "comment": "Single table with unique vindex match and NOT IN (null, 1, 2) predicates inverted", "query": "select id from music where id NOT IN (null, 1, 2) and user_id = 4", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id NOT IN (null, 1, 2) and user_id = 4", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id not in (null, 1, 2) and user_id = 4", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id NOT IN (null, 1, 2) and user_id = 4", "Instructions": { @@ -3944,76 +2437,7 @@ { "comment": "pullout sq after pullout sq", "query": "select id from user where not id in (select user_extra.col from user_extra where user_extra.user_id = 42) and id in (select user_extra.col from user_extra where user_extra.user_id = 411)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where not id in (select user_extra.col from user_extra where user_extra.user_id = 42) and id in (select user_extra.col from user_extra where user_extra.user_id = 411)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutNotIn", - "PulloutVars": [ - "__sq_has_values2", - "__sq2" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra where user_extra.user_id = 42", - "Table": "user_extra", - "Values": [ - "INT64(42)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra where user_extra.user_id = 411", - "Table": "user_extra", - "Values": [ - "INT64(411)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where :__sq_has_values1 = 1 and id in ::__vals and (:__sq_has_values2 = 0 or id not in ::__sq2)", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where not id in (select user_extra.col from user_extra where user_extra.user_id = 42) and id in (select user_extra.col from user_extra where user_extra.user_id = 411)", "Instructions": { @@ -4090,26 +2514,7 @@ { "comment": "solving LIKE query with a CFC prefix vindex", "query": "select c2 from cfc_vindex_col where c1 like 'A%'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select c2 from cfc_vindex_col where c1 like 'A%'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select c2 from cfc_vindex_col where 1 != 1", - "Query": "select c2 from cfc_vindex_col where c1 like 'A%'", - "Table": "cfc_vindex_col", - "Values": [ - "VARCHAR(\"A%\")" - ], - "Vindex": "cfc" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select c2 from cfc_vindex_col where c1 like 'A%'", "Instructions": { @@ -4135,26 +2540,7 @@ { "comment": "select * from samecolvin where col = :col", "query": "select * from samecolvin where col = :col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from samecolvin where col = :col", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from samecolvin where 1 != 1", - "Query": "select col from samecolvin where col = :col", - "Table": "samecolvin", - "Values": [ - ":col" - ], - "Vindex": "vindex1" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from samecolvin where col = :col", "Instructions": { @@ -4180,22 +2566,7 @@ { "comment": "non unique predicate on vindex", "query": "select id from user where user.id > 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id > 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id > 5", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id > 5", "Instructions": { @@ -4204,98 +2575,43 @@ "Keyspace": { "Name": "user", "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id > 5", - "Table": "`user`" - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "select from unsharded keyspace with uncorrelated subquery which should be merged to a single route", - "query": "select unsharded.id from unsharded where unsharded.name in (select name from unsharded_a)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.id from unsharded where unsharded.name in (select name from unsharded_a)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.`name` in (select `name` from unsharded_a)", - "Table": "unsharded" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.id from unsharded where unsharded.name in (select name from unsharded_a)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.`name` in (select `name` from unsharded_a)", - "Table": "unsharded, unsharded_a" - }, - "TablesUsed": [ - "main.unsharded", - "main.unsharded_a" - ] - } - }, - { - "comment": "in subquery the id will be scoped to local table as there is no qualifier associated with it.", - "query": "select id from user where id in (select col from unsharded where col = id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id in (select col from unsharded where col = id)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col from unsharded where 1 != 1", - "Query": "select col from unsharded where col = id", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where :__sq_has_values1 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + }, + "FieldQuery": "select id from `user` where 1 != 1", + "Query": "select id from `user` where `user`.id > 5", + "Table": "`user`" + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "select from unsharded keyspace with uncorrelated subquery which should be merged to a single route", + "query": "select unsharded.id from unsharded where unsharded.name in (select name from unsharded_a)", + "plan": { + "QueryType": "SELECT", + "Original": "select unsharded.id from unsharded where unsharded.name in (select name from unsharded_a)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select unsharded.id from unsharded where 1 != 1", + "Query": "select unsharded.id from unsharded where unsharded.`name` in (select `name` from unsharded_a)", + "Table": "unsharded, unsharded_a" + }, + "TablesUsed": [ + "main.unsharded", + "main.unsharded_a" + ] + } + }, + { + "comment": "in subquery the id will be scoped to local table as there is no qualifier associated with it.", + "query": "select id from user where id in (select col from unsharded where col = id)", + "plan": { "QueryType": "SELECT", "Original": "select id from user where id in (select col from unsharded where col = id)", "Instructions": { @@ -4348,22 +2664,7 @@ { "comment": "correlated subquery with same keyspace", "query": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id from `user` as u where 1 != 1", - "Query": "select u.id from `user` as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", "Instructions": { @@ -4405,22 +2706,7 @@ { "comment": "SelectReference with uncorrelated subqueries", "query": "select ref.col from ref where ref.col in (select ref.col from ref)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ref.col from ref where ref.col in (select ref.col from ref)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ref.col from ref where 1 != 1", - "Query": "select ref.col from ref where ref.col in (select ref.col from ref)", - "Table": "ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ref.col from ref where ref.col in (select ref.col from ref)", "Instructions": { @@ -4442,26 +2728,7 @@ { "comment": "SelectEqualUnique with uncorrelated subqueries", "query": "select u1.col from user as u1 where u1.id = 5 and u1.name in (select u2.name from user u2 where u2.id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.col from user as u1 where u1.id = 5 and u1.name in (select u2.name from user u2 where u2.id = 5)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.col from `user` as u1 where u1.id = 5 and u1.`name` in (select u2.`name` from `user` as u2 where u2.id = 5)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.col from user as u1 where u1.id = 5 and u1.name in (select u2.name from user u2 where u2.id = 5)", "Instructions": { @@ -4487,26 +2754,7 @@ { "comment": "SelectEqualUnique with EXISTS uncorrelated subquery", "query": "select u1.col from user as u1 where u1.id = 5 and exists (select u2.name from user u2 where u2.id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.col from user as u1 where u1.id = 5 and exists (select u2.name from user u2 where u2.id = 5)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.col from `user` as u1 where u1.id = 5 and exists (select 1 from `user` as u2 where u2.id = 5 limit 1)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.col from user as u1 where u1.id = 5 and exists (select u2.name from user u2 where u2.id = 5)", "Instructions": { @@ -4532,26 +2780,7 @@ { "comment": "SelectEqualUnique with NOT EXISTS uncorrelated subquery", "query": "select u1.col from user as u1 where u1.id = 5 and not exists (select u2.name from user u2 where u2.id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.col from user as u1 where u1.id = 5 and not exists (select u2.name from user u2 where u2.id = 5)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.col from `user` as u1 where u1.id = 5 and not exists (select 1 from `user` as u2 where u2.id = 5 limit 1)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.col from user as u1 where u1.id = 5 and not exists (select u2.name from user u2 where u2.id = 5)", "Instructions": { @@ -4577,47 +2806,7 @@ { "comment": "SelectScatter with NOT EXISTS uncorrelated subquery", "query": "select u1.col from user as u1 where not exists (select u2.name from user u2 where u2.id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.col from user as u1 where not exists (select u2.name from user u2 where u2.id = 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2 where u2.id = 5 limit 1", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.col from `user` as u1 where not :__sq_has_values1", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.col from user as u1 where not exists (select u2.name from user u2 where u2.id = 5)", "Instructions": { @@ -4663,51 +2852,7 @@ { "comment": "The outer and first inner are SelectEqualUnique with same Vindex value, the second inner has different Vindex value", "query": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 5) and id in (select user_extra.col from user_extra where user_extra.user_id = 4)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 5) and id in (select user_extra.col from user_extra where user_extra.user_id = 4)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra where user_extra.user_id = 4", - "Table": "user_extra", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5 and :__sq_has_values1 = 1 and id in ::__sq1 and id not in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 5) and id in (select user_extra.col from user_extra where user_extra.user_id = 4)", "Instructions": { @@ -4759,51 +2904,7 @@ { "comment": "The outer and second inner are SelectEqualUnique with same Vindex value, the first inner has different Vindex value", "query": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 4) and id in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 4) and id in (select user_extra.col from user_extra where user_extra.user_id = 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutNotIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.col from user_extra where user_extra.user_id = 4", - "Table": "user_extra", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "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 (:__sq_has_values1 = 0 or id not in ::__sq1)", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 5 and not id in (select user_extra.col from user_extra where user_extra.user_id = 4) and id in (select user_extra.col from user_extra where user_extra.user_id = 5)", "Instructions": { @@ -4853,24 +2954,9 @@ } }, { - "comment": "two correlated subqueries that can be merge in a single route", - "query": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id) and u.col2 in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id) and u.col2 in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id from `user` as u where 1 != 1", - "Query": "select u.id from `user` as u where u.col2 in (select ue.user_id from user_extra as ue where ue.user_id = u.id) and u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "comment": "two correlated subqueries that can be merge in a single route", + "query": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id) and u.col2 in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", + "plan": { "QueryType": "SELECT", "Original": "select u.id from user as u where u.col in (select ue.user_id from user_extra as ue where ue.user_id = u.id) and u.col2 in (select ue.user_id from user_extra as ue where ue.user_id = u.id)", "Instructions": { @@ -4893,22 +2979,7 @@ { "comment": "transitive closures for the win", "query": "select id from user where user.id = user.col and user.col = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where user.id = user.col and user.col = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where `user`.id = `user`.col and `user`.col = 5", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where user.id = user.col and user.col = 5", "Instructions": { @@ -4934,44 +3005,7 @@ { "comment": "join with transitive closures", "query": "select id from user, user_extra where user.id = user_extra.col and user_extra.col = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user, user_extra where user.id = user_extra.col and user_extra.col = user_extra.user_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.col = :user_id and user_extra.col = user_extra.user_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user, user_extra where user.id = user_extra.col and user_extra.col = user_extra.user_id", "Instructions": { @@ -4994,44 +3028,7 @@ { "comment": "not supported transitive closures with equality inside of an OR", "query": "select id from user, user_extra where user.id = user_extra.col and (user_extra.col = user_extra.user_id or user_extra.col2 = user_extra.name)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user, user_extra where user.id = user_extra.col and (user_extra.col = user_extra.user_id or user_extra.col2 = user_extra.name)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.col = :user_id and (user_extra.col = user_extra.user_id or user_extra.col2 = user_extra.`name`)", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user, user_extra where user.id = user_extra.col and (user_extra.col = user_extra.user_id or user_extra.col2 = user_extra.name)", "Instructions": { @@ -5080,22 +3077,7 @@ { "comment": "routing rules subquery merge with alias", "query": "select col from user where id = (select id from route1 as a where a.id = user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = (select id from route1 as a where a.id = user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = (select id from `user` as a where a.id = `user`.id)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = (select id from route1 as a where a.id = user.id)", "Instructions": { @@ -5226,48 +3208,7 @@ { "comment": "subquery on other table", "query": "select distinct user.id, user.col from user where user.col in (select id from music where col2 = 'a')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct user.id, user.col from user where user.col in (select id from music where col2 = 'a')", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where col2 = 'a'", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.col from `user` where 1 != 1", - "Query": "select `user`.id, `user`.col from `user` where :__sq_has_values1 = 1 and `user`.col in ::__sq1", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct user.id, user.col from user where user.col in (select id from music where col2 = 'a')", "Instructions": { @@ -5320,26 +3261,7 @@ { "comment": "should use colb_colc_map as first column of the vindex is present in predicate", "query": "select * from multicolvin where column_b = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicolvin where column_b = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "colb_colc_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1", "Instructions": { @@ -5365,26 +3287,7 @@ { "comment": "should only use first column of the vindex colb_colc_map", "query": "select * from multicolvin where column_b = 1 and column_c = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicolvin where column_b = 1 and column_c = 2", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1 and column_c = 2", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "colb_colc_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1 and column_c = 2", "Instructions": { @@ -5410,26 +3313,7 @@ { "comment": "uses vindex colb_colc_map", "query": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", - "Table": "multicolvin", - "Values": [ - "INT64(1)" - ], - "Vindex": "colb_colc_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicolvin where column_b = 1 and column_c = 2 and column_a = 3", "Instructions": { @@ -5453,28 +3337,9 @@ } }, { - "comment": "v3 takes cola_map, gen4 takes colb_colc_map, may be based on map key ordering", + "comment": "colb_colc_map vindex for routing", "query": "select * from multicolvin where column_a = 3 and column_b = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicolvin where column_a = 3 and column_b = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicolvin where 1 != 1", - "Query": "select * from multicolvin where column_a = 3 and column_b = 1", - "Table": "multicolvin", - "Values": [ - "INT64(3)" - ], - "Vindex": "cola_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicolvin where column_a = 3 and column_b = 1", "Instructions": { @@ -5498,24 +3363,9 @@ } }, { - "comment": "multi column vindex produces Equal plan in gen4 and Scatter in v3", + "comment": "multi column vindex produces Equal plan", "query": "select * from multicol_tbl where cola = 1 and colb = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where cola = 1 and colb = 2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where cola = 1 and colb = 2", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where cola = 1 and colb = 2", "Instructions": { @@ -5542,22 +3392,7 @@ { "comment": "multi column vindex with different order places the vindex keys in correct order", "query": "select * from multicol_tbl where colb = 2 and cola = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb = 2 and cola = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb = 2 and cola = 1", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb = 2 and cola = 1", "Instructions": { @@ -5582,24 +3417,9 @@ } }, { - "comment": "multi column vindex produces IN plan in gen4 and Scatter in v3", + "comment": "multi column vindex produces IN plan", "query": "select * from multicol_tbl where cola in (1,2) and colb in (3,4)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where cola in (1,2) and colb in (3,4)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where cola in (1, 2) and colb in (3, 4)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where cola in (1,2) and colb in (3,4)", "Instructions": { @@ -5622,26 +3442,11 @@ "user.multicol_tbl" ] } - }, - { - "comment": "multi column vindex with different order places the vindex keys in correct order in IN plan in gen4", - "query": "select * from multicol_tbl where colb in (3,4) and cola in (1,2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb in (3,4) and cola in (1,2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb in (3, 4) and cola in (1, 2)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + }, + { + "comment": "multi column vindex with different order places the vindex keys in correct order in IN plan", + "query": "select * from multicol_tbl where colb in (3,4) and cola in (1,2)", + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb in (3,4) and cola in (1,2)", "Instructions": { @@ -5668,22 +3473,7 @@ { "comment": "multi column vindex with different order with one IN predicate and one equality", "query": "select * from multicol_tbl where colb = 1 and cola in (3,4)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb = 1 and cola in (3,4)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb = 1 and cola in (3, 4)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb = 1 and cola in (3,4)", "Instructions": { @@ -5710,22 +3500,7 @@ { "comment": "deconstruct tuple equality comparisons", "query": "select id from user where (id, name) = (34, 'apa')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (id, name) = (34, 'apa')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where (id, `name`) = (34, 'apa')", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (id, name) = (34, 'apa')", "Instructions": { @@ -5751,22 +3526,7 @@ { "comment": "multi column vindex with both IN predicate and equality predicate", "query": "select * from multicol_tbl where cola in (1,10) and cola = 4 and colb in (5,6) and colb = 7", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where cola in (1,10) and cola = 4 and colb in (5,6) and colb = 7", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where cola in (1, 10) and cola = 4 and colb in (5, 6) and colb = 7", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where cola in (1,10) and cola = 4 and colb in (5,6) and colb = 7", "Instructions": { @@ -5793,22 +3553,7 @@ { "comment": "multi column vindex with one column with equal followed by IN predicate, ordering matters for now", "query": "select * from multicol_tbl where colb = 4 and colb in (1,10) and cola in (5,6)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb = 4 and colb in (1,10) and cola in (5,6)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb = 4 and colb in (1, 10) and cola in (5, 6)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb = 4 and colb in (1,10) and cola in (5,6)", "Instructions": { @@ -5835,22 +3580,7 @@ { "comment": "multi column vindex with one column with IN followed by equal predicate, ordering matters for now", "query": "select * from multicol_tbl where colb in (1,10) and colb = 4 and cola in (5,6)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb in (1,10) and colb = 4 and cola in (5,6)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb in (1, 10) and colb = 4 and cola in (5, 6)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb in (1,10) and colb = 4 and cola in (5,6)", "Instructions": { @@ -5877,22 +3607,7 @@ { "comment": "multi column vindex with better plan selection", "query": "select * from multicol_tbl where colb in (1,2) and cola IN (3,4) and cola = 5 and colb = 6", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where colb in (1,2) and cola IN (3,4) and cola = 5 and colb = 6", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where colb in (1, 2) and cola in (3, 4) and cola = 5 and colb = 6", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where colb in (1,2) and cola IN (3,4) and cola = 5 and colb = 6", "Instructions": { @@ -5919,22 +3634,7 @@ { "comment": "multi column vindex as tuple", "query": "select * from multicol_tbl where (cola,colb) in ((1,2),(3,4))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where (cola,colb) in ((1,2),(3,4))", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where (cola, colb) in ((1, 2), (3, 4))", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where (cola,colb) in ((1,2),(3,4))", "Instructions": { @@ -5961,22 +3661,7 @@ { "comment": "multi column vindex, partial vindex with SelectEqual", "query": "select * from multicol_tbl where cola = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where cola = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where cola = 1", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where cola = 1", "Instructions": { @@ -6002,22 +3687,7 @@ { "comment": "multi column vindex, partial vindex with SelectEqual over full vindex with SelectIN", "query": "select * from multicol_tbl where cola = 1 and colb in (2,3)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from multicol_tbl where cola = 1 and colb in (2,3)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from multicol_tbl where 1 != 1", - "Query": "select * from multicol_tbl where cola = 1 and colb in (2, 3)", - "Table": "multicol_tbl" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from multicol_tbl where cola = 1 and colb in (2,3)", "Instructions": { @@ -6042,7 +3712,7 @@ } }, { - "comment": "left join with where clause - should be handled by gen4 but still isn't", + "comment": "left join with where clause", "query": "select 0 from unsharded_a left join unsharded_b on unsharded_a.col = unsharded_b.col where coalesce(unsharded_b.col, 4) = 5", "plan": { "QueryType": "SELECT", @@ -6225,22 +3895,7 @@ { "comment": "optimize ORs to IN route op codes #1", "query": "select col from user where id = 1 or id = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = 1 or id = 2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = 1 or id = 2", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = 1 or id = 2", "Instructions": { @@ -6266,22 +3921,7 @@ { "comment": "optimize ORs to IN route op codes #2", "query": "select col from user where id = 1 or id = 2 or id = 3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = 1 or id = 2 or id = 3", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = 1 or id = 2 or id = 3", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = 1 or id = 2 or id = 3", "Instructions": { @@ -6307,22 +3947,7 @@ { "comment": "optimize ORs to IN route op codes #3", "query": "select col from user where (id = 1 or id = 2) or (id = 3 or id = 4)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where (id = 1 or id = 2) or (id = 3 or id = 4)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = 1 or id = 2 or (id = 3 or id = 4)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where (id = 1 or id = 2) or (id = 3 or id = 4)", "Instructions": { @@ -6348,26 +3973,7 @@ { "comment": "Don't pick a vindex for an IS NULL predicate if it's a lookup vindex", "query": "select id from music where id is null and user_id in (1,2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from music where id is null and user_id in (1,2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music where id is null and user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(1), INT64(2))" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from music where id is null and user_id in (1,2)", "Instructions": { @@ -6393,22 +3999,7 @@ { "comment": "Self referencing columns in HAVING should work", "query": "select a+2 as a from user having a = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a+2 as a from user having a = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a + 2 as a from `user` where 1 != 1", - "Query": "select a + 2 as a from `user` having a = 42", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a+2 as a from user having a = 42", "Instructions": { @@ -6430,22 +4021,7 @@ { "comment": "HAVING predicates that use table columns are safe to rewrite if we can move them to the WHERE clause", "query": "select user.col + 2 as a from user having a = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col + 2 as a from user having a = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col + 2 as a from `user` where 1 != 1", - "Query": "select `user`.col + 2 as a from `user` having a = 42", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col + 2 as a from user having a = 42", "Instructions": { @@ -6467,22 +4043,7 @@ { "comment": "HAVING predicates that use table columns should not get rewritten on unsharded keyspaces", "query": "select col + 2 as a from unsharded having a = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col + 2 as a from unsharded having a = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col + 2 as a from unsharded where 1 != 1", - "Query": "select col + 2 as a from unsharded having a = 42", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col + 2 as a from unsharded having a = 42", "Instructions": { @@ -6504,22 +4065,7 @@ { "comment": "Single table unique vindex route hiding behind a silly OR", "query": "select id from user where (id = 5 and name ='apa') or (id = 5 and foo = 'bar')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (id = 5 and name ='apa') or (id = 5 and foo = 'bar')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5 and `name` = 'apa' or id = 5 and foo = 'bar'", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (id = 5 and name ='apa') or (id = 5 and foo = 'bar')", "Instructions": { @@ -6545,22 +4091,7 @@ { "comment": "Single table IN vindex route hiding behind OR", "query": "select id from user where (id = 5 and name ='foo') or (id = 12 and name = 'bar')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where (id = 5 and name ='foo') or (id = 12 and name = 'bar')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "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'", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where (id = 5 and name ='foo') or (id = 12 and name = 'bar')", "Instructions": { @@ -6586,8 +4117,7 @@ { "comment": "Like clause evaluated on the vtgate", "query": "select a.textcol1 from user a join user b where a.textcol1 = b.textcol2 group by a.textcol1 having repeat(a.textcol1,sum(a.id)) like \"And%res\"", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.textcol1 from user a join user b where a.textcol1 = b.textcol2 group by a.textcol1 having repeat(a.textcol1,sum(a.id)) like \"And%res\"", "Instructions": { @@ -6663,22 +4193,7 @@ { "comment": "two predicates that mean the same thing", "query": "select textcol1 from user where foo = 42 and user.foo = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select textcol1 from user where foo = 42 and user.foo = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select textcol1 from `user` where 1 != 1", - "Query": "select textcol1 from `user` where foo = 42 and `user`.foo = 42", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select textcol1 from user where foo = 42 and user.foo = 42", "Instructions": { @@ -6700,8 +4215,7 @@ { "comment": "must merge subquery with the right side of the join", "query": "select 1 from unsharded join user u1 where exists (select 1 from unsharded u2 where u1.bar = u2.baz)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from unsharded join user u1 where exists (select 1 from unsharded u2 where u1.bar = u2.baz)", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index ecec6a803ea..533521881be 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -2,22 +2,7 @@ { "comment": "Single table sharded scatter", "query": "select col from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user", "Instructions": { @@ -39,22 +24,7 @@ { "comment": "Single table unsharded", "query": "select col from unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from unsharded", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col from unsharded where 1 != 1", - "Query": "select col from unsharded", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from unsharded", "Instructions": { @@ -76,22 +46,7 @@ { "comment": "Select from sequence", "query": "select next 2 values from seq", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select next 2 values from seq", - "Instructions": { - "OperatorType": "Route", - "Variant": "Next", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select next 2 values from seq where 1 != 1", - "Query": "select next 2 values from seq", - "Table": "seq" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select next 2 values from seq", "Instructions": { @@ -113,154 +68,32 @@ { "comment": "select next from non-sequence table", "query": "select next value from user", - "v3-plan": "VT03018: NEXT used on a non-sequence table", - "gen4-plan": "NEXT used on a non-sequence table `user`" + "plan": "NEXT used on a non-sequence table `user`" }, { "comment": "select next in derived table", "query": "select 1 from (select next value from seq) t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from (select next value from seq) t", - "Instructions": { - "OperatorType": "Route", - "Variant": "Next", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from (select next 1 values from seq where 1 != 1) as t where 1 != 1", - "Query": "select 1 from (select next 1 values from seq) as t", - "Table": "seq" - } - }, - "gen4-plan": "Incorrect usage/placement of 'NEXT'" + "plan": "Incorrect usage/placement of 'NEXT'" }, { "comment": "select next in derived table", "query": "select * from (select next value from seq) t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select next value from seq) t", - "Instructions": { - "OperatorType": "Route", - "Variant": "Next", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from (select next 1 values from seq where 1 != 1) as t where 1 != 1", - "Query": "select * from (select next 1 values from seq) as t", - "Table": "seq" - } - }, - "gen4-plan": "Incorrect usage/placement of 'NEXT'" + "plan": "Incorrect usage/placement of 'NEXT'" }, { "comment": "select next in subquery", "query": "select 1 from user where id in (select next value from seq)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user where id in (select next value from seq)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Next", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select next 1 values from seq where 1 != 1", - "Query": "select next 1 values from seq", - "Table": "seq" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where :__sq_has_values1 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": "Incorrect usage/placement of 'NEXT'" + "plan": "Incorrect usage/placement of 'NEXT'" }, { "comment": "select next in projection", "query": "select (select next value from seq) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select (select next value from seq) from user", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Next", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select next 1 values from seq where 1 != 1", - "Query": "select next 1 values from seq", - "Table": "seq" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__sq1 from `user` where 1 != 1", - "Query": "select :__sq1 from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": "Incorrect usage/placement of 'NEXT'" + "plan": "Incorrect usage/placement of 'NEXT'" }, { "comment": "Select from reference", "query": "select * from ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from ref", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from ref where 1 != 1", - "Query": "select * from ref", - "Table": "ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from ref", "Instructions": { @@ -282,22 +115,7 @@ { "comment": "Multi-table unsharded", "query": "select m1.col from unsharded as m1 join unsharded as m2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select m1.col from unsharded as m1 join unsharded as m2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select m1.col from unsharded as m1 join unsharded as m2 where 1 != 1", - "Query": "select m1.col from unsharded as m1 join unsharded as m2", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select m1.col from unsharded as m1 join unsharded as m2", "Instructions": { @@ -319,41 +137,7 @@ { "comment": "Multi-table, multi-chunk", "query": "select music.col from user join music", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select music.col from user join music", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col from music where 1 != 1", - "Query": "select music.col from music", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select music.col from user join music", "Instructions": { @@ -395,22 +179,7 @@ { "comment": "routing rules where table name matches, and there's no alias.", "query": "select * from second_user.user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from second_user.user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from second_user.user", "Instructions": { @@ -432,22 +201,7 @@ { "comment": "routing rules where table name matches, and there's an alias.", "query": "select * from second_user.user as a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from second_user.user as a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` as a where 1 != 1", - "Query": "select * from `user` as a", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from second_user.user as a", "Instructions": { @@ -469,22 +223,7 @@ { "comment": "routing rules where table name does not match, and there's no alias.", "query": "select * from route1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from route1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` as route1 where 1 != 1", - "Query": "select * from `user` as route1", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from route1", "Instructions": { @@ -506,22 +245,7 @@ { "comment": "routing rules where table name does not match, and there's an alias.", "query": "select * from route1 as a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from route1 as a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` as a where 1 != 1", - "Query": "select * from `user` as a", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from route1 as a", "Instructions": { @@ -543,22 +267,7 @@ { "comment": "routing rules with primary targeting", "query": "select * from primary_redirect", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from primary_redirect", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` as primary_redirect where 1 != 1", - "Query": "select * from `user` as primary_redirect", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from primary_redirect", "Instructions": { @@ -590,22 +299,7 @@ { "comment": "select second_user.foo.col from second_user.foo join user on second_user.foo.id = user.id where second_user.foo.col = 42", "query": "select second_user.foo.col from second_user.foo join user on second_user.foo.id = user.id where second_user.foo.col = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select second_user.foo.col from second_user.foo join user on second_user.foo.id = user.id where second_user.foo.col = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select foo.col from `user` as foo join `user` on foo.id = `user`.id where 1 != 1", - "Query": "select foo.col from `user` as foo join `user` on foo.id = `user`.id where foo.col = 42", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select second_user.foo.col from second_user.foo join user on second_user.foo.id = user.id where second_user.foo.col = 42", "Instructions": { @@ -627,48 +321,7 @@ { "comment": "select user.music.foo from user.music join user on user.music.id = user.id where user.music.col = 42", "query": "select user.music.foo from user.music join user on user.music.id = user.id where user.music.col = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.music.foo from user.music join user on user.music.id = user.id where user.music.col = 42", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "music_id": 1 - }, - "TableName": "music_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.foo, music.id from music where 1 != 1", - "Query": "select music.foo, music.id from music where music.col = 42", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where `user`.id = :music_id", - "Table": "`user`", - "Values": [ - ":music_id" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.music.foo from user.music join user on user.music.id = user.id where user.music.col = 42", "Instructions": { @@ -717,41 +370,7 @@ { "comment": "',' join", "query": "select music.col from user, music", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select music.col from user, music", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col from music where 1 != 1", - "Query": "select music.col from music", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select music.col from user, music", "Instructions": { @@ -793,22 +412,7 @@ { "comment": "',' join unsharded", "query": "select u1.a, u2.a from unsharded u1, unsharded u2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.a, u2.a from unsharded u1, unsharded u2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select u1.a, u2.a from unsharded as u1, unsharded as u2 where 1 != 1", - "Query": "select u1.a, u2.a from unsharded as u1, unsharded as u2", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.a, u2.a from unsharded u1, unsharded u2", "Instructions": { @@ -830,22 +434,7 @@ { "comment": "',' 3-way join unsharded", "query": "select u1.a, u2.a from unsharded u1, unsharded u2, unsharded u3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.a, u2.a from unsharded u1, unsharded u2, unsharded u3", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select u1.a, u2.a from unsharded as u1, unsharded as u2, unsharded as u3 where 1 != 1", - "Query": "select u1.a, u2.a from unsharded as u1, unsharded as u2, unsharded as u3", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.a, u2.a from unsharded u1, unsharded u2, unsharded u3", "Instructions": { @@ -1110,24 +699,9 @@ } }, { - "comment": "Straight-join (Gen4 ignores the straight_join hint)", + "comment": "Straight-join (ignores the straight_join hint)", "query": "select m1.col from unsharded as m1 straight_join unsharded as m2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select m1.col from unsharded as m1 straight_join unsharded as m2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select m1.col from unsharded as m1 straight_join unsharded as m2 where 1 != 1", - "Query": "select m1.col from unsharded as m1 straight_join unsharded as m2", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select m1.col from unsharded as m1 straight_join unsharded as m2", "Instructions": { @@ -1149,60 +723,7 @@ { "comment": "Three-way join", "query": "select user.col from user join unsharded as m1 join unsharded as m2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join unsharded as m1 join unsharded as m2", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_unsharded_unsharded", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded as m1 where 1 != 1", - "Query": "select 1 from unsharded as m1", - "Table": "unsharded" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded as m2 where 1 != 1", - "Query": "select 1 from unsharded as m2", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join unsharded as m1 join unsharded as m2", "Instructions": { @@ -1244,41 +765,7 @@ { "comment": "Parenthesized, single chunk", "query": "select user.col from user join (unsharded as m1 join unsharded as m2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join (unsharded as m1 join unsharded as m2)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from (unsharded as m1 join unsharded as m2) where 1 != 1", - "Query": "select 1 from (unsharded as m1 join unsharded as m2)", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join (unsharded as m1 join unsharded as m2)", "Instructions": { @@ -1320,59 +807,7 @@ { "comment": "Parenthesized, multi-chunk", "query": "select user.col from user join (user as u1 join unsharded)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join (user as u1 join unsharded)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u1 where 1 != 1", - "Query": "select 1 from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded where 1 != 1", - "Query": "select 1 from unsharded", - "Table": "unsharded" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join (user as u1 join unsharded)", "Instructions": { @@ -1433,22 +868,7 @@ { "comment": "index hints, make sure they are not stripped.", "query": "select user.col from user use index(a)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user use index(a)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` use index (a) where 1 != 1", - "Query": "select `user`.col from `user` use index (a)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user use index(a)", "Instructions": { @@ -1470,22 +890,7 @@ { "comment": "multiple index hints, make sure they are not stripped.", "query": "select user.col from user use index(a) use index for group by (b)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user use index(a) use index for group by (b)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` use index (a) use index for group by (b) where 1 != 1", - "Query": "select `user`.col from `user` use index (a) use index for group by (b)", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user use index(a) use index for group by (b)", "Instructions": { @@ -1507,7 +912,7 @@ { "comment": "mergeable sharded join on unique vindex", "query": "select user.col from user join user_extra on user.id = user_extra.user_id", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.id = user_extra.user_id", "Instructions": { @@ -1517,23 +922,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select `user`.col from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on `user`.id = user_extra.user_id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user`, user_extra where 1 != 1", - "Query": "select `user`.col from `user`, user_extra where `user`.id = user_extra.user_id", + "FieldQuery": "select `user`.col from `user`, user_extra where 1 != 1", + "Query": "select `user`.col from `user`, user_extra where `user`.id = user_extra.user_id", "Table": "`user`, user_extra" }, "TablesUsed": [ @@ -1545,22 +935,7 @@ { "comment": "mergeable sharded join on unique vindex (parenthesized ON clause)", "query": "select user.col from user join user_extra on (user.id = user_extra.user_id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on (user.id = user_extra.user_id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on `user`.id = user_extra.user_id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on (user.id = user_extra.user_id)", "Instructions": { @@ -1583,22 +958,7 @@ { "comment": "mergeable sharded join on unique vindex, with a stray condition", "query": "select user.col from user join user_extra on user.col between 1 and 2 and user.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.col between 1 and 2 and user.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join user_extra on `user`.col between 1 and 2 and `user`.id = user_extra.user_id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on `user`.col between 1 and 2 and `user`.id = user_extra.user_id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.col between 1 and 2 and user.id = user_extra.user_id", "Instructions": { @@ -1621,22 +981,7 @@ { "comment": "mergeable sharded join on unique vindex, swapped operands", "query": "select user.col from user join user_extra on user_extra.user_id = user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user_extra.user_id = user.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join user_extra on user_extra.user_id = `user`.id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on user_extra.user_id = `user`.id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user_extra.user_id = user.id", "Instructions": { @@ -1659,26 +1004,7 @@ { "comment": "mergeable sharded join on unique vindex, and condition", "query": "select user.col from user join user_extra on user.id = 5 and user.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.id = 5 and user.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join user_extra on `user`.id = 5 and `user`.id = user_extra.user_id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on `user`.id = 5 and `user`.id = user_extra.user_id", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.id = 5 and user.id = user_extra.user_id", "Instructions": { @@ -1705,44 +1031,7 @@ { "comment": "sharded join on unique vindex, inequality", "query": "select user.col from user join user_extra on user.id < user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.id < user_extra.user_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col, `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where :user_id < user_extra.user_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.id < user_extra.user_id", "Instructions": { @@ -1787,45 +1076,7 @@ { "comment": "sharded join, non-col reference RHS", "query": "select user.col from user join user_extra on user.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.id = 5", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `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 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.id = 5", "Instructions": { @@ -1871,45 +1122,7 @@ { "comment": "sharded join, non-col reference LHS", "query": "select user.col from user join user_extra on 5 = user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on 5 = user.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `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 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on 5 = user.id", "Instructions": { @@ -1955,44 +1168,7 @@ { "comment": "sharded join, non-vindex col", "query": "select user.col from user join user_extra on user.id = user_extra.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.id = user_extra.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col, `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.col = :user_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra on user.id = user_extra.col", "Instructions": { @@ -2041,48 +1217,7 @@ { "comment": "sharded join, non-unique vindex", "query": "select user.col from user_extra join user on user_extra.user_id = user.name", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user_extra join user on user_extra.user_id = user.name", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_extra_user_id": 0 - }, - "TableName": "user_extra_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.user_id from user_extra where 1 != 1", - "Query": "select user_extra.user_id from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user` where `user`.`name` = :user_extra_user_id", - "Table": "`user`", - "Values": [ - ":user_extra_user_id" - ], - "Vindex": "name_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user_extra join user on user_extra.user_id = user.name", "Instructions": { @@ -2131,22 +1266,7 @@ { "comment": "join with reference table", "query": "select user.col from user join ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join ref", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join ref where 1 != 1", - "Query": "select `user`.col from `user` join ref", - "Table": "`user`, ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join ref", "Instructions": { @@ -2169,22 +1289,7 @@ { "comment": "reference table self-join", "query": "select r1.col from ref r1 join ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select r1.col from ref r1 join ref", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select r1.col from ref as r1 join ref where 1 != 1", - "Query": "select r1.col from ref as r1 join ref", - "Table": "ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select r1.col from ref r1 join ref", "Instructions": { @@ -2206,7 +1311,7 @@ { "comment": "reference table can merge with other opcodes left to right.", "query": "select ref.col from ref join user", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ref.col from ref join user", "Instructions": { @@ -2216,23 +1321,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select ref.col from ref join `user` where 1 != 1", - "Query": "select ref.col from ref join `user`", - "Table": "`user`, ref" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select ref.col from ref join user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ref.col from ref, `user` where 1 != 1", - "Query": "select ref.col from ref, `user`", + "FieldQuery": "select ref.col from ref, `user` where 1 != 1", + "Query": "select ref.col from ref, `user`", "Table": "`user`, ref" }, "TablesUsed": [ @@ -2244,26 +1334,7 @@ { "comment": "reference table can merge with other opcodes left to right and vindex value is in the plan.\n# This tests that route.Merge also copies the condition to the LHS.", "query": "select ref.col from ref join (select aa from user where user.id=1) user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ref.col from ref join (select aa from user where user.id=1) user", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ref.col from ref join (select aa from `user` where 1 != 1) as `user` where 1 != 1", - "Query": "select ref.col from ref join (select aa from `user` where `user`.id = 1) as `user`", - "Table": "`user`, ref", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ref.col from ref join (select aa from user where user.id=1) user", "Instructions": { @@ -2290,41 +1361,7 @@ { "comment": "routing rules for join, unsharded route wins if we can't find a merged route", "query": "select route2.col from route2 join user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select route2.col from route2 join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select route2.col from unsharded as route2 where 1 != 1", - "Query": "select route2.col from unsharded as route2", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select route2.col from route2 join user_extra", "Instructions": { @@ -2366,26 +1403,7 @@ { "comment": "derived table", "query": "select id from (select id, col from user where id = 5) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select id, col from user where id = 5) as t", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from (select id, col from `user` where 1 != 1) as t where 1 != 1", - "Query": "select id from (select id, col from `user` where id = 5) as t", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select id, col from user where id = 5) as t", "Instructions": { @@ -2411,26 +1429,7 @@ { "comment": "derived table with join", "query": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from (select id from `user` where 1 != 1) as t join user_extra on t.id = user_extra.user_id where 1 != 1", - "Query": "select t.id from (select id from `user` where id = 5) as t join user_extra on t.id = user_extra.user_id", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.user_id", "Instructions": { @@ -2457,26 +1456,7 @@ { "comment": "derived table with join, and aliased references", "query": "select t.id from (select user.id from user where user.id = 5) as t join user_extra on t.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from (select user.id from user where user.id = 5) as t join user_extra on t.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from (select `user`.id from `user` where 1 != 1) as t join user_extra on t.id = user_extra.user_id where 1 != 1", - "Query": "select t.id from (select `user`.id from `user` where `user`.id = 5) as t join user_extra on t.id = user_extra.user_id", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from (select user.id from user where user.id = 5) as t join user_extra on t.id = user_extra.user_id", "Instructions": { @@ -2503,28 +1483,12 @@ { "comment": "derived table with join, duplicate columns", "query": "select t.id from (select user.id, id from user where user.id = 5) as t join user_extra on t.id = user_extra.user_id", - "v3-plan": "VT12001: unsupported: duplicate column aliases: id", - "gen4-plan": "Duplicate column name 'id'" + "plan": "Duplicate column name 'id'" }, { "comment": "derived table in RHS of join", "query": "select t.id from user_extra join (select id from user where id = 5) as t on t.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from user_extra join (select id from user where id = 5) as t on t.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from user_extra join (select id from `user` where 1 != 1) as t on t.id = user_extra.user_id where 1 != 1", - "Query": "select t.id from user_extra join (select id from `user` where id = 5) as t on t.id = user_extra.user_id", - "Table": "user_extra, `user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from user_extra join (select id from user where id = 5) as t on t.id = user_extra.user_id", "Instructions": { @@ -2551,48 +1515,7 @@ { "comment": "derived table in FROM with cross-shard join", "query": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "t_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from (select id from `user` where 1 != 1) as t where 1 != 1", - "Query": "select t.id from (select id from `user` where id = 5) as t", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.col = :t_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from (select id from user where id = 5) as t join user_extra on t.id = user_extra.col", "Instructions": { @@ -2641,26 +1564,7 @@ { "comment": "routing rules for derived table", "query": "select id from (select id, col from route1 where id = 5) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select id, col from route1 where id = 5) as t", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from (select id, col from `user` as route1 where 1 != 1) as t where 1 != 1", - "Query": "select id from (select id, col from `user` as route1 where id = 5) as t", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select id, col from route1 where id = 5) as t", "Instructions": { @@ -2686,46 +1590,12 @@ { "comment": "derived table missing columns", "query": "select t.id from (select id from user) as t join user_extra on t.id = user_extra.user_id where t.col = 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from (select id from user) as t join user_extra on t.id = user_extra.user_id where t.col = 42", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from (select id from `user` where 1 != 1) as t join user_extra on t.id = user_extra.user_id where 1 != 1", - "Query": "select t.id from (select id from `user`) as t join user_extra on t.id = user_extra.user_id where t.col = 42", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": "column 't.col' not found" + "plan": "column 't.col' not found" }, { "comment": "routing rules for derived table where the constraint is in the outer query", "query": "select id from (select id, col from route1) as t where id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select id, col from route1) as t where id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from (select id, col from `user` as route1 where 1 != 1) as t where 1 != 1", - "Query": "select id from (select id, col from `user` as route1) as t where id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select id, col from route1) as t where id = 5", "Instructions": { @@ -2751,42 +1621,12 @@ { "comment": "routing rules for derived table where the constraint is in the outer query", "query": "select id from (select id+col as foo from route1) as t where foo = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select id+col as foo from route1) as t where foo = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from (select id + col as foo from `user` as route1 where 1 != 1) as t where 1 != 1", - "Query": "select id from (select id + col as foo from `user` as route1) as t where foo = 5", - "Table": "`user`" - } - }, - "gen4-plan": "column 'id' not found in table 't'" + "plan": "column 'id' not found in table 't'" }, { "comment": "push predicate on joined derived tables", "query": "select t.id from (select id, textcol1 as baz from route1) as t join (select id, textcol1+textcol1 as baz from user) as s ON t.id = s.id WHERE t.baz = '3' AND s.baz = '3'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id from (select id, textcol1 as baz from route1) as t join (select id, textcol1+textcol1 as baz from user) as s ON t.id = s.id WHERE t.baz = '3' AND s.baz = '3'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id from (select id, textcol1 as baz from `user` as route1 where 1 != 1) as t join (select id, textcol1 + textcol1 as baz from `user` where 1 != 1) as s on t.id = s.id where 1 != 1", - "Query": "select t.id from (select id, textcol1 as baz from `user` as route1) as t join (select id, textcol1 + textcol1 as baz from `user`) as s on t.id = s.id where t.baz = '3' and s.baz = '3'", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from (select id, textcol1 as baz from route1) as t join (select id, textcol1+textcol1 as baz from user) as s ON t.id = s.id WHERE t.baz = '3' AND s.baz = '3'", "Instructions": { @@ -2808,22 +1648,7 @@ { "comment": "recursive derived table predicate push down", "query": "select bar from (select foo+4 as bar from (select colA+colB as foo from user) as u) as t where bar = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select bar from (select foo+4 as bar from (select colA+colB as foo from user) as u) as t where bar = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select bar from (select foo + 4 as bar from (select colA + colB as foo from `user` where 1 != 1) as u where 1 != 1) as t where 1 != 1", - "Query": "select bar from (select foo + 4 as bar from (select colA + colB as foo from `user`) as u) as t where bar = 5", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select bar from (select foo+4 as bar from (select colA+colB as foo from user) as u) as t where bar = 5", "Instructions": { @@ -2845,26 +1670,7 @@ { "comment": "recursive derived table lookups", "query": "select id from (select id from (select id from user) as u) as t where id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select id from (select id from user) as u) as t where id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from (select id from (select id from `user` where 1 != 1) as u where 1 != 1) as t where 1 != 1", - "Query": "select id from (select id from (select id from `user`) as u) as t where id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select id from (select id from user) as u) as t where id = 5", "Instructions": { @@ -2890,7 +1696,7 @@ { "comment": "merge derived tables with single-shard routes", "query": "select u.col, e.col from (select col from user where id = 5) as u join (select col from user_extra where user_id = 5) as e", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.col, e.col from (select col from user where id = 5) as u join (select col from user_extra where user_id = 5) as e", "Instructions": { @@ -2900,27 +1706,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select u.col, e.col from (select col from `user` where 1 != 1) as u join (select col from user_extra where 1 != 1) as e where 1 != 1", - "Query": "select u.col, e.col from (select col from `user` where id = 5) as u join (select col from user_extra where user_id = 5) as e", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select u.col, e.col from (select col from user where id = 5) as u join (select col from user_extra where user_id = 5) as e", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.col, e.col from (select col from `user` where 1 != 1) as u, (select col from user_extra where 1 != 1) as e where 1 != 1", - "Query": "select u.col, e.col from (select col from `user` where id = 5) as u, (select col from user_extra where user_id = 5) as e", + "FieldQuery": "select u.col, e.col from (select col from `user` where 1 != 1) as u, (select col from user_extra where 1 != 1) as e where 1 != 1", + "Query": "select u.col, e.col from (select col from `user` where id = 5) as u, (select col from user_extra where user_id = 5) as e", "Table": "`user`, user_extra", "Values": [ "INT64(5)" @@ -2936,41 +1723,7 @@ { "comment": "join of information_schema with normal table", "query": "select unsharded.foo from information_schema.CHARACTER_SETS join unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.foo from information_schema.CHARACTER_SETS join unsharded", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "TableName": "information_schema.CHARACTER_SETS_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from information_schema.CHARACTER_SETS where 1 != 1", - "Query": "select 1 from information_schema.CHARACTER_SETS", - "Table": "information_schema.CHARACTER_SETS" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.foo from unsharded where 1 != 1", - "Query": "select unsharded.foo from unsharded", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.foo from information_schema.CHARACTER_SETS join unsharded", "Instructions": { @@ -3011,41 +1764,7 @@ { "comment": "join of normal table with information_schema", "query": "select unsharded.foo from unsharded join information_schema.CHARACTER_SETS", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.foo from unsharded join information_schema.CHARACTER_SETS", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_information_schema.CHARACTER_SETS", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.foo from unsharded where 1 != 1", - "Query": "select unsharded.foo from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from information_schema.CHARACTER_SETS where 1 != 1", - "Query": "select 1 from information_schema.CHARACTER_SETS", - "Table": "information_schema.CHARACTER_SETS" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.foo from unsharded join information_schema.CHARACTER_SETS", "Instructions": { @@ -3086,73 +1805,7 @@ { "comment": "wire-up on join with cross-shard derived table", "query": "select t.col1 from (select user.id, user.col1 from user join user_extra) as t join unsharded on unsharded.col1 = t.col1 and unsharded.id = t.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.col1 from (select user.id, user.col1 from user join user_extra) as t join unsharded on unsharded.col1 = t.col1 and unsharded.id = t.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "t_col1": 0, - "t_id": 1 - }, - "TableName": "`user`_user_extra_unsharded", - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 1, - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.col1 from `user` where 1 != 1", - "Query": "select `user`.id, `user`.col1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded where 1 != 1", - "Query": "select 1 from unsharded where unsharded.col1 = :t_col1 and unsharded.id = :t_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.col1 from (select user.id, user.col1 from user join user_extra) as t join unsharded on unsharded.col1 = t.col1 and unsharded.id = t.id", "Instructions": { @@ -3218,52 +1871,7 @@ { "comment": "wire-up on within cross-shard derived table", "query": "select t.id from (select user.id, user.col1 from user join user_extra on user_extra.col = user.col) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 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": "L:0,L:1", - "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 `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 1 from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id from (select user.id, user.col1 from user join user_extra on user_extra.col = user.col) as t", "Instructions": { @@ -3308,68 +1916,7 @@ { "comment": "Join with cross-shard derived table on rhs", "query": "select t.col1 from unsharded_a ua join (select user.id, user.col1 from user join user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.col1 from unsharded_a ua join (select user.id, user.col1 from user join user_extra) as t", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "TableName": "unsharded_a_`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_a as ua where 1 != 1", - "Query": "select 1 from unsharded_a as ua", - "Table": "unsharded_a" - }, - { - "OperatorType": "SimpleProjection", - "Columns": [ - 1 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.col1 from `user` where 1 != 1", - "Query": "select `user`.id, `user`.col1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.col1 from unsharded_a ua join (select user.id, user.col1 from user join user_extra) as t", "Instructions": { @@ -3431,8 +1978,7 @@ { "comment": "Join with cross-shard derived table on rhs - push down join predicate to derived table", "query": "select t.col1 from unsharded_a ua join (select user.id, user.col1 from user join user_extra) as t on t.id = ua.id", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.col1 from unsharded_a ua join (select user.id, user.col1 from user join user_extra) as t on t.id = ua.id", "Instructions": { @@ -3501,14 +2047,13 @@ { "comment": "subquery in ON clause, single route", "query": "select unsharded_a.col from unsharded_a join unsharded_b on (select col from user)", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded_a.col from unsharded_a join unsharded_b on (select col from user)", "Instructions": { "OperatorType": "Subquery", "Variant": "PulloutValue", "PulloutVars": [ - "__sq_has_values1", "__sq1" ], "Inputs": [ @@ -3530,16 +2075,25 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select unsharded_a.col from unsharded_a join unsharded_b on :__sq1 where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a join unsharded_b on :__sq1", + "FieldQuery": "select unsharded_a.col from unsharded_a, unsharded_b where 1 != 1", + "Query": "select unsharded_a.col from unsharded_a, unsharded_b where :__sq1", "Table": "unsharded_a, unsharded_b" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "main.unsharded_a", + "main.unsharded_b", + "user.user" + ] + } + }, + { + "comment": "subquery in ON clause as sub-expression", + "query": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col+(select col from user)", + "plan": { "QueryType": "SELECT", - "Original": "select unsharded_a.col from unsharded_a join unsharded_b on (select col from user)", + "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col+(select col from user)", "Instructions": { "OperatorType": "Subquery", "Variant": "PulloutValue", @@ -3566,7 +2120,7 @@ "Sharded": false }, "FieldQuery": "select unsharded_a.col from unsharded_a, unsharded_b where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a, unsharded_b where :__sq1", + "Query": "select unsharded_a.col from unsharded_a, unsharded_b where unsharded_a.col + :__sq1", "Table": "unsharded_a, unsharded_b" } ] @@ -3579,14 +2133,14 @@ } }, { - "comment": "subquery in ON clause as sub-expression", - "query": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col+(select col from user)", - "v3-plan": { + "comment": "IN subquery in ON clause, single route", + "query": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col in (select col from user)", + "plan": { "QueryType": "SELECT", - "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col+(select col from user)", + "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col in (select col from user)", "Instructions": { "OperatorType": "Subquery", - "Variant": "PulloutValue", + "Variant": "PulloutIn", "PulloutVars": [ "__sq_has_values1", "__sq1" @@ -3610,124 +2164,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col + :__sq1 where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col + :__sq1", - "Table": "unsharded_a, unsharded_b" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col+(select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded_a.col from unsharded_a, unsharded_b where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a, unsharded_b where unsharded_a.col + :__sq1", - "Table": "unsharded_a, unsharded_b" - } - ] - }, - "TablesUsed": [ - "main.unsharded_a", - "main.unsharded_b", - "user.user" - ] - } - }, - { - "comment": "IN subquery in ON clause, single route", - "query": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col in (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded_a.col from unsharded_a join unsharded_b on :__sq_has_values1 = 1 and unsharded_a.col in ::__sq1 where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a join unsharded_b on :__sq_has_values1 = 1 and unsharded_a.col in ::__sq1", - "Table": "unsharded_a, unsharded_b" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select unsharded_a.col from unsharded_a join unsharded_b on unsharded_a.col in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded_a.col from unsharded_a, unsharded_b where 1 != 1", - "Query": "select unsharded_a.col from unsharded_a, unsharded_b where :__sq_has_values1 = 1 and unsharded_a.col in ::__sq1", + "FieldQuery": "select unsharded_a.col from unsharded_a, unsharded_b where 1 != 1", + "Query": "select unsharded_a.col from unsharded_a, unsharded_b where :__sq_has_values1 = 1 and unsharded_a.col in ::__sq1", "Table": "unsharded_a, unsharded_b" } ] @@ -3742,62 +2180,7 @@ { "comment": "subquery in ON clause, with join primitives", "query": "select unsharded.col from unsharded join user on user.col in (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.col from unsharded join user on user.col in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.col from unsharded where 1 != 1", - "Query": "select unsharded.col from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where :__sq_has_values1 = 1 and `user`.col in ::__sq1", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.col from unsharded join user on user.col in (select col from user)", "Instructions": { @@ -3923,81 +2306,7 @@ { "comment": "subquery in ON clause, with join primitives, and join on top\n# The subquery is not pulled all the way out.", "query": "select unsharded.col from unsharded join user on user.col in (select col from user) join unsharded_a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.col from unsharded join user on user.col in (select col from user) join unsharded_a", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_`user`_unsharded_a", - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.col from unsharded where 1 != 1", - "Query": "select unsharded.col from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where :__sq_has_values1 = 1 and `user`.col in ::__sq1", - "Table": "`user`" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_a where 1 != 1", - "Query": "select 1 from unsharded_a", - "Table": "unsharded_a" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.col from unsharded join user on user.col in (select col from user) join unsharded_a", "Instructions": { @@ -4061,44 +2370,7 @@ { "comment": "keyspace-qualified queries", "query": "select user.user.col1, main.unsharded.col1 from user.user join main.unsharded where main.unsharded.col2 = user.user.col2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.user.col1, main.unsharded.col1 from user.user join main.unsharded where main.unsharded.col2 = user.user.col2", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "user_col2": 1 - }, - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1, `user`.col2 from `user` where 1 != 1", - "Query": "select `user`.col1, `user`.col2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.col1 from unsharded where 1 != 1", - "Query": "select unsharded.col1 from unsharded where unsharded.col2 = :user_col2", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.user.col1, main.unsharded.col1 from user.user join main.unsharded where main.unsharded.col2 = user.user.col2", "Instructions": { @@ -4143,22 +2415,7 @@ { "comment": "implicit table reference for unsharded keyspace", "query": "select main.foo.col from main.foo", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select main.foo.col from main.foo", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select foo.col from foo where 1 != 1", - "Query": "select foo.col from foo", - "Table": "foo" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select main.foo.col from main.foo", "Instructions": { @@ -4173,95 +2430,37 @@ "Table": "foo" }, "TablesUsed": [ - "main.foo" - ] - } - }, - { - "comment": "col refs should be case-insensitive", - "query": "select user.col from user join user_extra on user.ID = user_extra.User_Id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.ID = user_extra.User_Id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join user_extra on `user`.ID = user_extra.User_Id where 1 != 1", - "Query": "select `user`.col from `user` join user_extra on `user`.ID = user_extra.User_Id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra on user.ID = user_extra.User_Id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user`, user_extra where 1 != 1", - "Query": "select `user`.col from `user`, user_extra where `user`.ID = user_extra.User_Id", - "Table": "`user`, user_extra" - }, - "TablesUsed": [ - "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "derived table with join primitive (FROM)", - "query": "select id, t.id from (select user.id from user join user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, t.id from (select user.id from user join user_extra) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0, - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "main.foo" + ] + } + }, + { + "comment": "col refs should be case-insensitive", + "query": "select user.col from user join user_extra on user.ID = user_extra.User_Id", + "plan": { + "QueryType": "SELECT", + "Original": "select user.col from user join user_extra on user.ID = user_extra.User_Id", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col from `user`, user_extra where 1 != 1", + "Query": "select `user`.col from `user`, user_extra where `user`.ID = user_extra.User_Id", + "Table": "`user`, user_extra" + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "derived table with join primitive (FROM)", + "query": "select id, t.id from (select user.id from user join user_extra) as t", + "plan": { "QueryType": "SELECT", "Original": "select id, t.id from (select user.id from user join user_extra) as t", "Instructions": { @@ -4303,22 +2502,7 @@ { "comment": "database call in ON clause.\n# The on clause is weird because the substitution must even for root expressions.", "query": "select u1.a from unsharded u1 join unsharded u2 on database()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.a from unsharded u1 join unsharded u2 on database()", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select u1.a from unsharded as u1 join unsharded as u2 on database() where 1 != 1", - "Query": "select u1.a from unsharded as u1 join unsharded as u2 on database()", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.a from unsharded u1 join unsharded u2 on database()", "Instructions": { @@ -4340,22 +2524,7 @@ { "comment": "last_insert_id for dual", "query": "select last_insert_id()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select last_insert_id()", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - ":__lastInsertId as last_insert_id()" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select last_insert_id()", "Instructions": { @@ -4377,22 +2546,7 @@ { "comment": "last_insert_id for sharded keyspace", "query": "select last_insert_id() from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select last_insert_id() from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__lastInsertId as `last_insert_id()` from `user` where 1 != 1", - "Query": "select :__lastInsertId as `last_insert_id()` from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select last_insert_id() from user", "Instructions": { @@ -4414,22 +2568,7 @@ { "comment": "last_insert_id for unsharded route", "query": "select last_insert_id() from main.unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select last_insert_id() from main.unsharded", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select :__lastInsertId as `last_insert_id()` from unsharded where 1 != 1", - "Query": "select :__lastInsertId as `last_insert_id()` from unsharded", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select last_insert_id() from main.unsharded", "Instructions": { @@ -4451,48 +2590,7 @@ { "comment": "join with bindvariables", "query": "SELECT `user`.`id` FROM `user` INNER JOIN `user_extra` ON `user`.`id` = `user_extra`.`assembly_id` WHERE `user_extra`.`user_id` = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT `user`.`id` FROM `user` INNER JOIN `user_extra` ON `user`.`id` = `user_extra`.`assembly_id` WHERE `user_extra`.`user_id` = 2", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.assembly_id = :user_id and user_extra.user_id = 2", - "Table": "user_extra", - "Values": [ - "INT64(2)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT `user`.`id` FROM `user` INNER JOIN `user_extra` ON `user`.`id` = `user_extra`.`assembly_id` WHERE `user_extra`.`user_id` = 2", "Instructions": { @@ -4545,8 +2643,7 @@ { "comment": "verify ',' vs JOIN precedence", "query": "select u1.a from unsharded u1, unsharded u2 join unsharded u3 on u1.a = u2.a", - "v3-plan": "VT03019: column u1.a not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.a from unsharded u1, unsharded u2 join unsharded u3 on u1.a = u2.a", "Instructions": { @@ -4573,8 +2670,7 @@ { "comment": "table names should be case-sensitive", "query": "select unsharded.id from unsharded where Unsharded.val = 1", - "v3-plan": "VT03019: column Unsharded.val not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select unsharded.id from unsharded where Unsharded.val = 1", "Instructions": { @@ -4626,22 +2722,7 @@ { "comment": "query with parens is planned correctly", "query": "select m1.col from (unsharded as m1, unsharded as m2)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select m1.col from (unsharded as m1, unsharded as m2)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select m1.col from (unsharded as m1, unsharded as m2) where 1 != 1", - "Query": "select m1.col from (unsharded as m1, unsharded as m2)", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select m1.col from (unsharded as m1, unsharded as m2)", "Instructions": { @@ -4661,72 +2742,9 @@ } }, { - "comment": "gen4 - optimise plan by merging user_extra and music first, and then querying for user info", + "comment": "optimise plan by merging user_extra and music first, and then querying for user info", "query": "select 1 from user u join user_extra ue on ue.id = u.id join music m on m.user_id = ue.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user u join user_extra ue on ue.id = u.id join music m on m.user_id = ue.user_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "ue_user_id": 1 - }, - "TableName": "`user`_user_extra_music", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "u_id": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1, u.id from `user` as u where 1 != 1", - "Query": "select 1, u.id from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ue.user_id from user_extra as ue where 1 != 1", - "Query": "select ue.user_id from user_extra as ue where ue.id = :u_id", - "Table": "user_extra" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music as m where 1 != 1", - "Query": "select 1 from music as m where m.user_id = :ue_user_id", - "Table": "music", - "Values": [ - ":ue_user_id" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user u join user_extra ue on ue.id = u.id join music m on m.user_id = ue.user_id", "Instructions": { @@ -4776,44 +2794,7 @@ { "comment": "join column selected as alias", "query": "SELECT u.id as uid, ue.id as ueid FROM user u join user_extra ue where u.id = ue.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT u.id as uid, ue.id as ueid FROM user u join user_extra ue where u.id = ue.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "u_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id as uid from `user` as u where 1 != 1", - "Query": "select u.id as uid from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select ue.id as ueid from user_extra as ue where 1 != 1", - "Query": "select ue.id as ueid from user_extra as ue where ue.id = :u_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT u.id as uid, ue.id as ueid FROM user u join user_extra ue where u.id = ue.id", "Instructions": { @@ -4862,37 +2843,7 @@ { "comment": "alias on column from derived table. TODO: to support alias in SimpleProjection engine primitive.", "query": "select a as k from (select count(*) as a from user) t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a as k from (select count(*) as a from user) t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) as a from `user` where 1 != 1", - "Query": "select count(*) as a from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a as k from (select count(*) as a from user) t", "Instructions": { @@ -4921,22 +2872,7 @@ { "comment": "select star from derived table on expandable and unsharded table", "query": "select u.* from (select * from unsharded) u", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.* from (select * from unsharded) u", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select u.* from (select * from unsharded where 1 != 1) as u where 1 != 1", - "Query": "select u.* from (select * from unsharded) as u", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.* from (select * from unsharded) u", "Instructions": { @@ -4958,8 +2894,7 @@ { "comment": "filtering on a cross-shard derived table", "query": "select id from (select user.id, user.col from user join user_extra) as t where id=5", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select user.id, user.col from user join user_extra) as t where id=5", "Instructions": { @@ -5005,8 +2940,7 @@ { "comment": "expression on a cross-shard derived table", "query": "select id+1 from (select user.id, user.col from user join user_extra) as t", - "v3-plan": "VT12001: unsupported: expression on results of a cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id+1 from (select user.id, user.col from user join user_extra) as t", "Instructions": { @@ -5048,8 +2982,7 @@ { "comment": "derived table with aliased columns and outer predicate pushed in derived table", "query": "select u.a from (select id as b, name from user) u(a, n) where u.n = 1", - "v3-plan": "VT12001: unsupported: column aliases in derived table", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.a from (select id as b, name from user) u(a, n) where u.n = 1", "Instructions": { @@ -5100,8 +3033,7 @@ { "comment": "derived table with aliased columns predicate in both the outer and inner", "query": "select u.a from (select id as b, name from user where b = 1) u(a, n) where u.n = 1", - "v3-plan": "VT12001: unsupported: column aliases in derived table", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.a from (select id as b, name from user where b = 1) u(a, n) where u.n = 1", "Instructions": { @@ -5152,8 +3084,7 @@ { "comment": "derived table with aliased columns and a join that requires pushProjection", "query": "select i+1 from (select user.id from user join user_extra) t(i)", - "v3-plan": "VT12001: unsupported: column aliases in derived table", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select i+1 from (select user.id from user join user_extra) t(i)", "Instructions": { @@ -5203,74 +3134,7 @@ { "comment": "two subqueries with different Select and OpCode", "query": "select id from user where id in (select id from user_extra) and col = (select user_id from user_extra limit 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id in (select id from user_extra) and col = (select user_id from user_extra limit 1)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values2", - "__sq2" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from user_extra where 1 != 1", - "Query": "select id from user_extra", - "Table": "user_extra" - }, - { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id from user_extra where 1 != 1", - "Query": "select user_id from user_extra limit :__upper_limit", - "Table": "user_extra" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where col = :__sq1 and :__sq_has_values2 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq2" - ], - "Vindex": "user_index" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id in (select id from user_extra) and col = (select user_id from user_extra limit 1)", "Instructions": { @@ -5345,44 +3209,7 @@ { "comment": "join on int columns", "query": "select u.id from user as u join user as uu on u.intcol = uu.intcol", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id from user as u join user as uu on u.intcol = uu.intcol", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "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 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 1 from `user` as uu where uu.intcol = :u_intcol", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user as u join user as uu on u.intcol = uu.intcol", "Instructions": { @@ -5426,8 +3253,7 @@ { "comment": "Duplicate output column from derived table having a join", "query": "select 0 from (select `user`.col1 from `user` join unsharded) as t join unsharded on unsharded.col1 = t.col1 and unsharded.a = t.col1", - "v3-plan": "VT12001: unsupported: expression on results of a cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 0 from (select `user`.col1 from `user` join unsharded) as t join unsharded on unsharded.col1 = t.col1 and unsharded.a = t.col1", "Instructions": { @@ -5550,41 +3376,7 @@ { "comment": "dont merge unsharded tables from different keyspaces", "query": "select 1 from main.unsharded join main_2.unsharded_tab", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from main.unsharded join main_2.unsharded_tab", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "unsharded_unsharded_tab", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded where 1 != 1", - "Query": "select 1 from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main_2", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_tab where 1 != 1", - "Query": "select 1 from unsharded_tab", - "Table": "unsharded_tab" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from main.unsharded join main_2.unsharded_tab", "Instructions": { @@ -5626,22 +3418,7 @@ { "comment": "Unsharded join with using", "query": "select * from unsharded_a join unsharded_b using (propertyId);", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from unsharded_a join unsharded_b using (propertyId);", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded_a join unsharded_b using (propertyId) where 1 != 1", - "Query": "select * from unsharded_a join unsharded_b using (propertyId)", - "Table": "unsharded_a, unsharded_b" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from unsharded_a join unsharded_b using (propertyId);", "Instructions": { @@ -5664,8 +3441,7 @@ { "comment": "Column aliases in Derived Table", "query": "select id2 from (select id from user) as x (id2)", - "v3-plan": "VT12001: unsupported: column aliases in derived table", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id2 from (select id from user) as x (id2)", "Instructions": { @@ -5687,22 +3463,7 @@ { "comment": "single unsharded keyspace with derived table", "query": "select col from (select col from unsharded join unsharded_b) as u join unsharded_a ua limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from (select col from unsharded join unsharded_b) as u join unsharded_a ua limit 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col from (select col from unsharded join unsharded_b where 1 != 1) as u join unsharded_a as ua where 1 != 1", - "Query": "select col from (select col from unsharded join unsharded_b) as u join unsharded_a as ua limit 1", - "Table": "unsharded, unsharded_b, unsharded_a" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from (select col from unsharded join unsharded_b) as u join unsharded_a ua limit 1", "Instructions": { @@ -5726,74 +3487,7 @@ { "comment": "query builder with derived table having join inside it", "query": "select u.col from (select user.col from user join user_extra) as u join user_extra ue limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.col from (select user.col from user join user_extra) as u join user_extra ue limit 1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra_user_extra", - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `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 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra as ue where 1 != 1", - "Query": "select 1 from user_extra as ue", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.col from (select user.col from user join user_extra) as u join user_extra ue limit 1", "Instructions": { @@ -6039,32 +3733,7 @@ { "comment": "Do not rewrite derived expressions when the derived table is merged with the outer", "query": "select col1, count(*) from (select colC+colD as col1 from user) as tbl group by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, count(*) from (select colC+colD as col1 from user) as tbl group by col1", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, count(*), weight_string(col1) from (select colC + colD as col1 from `user` where 1 != 1) as tbl where 1 != 1 group by col1, weight_string(col1)", - "OrderBy": "(0|2) ASC", - "Query": "select col1, count(*), weight_string(col1) from (select colC + colD as col1 from `user`) as tbl group by col1, weight_string(col1) order by col1 asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, count(*) from (select colC+colD as col1 from user) as tbl group by col1", "Instructions": { @@ -6096,8 +3765,7 @@ { "comment": "join with USING construct", "query": "select * from authoritative join unsharded_authoritative using(col1)", - "v3-plan": "VT12001: unsupported: JOIN with USING(column_list) clause for complex queries", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative join unsharded_authoritative using(col1)", "Instructions": { @@ -6142,26 +3810,7 @@ { "comment": "derived table inside derived table with a where clause depending on columns from the derived table", "query": "select * from (select bar as push_it from (select foo as bar from (select id as foo from user) as t1) as t2) as t3 where push_it = 12", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select bar as push_it from (select foo as bar from (select id as foo from user) as t1) as t2) as t3 where push_it = 12", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select bar as push_it from (select foo as bar from (select id as foo from `user` where 1 != 1) as t1 where 1 != 1) as t2 where 1 != 1) as t3 where 1 != 1", - "Query": "select * from (select bar as push_it from (select foo as bar from (select id as foo from `user`) as t1) as t2) as t3 where push_it = 12", - "Table": "`user`", - "Values": [ - "INT64(12)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select bar as push_it from (select foo as bar from (select id as foo from user) as t1) as t2) as t3 where push_it = 12", "Instructions": { @@ -6187,22 +3836,7 @@ { "comment": "use a view", "query": "select * from user.user_details_view", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user.user_details_view", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1) as user_details_view where 1 != 1", - "Query": "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id) as user_details_view", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user.user_details_view", "Instructions": { @@ -6225,22 +3859,7 @@ { "comment": "use a view without qualifying the keyspace", "query": "select * from user_details_view", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user_details_view", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1) as user_details_view where 1 != 1", - "Query": "select * from (select `user`.id, user_extra.col from `user` join user_extra on `user`.id = user_extra.user_id) as user_details_view", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user_details_view", "Instructions": { @@ -6322,22 +3941,7 @@ { "comment": "missing and ambiguous column info is OK as long as we can send the query to a single unsharded keyspace", "query": "select missing_column from unsharded, unsharded_a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select missing_column from unsharded, unsharded_a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select missing_column from unsharded, unsharded_a where 1 != 1", - "Query": "select missing_column from unsharded, unsharded_a", - "Table": "unsharded, unsharded_a" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select missing_column from unsharded, unsharded_a", "Instructions": { @@ -6360,8 +3964,7 @@ { "comment": "missing and ambiguous column info is not valid when we have two different unsharded keyspaces in the query", "query": "select missing_column from unsharded, unsharded_tab", - "v3-plan": "VT03019: column missing_column not found", - "gen4-plan": "Column 'missing_column' in field list is ambiguous" + "plan": "Column 'missing_column' in field list is ambiguous" }, { "comment": "join predicate only depending on the RHS should not turn outer join into inner join", diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json index d96ac0d9caf..b60111562ed 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json @@ -21,22 +21,7 @@ { "comment": "',' join information_schema", "query": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.`ENGINE`, b.DATA_TYPE from information_schema.`TABLES` as a, information_schema.`COLUMNS` as b where 1 != 1", - "Query": "select a.`ENGINE`, b.DATA_TYPE from information_schema.`TABLES` as a, information_schema.`COLUMNS` as b", - "Table": "information_schema.`TABLES`, information_schema.`COLUMNS`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", "Instructions": { @@ -74,8 +59,7 @@ { "comment": "information schema join", "query": "select tables.TABLE_SCHEMA, files.`STATUS` from information_schema.tables join information_schema.files", - "v3-plan": "VT03019: column `tables`.TABLE_SCHEMA not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select tables.TABLE_SCHEMA, files.`STATUS` from information_schema.tables join information_schema.files", "Instructions": { @@ -94,22 +78,7 @@ { "comment": "access to qualified column names in information_schema", "query": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`COLUMNS` where 1 != 1", - "Query": "select * from information_schema.`COLUMNS` where information_schema.`COLUMNS`.COLUMN_NAME = 'toto'", - "Table": "information_schema.`COLUMNS`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", "Instructions": { @@ -147,45 +116,7 @@ { "comment": "union between information_schema tables that should not be merged", "query": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`tables` where 1 != 1", - "Query": "select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`tables` where 1 != 1", - "Query": "select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"main\")]", - "Table": "information_schema.`tables`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", "Instructions": { @@ -251,24 +182,7 @@ { "comment": "Select from information schema query with two tables that route should be merged", "query": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select RC.CONSTRAINT_NAME, ORDINAL_POSITION from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", - "Query": "select RC.CONSTRAINT_NAME, ORDINAL_POSITION from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME /* VARCHAR */ and KCU.COLUMN_NAME = 'id' and KCU.REFERENCED_TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", - "SysTableTableName": "[KCU_TABLE_NAME:VARCHAR(\"data_type_table\")]", - "SysTableTableSchema": "[VARCHAR(\"test\"), VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", "Instructions": { @@ -289,45 +203,7 @@ { "comment": "Select from information schema query with three tables such that route for 2 should be merged but not for the last.", "query": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS_INFORMATION_SCHEMA.`TABLES`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select KCU.TABLE_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", - "Query": "select KCU.TABLE_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME1 /* VARCHAR */ order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", - "SysTableTableName": "[KCU_TABLE_NAME1:VARCHAR(\"data_type_table\"), KCU_TABLE_NAME:VARCHAR(\"data_type_table\")]", - "SysTableTableSchema": "[VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select S.TABLE_NAME from INFORMATION_SCHEMA.`TABLES` as S where 1 != 1", - "Query": "select S.TABLE_NAME from INFORMATION_SCHEMA.`TABLES` as S where S.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and S.TABLE_NAME = :S_TABLE_NAME /* VARCHAR */", - "SysTableTableName": "[S_TABLE_NAME:VARCHAR(\"sc\")]", - "SysTableTableSchema": "[VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", "Instructions": { @@ -388,23 +264,7 @@ { "comment": "information_schema referential contraints", "query": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where 1 != 1", - "Query": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where kcu.table_schema = :__vtschemaname /* VARCHAR */ and rc.constraint_schema = :__vtschemaname /* VARCHAR */ and kcu.referenced_column_name is not null order by ordinal_position asc", - "SysTableTableSchema": "[:v1, :v2]", - "Table": "information_schema.key_column_usage, information_schema.referential_constraints" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", "Instructions": { @@ -447,23 +307,7 @@ { "comment": "rails query", "query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :fk_table_name /* VARCHAR */ and rc.constraint_schema = database() and rc.table_name = :rc_table_name /* VARCHAR */", - "SysTableTableName": "[fk_table_name:VARCHAR(\":vtg1\"), rc_table_name:VARCHAR(\":vtg1\")]", - "Table": "information_schema.referential_constraints, information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", "Instructions": { @@ -483,23 +327,7 @@ { "comment": "rails_query 2", "query": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.schemata where 1 != 1", - "Query": "select * from information_schema.schemata where schema_name = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\")]", - "Table": "information_schema.schemata" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", "Instructions": { @@ -540,24 +368,7 @@ { "comment": "rails_query 4", "query": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname /* VARCHAR */ and fk.table_name = :fk_table_name /* VARCHAR */ and rc.constraint_schema = :__vtschemaname /* VARCHAR */ and rc.table_name = :rc_table_name /* VARCHAR */", - "SysTableTableName": "[fk_table_name:VARCHAR(\"table_name\"), rc_table_name:VARCHAR(\"table_name\")]", - "SysTableTableSchema": "[VARCHAR(\"table_schema\"), VARCHAR(\"table_schema\")]", - "Table": "information_schema.referential_constraints, information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", "Instructions": { @@ -639,23 +450,7 @@ { "comment": "rails_query 9", "query": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", - "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */) as _subquery", - "SysTableTableSchema": "[VARCHAR(\"table_schema\")]", - "Table": "information_schema.`tables`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", "Instructions": { @@ -675,24 +470,7 @@ { "comment": "rails_query 10", "query": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", - "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */) as _subquery where _subquery.table_type = 'table_type' and _subquery.table_name = :_subquery_table_name /* VARCHAR */", - "SysTableTableName": "[_subquery_table_name:VARCHAR(\"table_name\")]", - "SysTableTableSchema": "[VARCHAR(\"table_schema\")]", - "Table": "information_schema.`tables`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", "Instructions": { @@ -733,8 +511,7 @@ { "comment": "subquery of information_schema with itself", "query": "select TABLES.CHECKSUM from information_schema.`TABLES` where `TABLE_NAME` in (select `TABLE_NAME` from information_schema.`COLUMNS`)", - "v3-plan": "VT03019: column `TABLES`.`CHECKSUM` not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select TABLES.CHECKSUM from information_schema.`TABLES` where `TABLE_NAME` in (select `TABLE_NAME` from information_schema.`COLUMNS`)", "Instructions": { @@ -753,23 +530,7 @@ { "comment": "query trying to query two different keyspaces at the same time", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\"), VARCHAR(\"main\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", "Instructions": { @@ -789,22 +550,7 @@ { "comment": "information_schema query using database() func", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = database()", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", "Instructions": { @@ -823,23 +569,7 @@ { "comment": "table_schema predicate the wrong way around", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", "Instructions": { @@ -859,24 +589,7 @@ { "comment": "table_name predicate against a routed table", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and TABLE_NAME = :TABLE_NAME /* VARCHAR */", - "SysTableTableName": "[TABLE_NAME:VARCHAR(\"route1\")]", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", "Instructions": { @@ -917,23 +630,7 @@ { "comment": "able to isolate table_schema value even when hidden inside of ORs", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and (DATA_FREE = 42 or `CHECKSUM` = 'value')", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", "Instructions": { @@ -953,22 +650,7 @@ { "comment": "expand star with information schema", "query": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select x.table_name from (select a.* from information_schema.key_column_usage as a where 1 != 1) as x where 1 != 1", - "Query": "select x.table_name from (select a.* from information_schema.key_column_usage as a) as x", - "Table": "information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", "Instructions": { @@ -987,48 +669,7 @@ { "comment": "expand star with information schema in a derived table", "query": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "x_COLUMN_NAME": 1 - }, - "TableName": "information_schema.key_column_usage_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select x.table_name, x.COLUMN_NAME from (select a.* from information_schema.key_column_usage as a where 1 != 1) as x where 1 != 1", - "Query": "select x.table_name, x.COLUMN_NAME from (select a.* from information_schema.key_column_usage as a) as x", - "Table": "information_schema.key_column_usage" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where `user`.id = :x_COLUMN_NAME", - "Table": "`user`", - "Values": [ - ":x_COLUMN_NAME" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", "Instructions": { @@ -1076,22 +717,7 @@ { "comment": "join of information_schema queries with select stars exprs", "query": "select a.*, b.* from information_schema.GLOBAL_STATUS a, information_schema.CHARACTER_SETS b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.*, b.* from information_schema.GLOBAL_STATUS a, information_schema.CHARACTER_SETS b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.*, b.* from information_schema.GLOBAL_STATUS as a, information_schema.CHARACTER_SETS as b where 1 != 1", - "Query": "select a.*, b.* from information_schema.GLOBAL_STATUS as a, information_schema.CHARACTER_SETS as b", - "Table": "information_schema.GLOBAL_STATUS, information_schema.CHARACTER_SETS" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.*, b.* from information_schema.GLOBAL_STATUS a, information_schema.CHARACTER_SETS b", "Instructions": { @@ -1110,23 +736,7 @@ { "comment": "join two routes with SysTableTableName entries in LHS and RHS", "query": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.table_name from (select * from information_schema.key_column_usage as a where 1 != 1) as a join (select * from information_schema.referential_constraints where 1 != 1) as b where 1 != 1", - "Query": "select a.table_name from (select * from information_schema.key_column_usage as a where a.table_name = :a_table_name /* VARCHAR */) as a join (select * from information_schema.referential_constraints where table_name = :table_name /* VARCHAR */) as b", - "SysTableTableName": "[a_table_name:VARCHAR(\"users\"), table_name:VARCHAR(\"users\")]", - "Table": "information_schema.key_column_usage, information_schema.referential_constraints" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", "Instructions": { @@ -1146,8 +756,7 @@ { "comment": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "query": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "Instructions": { @@ -1167,48 +776,7 @@ { "comment": "union as a derived table", "query": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\")]", - "Table": "information_schema.views" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "Instructions": { @@ -1228,40 +796,7 @@ { "comment": "merge system schema queries as long as they have any same table_schema", "query": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", "Instructions": { @@ -1281,40 +816,7 @@ { "comment": "merge system schema queries as long as they have any same table_name", "query": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", "Instructions": { @@ -1334,62 +836,7 @@ { "comment": "merge union subquery with outer query referencing the same system schemas", "query": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_name = :table_name2 /* VARCHAR */ and table_name = :table_name3 /* VARCHAR */", - "SysTableTableName": "[table_name2:VARCHAR(\"music\"), table_name3:VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_name = :table_name4 /* VARCHAR */ and table_name = :table_name5 /* VARCHAR */ limit 1", - "SysTableTableName": "[table_name4:VARCHAR(\"music\"), table_name5:VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_name = :table_name /* VARCHAR */ and table_name = :table_name1 /* VARCHAR */ and :__sq_has_values1", - "SysTableTableName": "[table_name1:VARCHAR(\"Music\"), table_name:VARCHAR(\"music\")]", - "Table": "information_schema.`tables`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", "Instructions": { @@ -1409,52 +856,7 @@ { "comment": "merge even one side have schema name in derived table", "query": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select TABLE_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select TABLE_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"a\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select TABLE_NAME from information_schema.`columns` where 1 != 1", - "Query": "select TABLE_NAME from information_schema.`columns`", - "Table": "information_schema.`columns`" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", "Instructions": { @@ -1474,65 +876,7 @@ { "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)", - "v3-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)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLUMN_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select COLUMN_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"a\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLUMN_NAME from information_schema.`columns` where 1 != 1", - "Query": "select COLUMN_NAME from information_schema.`columns`", - "Table": "information_schema.`columns`" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLLATION_NAME from information_schema.`COLUMNS` as t where 1 != 1", - "Query": "select COLLATION_NAME from information_schema.`COLUMNS` as t where :__sq_has_values1 = 1 and COLUMN_NAME in ::__sq1", - "Table": "information_schema.`COLUMNS`" - } - ] - } - }, - "gen4-plan": { + "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)", "Instructions": { @@ -1552,22 +896,7 @@ { "comment": "table_schema OR predicate\n# It is unsupported because we do not route queries to multiple keyspaces right now", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = 'ks' or TABLE_SCHEMA = 'main'", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json index 6363203b88a..83d1e51afc8 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json @@ -21,22 +21,7 @@ { "comment": "',' join information_schema", "query": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.`ENGINE`, b.DATA_TYPE from information_schema.`TABLES` as a, information_schema.`COLUMNS` as b where 1 != 1", - "Query": "select a.`ENGINE`, b.DATA_TYPE from information_schema.`TABLES` as a, information_schema.`COLUMNS` as b", - "Table": "information_schema.`TABLES`, information_schema.`COLUMNS`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.ENGINE, b.DATA_TYPE from information_schema.TABLES as a, information_schema.COLUMNS as b", "Instructions": { @@ -74,8 +59,7 @@ { "comment": "information schema join", "query": "select tables.TABLE_SCHEMA, files.`STATUS` from information_schema.tables join information_schema.files", - "v3-plan": "VT03019: column `tables`.TABLE_SCHEMA not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select tables.TABLE_SCHEMA, files.`STATUS` from information_schema.tables join information_schema.files", "Instructions": { @@ -94,22 +78,7 @@ { "comment": "access to qualified column names in information_schema", "query": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`COLUMNS` where 1 != 1", - "Query": "select * from information_schema.`COLUMNS` where information_schema.`COLUMNS`.COLUMN_NAME = 'toto'", - "Table": "information_schema.`COLUMNS`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from information_schema.COLUMNS where information_schema.COLUMNS.COLUMN_NAME='toto'", "Instructions": { @@ -147,45 +116,7 @@ { "comment": "union between information_schema tables that should not be merged", "query": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`tables` where 1 != 1", - "Query": "select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.`tables` where 1 != 1", - "Query": "select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"main\")]", - "Table": "information_schema.`tables`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from information_schema.tables where table_schema = 'user' union select * from information_schema.tables where table_schema = 'main'", "Instructions": { @@ -251,24 +182,7 @@ { "comment": "Select from information schema query with two tables that route should be merged", "query": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select RC.CONSTRAINT_NAME, ORDINAL_POSITION from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", - "Query": "select RC.CONSTRAINT_NAME, ORDINAL_POSITION from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME /* VARCHAR */ and KCU.COLUMN_NAME = 'id' and KCU.REFERENCED_TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", - "SysTableTableName": "[KCU_TABLE_NAME:VARCHAR(\"data_type_table\")]", - "SysTableTableSchema": "[VARCHAR(\"test\"), VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT RC.CONSTRAINT_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", "Instructions": { @@ -289,45 +203,7 @@ { "comment": "Select from information schema query with three tables such that route for 2 should be merged but not for the last.", "query": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS_INFORMATION_SCHEMA.`TABLES`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select KCU.TABLE_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", - "Query": "select KCU.TABLE_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME /* VARCHAR */ and KCU.TABLE_NAME = :KCU_TABLE_NAME1 /* VARCHAR */ order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", - "SysTableTableName": "[KCU_TABLE_NAME1:VARCHAR(\"data_type_table\"), KCU_TABLE_NAME:VARCHAR(\"data_type_table\")]", - "SysTableTableSchema": "[VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select S.TABLE_NAME from INFORMATION_SCHEMA.`TABLES` as S where 1 != 1", - "Query": "select S.TABLE_NAME from INFORMATION_SCHEMA.`TABLES` as S where S.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and S.TABLE_NAME = :S_TABLE_NAME /* VARCHAR */", - "SysTableTableName": "[S_TABLE_NAME:VARCHAR(\"sc\")]", - "SysTableTableSchema": "[VARCHAR(\"test\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT KCU.`TABLE_NAME`, S.`TABLE_NAME` FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.`TABLES` AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", "Instructions": { @@ -388,23 +264,7 @@ { "comment": "information_schema referential contraints - cant merge without knowing values", "query": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where 1 != 1", - "Query": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where kcu.table_schema = :__vtschemaname /* VARCHAR */ and rc.constraint_schema = :__vtschemaname /* VARCHAR */ and kcu.referenced_column_name is not null order by ordinal_position asc", - "SysTableTableSchema": "[:v1, :v2]", - "Table": "information_schema.key_column_usage, information_schema.referential_constraints" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", "Instructions": { @@ -447,23 +307,7 @@ { "comment": "rails query", "query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :fk_table_name /* VARCHAR */ and rc.constraint_schema = database() and rc.table_name = :rc_table_name /* VARCHAR */", - "SysTableTableName": "[fk_table_name:VARCHAR(\":vtg1\"), rc_table_name:VARCHAR(\":vtg1\")]", - "Table": "information_schema.referential_constraints, information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", "Instructions": { @@ -483,23 +327,7 @@ { "comment": "rails_query 2", "query": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.schemata where 1 != 1", - "Query": "select * from information_schema.schemata where schema_name = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\")]", - "Table": "information_schema.schemata" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM information_schema.schemata WHERE schema_name = 'user'", "Instructions": { @@ -540,24 +368,7 @@ { "comment": "rails_query 4", "query": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname /* VARCHAR */ and fk.table_name = :fk_table_name /* VARCHAR */ and rc.constraint_schema = :__vtschemaname /* VARCHAR */ and rc.table_name = :rc_table_name /* VARCHAR */", - "SysTableTableName": "[fk_table_name:VARCHAR(\"table_name\"), rc_table_name:VARCHAR(\"table_name\")]", - "SysTableTableSchema": "[VARCHAR(\"table_schema\"), VARCHAR(\"table_schema\")]", - "Table": "information_schema.referential_constraints, information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", "Instructions": { @@ -578,24 +389,7 @@ { "comment": "rails_query 5", "query": "SELECT cc.constraint_name AS 'name', cc.check_clause AS 'expression' FROM information_schema.check_constraints cc JOIN information_schema.table_constraints tc USING (constraint_schema, constraint_name) WHERE tc.table_schema = 'table_schema' AND tc.table_name = 'table_name' AND cc.constraint_schema = 'constraint_schema'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT cc.constraint_name AS 'name', cc.check_clause AS 'expression' FROM information_schema.check_constraints cc JOIN information_schema.table_constraints tc USING (constraint_schema, constraint_name) WHERE tc.table_schema = 'table_schema' AND tc.table_name = 'table_name' AND cc.constraint_schema = 'constraint_schema'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc using (constraint_schema, constraint_name) where 1 != 1", - "Query": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc using (constraint_schema, constraint_name) where tc.table_schema = :__vtschemaname /* VARCHAR */ and tc.table_name = :tc_table_name /* VARCHAR */ and cc.constraint_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableName": "[tc_table_name:VARCHAR(\"table_name\")]", - "SysTableTableSchema": "[VARCHAR(\"table_schema\"), VARCHAR(\"constraint_schema\")]", - "Table": "information_schema.check_constraints, information_schema.table_constraints" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT cc.constraint_name AS 'name', cc.check_clause AS 'expression' FROM information_schema.check_constraints cc JOIN information_schema.table_constraints tc USING (constraint_schema, constraint_name) WHERE tc.table_schema = 'table_schema' AND tc.table_name = 'table_name' AND cc.constraint_schema = 'constraint_schema'", "Instructions": { @@ -701,23 +495,7 @@ { "comment": "rails_query 9", "query": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", - "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */) as _subquery", - "SysTableTableSchema": "[VARCHAR(\"table_schema\")]", - "Table": "information_schema.`tables`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery", "Instructions": { @@ -737,24 +515,7 @@ { "comment": "rails_query 10", "query": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", - "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */) as _subquery where _subquery.table_type = 'table_type' and _subquery.table_name = :_subquery_table_name /* VARCHAR */", - "SysTableTableName": "[_subquery_table_name:VARCHAR(\"table_name\")]", - "SysTableTableSchema": "[VARCHAR(\"table_schema\")]", - "Table": "information_schema.`tables`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT table_name FROM (SELECT * FROM information_schema.tables WHERE table_schema = 'table_schema') _subquery WHERE _subquery.table_type = 'table_type' AND _subquery.table_name = 'table_name'", "Instructions": { @@ -815,8 +576,7 @@ { "comment": "subquery of information_schema with itself", "query": "select TABLES.CHECKSUM from information_schema.`TABLES` where `TABLE_NAME` in (select `TABLE_NAME` from information_schema.`COLUMNS`)", - "v3-plan": "VT03019: column `TABLES`.`CHECKSUM` not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select TABLES.CHECKSUM from information_schema.`TABLES` where `TABLE_NAME` in (select `TABLE_NAME` from information_schema.`COLUMNS`)", "Instructions": { @@ -835,23 +595,7 @@ { "comment": "query trying to query two different keyspaces at the same time", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"user\"), VARCHAR(\"main\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", "Instructions": { @@ -871,22 +615,7 @@ { "comment": "information_schema query using database() func", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = database()", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()", "Instructions": { @@ -905,23 +634,7 @@ { "comment": "table_schema predicate the wrong way around", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE 'ks' = TABLE_SCHEMA", "Instructions": { @@ -941,24 +654,7 @@ { "comment": "table_name predicate against a routed table", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and TABLE_NAME = :TABLE_NAME /* VARCHAR */", - "SysTableTableName": "[TABLE_NAME:VARCHAR(\"route1\")]", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' AND TABLE_NAME = 'route1'", "Instructions": { @@ -999,23 +695,7 @@ { "comment": "able to isolate table_schema value even when hidden inside of ORs", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and (DATA_FREE = 42 or `CHECKSUM` = 'value')", - "SysTableTableSchema": "[VARCHAR(\"ks\")]", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and DATA_FREE = 42) OR (TABLE_SCHEMA = 'ks' and CHECKSUM = 'value')", "Instructions": { @@ -1035,22 +715,7 @@ { "comment": "expand star with information schema", "query": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select x.table_name from (select a.* from information_schema.key_column_usage as a where 1 != 1) as x where 1 != 1", - "Query": "select x.table_name from (select a.* from information_schema.key_column_usage as a) as x", - "Table": "information_schema.key_column_usage" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x", "Instructions": { @@ -1069,48 +734,7 @@ { "comment": "expand star with information schema in a derived table", "query": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "x_COLUMN_NAME": 1 - }, - "TableName": "information_schema.key_column_usage_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select x.table_name, x.COLUMN_NAME from (select a.* from information_schema.key_column_usage as a where 1 != 1) as x where 1 != 1", - "Query": "select x.table_name, x.COLUMN_NAME from (select a.* from information_schema.key_column_usage as a) as x", - "Table": "information_schema.key_column_usage" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where `user`.id = :x_COLUMN_NAME", - "Table": "`user`", - "Values": [ - ":x_COLUMN_NAME" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select x.table_name from (select a.* from information_schema.key_column_usage a) x join user on x.`COLUMN_NAME` = user.id", "Instructions": { @@ -1158,22 +782,7 @@ { "comment": "join of information_schema queries with select stars exprs", "query": "select a.*, b.* from information_schema.CHECK_CONSTRAINTS a, information_schema.CHARACTER_SETS b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.*, b.* from information_schema.CHECK_CONSTRAINTS a, information_schema.CHARACTER_SETS b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.*, b.* from information_schema.CHECK_CONSTRAINTS as a, information_schema.CHARACTER_SETS as b where 1 != 1", - "Query": "select a.*, b.* from information_schema.CHECK_CONSTRAINTS as a, information_schema.CHARACTER_SETS as b", - "Table": "information_schema.CHECK_CONSTRAINTS, information_schema.CHARACTER_SETS" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.*, b.* from information_schema.CHECK_CONSTRAINTS a, information_schema.CHARACTER_SETS b", "Instructions": { @@ -1192,23 +801,7 @@ { "comment": "join two routes with SysTableTableName entries in LHS and RHS", "query": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a.table_name from (select * from information_schema.key_column_usage as a where 1 != 1) as a join (select * from information_schema.referential_constraints where 1 != 1) as b where 1 != 1", - "Query": "select a.table_name from (select * from information_schema.key_column_usage as a where a.table_name = :a_table_name /* VARCHAR */) as a join (select * from information_schema.referential_constraints where table_name = :table_name /* VARCHAR */) as b", - "SysTableTableName": "[a_table_name:VARCHAR(\"users\"), table_name:VARCHAR(\"users\")]", - "Table": "information_schema.key_column_usage, information_schema.referential_constraints" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.table_name from (select * from information_schema.key_column_usage a where a.table_name = 'users') a join (select * from information_schema.referential_constraints where table_name = 'users') b", "Instructions": { @@ -1228,8 +821,7 @@ { "comment": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "query": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(found) from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "Instructions": { @@ -1249,48 +841,7 @@ { "comment": "union as a derived table", "query": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\")]", - "Table": "information_schema.views" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select found from (select 1 as found from information_schema.`tables` where table_schema = 'music' union all (select 1 as found from information_schema.views where table_schema = 'music' limit 1)) as t", "Instructions": { @@ -1310,40 +861,7 @@ { "comment": "merge system schema queries as long as they have any same table_schema", "query": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", "Instructions": { @@ -1363,40 +881,7 @@ { "comment": "merge system schema queries as long as they have any same table_name", "query": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1", - "SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_schema = 'music' and table_schema = 'Music' union all (select 1 as found from information_schema.views where table_schema = 'music' and table_schema = 'user' limit 1)", "Instructions": { @@ -1416,62 +901,7 @@ { "comment": "merge union subquery with outer query referencing the same system schemas", "query": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_name = :table_name2 /* VARCHAR */ and table_name = :table_name3 /* VARCHAR */", - "SysTableTableName": "[table_name2:VARCHAR(\"music\"), table_name3:VARCHAR(\"Music\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.views where 1 != 1", - "Query": "select 1 as found from information_schema.views where table_name = :table_name4 /* VARCHAR */ and table_name = :table_name5 /* VARCHAR */ limit 1", - "SysTableTableName": "[table_name4:VARCHAR(\"music\"), table_name5:VARCHAR(\"user\")]", - "Table": "information_schema.views" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1", - "Query": "select 1 as found from information_schema.`tables` where table_name = :table_name /* VARCHAR */ and table_name = :table_name1 /* VARCHAR */ and :__sq_has_values1", - "SysTableTableName": "[table_name1:VARCHAR(\"Music\"), table_name:VARCHAR(\"music\")]", - "Table": "information_schema.`tables`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' and exists (select 1 as found from information_schema.`tables` where table_name = 'music' and table_name = 'Music' union all (select 1 as found from information_schema.views where table_name = 'music' and table_name = 'user' limit 1))", "Instructions": { @@ -1491,52 +921,7 @@ { "comment": "merge even one side have schema name in derived table", "query": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select TABLE_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select TABLE_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"a\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select TABLE_NAME from information_schema.`columns` where 1 != 1", - "Query": "select TABLE_NAME from information_schema.`columns`", - "Table": "information_schema.`columns`" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select TABLE_NAME from information_schema.tables t where t.TABLE_SCHEMA = 'a' union select TABLE_NAME from information_schema.columns) dt", "Instructions": { @@ -1556,65 +941,7 @@ { "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)", - "v3-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)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLUMN_NAME from information_schema.`tables` as t where 1 != 1", - "Query": "select COLUMN_NAME from information_schema.`tables` as t where t.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */", - "SysTableTableSchema": "[VARCHAR(\"a\")]", - "Table": "information_schema.`tables`" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLUMN_NAME from information_schema.`columns` where 1 != 1", - "Query": "select COLUMN_NAME from information_schema.`columns`", - "Table": "information_schema.`columns`" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select COLLATION_NAME from information_schema.`COLUMNS` as t where 1 != 1", - "Query": "select COLLATION_NAME from information_schema.`COLUMNS` as t where :__sq_has_values1 = 1 and COLUMN_NAME in ::__sq1", - "Table": "information_schema.`COLUMNS`" - } - ] - } - }, - "gen4-plan": { + "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)", "Instructions": { @@ -1634,22 +961,7 @@ { "comment": "table_schema OR predicate\n# It is unsupported because we do not route queries to multiple keyspaces right now", "query": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", - "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = 'ks' or TABLE_SCHEMA = 'main'", - "Table": "INFORMATION_SCHEMA.`TABLES`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'ks' OR TABLE_SCHEMA = 'main'", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/large_cases.json b/go/vt/vtgate/planbuilder/testdata/large_cases.json index 4b2fae633ab..43adc1f5343 100644 --- a/go/vt/vtgate/planbuilder/testdata/large_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/large_cases.json @@ -2,191 +2,7 @@ { "comment": "select user.id from user, user_extra, user_metadata, music, unsharded, unsharded_a, unsharded_b, unsharded_auto, music_extra where user.id = user_extra.user_id and user_metadata.user_id = user_extra.user_id and music.id = music_extra.music_id and unsharded.x = unsharded_a.y", "query": "select user.id from user, user_extra, user_metadata, music, unsharded, unsharded_a, unsharded_b, unsharded_auto, music_extra where user.id = user_extra.user_id and user_metadata.user_id = user_extra.user_id and music.id = music_extra.music_id and unsharded.x = unsharded_a.y", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.id from user, user_extra, user_metadata, music, unsharded, unsharded_a, unsharded_b, unsharded_auto, music_extra where user.id = user_extra.user_id and user_metadata.user_id = user_extra.user_id and music.id = music_extra.music_id and unsharded.x = unsharded_a.y", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_user_extra_user_metadata_music_unsharded_unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinVars": { - "user_extra_user_id": 0 - }, - "TableName": "user_extra_user_metadata_music_unsharded_unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.user_id from user_extra where 1 != 1", - "Query": "select user_extra.user_id from user_extra where user_extra.user_id = :user_id", - "Table": "user_extra", - "Values": [ - ":user_id" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "user_metadata_music_unsharded_unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_metadata where 1 != 1", - "Query": "select 1 from user_metadata where user_metadata.user_id = :user_extra_user_id", - "Table": "user_metadata", - "Values": [ - ":user_extra_user_id" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinVars": { - "music_id": 0 - }, - "TableName": "music_unsharded_unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music", - "Table": "music" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinVars": { - "unsharded_x": 0 - }, - "TableName": "unsharded_unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.x from unsharded where 1 != 1", - "Query": "select unsharded.x from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "unsharded_a_unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_a where 1 != 1", - "Query": "select 1 from unsharded_a where unsharded_a.y = :unsharded_x", - "Table": "unsharded_a" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "unsharded_b_unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_b where 1 != 1", - "Query": "select 1 from unsharded_b", - "Table": "unsharded_b" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "unsharded_auto_music_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded_auto where 1 != 1", - "Query": "select 1 from unsharded_auto", - "Table": "unsharded_auto" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music_extra where 1 != 1", - "Query": "select 1 from music_extra where music_extra.music_id = :music_id", - "Table": "music_extra", - "Values": [ - ":music_id" - ], - "Vindex": "music_user_map" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id from user, user_extra, user_metadata, music, unsharded, unsharded_a, unsharded_b, unsharded_auto, music_extra where user.id = user_extra.user_id and user_metadata.user_id = user_extra.user_id and music.id = music_extra.music_id and unsharded.x = unsharded_a.y", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/large_union_cases.json b/go/vt/vtgate/planbuilder/testdata/large_union_cases.json index 9120e39bfd6..c50ba09d3ce 100644 --- a/go/vt/vtgate/planbuilder/testdata/large_union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/large_union_cases.json @@ -2,1626 +2,7 @@ { "comment": "this testcase breaks goland, so it lives on its own file", "query": "(SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270703806 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270714657 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270721330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270812079 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271011532 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034164 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034177 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271066849 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271098740 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271355000 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271924504 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272086055 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270650576 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270652906 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270660650 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270649256 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270653671 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270717223 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270720898 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271346411 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271352121 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271354908 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271367516 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271472522 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271821733 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272068709 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270703806 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270714657 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270721330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270812079 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271011532 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034164 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034177 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271066849 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271098740 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271355000 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271924504 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272086055 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270650576 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270652906 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270660650 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270649256 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270653671 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270717223 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270720898 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271346411 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271352121 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271354908 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271367516 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271472522 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271821733 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272068709 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11)", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270698330 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270698330)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270699497 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270699497)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270703806 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270703806)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270707364 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270707364)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270714657 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270714657)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270721330 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270721330)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270812079 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270812079)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271011532 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271011532)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271034164 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271034164)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271034177 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271034177)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271066849 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271066849)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271098740 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271098740)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271355000 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271355000)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271639345 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271639345)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271914117 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271914117)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271924504 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271924504)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272086055 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272086055)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272127855 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272127855)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272191137 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272191137)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272468271 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272468271)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270637436 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270637436)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270644941 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270644941)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270650576 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270650576)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270652906 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270652906)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270660650 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270660650)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270670201 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270670201)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270698330 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270698330)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270699497 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270699497)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270707364 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270707364)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271365691 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271365691)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271799956 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271799956)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271914117 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271914117)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270637436 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270637436)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271799956 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271799956)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270637436 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270637436)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271639345 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271639345)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270644941 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270644941)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270649256 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270649256)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270653671 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270653671)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270670201 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270670201)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270717223 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270717223)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270720898 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270720898)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270982590 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270982590)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271346411 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271346411)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271352121 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271352121)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271354908 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271354908)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271365691 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271365691)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271367516 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271367516)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271472522 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271472522)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271607757 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271607757)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271639345 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271639345)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271821733 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271821733)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271914117 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271914117)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272068709 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272068709)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272127855 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272127855)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272191137 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272191137)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272244005 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272244005)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272468271 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272468271)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270982590 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270982590)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271365691 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271365691)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271607757 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271607757)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1270982590 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1270982590)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271365691 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271365691)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1271607757 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1271607757)" - ], - "Vindex": "user_index" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select content, user_id from music where 1 != 1", - "Query": "select content, user_id from music where user_id = 1272244005 order by created_at asc, id asc limit 11", - "Table": "music", - "Values": [ - "INT64(1272244005)" - ], - "Vindex": "user_index" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270703806 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270714657 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270721330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270812079 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271011532 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034164 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271034177 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271066849 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271098740 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271355000 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271924504 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272086055 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270650576 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270652906 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270660650 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270698330 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270699497 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270707364 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271799956 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270637436 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270644941 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270649256 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270653671 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270670201 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270717223 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270720898 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271346411 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271352121 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271354908 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271367516 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271472522 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271639345 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271821733 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271914117 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272068709 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272127855 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272191137 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272468271 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1270982590 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271365691 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1271607757 ORDER BY created_at ASC, id ASC LIMIT 11) UNION (SELECT `content`, `user_id` FROM `music` WHERE `user_id` = 1272244005 ORDER BY created_at ASC, id ASC LIMIT 11)", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/lock_cases.json b/go/vt/vtgate/planbuilder/testdata/lock_cases.json index 98ffa9d1bb9..c14ba026869 100644 --- a/go/vt/vtgate/planbuilder/testdata/lock_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/lock_cases.json @@ -2,23 +2,7 @@ { "comment": "get_lock from dual", "query": "select get_lock('xyz', 10) from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select get_lock('xyz', 10) from dual", - "Instructions": { - "OperatorType": "Lock", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetDestination": "KeyspaceID(00)", - "FieldQuery": "select get_lock('xyz', 10) from dual where 1 != 1", - "lock_func": [ - "get_lock('xyz', 10)" - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select get_lock('xyz', 10) from dual", "Instructions": { @@ -41,23 +25,7 @@ { "comment": "is_free_lock from dual", "query": "select is_free_lock('xyz') from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select is_free_lock('xyz') from dual", - "Instructions": { - "OperatorType": "Lock", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetDestination": "KeyspaceID(00)", - "FieldQuery": "select is_free_lock('xyz') from dual where 1 != 1", - "lock_func": [ - "is_free_lock('xyz')" - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select is_free_lock('xyz') from dual", "Instructions": { @@ -80,23 +48,7 @@ { "comment": "get_lock from dual prepare query", "query": "select get_lock(?, ?)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select get_lock(?, ?)", - "Instructions": { - "OperatorType": "Lock", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetDestination": "KeyspaceID(00)", - "FieldQuery": "select get_lock(:v1, :v2) from dual where 1 != 1", - "lock_func": [ - "get_lock(:v1, :v2)" - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select get_lock(?, ?)", "Instructions": { @@ -152,24 +104,7 @@ { "comment": "multiple lock functions", "query": "select get_lock('xyz', 10), is_free_lock('abc') from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select get_lock('xyz', 10), is_free_lock('abc') from dual", - "Instructions": { - "OperatorType": "Lock", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "TargetDestination": "KeyspaceID(00)", - "FieldQuery": "select get_lock('xyz', 10), is_free_lock('abc') from dual where 1 != 1", - "lock_func": [ - "get_lock('xyz', 10)", - "is_free_lock('abc')" - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select get_lock('xyz', 10), is_free_lock('abc') from dual", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json index 944e5cd617c..58e6744f1a6 100644 --- a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.json @@ -2,41 +2,7 @@ { "comment": "Test cases in this file follow the code in memory_sort.go.\n# scatter aggregate order by references ungrouped column", "query": "select a, b, count(*) from user group by a order by b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) from user group by a order by b", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(1|3) ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0", - "ResultColumns": 4, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|4) ASC", - "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by a, weight_string(a) order by a asc", - "ResultColumns": 4, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) from user group by a order by b", "Instructions": { @@ -75,39 +41,7 @@ { "comment": "scatter aggregate order by references aggregate expression", "query": "select a, b, count(*) k from user group by a order by k", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) k from user group by a order by k", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "2 ASC", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|3) ASC", - "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a, weight_string(a) order by a asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) k from user group by a order by k", "Instructions": { @@ -146,41 +80,7 @@ { "comment": "select a, b, count(*) k from user group by a order by b, a, k", "query": "select a, b, count(*) k from user group by a order by b, a, k", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) k from user group by a order by b, a, k", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(1|3) ASC, (0|4) ASC, 2 ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0", - "ResultColumns": 5, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*) as k, weight_string(b), weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|4) ASC", - "Query": "select a, b, count(*) as k, weight_string(b), weight_string(a) from `user` group by a, weight_string(a) order by a asc", - "ResultColumns": 5, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) k from user group by a order by b, a, k", "Instructions": { @@ -219,45 +119,7 @@ { "comment": "scatter aggregate with memory sort and limit", "query": "select a, b, count(*) k from user group by a order by k desc limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) k from user group by a order by k desc limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "2 DESC", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|3) ASC", - "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a, weight_string(a) order by a asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) k from user group by a order by k desc limit 10", "Instructions": { @@ -302,41 +164,7 @@ { "comment": "scatter aggregate with memory sort and order by number", "query": "select a, b, count(*) k from user group by a order by 1,3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, b, count(*) k from user group by a order by 1,3", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(0|3) ASC, 2 ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(2) AS count", - "GroupBy": "0", - "ResultColumns": 4, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a, weight_string(a)", - "OrderBy": "(0|3) ASC", - "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a, weight_string(a) order by 1 asc", - "ResultColumns": 4, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, b, count(*) k from user group by a order by 1,3", "Instructions": { @@ -375,41 +203,7 @@ { "comment": "scatter aggregate with memory sort and order by number, reuse weight_string\n# we have to use a meaningless construct to test this", "query": "select textcol1 as t, count(*) k from user group by textcol1 order by textcol1, k, textcol1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select textcol1 as t, count(*) k from user group by textcol1 order by textcol1, k, textcol1", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(0|2) ASC, 1 ASC, (0|2) ASC", - "ResultColumns": 2, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(1) AS count", - "GroupBy": "2", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select textcol1 as t, count(*) as k, weight_string(textcol1) from `user` where 1 != 1 group by textcol1, weight_string(textcol1)", - "OrderBy": "(0|2) ASC, (0|2) ASC", - "Query": "select textcol1 as t, count(*) as k, weight_string(textcol1) from `user` group by textcol1, weight_string(textcol1) order by textcol1 asc, textcol1 asc", - "ResultColumns": 3, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select textcol1 as t, count(*) k from user group by textcol1 order by textcol1, k, textcol1", "Instructions": { @@ -447,57 +241,7 @@ { "comment": "order by on a cross-shard derived table", "query": "select id from (select user.id, user.col from user join user_extra) as t order by id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from (select user.id, user.col from user join user_extra) as t order by id", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(0|2) ASC", - "ResultColumns": 1, - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,L:2", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.col, weight_string(`user`.id) from `user` where 1 != 1", - "Query": "select `user`.id, `user`.col, weight_string(`user`.id) from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from (select user.id, user.col from user join user_extra) as t order by id", "Instructions": { @@ -540,60 +284,7 @@ { "comment": "order by on a cross-shard query. Note: this happens only when an order by column is from the second table", "query": "select user.col1 as a, user.col2 b, music.col3 c from user, music where user.id = music.id and user.id = 1 order by c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2 b, music.col3 c from user, music where user.id = music.id and user.id = 1 order by c", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(2|3) ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0,R:1", - "JoinVars": { - "user_id": 2 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2 as b, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2 as b, `user`.id from `user` where `user`.id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3 as c, weight_string(music.col3) from music where 1 != 1", - "Query": "select music.col3 as c, weight_string(music.col3) from music where music.id = :user_id", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2 b, music.col3 c from user, music where user.id = music.id and user.id = 1 order by c", "Instructions": { @@ -654,60 +345,7 @@ { "comment": "Order by for join, with mixed cross-shard ordering", "query": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by 1 asc, 3 desc, 2 asc", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by 1 asc, 3 desc, 2 asc", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(0|3) ASC, (2|4) DESC, (1|5) ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0,L:2,R:1,L:3", - "JoinVars": { - "user_id": 4 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2, weight_string(`user`.col1), weight_string(`user`.col2), `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2, weight_string(`user`.col1), weight_string(`user`.col2), `user`.id from `user` where `user`.id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3, weight_string(music.col3) from music where 1 != 1", - "Query": "select music.col3, weight_string(music.col3) from music where music.id = :user_id", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by 1 asc, 3 desc, 2 asc", "Instructions": { @@ -768,49 +406,7 @@ { "comment": "Order by for join, on text column in LHS.", "query": "select u.a, u.textcol1, un.col2 from user u join unsharded un order by u.textcol1, un.col2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.a, u.textcol1, un.col2 from user u join unsharded un order by u.textcol1, un.col2", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(1|3) ASC, (2|4) ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0,L:2,R:1", - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.a, u.textcol1, weight_string(u.textcol1) from `user` as u where 1 != 1", - "Query": "select u.a, u.textcol1, weight_string(u.textcol1) from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select un.col2, weight_string(un.col2) from unsharded as un where 1 != 1", - "Query": "select un.col2, weight_string(un.col2) from unsharded as un", - "Table": "unsharded" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.a, u.textcol1, un.col2 from user u join unsharded un order by u.textcol1, un.col2", "Instructions": { @@ -860,49 +456,7 @@ { "comment": "Order by for join, on text column in RHS.", "query": "select u.a, u.textcol1, un.col2 from unsharded un join user u order by u.textcol1, un.col2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.a, u.textcol1, un.col2 from unsharded un join user u order by u.textcol1, un.col2", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(1|3) ASC, (2|4) ASC", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0,R:1,L:0,R:2,L:1", - "TableName": "unsharded_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select un.col2, weight_string(un.col2) from unsharded as un where 1 != 1", - "Query": "select un.col2, weight_string(un.col2) from unsharded as un", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.a, u.textcol1, weight_string(u.textcol1) from `user` as u where 1 != 1", - "Query": "select u.a, u.textcol1, weight_string(u.textcol1) from `user` as u", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.a, u.textcol1, un.col2 from unsharded un join user u order by u.textcol1, un.col2", "Instructions": { @@ -952,36 +506,7 @@ { "comment": "order by for vindex func", "query": "select id, keyspace_id, range_start, range_end from user_index where id = :id order by range_start", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, keyspace_id, range_start, range_end from user_index where id = :id order by range_start", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "2 ASC", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1, - 2, - 3 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY", - "range_end": "VARBINARY", - "range_start": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, keyspace_id, range_start, range_end from user_index where id = :id order by range_start", "Instructions": { @@ -1017,8 +542,7 @@ { "comment": "unary expression", "query": "select a from user order by binary a desc", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: convert(a, binary)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a from user order by binary a desc", "Instructions": { @@ -1042,8 +566,7 @@ { "comment": "unary expression in join query", "query": "select u.a from user u join music m on u.a = m.a order by binary a desc", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: convert(a, binary)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.a from user u join music m on u.a = m.a order by binary a desc", "Instructions": { @@ -1089,23 +612,7 @@ { "comment": "intcol order by", "query": "select id, intcol from user order by intcol", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, intcol from user order by intcol", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, intcol from `user` where 1 != 1", - "OrderBy": "1 ASC", - "Query": "select id, intcol from `user` order by intcol asc", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, intcol from user order by intcol", "Instructions": { @@ -1128,8 +635,7 @@ { "comment": "scatter order by with order by column not present", "query": "select col from user order by id", - "v3-plan": "VT12001: unsupported: in scatter query: ORDER BY must reference a column in the SELECT list: id asc", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user order by id", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/misc_cases.json b/go/vt/vtgate/planbuilder/testdata/misc_cases.json index 38ea0377773..399cebe8939 100644 --- a/go/vt/vtgate/planbuilder/testdata/misc_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/misc_cases.json @@ -2,14 +2,7 @@ { "comment": "prepare statement with select", "query": "prepare prep from 'select * from user where id = ?'", - "v3-plan": { - "QueryType": "PREPARE", - "Original": "prepare prep from 'select * from user where id = ?'", - "Instructions": { - "OperatorType": "Rows" - } - }, - "gen4-plan": { + "plan": { "QueryType": "PREPARE", "Original": "prepare prep from 'select * from user where id = ?'", "Instructions": { @@ -51,14 +44,7 @@ { "comment": "prepare statement with user defined variable", "query": "prepare prep from @prep_stmt", - "v3-plan": { - "QueryType": "PREPARE", - "Original": "prepare prep from @prep_stmt", - "Instructions": { - "OperatorType": "Rows" - } - }, - "gen4-plan": { + "plan": { "QueryType": "PREPARE", "Original": "prepare prep from @prep_stmt", "Instructions": { @@ -82,34 +68,7 @@ { "comment": "execute one param statement", "query": "execute prep_one_param using @foo", - "v3-plan": { - "QueryType": "EXECUTE", - "Original": "execute prep_one_param using @foo", - "Instructions": { - "OperatorType": "EXECUTE", - "Parameters": [ - "foo" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where id = :v1", - "Table": "`user`", - "Values": [ - ":v1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "EXECUTE", "Original": "execute prep_one_param using @foo", "Instructions": { @@ -143,35 +102,7 @@ { "comment": "execute in param statement", "query": "execute prep_in_param using @x, @y", - "v3-plan": { - "QueryType": "EXECUTE", - "Original": "execute prep_in_param using @x, @y", - "Instructions": { - "OperatorType": "EXECUTE", - "Parameters": [ - "x", - "y" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where id in ::__vals", - "Table": "`user`", - "Values": [ - "(:v1, :v2)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "EXECUTE", "Original": "execute prep_in_param using @x, @y", "Instructions": { @@ -206,28 +137,7 @@ { "comment": "execute no param statement", "query": "execute prep_no_param", - "v3-plan": { - "QueryType": "EXECUTE", - "Original": "execute prep_no_param", - "Instructions": { - "OperatorType": "EXECUTE", - "Parameters": null, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "EXECUTE", "Original": "execute prep_no_param", "Instructions": { @@ -270,14 +180,7 @@ { "comment": "prepare a dual query", "query": "prepare prep_dual from 'select 1+?, 10/?'", - "v3-plan": { - "QueryType": "PREPARE", - "Original": "prepare prep_dual from 'select 1+?, 10/?'", - "Instructions": { - "OperatorType": "Rows" - } - }, - "gen4-plan": { + "plan": { "QueryType": "PREPARE", "Original": "prepare prep_dual from 'select 1+?, 10/?'", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/oltp_cases.json b/go/vt/vtgate/planbuilder/testdata/oltp_cases.json index 9fdf352aee7..b366f1a8f04 100644 --- a/go/vt/vtgate/planbuilder/testdata/oltp_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/oltp_cases.json @@ -2,26 +2,7 @@ { "comment": "OLTP simple select", "query": "SELECT c FROM sbtest34 WHERE id=15", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c FROM sbtest34 WHERE id=15", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c from sbtest34 where 1 != 1", - "Query": "select c from sbtest34 where id = 15", - "Table": "sbtest34", - "Values": [ - "INT64(15)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c FROM sbtest34 WHERE id=15", "Instructions": { @@ -47,22 +28,7 @@ { "comment": "OLTP simple range select", "query": "SELECT c FROM sbtest12 WHERE id BETWEEN 1 AND 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c FROM sbtest12 WHERE id BETWEEN 1 AND 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c from sbtest12 where 1 != 1", - "Query": "select c from sbtest12 where id between 1 and 10", - "Table": "sbtest12" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c FROM sbtest12 WHERE id BETWEEN 1 AND 10", "Instructions": { @@ -84,29 +50,7 @@ { "comment": "OLTP sum range select", "query": "SELECT SUM(k) FROM sbtest43 WHERE id BETWEEN 90 AND 990", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT SUM(k) FROM sbtest43 WHERE id BETWEEN 90 AND 990", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum(0)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select sum(k) from sbtest43 where 1 != 1", - "Query": "select sum(k) from sbtest43 where id between 90 and 990", - "Table": "sbtest43" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT SUM(k) FROM sbtest43 WHERE id BETWEEN 90 AND 990", "Instructions": { @@ -135,24 +79,7 @@ { "comment": "OLTP order range select", "query": "SELECT c FROM sbtest1 WHERE id BETWEEN 50 AND 235 ORDER BY c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c FROM sbtest1 WHERE id BETWEEN 50 AND 235 ORDER BY c", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c, weight_string(c) from sbtest1 where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select c, weight_string(c) from sbtest1 where id between 50 and 235 order by c asc", - "ResultColumns": 1, - "Table": "sbtest1" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c FROM sbtest1 WHERE id BETWEEN 50 AND 235 ORDER BY c", "Instructions": { @@ -175,32 +102,7 @@ { "comment": "OLTP distinct range select", "query": "SELECT DISTINCT c FROM sbtest30 WHERE id BETWEEN 1 AND 10 ORDER BY c", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT DISTINCT c FROM sbtest30 WHERE id BETWEEN 1 AND 10 ORDER BY c", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "1", - "ResultColumns": 1, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c, weight_string(c) from sbtest30 where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select distinct c, weight_string(c) from sbtest30 where id between 1 and 10 order by c asc", - "ResultColumns": 2, - "Table": "sbtest30" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT DISTINCT c FROM sbtest30 WHERE id BETWEEN 1 AND 10 ORDER BY c", "Instructions": { @@ -230,29 +132,7 @@ { "comment": "OLTP index udpate", "query": "UPDATE sbtest6 SET k=k+1 WHERE id=5", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE sbtest6 SET k=k+1 WHERE id=5", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update sbtest6 set k = k + 1 where id = 5", - "Table": "sbtest6", - "Values": [ - "INT64(5)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.sbtest6" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE sbtest6 SET k=k+1 WHERE id=5", "Instructions": { @@ -278,29 +158,7 @@ { "comment": "OLTP non index update", "query": "UPDATE sbtest9 SET c=7 WHERE id=8", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE sbtest9 SET c=7 WHERE id=8", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update sbtest9 set c = 7 where id = 8", - "Table": "sbtest9", - "Values": [ - "INT64(8)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.sbtest9" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE sbtest9 SET c=7 WHERE id=8", "Instructions": { @@ -326,29 +184,7 @@ { "comment": "OLTP delete", "query": "DELETE FROM sbtest15 WHERE id=7525", - "v3-plan": { - "QueryType": "DELETE", - "Original": "DELETE FROM sbtest15 WHERE id=7525", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from sbtest15 where id = 7525", - "Table": "sbtest15", - "Values": [ - "INT64(7525)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.sbtest15" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "DELETE FROM sbtest15 WHERE id=7525", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json index 4908a29d134..bdbd665bbac 100644 --- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json @@ -2,22 +2,7 @@ { "comment": "HAVING implicitly references table col", "query": "select user.col1 from user having col2 = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 from user having col2 = 2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 from `user` where 1 != 1", - "Query": "select `user`.col1 from `user` having col2 = 2", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 from user having col2 = 2", "Instructions": { @@ -39,47 +24,12 @@ { "comment": "ambiguous symbol reference", "query": "select user.col1, user_extra.col1 from user join user_extra having col1 = 2", - "v3-plan": "VT03021: ambiguous column reference: col1", - "gen4-plan": "Column 'col1' in field list is ambiguous" + "plan": "Column 'col1' in field list is ambiguous" }, { "comment": "TODO: this should be 'Column 'col1' in having clause is ambiguous'\n# non-ambiguous symbol reference", "query": "select user.col1, user_extra.col1 from user join user_extra having user_extra.col1 = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1, user_extra.col1 from user join user_extra having user_extra.col1 = 2", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 from `user` where 1 != 1", - "Query": "select `user`.col1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col1 from user_extra where 1 != 1", - "Query": "select user_extra.col1 from user_extra having user_extra.col1 = 2", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1, user_extra.col1 from user join user_extra having user_extra.col1 = 2", "Instructions": { @@ -121,41 +71,7 @@ { "comment": "HAVING multi-route", "query": "select user.col1 as a, user.col2, user_extra.col3 from user join user_extra having 1 = 1 and a = 1 and a = user.col2 and user_extra.col3 = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, user_extra.col3 from user join user_extra having 1 = 1 and a = 1 and a = user.col2 and user_extra.col3 = 1", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "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` having 1 = 1 and a = 1 and a = `user`.col2", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col3 from user_extra where 1 != 1", - "Query": "select user_extra.col3 from user_extra having user_extra.col3 = 1", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2, user_extra.col3 from user join user_extra having 1 = 1 and a = 1 and a = user.col2 and user_extra.col3 = 1", "Instructions": { @@ -197,47 +113,7 @@ { "comment": "HAVING uses subquery", "query": "select id from user having id in (select col from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user having id in (select col from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` having :__sq_has_values1 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user having id in (select col from user)", "Instructions": { @@ -284,26 +160,7 @@ { "comment": "ORDER BY, reference col from local table.", "query": "select col from user where id = 5 order by aa", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = 5 order by aa", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = 5 order by aa asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = 5 order by aa", "Instructions": { @@ -329,26 +186,7 @@ { "comment": "ORDER BY uses column numbers", "query": "select col from user where id = 1 order by 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where id = 1 order by 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where id = 1 order by 1 asc", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where id = 1 order by 1", "Instructions": { @@ -374,23 +212,7 @@ { "comment": "ORDER BY on scatter", "query": "select col from user order by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user order by col", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "OrderBy": "0 ASC", - "Query": "select col from `user` order by col asc", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user order by col", "Instructions": { @@ -413,48 +235,27 @@ { "comment": "ORDER BY on select t.*", "query": "select t.*, t.col from user t order by t.col", - "v3-plan": "VT12001: unsupported: in scatter query, cannot ORDER BY a column that comes after `*` expressions in the SELECT list", - "gen4-plan": "VT12001: unsupported: '*' expression in cross-shard query" + "plan": "VT12001: unsupported: '*' expression in cross-shard query" }, { "comment": "ORDER BY on select *", "query": "select *, col from user order by col", - "v3-plan": "VT12001: unsupported: in scatter query, cannot ORDER BY a column that comes after `*` expressions in the SELECT list", - "gen4-plan": "VT12001: unsupported: '*' expression in cross-shard query" + "plan": "VT12001: unsupported: '*' expression in cross-shard query" }, { "comment": "ORDER BY on select multi t.*", "query": "select t.*, t.name, t.*, t.col from user t order by t.col", - "v3-plan": "VT12001: unsupported: in scatter query, cannot ORDER BY a column that comes after `*` expressions in the SELECT list", - "gen4-plan": "VT12001: unsupported: '*' expression in cross-shard query" + "plan": "VT12001: unsupported: '*' expression in cross-shard query" }, { "comment": "ORDER BY on select multi *", "query": "select *, name, *, col from user order by col", - "v3-plan": "VT12001: unsupported: in scatter query, cannot ORDER BY a column that comes after `*` expressions in the SELECT list", - "gen4-plan": "VT12001: unsupported: '*' expression in cross-shard query" + "plan": "VT12001: unsupported: '*' expression in cross-shard query" }, { "comment": "ORDER BY works for select * from authoritative table", "query": "select * from authoritative order by user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from authoritative order by user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id, col1, col2, weight_string(user_id) from authoritative where 1 != 1", - "OrderBy": "(0|3) ASC", - "Query": "select user_id, col1, col2, weight_string(user_id) from authoritative order by user_id asc", - "ResultColumns": 3, - "Table": "authoritative" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative order by user_id", "Instructions": { @@ -478,24 +279,7 @@ { "comment": "ORDER BY works for select * from authoritative table", "query": "select * from authoritative order by col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from authoritative order by col1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id, col1, col2, weight_string(col1) from authoritative where 1 != 1", - "OrderBy": "(1|3) ASC", - "Query": "select user_id, col1, col2, weight_string(col1) from authoritative order by col1 asc", - "ResultColumns": 3, - "Table": "authoritative" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative order by col1", "Instructions": { @@ -518,24 +302,7 @@ { "comment": "ORDER BY on scatter with text column", "query": "select a, textcol1, b from user order by a, textcol1, b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, textcol1, b from user order by a, textcol1, b", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, textcol1, b, weight_string(a), weight_string(textcol1), weight_string(b) from `user` where 1 != 1", - "OrderBy": "(0|3) ASC, (1|4) ASC, (2|5) ASC", - "Query": "select a, textcol1, b, weight_string(a), weight_string(textcol1), weight_string(b) from `user` order by a asc, textcol1 asc, b asc", - "ResultColumns": 3, - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, textcol1, b from user order by a, textcol1, b", "Instructions": { @@ -559,24 +326,7 @@ { "comment": "ORDER BY on scatter with text column, qualified name TODO: can plan better", "query": "select a, user.textcol1, b from user order by a, textcol1, b", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, user.textcol1, b from user order by a, textcol1, b", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, `user`.textcol1, b, weight_string(a), weight_string(`user`.textcol1), weight_string(b) from `user` where 1 != 1", - "OrderBy": "(0|3) ASC, (1|4) ASC, (2|5) ASC", - "Query": "select a, `user`.textcol1, b, weight_string(a), weight_string(`user`.textcol1), weight_string(b) from `user` order by a asc, textcol1 asc, b asc", - "ResultColumns": 3, - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, user.textcol1, b from user order by a, textcol1, b", "Instructions": { @@ -600,24 +350,7 @@ { "comment": "ORDER BY on scatter with multiple text columns", "query": "select a, textcol1, b, textcol2 from user order by a, textcol1, b, textcol2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, textcol1, b, textcol2 from user order by a, textcol1, b, textcol2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a, textcol1, b, textcol2, weight_string(a), weight_string(textcol1), weight_string(b), weight_string(textcol2) from `user` where 1 != 1", - "OrderBy": "(0|4) ASC, (1|5) ASC, (2|6) ASC, (3|7) ASC", - "Query": "select a, textcol1, b, textcol2, weight_string(a), weight_string(textcol1), weight_string(b), weight_string(textcol2) from `user` order by a asc, textcol1 asc, b asc, textcol2 asc", - "ResultColumns": 4, - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, textcol1, b, textcol2 from user order by a, textcol1, b, textcol2", "Instructions": { @@ -641,30 +374,12 @@ { "comment": "ORDER BY invalid col number on scatter", "query": "select col from user order by 2", - "v3-plan": "VT03014: unknown column '2' in 'order clause'", - "gen4-plan": "Unknown column '2' in 'order clause'" + "plan": "Unknown column '2' in 'order clause'" }, { "comment": "ORDER BY column offset", "query": "select id as foo from music order by 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id as foo from music order by 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id as foo, weight_string(id) from music where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id as foo, weight_string(id) from music order by 1 asc", - "ResultColumns": 1, - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id as foo from music order by 1", "Instructions": { @@ -688,22 +403,7 @@ { "comment": "ORDER BY NULL", "query": "select col from user order by null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user order by null", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` order by null", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user order by null", "Instructions": { @@ -725,7 +425,7 @@ { "comment": "ORDER BY after pull-out subquery", "query": "select col from user where col in (select col2 from user) order by col", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where col in (select col2 from user) order by col", "Instructions": { @@ -760,100 +460,18 @@ "Table": "`user`" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "ORDER BY NULL for join", + "query": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by null", + "plan": { "QueryType": "SELECT", - "Original": "select col from user where col in (select col2 from user) order by col", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col2 from `user` where 1 != 1", - "Query": "select col2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "OrderBy": "0 ASC", - "Query": "select col from `user` where :__sq_has_values1 = 1 and col in ::__sq1 order by col asc", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "ORDER BY NULL for join", - "query": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by null", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_id": 2 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where `user`.id = 1 order by null", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id order by null", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by null", + "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by null", "Instructions": { "OperatorType": "Join", "Variant": "Join", @@ -904,52 +522,7 @@ { "comment": "ORDER BY non-key column for join", "query": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by a", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_id": 2 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where `user`.id = 1 order by a asc", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by a", "Instructions": { @@ -1002,52 +575,7 @@ { "comment": "ORDER BY non-key column for implicit join", "query": "select user.col1 as a, user.col2, music.col3 from user, music where user.id = music.id and user.id = 1 order by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user, music where user.id = music.id and user.id = 1 order by a", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_id": 2 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where `user`.id = 1 order by a asc", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2, music.col3 from user, music where user.id = music.id and user.id = 1 order by a", "Instructions": { @@ -1100,43 +628,7 @@ { "comment": "ORDER BY NULL after pull-out subquery", "query": "select col from user where col in (select col2 from user) order by null", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where col in (select col2 from user) order by null", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col2 from `user` where 1 != 1", - "Query": "select col2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where :__sq_has_values1 = 1 and col in ::__sq1 order by null", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where col in (select col2 from user) order by null", "Instructions": { @@ -1179,22 +671,7 @@ { "comment": "ORDER BY RAND()", "query": "select col from user order by RAND()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user order by RAND()", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` order by RAND()", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user order by RAND()", "Instructions": { @@ -1216,52 +693,7 @@ { "comment": "ORDER BY RAND() for join", "query": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by RAND()", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by RAND()", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_id": 2 - }, - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2, `user`.id from `user` where `user`.id = 1 order by RAND()", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.col3 from music where 1 != 1", - "Query": "select music.col3 from music where music.id = :user_id order by RAND()", - "Table": "music", - "Values": [ - ":user_id" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a, user.col2, music.col3 from user join music on user.id = music.id where user.id = 1 order by RAND()", "Instructions": { @@ -1314,7 +746,7 @@ { "comment": "ORDER BY RAND() after pull-out subquery", "query": "select col from user where col in (select col2 from user) order by rand()", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where col in (select col2 from user) order by rand()", "Instructions": { @@ -1348,73 +780,18 @@ "Table": "`user`" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "Order by, '*' expression", + "query": "select * from user where id = 5 order by col", + "plan": { "QueryType": "SELECT", - "Original": "select col from user where col in (select col2 from user) order by rand()", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col2 from `user` where 1 != 1", - "Query": "select col2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where :__sq_has_values1 = 1 and col in ::__sq1 order by rand()", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "Order by, '*' expression", - "query": "select * from user where id = 5 order by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by col", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by col asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by col", + "Original": "select * from user where id = 5 order by col", "Instructions": { "OperatorType": "Route", "Variant": "EqualUnique", @@ -1438,26 +815,7 @@ { "comment": "Order by, qualified '*' expression", "query": "select user.* from user where id = 5 order by user.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.* from user where id = 5 order by user.col", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.* from `user` where 1 != 1", - "Query": "select `user`.* from `user` where id = 5 order by `user`.col asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.* from user where id = 5 order by user.col", "Instructions": { @@ -1483,26 +841,7 @@ { "comment": "Order by, '*' expression with qualified reference", "query": "select * from user where id = 5 order by user.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by user.col", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by `user`.col asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 5 order by user.col", "Instructions": { @@ -1528,44 +867,7 @@ { "comment": "Order by, '*' expression in a subquery", "query": "select u.id, e.id from user u join user_extra e where u.col = e.col and u.col in (select * from user where user.id = u.id order by col)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id, e.id from user u join user_extra e where u.col = e.col and u.col in (select * from user where user.id = u.id order by col)", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "u_col": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, u.col from `user` as u where 1 != 1", - "Query": "select u.id, u.col from `user` as u where u.col in (select * from `user` where `user`.id = u.id order by col asc)", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.id from user_extra as e where 1 != 1", - "Query": "select e.id from user_extra as e where e.col = :u_col", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id, e.id from user u join user_extra e where u.col = e.col and u.col in (select * from user where user.id = u.id order by col)", "Instructions": { @@ -1610,8 +912,7 @@ { "comment": "Order by, verify outer symtab is searched according to its own context.", "query": "select u.id from user u having u.id in (select col2 from user where user.id = u.id order by u.col)", - "v3-plan": "VT03020: column u.col not found in subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user u having u.id in (select col2 from user where user.id = u.id order by u.col)", "Instructions": { @@ -1633,44 +934,22 @@ { "comment": "Order by, qualified '*' expression, name mismatched.", "query": "select user.* from user where id = 5 order by e.col", - "v3-plan": "VT03019: column e.col not found", - "gen4-plan": "column 'e.col' not found" + "plan": "column 'e.col' not found" }, { "comment": "Order by, invalid column number", "query": "select col from user order by 18446744073709551616", - "v3-plan": "VT13001: [BUG] error parsing column number: 18446744073709551616", - "gen4-plan": "error parsing column number: 18446744073709551616" + "plan": "error parsing column number: 18446744073709551616" }, { "comment": "Order by, out of range column number", "query": "select col from user order by 2", - "v3-plan": "VT03014: unknown column '2' in 'order clause'", - "gen4-plan": "Unknown column '2' in 'order clause'" + "plan": "Unknown column '2' in 'order clause'" }, { "comment": "Order by, '*' expression with qualified reference and using collate", "query": "select * from user where id = 5 order by user.col collate utf8_general_ci", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by user.col collate utf8_general_ci", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by `user`.col collate utf8_general_ci asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 5 order by user.col collate utf8_general_ci", "Instructions": { @@ -1696,26 +975,7 @@ { "comment": "Order by with math functions", "query": "select * from user where id = 5 order by -col1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by -col1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by -col1 asc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 5 order by -col1", "Instructions": { @@ -1741,26 +1001,7 @@ { "comment": "Order by with string operations", "query": "select * from user where id = 5 order by concat(col,col1) collate utf8_general_ci desc", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by concat(col,col1) collate utf8_general_ci desc", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by concat(col, col1) collate utf8_general_ci desc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 5 order by concat(col,col1) collate utf8_general_ci desc", "Instructions": { @@ -1786,26 +1027,7 @@ { "comment": "Order by with math operations", "query": "select * from user where id = 5 order by id+col collate utf8_general_ci desc", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 5 order by id+col collate utf8_general_ci desc", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 order by id + col collate utf8_general_ci desc", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 5 order by id+col collate utf8_general_ci desc", "Instructions": { @@ -1831,26 +1053,7 @@ { "comment": "Order by derived table column", "query": "select * from user u join (select user_id from user_extra where user_id = 5) eu on u.id = eu.user_id where u.id = 5 order by eu.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user u join (select user_id from user_extra where user_id = 5) eu on u.id = eu.user_id where u.id = 5 order by eu.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` as u join (select user_id from user_extra where 1 != 1) as eu on u.id = eu.user_id where 1 != 1", - "Query": "select * from `user` as u join (select user_id from user_extra where user_id = 5) as eu on u.id = eu.user_id where u.id = 5 order by eu.user_id asc", - "Table": "`user`, user_extra", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user u join (select user_id from user_extra where user_id = 5) eu on u.id = eu.user_id where u.id = 5 order by eu.user_id", "Instructions": { @@ -1877,26 +1080,7 @@ { "comment": "routing rules: order by gets pushed for routes", "query": "select col from route1 where id = 1 order by col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from route1 where id = 1 order by col", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` as route1 where 1 != 1", - "Query": "select col from `user` as route1 where id = 1 order by col asc", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from route1 where id = 1 order by col", "Instructions": { @@ -1922,26 +1106,7 @@ { "comment": "LIMIT", "query": "select col1 from user where id = 1 limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1 from user where id = 1 limit 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1 from `user` where 1 != 1", - "Query": "select col1 from `user` where id = 1 limit 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1 from user where id = 1 limit 1", "Instructions": { @@ -1967,47 +1132,7 @@ { "comment": "limit for joins. Can't push down the limit because result\n# counts get multiplied by join operations.", "query": "select user.col from user join user_extra limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra limit 1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `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 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join user_extra limit 1", "Instructions": { @@ -2055,28 +1180,7 @@ { "comment": "limit for scatter", "query": "select col from user limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user limit 1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user limit 1", "Instructions": { @@ -2104,7 +1208,7 @@ { "comment": "limit for scatter with bind var", "query": "select col from user limit :a", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user limit :a", "Instructions": { @@ -2123,128 +1227,44 @@ "Table": "`user`" } ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select col from user limit :a", - "Instructions": { - "OperatorType": "Limit", - "Count": ":a", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "cross-shard expression in parenthesis with limit", - "query": "select * from user where (id1 = 4 AND name1 ='abc') limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id1 = 4 AND name1 ='abc') limit 5", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id1 = 4 and name1 = 'abc' limit :__upper_limit", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id1 = 4 AND name1 ='abc') limit 5", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id1 = 4 and name1 = 'abc' limit :__upper_limit", - "Table": "`user`" - } - ] }, "TablesUsed": [ "user.user" - ] - } - }, - { - "comment": "scatter limit after pullout subquery", - "query": "select col from user where col in (select col1 from user) limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from user where col in (select col1 from user) limit 1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1 from `user` where 1 != 1", - "Query": "select col1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` where :__sq_has_values1 = 1 and col in ::__sq1 limit :__upper_limit", - "Table": "`user`" - } - ] + ] + } + }, + { + "comment": "cross-shard expression in parenthesis with limit", + "query": "select * from user where (id1 = 4 AND name1 ='abc') limit 5", + "plan": { + "QueryType": "SELECT", + "Original": "select * from user where (id1 = 4 AND name1 ='abc') limit 5", + "Instructions": { + "OperatorType": "Limit", + "Count": "INT64(5)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select * from `user` where 1 != 1", + "Query": "select * from `user` where id1 = 4 and name1 = 'abc' limit :__upper_limit", + "Table": "`user`" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "scatter limit after pullout subquery", + "query": "select col from user where col in (select col1 from user) limit 1", + "plan": { "QueryType": "SELECT", "Original": "select col from user where col in (select col1 from user) limit 1", "Instructions": { @@ -2293,22 +1313,7 @@ { "comment": "limit on reference table", "query": "select col from ref limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from ref limit 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from ref where 1 != 1", - "Query": "select col from ref limit 1", - "Table": "ref" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from ref limit 1", "Instructions": { @@ -2330,28 +1335,7 @@ { "comment": "arithmetic limit", "query": "select id from user limit 1+1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user limit 1+1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(2)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user limit 1+1", "Instructions": { @@ -2379,24 +1363,7 @@ { "comment": "order by column alias", "query": "select id as foo from music order by foo", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id as foo from music order by foo", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id as foo, weight_string(id) from music where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id as foo, weight_string(id) from music order by foo asc", - "ResultColumns": 1, - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id as foo from music order by foo", "Instructions": { @@ -2420,24 +1387,7 @@ { "comment": "column alias for a table column in order by", "query": "select id as foo, id2 as id from music order by id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id as foo, id2 as id from music order by id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id as foo, id2 as id, weight_string(id2) from music where 1 != 1", - "OrderBy": "(1|2) ASC", - "Query": "select id as foo, id2 as id, weight_string(id2) from music order by id asc", - "ResultColumns": 2, - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id as foo, id2 as id from music order by id", "Instructions": { @@ -2461,43 +1411,7 @@ { "comment": "ordering on the left side of the join", "query": "select name from user, music order by name", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select name from user, music order by name", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `name`, weight_string(`name`) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select `name`, weight_string(`name`) from `user` order by `name` asc", - "ResultColumns": 1, - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select 1 from music", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select name from user, music order by name", "Instructions": { @@ -2540,29 +1454,7 @@ { "comment": "aggregation and non-aggregations column without group by", "query": "select count(id), num from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(id), num from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(id), num from `user` where 1 != 1", - "Query": "select count(id), num from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(id), num from user", "Instructions": { @@ -2591,38 +1483,7 @@ { "comment": "aggregation and non-aggregations column with order by", "query": "select count(id), num from user order by 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(id), num from user order by 2", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "(1|2) ASC", - "ResultColumns": 2, - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "ResultColumns": 3, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(id), num, weight_string(num) from `user` where 1 != 1", - "Query": "select count(id), num, weight_string(num) from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(id), num from user order by 2", "Instructions": { @@ -2659,32 +1520,7 @@ { "comment": "aggregation and non-aggregations column with group by", "query": "select count(id), num from user group by 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(id), num from user group by 2", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(0) AS count", - "GroupBy": "1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(id), num, weight_string(num) from `user` where 1 != 1 group by 2, weight_string(num)", - "OrderBy": "(1|2) ASC", - "Query": "select count(id), num, weight_string(num) from `user` group by 2, weight_string(num) order by num asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(id), num from user group by 2", "Instructions": { @@ -2716,39 +1552,7 @@ { "comment": "aggregation and non-aggregations column with group by and order by", "query": "select count(id), num from user group by 2 order by 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(id), num from user group by 2 order by 1", - "Instructions": { - "OperatorType": "Sort", - "Variant": "Memory", - "OrderBy": "0 ASC", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "Aggregates": "sum_count(0) AS count", - "GroupBy": "1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(id), num, weight_string(num) from `user` where 1 != 1 group by 2, weight_string(num)", - "OrderBy": "(1|2) ASC", - "Query": "select count(id), num, weight_string(num) from `user` group by 2, weight_string(num) order by num asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(id), num from user group by 2 order by 1", "Instructions": { @@ -2787,8 +1591,7 @@ { "comment": "join order by with ambiguous column reference ; valid in MySQL", "query": "select name, name from user, music order by name", - "v3-plan": "VT03021: ambiguous column reference: `name`", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select name, name from user, music order by name", "Instructions": { @@ -2831,8 +1634,7 @@ { "comment": "order by with ambiguous column reference ; valid in MySQL", "query": "select id, id from user order by id", - "v3-plan": "VT03021: ambiguous column reference: id", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, id from user order by id", "Instructions": { @@ -2856,8 +1658,7 @@ { "comment": "Scatter order by and aggregation: order by column must reference column from select list", "query": "select col, count(*) from user group by col order by c1", - "v3-plan": "VT12001: unsupported: memory sort: ORDER BY must reference a column in the SELECT list: c1 asc", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col, count(*) from user group by col order by c1", "Instructions": { @@ -2896,46 +1697,7 @@ { "comment": "Distinct with cross shard query", "query": "select distinct user.a from user join user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct user.a from user join user_extra", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.a from `user` where 1 != 1", - "Query": "select `user`.a from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct user.a from user join user_extra", "Instructions": { @@ -2986,31 +1748,7 @@ { "comment": "Distinct with column alias", "query": "select distinct a as c, a from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select distinct a as c, a from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Ordered", - "GroupBy": "0, 1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a as c, a, weight_string(a) from `user` where 1 != 1", - "OrderBy": "(0|2) ASC, (0|2) ASC", - "Query": "select distinct a as c, a, weight_string(a) from `user` order by c asc, a asc", - "ResultColumns": 2, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct a as c, a from user", "Instructions": { @@ -3041,8 +1779,7 @@ { "comment": "Distinct with same column", "query": "select distinct a, a from user", - "v3-plan": "generating ORDER BY clause: VT03021: ambiguous column reference: a", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select distinct a, a from user", "Instructions": { @@ -3073,8 +1810,7 @@ { "comment": "Order by has subqueries", "query": "select id from unsharded order by (select id from unsharded)", - "v3-plan": "VT12001: unsupported: subqueries disallowed in sqlparser.OrderBy", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from unsharded order by (select id from unsharded)", "Instructions": { @@ -3096,8 +1832,7 @@ { "comment": "Equal filter with hexadecimal value", "query": "select count(*) a from user having a = 0x01", - "v3-plan": "VT12001: unsupported: filtering on results of aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) a from user having a = 0x01", "Instructions": { @@ -3132,8 +1867,7 @@ { "comment": "Order by uses cross-shard expression", "query": "select id from user order by id+1", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: id + 1", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user order by id+1", "Instructions": { @@ -3157,8 +1891,7 @@ { "comment": "Order by column number with collate", "query": "select user.col1 as a from user order by 1 collate utf8_general_ci", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: 1 collate utf8_general_ci", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a from user order by 1 collate utf8_general_ci", "Instructions": { @@ -3182,8 +1915,7 @@ { "comment": "Order by uses cross-shard expression", "query": "select id from user order by id+1", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: id + 1", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user order by id+1", "Instructions": { @@ -3207,8 +1939,7 @@ { "comment": "Order by column number with collate", "query": "select user.col1 as a from user order by 1 collate utf8_general_ci", - "v3-plan": "VT12001: unsupported: in scatter query: complex ORDER BY expression: 1 collate utf8_general_ci", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col1 as a from user order by 1 collate utf8_general_ci", "Instructions": { @@ -3232,8 +1963,7 @@ { "comment": "Order by column number with coalesce with columns from both sides", "query": "select id from user, user_extra order by coalesce(user.col, user_extra.col)", - "v3-plan": "VT12001: unsupported: memory sort: complex ORDER BY expression: coalesce(`user`.col, user_extra.col)", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user, user_extra order by coalesce(user.col, user_extra.col)", "Instructions": { @@ -3286,8 +2016,7 @@ { "comment": "having filter with %", "query": "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", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "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": { diff --git a/go/vt/vtgate/planbuilder/testdata/rails_cases.json b/go/vt/vtgate/planbuilder/testdata/rails_cases.json index 94ed9961b87..ef36b79c855 100644 --- a/go/vt/vtgate/planbuilder/testdata/rails_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/rails_cases.json @@ -2,122 +2,7 @@ { "comment": "Author5.joins(books: [{orders: :customer}, :supplier])", "query": "select 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", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 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": "L:0,L:1,L:2,L:3", - "JoinVars": { - "book6s_supplier5_id": 4 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s_customer2s_supplier5s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,L:2,L:3,L:4", - "JoinVars": { - "order2s_customer2_id": 5 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s_customer2s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,L:2,L:3,L:4,R:0", - "JoinVars": { - "book6s_order2s_order2_id": 5 - }, - "TableName": "author5s, book6s_book6s_order2s_order2s", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,L:2,L:3,L:4,R:0", - "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 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 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 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 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 1 from supplier5s where supplier5s.id = :book6s_supplier5_id", - "Table": "supplier5s", - "Values": [ - ":book6s_supplier5_id" - ], - "Vindex": "binary_md5" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 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": { diff --git a/go/vt/vtgate/planbuilder/testdata/reference_cases.json b/go/vt/vtgate/planbuilder/testdata/reference_cases.json index 289e23b0b07..351cb54190e 100644 --- a/go/vt/vtgate/planbuilder/testdata/reference_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/reference_cases.json @@ -2,22 +2,7 @@ { "comment": "select from unqualified ambiguous reference routes to reference source", "query": "select * from ambiguous_ref_with_source", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from ambiguous_ref_with_source", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from ambiguous_ref_with_source where 1 != 1", - "Query": "select * from ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from ambiguous_ref_with_source", "Instructions": { @@ -39,41 +24,7 @@ { "comment": "join with unqualified ambiguous reference table routes to optimal keyspace", "query": "select user.col from user join ambiguous_ref_with_source", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join ambiguous_ref_with_source", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_ambiguous_ref_with_source", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from ambiguous_ref_with_source where 1 != 1", - "Query": "select 1 from ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join ambiguous_ref_with_source", "Instructions": { @@ -96,22 +47,7 @@ { "comment": "ambiguous unqualified reference table self-join routes to reference source", "query": "select r1.col from ambiguous_ref_with_source r1 join ambiguous_ref_with_source", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select r1.col from ambiguous_ref_with_source r1 join ambiguous_ref_with_source", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select r1.col from ambiguous_ref_with_source as r1 join ambiguous_ref_with_source where 1 != 1", - "Query": "select r1.col from ambiguous_ref_with_source as r1 join ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select r1.col from ambiguous_ref_with_source r1 join ambiguous_ref_with_source", "Instructions": { @@ -133,41 +69,7 @@ { "comment": "ambiguous unqualified reference table can merge with other opcodes left to right.", "query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join user", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "ambiguous_ref_with_source_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source where 1 != 1", - "Query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join user", "Instructions": { @@ -190,45 +92,7 @@ { "comment": "ambiguous unqualified reference table can merge with other opcodes left to right and vindex value is in the plan", "query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join (select aa from user where user.id=1) user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join (select aa from user where user.id=1) user", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "ambiguous_ref_with_source_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source where 1 != 1", - "Query": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from (select aa from `user` where 1 != 1) as `user` where 1 != 1", - "Query": "select 1 from (select aa from `user` where `user`.id = 1) as `user`", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ambiguous_ref_with_source.col from ambiguous_ref_with_source join (select aa from user where user.id=1) user", "Instructions": { @@ -255,41 +119,7 @@ { "comment": "qualified join to reference table routes to optimal keyspace", "query": "select user.col from user join main.ambiguous_ref_with_source", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join main.ambiguous_ref_with_source", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_ambiguous_ref_with_source", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from ambiguous_ref_with_source where 1 != 1", - "Query": "select 1 from ambiguous_ref_with_source", - "Table": "ambiguous_ref_with_source" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join main.ambiguous_ref_with_source", "Instructions": { @@ -332,27 +162,9 @@ } }, { - "comment": "insert into qualified ambiguous reference table routes v3 to requested keyspace gen4 to source", + "comment": "insert into qualified ambiguous reference table routes to source", "query": "insert into user.ambiguous_ref_with_source(col) values(1)", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user.ambiguous_ref_with_source(col) values(1)", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Sharded", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into ambiguous_ref_with_source(col) values (1)", - "TableName": "ambiguous_ref_with_source" - }, - "TablesUsed": [ - "user.ambiguous_ref_with_source" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user.ambiguous_ref_with_source(col) values(1)", "Instructions": { @@ -394,10 +206,9 @@ } }, { - "comment": "update qualified ambiguous reference table v3 error no primary vindex v4 route to source", + "comment": "update qualified ambiguous reference table route to source", "query": "update user.ambiguous_ref_with_source set col = 1", - "v3-plan": "VT09001: table 'ambiguous_ref_with_source' does not have a primary vindex", - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "update user.ambiguous_ref_with_source set col = 1", "Instructions": { @@ -439,10 +250,9 @@ } }, { - "comment": "delete from qualified ambiguous reference table v3 error no primary vindex v4 route to source", + "comment": "delete from qualified ambiguous reference table route to source", "query": "delete from user.ambiguous_ref_with_source where col = 1", - "v3-plan": "VT09001: table 'ambiguous_ref_with_source' does not have a primary vindex", - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "delete from user.ambiguous_ref_with_source where col = 1", "Instructions": { @@ -464,22 +274,7 @@ { "comment": "join with unqualified unambiguous ref with source routes to requested table", "query": "select user.col from user join ref_with_source", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join ref_with_source", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` join ref_with_source where 1 != 1", - "Query": "select `user`.col from `user` join ref_with_source", - "Table": "`user`, ref_with_source" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join ref_with_source", "Instructions": { @@ -502,41 +297,7 @@ { "comment": "join with unqualified reference optimize routes when source & reference have different names", "query": "select user.col from user join source_of_ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join source_of_ref", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_source_of_ref", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from source_of_ref where 1 != 1", - "Query": "select 1 from source_of_ref", - "Table": "source_of_ref" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join source_of_ref", "Instructions": { @@ -559,41 +320,7 @@ { "comment": "join with unqualified reference respects routing rules", "query": "select user.col from user join rerouted_ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join rerouted_ref", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_rerouted_ref", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from rerouted_ref where 1 != 1", - "Query": "select 1 from rerouted_ref", - "Table": "rerouted_ref" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join rerouted_ref", "Instructions": { @@ -616,41 +343,7 @@ { "comment": "join with reference to unqualified source routes to optimal keyspace", "query": "select user.col from user join global_ref", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join global_ref", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_global_ref", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from global_ref where 1 != 1", - "Query": "select 1 from global_ref", - "Table": "global_ref" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col from user join global_ref", "Instructions": { @@ -671,27 +364,9 @@ } }, { - "comment": "insert into qualified reference with unqualified source routes v3 to requested keyspace gen4 to source", + "comment": "insert into qualified reference with unqualified source routes to source", "query": "insert into user.global_ref(col) values(1)", - "v3-plan": { - "QueryType": "INSERT", - "Original": "insert into user.global_ref(col) values(1)", - "Instructions": { - "OperatorType": "Insert", - "Variant": "Sharded", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "insert into global_ref(col) values (1)", - "TableName": "global_ref" - }, - "TablesUsed": [ - "user.global_ref" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "INSERT", "Original": "insert into user.global_ref(col) values(1)", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index b0cef24cce9..825e405a50d 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -2,22 +2,7 @@ { "comment": "No column referenced", "query": "select 1 from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user", "Instructions": { @@ -39,22 +24,7 @@ { "comment": "'*' expression for simple route", "query": "select user.* from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.* from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.* from `user` where 1 != 1", - "Query": "select `user`.* from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.* from user", "Instructions": { @@ -76,22 +46,7 @@ { "comment": "unqualified '*' expression for simple route", "query": "select * from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user", "Instructions": { @@ -113,23 +68,7 @@ { "comment": "select with timeout directive sets QueryTimeout in the route", "query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from `user`", - "QueryTimeout": 1000, - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user", "Instructions": { @@ -152,30 +91,7 @@ { "comment": "select aggregation with timeout directive sets QueryTimeout in the route", "query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ count(*) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ count(*) from `user`", - "QueryTimeout": 1000, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ count(*) from user", "Instructions": { @@ -205,29 +121,7 @@ { "comment": "select limit with timeout directive sets QueryTimeout in the route", "query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from `user` limit :__upper_limit", - "QueryTimeout": 1000, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from user limit 10", "Instructions": { @@ -256,23 +150,7 @@ { "comment": "select limit with timeout directive sets QueryTimeout in the route", "query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from main.unsharded limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from main.unsharded limit 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded where 1 != 1", - "Query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from unsharded limit 10", - "QueryTimeout": 1000, - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from main.unsharded limit 10", "Instructions": { @@ -295,23 +173,7 @@ { "comment": "select with partial scatter directive", "query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS */ * from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS */ * from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS */ * from `user`", - "ScatterErrorsAsWarnings": true, - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS */ * from user", "Instructions": { @@ -334,30 +196,7 @@ { "comment": "select aggregation with partial scatter directive", "query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from `user`", - "ScatterErrorsAsWarnings": true, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", "Instructions": { @@ -387,30 +226,7 @@ { "comment": "select aggregation with partial scatter directive - added comments to try to confuse the hint extraction", "query": "/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from `user`", - "ScatterErrorsAsWarnings": true, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", "Instructions": { @@ -440,29 +256,7 @@ { "comment": "select limit with partial scatter directive", "query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from user limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from user limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from `user` limit :__upper_limit", - "ScatterErrorsAsWarnings": true, - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from user limit 10", "Instructions": { @@ -491,22 +285,7 @@ { "comment": "qualified '*' expression for simple route", "query": "select user.* from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.* from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.* from `user` where 1 != 1", - "Query": "select `user`.* from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.* from user", "Instructions": { @@ -528,22 +307,7 @@ { "comment": "fully qualified '*' expression for simple route", "query": "select user.user.* from user.user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.user.* from user.user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.* from `user` where 1 != 1", - "Query": "select `user`.* from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.user.* from user.user", "Instructions": { @@ -565,22 +329,7 @@ { "comment": "select * from authoritative table", "query": "select * from authoritative", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from authoritative", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id, col1, col2 from authoritative where 1 != 1", - "Query": "select user_id, col1, col2 from authoritative", - "Table": "authoritative" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative", "Instructions": { @@ -602,22 +351,7 @@ { "comment": "select * from join of authoritative tables", "query": "select * from authoritative a join authoritative b on a.user_id=b.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from authoritative a join authoritative b on a.user_id=b.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a.user_id as user_id, a.col1 as col1, a.col2 as col2, b.user_id as user_id, b.col1 as col1, b.col2 as col2 from authoritative as a join authoritative as b on a.user_id = b.user_id where 1 != 1", - "Query": "select a.user_id as user_id, a.col1 as col1, a.col2 as col2, b.user_id as user_id, b.col1 as col1, b.col2 as col2 from authoritative as a join authoritative as b on a.user_id = b.user_id", - "Table": "authoritative" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative a join authoritative b on a.user_id=b.user_id", "Instructions": { @@ -639,28 +373,12 @@ { "comment": "test table lookup failure for authoritative code path", "query": "select a.* from authoritative", - "v3-plan": "VT05004: table 'a' does not exist", - "gen4-plan": "Unknown table 'a'" + "plan": "Unknown table 'a'" }, { "comment": "select * from qualified authoritative table", "query": "select a.* from authoritative a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a.* from authoritative a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a.user_id, a.col1, a.col2 from authoritative as a where 1 != 1", - "Query": "select a.user_id, a.col1, a.col2 from authoritative as a", - "Table": "authoritative" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a.* from authoritative a", "Instructions": { @@ -682,22 +400,7 @@ { "comment": "select * from intermixing of authoritative table with non-authoritative results in no expansion", "query": "select * from authoritative join user on authoritative.user_id=user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from authoritative join user on authoritative.user_id=user.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from authoritative join `user` on authoritative.user_id = `user`.id where 1 != 1", - "Query": "select * from authoritative join `user` on authoritative.user_id = `user`.id", - "Table": "authoritative, `user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from authoritative join user on authoritative.user_id=user.id", "Instructions": { @@ -720,22 +423,7 @@ { "comment": "select authoritative.* with intermixing still expands", "query": "select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, a.user_id, a.col1, a.col2, `user`.col1 from authoritative as a join `user` on a.user_id = `user`.id where 1 != 1", - "Query": "select `user`.id, a.user_id, a.col1, a.col2, `user`.col1 from authoritative as a join `user` on a.user_id = `user`.id", - "Table": "authoritative, `user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id, a.*, user.col1 from authoritative a join user on a.user_id=user.id", "Instructions": { @@ -758,22 +446,7 @@ { "comment": "auto-resolve anonymous columns for simple route", "query": "select anon_col from user join user_extra on user.id = user_extra.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select anon_col from user join user_extra on user.id = user_extra.user_id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select anon_col from `user` join user_extra on `user`.id = user_extra.user_id where 1 != 1", - "Query": "select anon_col from `user` join user_extra on `user`.id = user_extra.user_id", - "Table": "`user`, user_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select anon_col from user join user_extra on user.id = user_extra.user_id", "Instructions": { @@ -796,47 +469,12 @@ { "comment": "Cannot auto-resolve for cross-shard joins", "query": "select col from user join user_extra", - "v3-plan": "VT03019: column col not found", - "gen4-plan": "Column 'col' in field list is ambiguous" + "plan": "Column 'col' in field list is ambiguous" }, { "comment": "Auto-resolve should work if unique vindex columns are referenced", "query": "select id, user_id from user join user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, user_id from user join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id from user_extra where 1 != 1", - "Query": "select user_id from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, user_id from user join user_extra", "Instructions": { @@ -878,22 +516,7 @@ { "comment": "database calls should be substituted", "query": "select database() from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select database() from dual", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - ":__vtdbname as database()" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select database() from dual", "Instructions": { @@ -915,22 +538,7 @@ { "comment": "last_insert_id for unsharded route", "query": "select last_insert_id() as x from main.unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select last_insert_id() as x from main.unsharded", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select :__lastInsertId as x from unsharded where 1 != 1", - "Query": "select :__lastInsertId as x from unsharded", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select last_insert_id() as x from main.unsharded", "Instructions": { @@ -952,22 +560,7 @@ { "comment": "select from dual on unqualified keyspace", "query": "select @@session.auto_increment_increment from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select @@session.auto_increment_increment from dual", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select @@auto_increment_increment from dual where 1 != 1", - "Query": "select @@auto_increment_increment from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select @@session.auto_increment_increment from dual", "Instructions": { @@ -989,26 +582,7 @@ { "comment": "select from pinned table", "query": "select * from pin_test", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from pin_test", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from pin_test where 1 != 1", - "Query": "select * from pin_test", - "Table": "pin_test", - "Values": [ - "VARCHAR(\"\\x80\")" - ], - "Vindex": "binary" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from pin_test", "Instructions": { @@ -1039,7 +613,7 @@ { "comment": "RHS route referenced", "query": "select user_extra.id from user join user_extra", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.id from user join user_extra", "Instructions": { @@ -1071,15 +645,23 @@ "Table": "user_extra" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "Both routes referenced", + "query": "select user.col, user_extra.id from user join user_extra", + "plan": { "QueryType": "SELECT", - "Original": "select user_extra.id from user join user_extra", + "Original": "select user.col, user_extra.id from user join user_extra", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "R:0", + "JoinColumnIndexes": "L:0,R:0", "TableName": "`user`_user_extra", "Inputs": [ { @@ -1089,8 +671,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user`", + "FieldQuery": "select `user`.col from `user` where 1 != 1", + "Query": "select `user`.col from `user`", "Table": "`user`" }, { @@ -1113,11 +695,11 @@ } }, { - "comment": "Both routes referenced", - "query": "select user.col, user_extra.id from user join user_extra", - "v3-plan": { + "comment": "Expression with single-route reference", + "query": "select user.col, user_extra.id + user_extra.col from user join user_extra", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id from user join user_extra", + "Original": "select user.col, user_extra.id + user_extra.col from user join user_extra", "Instructions": { "OperatorType": "Join", "Variant": "Join", @@ -1142,20 +724,28 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra", + "FieldQuery": "select user_extra.id + user_extra.col from user_extra where 1 != 1", + "Query": "select user_extra.id + user_extra.col from user_extra", "Table": "user_extra" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "Jumbled references", + "query": "select user.col, user_extra.id, user.col2 from user join user_extra", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id from user join user_extra", + "Original": "select user.col, user_extra.id, user.col2 from user join user_extra", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", + "JoinColumnIndexes": "L:0,R:0,L:1", "TableName": "`user`_user_extra", "Inputs": [ { @@ -1165,8 +755,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", + "FieldQuery": "select `user`.col, `user`.col2 from `user` where 1 != 1", + "Query": "select `user`.col, `user`.col2 from `user`", "Table": "`user`" }, { @@ -1189,15 +779,15 @@ } }, { - "comment": "Expression with single-route reference", - "query": "select user.col, user_extra.id + user_extra.col from user join user_extra", - "v3-plan": { + "comment": "Comments", + "query": "select /* comment */ user.col from user join user_extra", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id + user_extra.col from user join user_extra", + "Original": "select /* comment */ user.col from user join user_extra", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", + "JoinColumnIndexes": "L:0", "TableName": "`user`_user_extra", "Inputs": [ { @@ -1208,7 +798,7 @@ "Sharded": true }, "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", + "Query": "select /* comment */ `user`.col from `user`", "Table": "`user`" }, { @@ -1218,20 +808,28 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select user_extra.id + user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.id + user_extra.col from user_extra", + "FieldQuery": "select 1 from user_extra where 1 != 1", + "Query": "select /* comment */ 1 from user_extra", "Table": "user_extra" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, + { + "comment": "for update", + "query": "select user.col from user join user_extra for update", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id + user_extra.col from user join user_extra", + "Original": "select user.col from user join user_extra for update", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", + "JoinColumnIndexes": "L:0", "TableName": "`user`_user_extra", "Inputs": [ { @@ -1242,7 +840,7 @@ "Sharded": true }, "FieldQuery": "select `user`.col from `user` where 1 != 1", - "Query": "select `user`.col from `user`", + "Query": "select `user`.col from `user` for update", "Table": "`user`" }, { @@ -1252,8 +850,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select user_extra.id + user_extra.col from user_extra where 1 != 1", - "Query": "select user_extra.id + user_extra.col from user_extra", + "FieldQuery": "select 1 from user_extra where 1 != 1", + "Query": "select 1 from user_extra for update", "Table": "user_extra" } ] @@ -1265,16 +863,19 @@ } }, { - "comment": "Jumbled references", - "query": "select user.col, user_extra.id, user.col2 from user join user_extra", - "v3-plan": { + "comment": "Field query should work for joins select bind vars", + "query": "select user.id, (select user.id+outm.m+unsharded.m from unsharded) from user join unsharded outm", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id, user.col2 from user join user_extra", + "Original": "select user.id, (select user.id+outm.m+unsharded.m from unsharded) from user join unsharded outm", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0,L:1", - "TableName": "`user`_user_extra", + "JoinColumnIndexes": "L:0,R:0", + "JoinVars": { + "user_id": 0 + }, + "TableName": "`user`_unsharded", "Inputs": [ { "OperatorType": "Route", @@ -1283,31 +884,39 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select `user`.col, `user`.col2 from `user` where 1 != 1", - "Query": "select `user`.col, `user`.col2 from `user`", + "FieldQuery": "select `user`.id from `user` where 1 != 1", + "Query": "select `user`.id from `user`", "Table": "`user`" }, { "OperatorType": "Route", - "Variant": "Scatter", + "Variant": "Unsharded", "Keyspace": { - "Name": "user", - "Sharded": true + "Name": "main", + "Sharded": false }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra", - "Table": "user_extra" + "FieldQuery": "select (select :user_id + outm.m + unsharded.m from unsharded where 1 != 1) from unsharded as outm where 1 != 1", + "Query": "select (select :user_id + outm.m + unsharded.m from unsharded) from unsharded as outm", + "Table": "unsharded" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "main.unsharded", + "user.user" + ] + } + }, + { + "comment": "Case preservation", + "query": "select user.Col, user_extra.Id from user join user_extra", + "plan": { "QueryType": "SELECT", - "Original": "select user.col, user_extra.id, user.col2 from user join user_extra", + "Original": "select user.Col, user_extra.Id from user join user_extra", "Instructions": { "OperatorType": "Join", "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0,L:1", + "JoinColumnIndexes": "L:0,R:0", "TableName": "`user`_user_extra", "Inputs": [ { @@ -1317,8 +926,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select `user`.col, `user`.col2 from `user` where 1 != 1", - "Query": "select `user`.col, `user`.col2 from `user`", + "FieldQuery": "select `user`.Col from `user` where 1 != 1", + "Query": "select `user`.Col from `user`", "Table": "`user`" }, { @@ -1328,8 +937,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select user_extra.id from user_extra where 1 != 1", - "Query": "select user_extra.id from user_extra", + "FieldQuery": "select user_extra.Id from user_extra where 1 != 1", + "Query": "select user_extra.Id from user_extra", "Table": "user_extra" } ] @@ -1341,339 +950,14 @@ } }, { - "comment": "Comments", - "query": "select /* comment */ user.col from user join user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /* comment */ user.col from user join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 /* comment */ `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 /* comment */ 1 from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select /* comment */ user.col from user join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 /* comment */ `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 /* comment */ 1 from user_extra", - "Table": "user_extra" - } - ] - }, - "TablesUsed": [ - "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "for update", - "query": "select user.col from user join user_extra for update", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra for update", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `user`.col from `user` for update", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra for update", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.col from user join user_extra for update", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L: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 `user`.col from `user` for update", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra for update", - "Table": "user_extra" - } - ] - }, - "TablesUsed": [ - "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "Field query should work for joins select bind vars", - "query": "select user.id, (select user.id+outm.m+unsharded.m from unsharded) from user join unsharded outm", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.id, (select user.id+outm.m+unsharded.m from unsharded) from user join unsharded outm", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select (select :user_id + outm.m + unsharded.m from unsharded where 1 != 1) from unsharded as outm where 1 != 1", - "Query": "select (select :user_id + outm.m + unsharded.m from unsharded) from unsharded as outm", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.id, (select user.id+outm.m+unsharded.m from unsharded) from user join unsharded outm", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select (select :user_id + outm.m + unsharded.m from unsharded where 1 != 1) from unsharded as outm where 1 != 1", - "Query": "select (select :user_id + outm.m + unsharded.m from unsharded) from unsharded as outm", - "Table": "unsharded" - } - ] - }, - "TablesUsed": [ - "main.unsharded", - "user.user" - ] - } - }, - { - "comment": "Case preservation", - "query": "select user.Col, user_extra.Id from user join user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.Col, user_extra.Id from user join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R: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 `user`.Col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.Id from user_extra where 1 != 1", - "Query": "select user_extra.Id from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select user.Col, user_extra.Id from user join user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R: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 `user`.Col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.Id from user_extra where 1 != 1", - "Query": "select user_extra.Id from user_extra", - "Table": "user_extra" - } - ] - }, - "TablesUsed": [ - "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "syntax error", - "query": "the quick brown fox", - "plan": "syntax error at position 4 near 'the'" - }, - { - "comment": "Hex number is not treated as a simple value", - "query": "select * from user where id = 0x04", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 0x04", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 0x04", - "Table": "`user`" - } - }, - "gen4-plan": { + "comment": "syntax error", + "query": "the quick brown fox", + "plan": "syntax error at position 4 near 'the'" + }, + { + "comment": "Hex number is not treated as a simple value", + "query": "select * from user where id = 0x04", + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 0x04", "Instructions": { @@ -1699,31 +983,7 @@ { "comment": "sharded limit offset", "query": "select user_id from music order by user_id limit 10, 20", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_id from music order by user_id limit 10, 20", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(20)", - "Offset": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id, weight_string(user_id) from music where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select user_id, weight_string(user_id) from music order by user_id asc limit :__upper_limit", - "ResultColumns": 1, - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_id from music order by user_id limit 10, 20", "Instructions": { @@ -1754,26 +1014,7 @@ { "comment": "Sharding Key Condition in Parenthesis", "query": "select * from user where name ='abc' AND (id = 4) limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where name ='abc' AND (id = 4) limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where `name` = 'abc' and id = 4 limit 5", - "Table": "`user`", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where name ='abc' AND (id = 4) limit 5", "Instructions": { @@ -1799,26 +1040,7 @@ { "comment": "Multiple parenthesized expressions", "query": "select * from user where (id = 4) AND (name ='abc') limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 4) AND (name ='abc') limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 4 and `name` = 'abc' limit 5", - "Table": "`user`", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where (id = 4) AND (name ='abc') limit 5", "Instructions": { @@ -1843,74 +1065,10 @@ }, { "comment": "Multiple parenthesized expressions", - "query": "select * from user where (id = 4 and name ='abc') limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 4 and name ='abc') limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 4 and `name` = 'abc' limit 5", - "Table": "`user`", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 4 and name ='abc') limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 4 and `name` = 'abc' limit 5", - "Table": "`user`", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.user" - ] - } - }, - { - "comment": "Column Aliasing with Table.Column", - "query": "select user0_.col as col0_ from user user0_ where id = 1 order by user0_.col desc limit 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user0_.col as col0_ from user user0_ where id = 1 order by user0_.col desc limit 2", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user0_.col as col0_ from `user` as user0_ where 1 != 1", - "Query": "select user0_.col as col0_ from `user` as user0_ where id = 1 order by user0_.col desc limit 2", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "query": "select * from user where (id = 4 and name ='abc') limit 5", + "plan": { "QueryType": "SELECT", - "Original": "select user0_.col as col0_ from user user0_ where id = 1 order by user0_.col desc limit 2", + "Original": "select * from user where (id = 4 and name ='abc') limit 5", "Instructions": { "OperatorType": "Route", "Variant": "EqualUnique", @@ -1918,11 +1076,11 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select user0_.col as col0_ from `user` as user0_ where 1 != 1", - "Query": "select user0_.col as col0_ from `user` as user0_ where id = 1 order by user0_.col desc limit 2", + "FieldQuery": "select * from `user` where 1 != 1", + "Query": "select * from `user` where id = 4 and `name` = 'abc' limit 5", "Table": "`user`", "Values": [ - "INT64(1)" + "INT64(4)" ], "Vindex": "user_index" }, @@ -1932,11 +1090,11 @@ } }, { - "comment": "Column Aliasing with Column", - "query": "select user0_.col as col0_ from user user0_ where id = 1 order by col0_ desc limit 3", - "v3-plan": { + "comment": "Column Aliasing with Table.Column", + "query": "select user0_.col as col0_ from user user0_ where id = 1 order by user0_.col desc limit 2", + "plan": { "QueryType": "SELECT", - "Original": "select user0_.col as col0_ from user user0_ where id = 1 order by col0_ desc limit 3", + "Original": "select user0_.col as col0_ from user user0_ where id = 1 order by user0_.col desc limit 2", "Instructions": { "OperatorType": "Route", "Variant": "EqualUnique", @@ -1945,15 +1103,22 @@ "Sharded": true }, "FieldQuery": "select user0_.col as col0_ from `user` as user0_ where 1 != 1", - "Query": "select user0_.col as col0_ from `user` as user0_ where id = 1 order by col0_ desc limit 3", + "Query": "select user0_.col as col0_ from `user` as user0_ where id = 1 order by user0_.col desc limit 2", "Table": "`user`", "Values": [ "INT64(1)" ], "Vindex": "user_index" - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.user" + ] + } + }, + { + "comment": "Column Aliasing with Column", + "query": "select user0_.col as col0_ from user user0_ where id = 1 order by col0_ desc limit 3", + "plan": { "QueryType": "SELECT", "Original": "select user0_.col as col0_ from user user0_ where id = 1 order by col0_ desc limit 3", "Instructions": { @@ -1979,26 +1144,7 @@ { "comment": "Booleans and parenthesis", "query": "select * from user where (id = 1) AND name = true limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 1) AND name = true limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 1 and `name` = true limit 5", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where (id = 1) AND name = true limit 5", "Instructions": { @@ -2024,26 +1170,7 @@ { "comment": "Column as boolean-ish", "query": "select * from user where (id = 1) AND name limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 1) AND name limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 1 and `name` limit 5", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where (id = 1) AND name limit 5", "Instructions": { @@ -2069,26 +1196,7 @@ { "comment": "PK as fake boolean, and column as boolean-ish", "query": "select * from user where (id = 5) AND name = true limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where (id = 5) AND name = true limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 5 and `name` = true limit 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where (id = 5) AND name = true limit 5", "Instructions": { @@ -2114,43 +1222,7 @@ { "comment": "top level subquery in select", "query": "select a, (select col from user) from unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, (select col from user) from unsharded", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a, :__sq1 from unsharded where 1 != 1", - "Query": "select a, :__sq1 from unsharded", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, (select col from user) from unsharded", "Instructions": { @@ -2193,43 +1265,7 @@ { "comment": "sub-expression subquery in select", "query": "select a, 1+(select col from user) from unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select a, 1+(select col from user) from unsharded", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select a, 1 + :__sq1 from unsharded where 1 != 1", - "Query": "select a, 1 + :__sq1 from unsharded", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select a, 1+(select col from user) from unsharded", "Instructions": { @@ -2272,50 +1308,7 @@ { "comment": "select * from derived table expands specific columns", "query": "select * from (select user.id id1, user_extra.id id2 from user join user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select user.id id1, user_extra.id id2 from user join user_extra) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0, - 1 - ], - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id as id1 from `user` where 1 != 1", - "Query": "select `user`.id as id1 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.id as id2 from user_extra where 1 != 1", - "Query": "select user_extra.id as id2 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select user.id id1, user_extra.id id2 from user join user_extra) as t", "Instructions": { @@ -2357,38 +1350,17 @@ { "comment": "duplicate columns not allowed in derived table", "query": "select * from (select user.id, user_extra.id from user join user_extra) as t", - "v3-plan": "VT12001: unsupported: duplicate column names in subquery: id", - "gen4-plan": "Duplicate column name 'id'" + "plan": "Duplicate column name 'id'" }, { "comment": "non-existent symbol in cross-shard derived table", "query": "select t.col from (select user.id from user join user_extra) as t", - "v3-plan": "VT03019: column t.col not found", - "gen4-plan": "column 't.col' not found" + "plan": "column 't.col' not found" }, { "comment": "union with the same target shard", "query": "select * from music where user_id = 1 union select * from user where id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from music where user_id = 1 union select * from user where id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from music where 1 != 1 union select * from `user` where 1 != 1", - "Query": "select * from music where user_id = 1 union select * from `user` where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from music where user_id = 1 union select * from user where id = 1", "Instructions": { @@ -2415,26 +1387,7 @@ { "comment": "union with the same target shard last_insert_id", "query": "select *, last_insert_id() from music where user_id = 1 union select * from user where id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select *, last_insert_id() from music where user_id = 1 union select * from user where id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select *, :__lastInsertId as `last_insert_id()` from music where 1 != 1 union select * from `user` where 1 != 1", - "Query": "select *, :__lastInsertId as `last_insert_id()` from music where user_id = 1 union select * from `user` where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select *, last_insert_id() from music where user_id = 1 union select * from user where id = 1", "Instructions": { @@ -2461,22 +1414,7 @@ { "comment": "unsharded union in derived table", "query": "select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from (select col1, col2 from unsharded where 1 != 1 union select col1, col2 from unsharded where 1 != 1) as a where 1 != 1", - "Query": "select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) as a", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) a", "Instructions": { @@ -2498,22 +1436,7 @@ { "comment": "unsharded union in subquery", "query": "select id, name from unsharded where id in (select id from unsharded where id = 1 union select id from unsharded where id = 3)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, name from unsharded where id in (select id from unsharded where id = 1 union select id from unsharded where id = 3)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id, `name` from unsharded where 1 != 1", - "Query": "select id, `name` from unsharded where id in (select id from unsharded where id = 1 union select id from unsharded where id = 3)", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, name from unsharded where id in (select id from unsharded where id = 1 union select id from unsharded where id = 3)", "Instructions": { @@ -2531,26 +1454,11 @@ "main.unsharded" ] } - }, - { - "comment": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", - "query": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id from unsharded where 1 != 1 union select id from unsharded_auto where 1 != 1", - "Query": "select id from unsharded union select id from unsharded_auto order by id asc limit 5", - "Table": "unsharded" - } - }, - "gen4-plan": { + }, + { + "comment": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", + "query": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", + "plan": { "QueryType": "SELECT", "Original": "(select id from unsharded) union (select id from unsharded_auto) order by id limit 5", "Instructions": { @@ -2573,22 +1481,7 @@ { "comment": "unsharded union", "query": "select id from unsharded union select id from unsharded_auto union select id from unsharded_auto where id in (132)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from unsharded union select id from unsharded_auto union select id from unsharded_auto where id in (132)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id from unsharded where 1 != 1 union select id from unsharded_auto where 1 != 1 union select id from unsharded_auto where 1 != 1", - "Query": "select id from unsharded union select id from unsharded_auto union select id from unsharded_auto where id in (132)", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from unsharded union select id from unsharded_auto union select id from unsharded_auto where id in (132)", "Instructions": { @@ -2611,22 +1504,7 @@ { "comment": "unsharded nested union", "query": "(select id from unsharded union select id from unsharded_auto) union (select id from unsharded_auto union select name from unsharded)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from unsharded union select id from unsharded_auto) union (select id from unsharded_auto union select name from unsharded)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id from unsharded where 1 != 1 union select id from unsharded_auto where 1 != 1 union select id from unsharded_auto where 1 != 1 union select `name` from unsharded where 1 != 1", - "Query": "select id from unsharded union select id from unsharded_auto union select id from unsharded_auto union select `name` from unsharded", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from unsharded union select id from unsharded_auto) union (select id from unsharded_auto union select name from unsharded)", "Instructions": { @@ -2649,22 +1527,7 @@ { "comment": "unsharded nested union with limit", "query": "(select id from unsharded order by id asc limit 1) union (select id from unsharded order by id desc limit 1) order by id asc limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from unsharded order by id asc limit 1) union (select id from unsharded order by id desc limit 1) order by id asc limit 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "(select id from unsharded where 1 != 1) union (select id from unsharded where 1 != 1)", - "Query": "(select id from unsharded order by id asc limit 1) union (select id from unsharded order by id desc limit 1) order by id asc limit 1", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from unsharded order by id asc limit 1) union (select id from unsharded order by id desc limit 1) order by id asc limit 1", "Instructions": { @@ -2686,23 +1549,7 @@ { "comment": "routing rules: ensure directives are not lost", "query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from route2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from route2", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded as route2 where 1 != 1", - "Query": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from unsharded as route2", - "QueryTimeout": 1000, - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select /*vt+ QUERY_TIMEOUT_MS=1000 */ * from route2", "Instructions": { @@ -2725,22 +1572,7 @@ { "comment": "testing SingleRow Projection", "query": "select 42", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 42", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "INT64(42) as 42" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 42", "Instructions": { @@ -2762,22 +1594,7 @@ { "comment": "don't filter on the vtgate", "query": "select 42 from dual where false", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 42 from dual where false", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 42 from dual where 1 != 1", - "Query": "select 42 from dual where false", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 42 from dual where false", "Instructions": { @@ -2799,22 +1616,7 @@ { "comment": "testing SingleRow Projection with arithmetics", "query": "select 42+2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 42+2", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "INT64(44) as 42 + 2" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 42+2", "Instructions": { @@ -2836,26 +1638,7 @@ { "comment": "sql_calc_found_rows without limit", "query": "select sql_calc_found_rows * from music where user_id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select sql_calc_found_rows * from music where user_id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from music where 1 != 1", - "Query": "select * from music where user_id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sql_calc_found_rows * from music where user_id = 1", "Instructions": { @@ -2881,51 +1664,7 @@ { "comment": "sql_calc_found_rows with limit", "query": "select sql_calc_found_rows * from music limit 100", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select sql_calc_found_rows * from music limit 100", - "Instructions": { - "OperatorType": "SQL_CALC_FOUND_ROWS", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(100)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from music where 1 != 1", - "Query": "select * from music limit :__upper_limit", - "Table": "music" - } - ] - }, - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from music where 1 != 1", - "Query": "select count(*) from music", - "Table": "music" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sql_calc_found_rows * from music limit 100", "Instructions": { @@ -2976,46 +1715,7 @@ { "comment": "sql_calc_found_rows with SelectEqualUnique plans", "query": "select sql_calc_found_rows * from music where user_id = 1 limit 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select sql_calc_found_rows * from music where user_id = 1 limit 2", - "Instructions": { - "OperatorType": "SQL_CALC_FOUND_ROWS", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from music where 1 != 1", - "Query": "select * from music where user_id = 1 limit 2", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from music where 1 != 1", - "Query": "select count(*) from music where user_id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sql_calc_found_rows * from music where user_id = 1 limit 2", "Instructions": { @@ -3061,53 +1761,7 @@ { "comment": "sql_calc_found_rows with group by and having", "query": "select sql_calc_found_rows user_id, count(id) from music group by user_id having count(user_id) = 1 order by user_id limit 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select sql_calc_found_rows user_id, count(id) from music group by user_id having count(user_id) = 1 order by user_id limit 2", - "Instructions": { - "OperatorType": "SQL_CALC_FOUND_ROWS", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(2)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id, count(id), weight_string(user_id) from music where 1 != 1 group by user_id", - "OrderBy": "(0|2) ASC", - "Query": "select user_id, count(id), weight_string(user_id) from music group by user_id having count(user_id) = 1 order by user_id asc limit :__upper_limit", - "ResultColumns": 2, - "Table": "music" - } - ] - }, - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from (select user_id, count(id) from music where 1 != 1 group by user_id) as t where 1 != 1", - "Query": "select count(*) from (select user_id, count(id) from music group by user_id having count(user_id) = 1) as t", - "Table": "music" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sql_calc_found_rows user_id, count(id) from music group by user_id having count(user_id) = 1 order by user_id limit 2", "Instructions": { @@ -3159,35 +1813,18 @@ }, { "comment": "sql_calc_found_rows in sub queries", - "query": "select * from music where user_id IN (select sql_calc_found_rows * from music limit 10)", - "v3-plan": "VT03008: incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'", - "gen4-plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" - }, - { - "comment": "sql_calc_found_rows in derived table", - "query": "select sql_calc_found_rows * from (select sql_calc_found_rows * from music limit 10) t limit 1", - "v3-plan": "VT03008: incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'", - "gen4-plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" - }, - { - "comment": "select from unsharded keyspace into dumpfile", - "query": "select * from main.unsharded into Dumpfile 'x.txt'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from main.unsharded into Dumpfile 'x.txt'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded where 1 != 1", - "Query": "select * from unsharded into dumpfile 'x.txt'", - "Table": "unsharded" - } - }, - "gen4-plan": { + "query": "select * from music where user_id IN (select sql_calc_found_rows * from music limit 10)", + "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" + }, + { + "comment": "sql_calc_found_rows in derived table", + "query": "select sql_calc_found_rows * from (select sql_calc_found_rows * from music limit 10) t limit 1", + "plan": "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'" + }, + { + "comment": "select from unsharded keyspace into dumpfile", + "query": "select * from main.unsharded into Dumpfile 'x.txt'", + "plan": { "QueryType": "SELECT", "Original": "select * from main.unsharded into Dumpfile 'x.txt'", "Instructions": { @@ -3209,22 +1846,7 @@ { "comment": "select from unsharded keyspace into outfile", "query": "select * from main.unsharded into outfile 'x.txt' character set binary fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from main.unsharded into outfile 'x.txt' character set binary fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded where 1 != 1", - "Query": "select * from unsharded into outfile 'x.txt' character set binary fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\\n'", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from main.unsharded into outfile 'x.txt' character set binary fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n'", "Instructions": { @@ -3246,22 +1868,7 @@ { "comment": "select from unsharded keyspace into outfile s3", "query": "select * from main.unsharded into outfile s3 'out_file_name' character set binary format csv header fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n' manifest on overwrite off", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from main.unsharded into outfile s3 'out_file_name' character set binary format csv header fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n' manifest on overwrite off", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded where 1 != 1", - "Query": "select * from unsharded into outfile s3 'out_file_name' character set binary format csv header fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\\n' manifest on overwrite off", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from main.unsharded into outfile s3 'out_file_name' character set binary format csv header fields terminated by 'term' optionally enclosed by 'c' escaped by 'e' lines starting by 'a' terminated by '\n' manifest on overwrite off", "Instructions": { @@ -3298,26 +1905,7 @@ { "comment": "select (select u.id from user as u where u.id = 1), a.id from user as a where a.id = 1", "query": "select (select u.id from user as u where u.id = 1), a.id from user as a where a.id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select (select u.id from user as u where u.id = 1), a.id from user as a where a.id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select (select u.id from `user` as u where 1 != 1), a.id from `user` as a where 1 != 1", - "Query": "select (select u.id from `user` as u where u.id = 1), a.id from `user` as a where a.id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select (select u.id from user as u where u.id = 1), a.id from user as a where a.id = 1", "Instructions": { @@ -3343,41 +1931,7 @@ { "comment": "Add two tables with the same column in a join", "query": "select t.id, s.id from user t join user_extra s on t.id = s.user_id join unsharded", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.id, s.id from user t join user_extra s on t.id = s.user_id join unsharded", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`, user_extra_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select t.id, s.id from `user` as t join user_extra as s on t.id = s.user_id where 1 != 1", - "Query": "select t.id, s.id from `user` as t join user_extra as s on t.id = s.user_id", - "Table": "`user`, user_extra" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from unsharded where 1 != 1", - "Query": "select 1 from unsharded", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.id, s.id from user t join user_extra s on t.id = s.user_id join unsharded", "Instructions": { @@ -3420,22 +1974,7 @@ { "comment": "((((select 1))))", "query": "((((select 1))))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "((((select 1))))", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "INT64(1) as 1" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "((((select 1))))", "Instructions": { @@ -3457,41 +1996,7 @@ { "comment": "Merging dual with user", "query": "select 42, id from dual, user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 42, id from dual, user", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "dual_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 42 from dual where 1 != 1", - "Query": "select 42 from dual", - "Table": "dual" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 42, id from dual, user", "Instructions": { @@ -3514,70 +2019,7 @@ { "comment": "select (select col from user limit 1) as a from user join user_extra order by a", "query": "select (select col from user limit 1) as a from user join user_extra order by a", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select (select col from user limit 1) as a from user join user_extra order by a", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__sq1 as a, weight_string(:__sq1) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select :__sq1 as a, weight_string(:__sq1) from `user` order by a asc", - "ResultColumns": 1, - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select (select col from user limit 1) as a from user join user_extra order by a", "Instructions": { @@ -3639,83 +2081,14 @@ }, "TablesUsed": [ "user.user", - "user.user_extra" - ] - } - }, - { - "comment": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", - "query": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__sq1 as a from `user` where 1 != 1", - "Query": "select :__sq1 as a from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "user.user_extra" + ] + } + }, + { + "comment": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", + "query": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", + "plan": { "QueryType": "SELECT", "Original": "select t.a from (select (select col from user limit 1) as a from user join user_extra) t", "Instructions": { @@ -3796,22 +2169,7 @@ { "comment": "plan test for a natural character set string", "query": "select N'string' from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select N'string' from dual", - "Instructions": { - "OperatorType": "Projection", - "Expressions": [ - "VARCHAR(\"string\") as N'string'" - ], - "Inputs": [ - { - "OperatorType": "SingleRow" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select N'string' from dual", "Instructions": { @@ -3833,44 +2191,7 @@ { "comment": "select expression having dependencies on both sides of a join", "query": "select user.id * user_id as amount from user, user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.id * user_id as amount from user, user_extra", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_id": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` where 1 != 1", - "Query": "select `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :user_id * user_id as amount from user_extra where 1 != 1", - "Query": "select :user_id * user_id as amount from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id * user_id as amount from user, user_extra", "Instructions": { @@ -3915,8 +2236,7 @@ { "comment": "correlated subquery in exists clause", "query": "select col from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id)", "Instructions": { @@ -3964,8 +2284,7 @@ { "comment": "correlated subquery in exists clause with an order by", "query": "select col from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id) order by col", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from user where exists(select user_id from user_extra where user_id = 3 and user_id < user.id) order by col", "Instructions": { @@ -4014,8 +2333,7 @@ { "comment": "correlated subquery having dependencies on two tables", "query": "select 1 from user u1, user u2 where exists (select 1 from user_extra ue where ue.col = u1.col and ue.col = u2.col)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user u1, user u2 where exists (select 1 from user_extra ue where ue.col = u1.col and ue.col = u2.col)", "Instructions": { @@ -4079,8 +2397,7 @@ { "comment": "correlated subquery using a column twice", "query": "select 1 from user u where exists (select 1 from user_extra ue where ue.col = u.col and u.col = ue.col2)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user u where exists (select 1 from user_extra ue where ue.col = u.col and u.col = ue.col2)", "Instructions": { @@ -4124,32 +2441,12 @@ { "comment": "correlated subquery part of an OR clause", "query": "select 1 from user u where u.col = 6 or exists (select 1 from user_extra ue where ue.col = u.col and u.col = ue.col2)", - "v3-plan": "VT12001: unsupported: cross-shard correlated subquery", - "gen4-plan": "VT12001: unsupported: EXISTS sub-queries are only supported with AND clause" + "plan": "VT12001: unsupported: EXISTS sub-queries are only supported with AND clause" }, { "comment": "correlated subquery that is dependent on one side of a join, fully mergeable", "query": "SELECT music.id FROM music INNER JOIN user ON music.user_id = user.id WHERE music.user_id = 5 AND music.id = (SELECT MAX(m2.id) FROM music m2 WHERE m2.user_id = user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music INNER JOIN user ON music.user_id = user.id WHERE music.user_id = 5 AND music.id = (SELECT MAX(m2.id) FROM music m2 WHERE m2.user_id = user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music join `user` on music.user_id = `user`.id where 1 != 1", - "Query": "select music.id from music join `user` on music.user_id = `user`.id where music.user_id = 5 and music.id = (select max(m2.id) from music as m2 where m2.user_id = `user`.id)", - "Table": "music, `user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music INNER JOIN user ON music.user_id = user.id WHERE music.user_id = 5 AND music.id = (SELECT MAX(m2.id) FROM music m2 WHERE m2.user_id = user.id)", "Instructions": { @@ -4176,46 +2473,7 @@ { "comment": "union as a derived table", "query": "select found from (select id as found from user union all (select id from unsharded)) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select found from (select id as found from user union all (select id from unsharded)) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id as found from `user` where 1 != 1", - "Query": "select id as found from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id from unsharded where 1 != 1", - "Query": "select id from unsharded", - "Table": "unsharded" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select found from (select id as found from user union all (select id from unsharded)) as t", "Instructions": { @@ -4262,45 +2520,7 @@ { "comment": "use output column containing data from both sides of the join", "query": "select user_extra.col + user.col from user join user_extra on user.id = user_extra.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_extra.col + user.col from user join user_extra on user.id = user_extra.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "user_col": 0, - "user_id": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.col, `user`.id from `user` where 1 != 1", - "Query": "select `user`.col, `user`.id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.col + :user_col from user_extra where 1 != 1", - "Query": "select user_extra.col + :user_col from user_extra where user_extra.id = :user_id", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_extra.col + user.col from user join user_extra on user.id = user_extra.id", "Instructions": { @@ -4394,22 +2614,7 @@ { "comment": "select user.id, trim(leading 'x' from user.name) from user", "query": "select user.id, trim(leading 'x' from user.name) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.id, trim(leading 'x' from user.name) from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, trim(leading 'x' from `user`.`name`) from `user` where 1 != 1", - "Query": "select `user`.id, trim(leading 'x' from `user`.`name`) from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.id, trim(leading 'x' from user.name) from user", "Instructions": { @@ -4431,22 +2636,7 @@ { "comment": "json utility functions", "query": "select jcol, JSON_STORAGE_SIZE(jcol), JSON_STORAGE_FREE(jcol), JSON_PRETTY(jcol) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select jcol, JSON_STORAGE_SIZE(jcol), JSON_STORAGE_FREE(jcol), JSON_PRETTY(jcol) from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select jcol, json_storage_size(jcol), json_storage_free(jcol), json_pretty(jcol) from `user` where 1 != 1", - "Query": "select jcol, json_storage_size(jcol), json_storage_free(jcol), json_pretty(jcol) from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select jcol, JSON_STORAGE_SIZE(jcol), JSON_STORAGE_FREE(jcol), JSON_PRETTY(jcol) from user", "Instructions": { @@ -4468,24 +2658,7 @@ { "comment": "dual query with exists clause", "query": "select 1 from dual where exists (select 1 from information_schema.TABLES where information_schema.TABLES.TABLE_NAME = 'proc' and information_schema.TABLES.TABLE_SCHEMA = 'mysql')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from dual where exists (select 1 from information_schema.TABLES where information_schema.TABLES.TABLE_NAME = 'proc' and information_schema.TABLES.TABLE_SCHEMA = 'mysql')", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from dual where 1 != 1", - "Query": "select 1 from dual where exists (select 1 from information_schema.`TABLES` where information_schema.`TABLES`.TABLE_NAME = :TABLES_TABLE_NAME /* VARCHAR */ and information_schema.`TABLES`.TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ limit 1)", - "SysTableTableName": "[TABLES_TABLE_NAME:VARCHAR(\"proc\")]", - "SysTableTableSchema": "[VARCHAR(\"mysql\")]", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from dual where exists (select 1 from information_schema.TABLES where information_schema.TABLES.TABLE_NAME = 'proc' and information_schema.TABLES.TABLE_SCHEMA = 'mysql')", "Instructions": { @@ -4508,89 +2681,30 @@ }, { "comment": "json_quote, json_object and json_array", - "query": "SELECT JSON_QUOTE('null'), JSON_QUOTE('\"null\"'), JSON_OBJECT(BIN(1),2,'abc',ASCII(4)), JSON_ARRAY(1, \"abc\", NULL, TRUE, CURTIME())", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT JSON_QUOTE('null'), JSON_QUOTE('\"null\"'), JSON_OBJECT(BIN(1),2,'abc',ASCII(4)), JSON_ARRAY(1, \"abc\", NULL, TRUE, CURTIME())", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual where 1 != 1", - "Query": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual", - "Table": "dual" - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "SELECT JSON_QUOTE('null'), JSON_QUOTE('\"null\"'), JSON_OBJECT(BIN(1),2,'abc',ASCII(4)), JSON_ARRAY(1, \"abc\", NULL, TRUE, CURTIME())", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual where 1 != 1", - "Query": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual", - "Table": "dual" - }, - "TablesUsed": [ - "main.dual" - ] - } - }, - { - "comment": "select (select id from user order by id limit 1) from user_extra", - "query": "select (select id from user order by id limit 1) from user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select (select id from user order by id limit 1) from user_extra", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id, weight_string(id) from `user` order by id asc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__sq1 from user_extra where 1 != 1", - "Query": "select :__sq1 from user_extra", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "query": "SELECT JSON_QUOTE('null'), JSON_QUOTE('\"null\"'), JSON_OBJECT(BIN(1),2,'abc',ASCII(4)), JSON_ARRAY(1, \"abc\", NULL, TRUE, CURTIME())", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT JSON_QUOTE('null'), JSON_QUOTE('\"null\"'), JSON_OBJECT(BIN(1),2,'abc',ASCII(4)), JSON_ARRAY(1, \"abc\", NULL, TRUE, CURTIME())", + "Instructions": { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual where 1 != 1", + "Query": "select json_quote('null'), json_quote('\\\"null\\\"'), json_object(BIN(1), 2, 'abc', ASCII(4)), json_array(1, 'abc', null, true, curtime()) from dual", + "Table": "dual" + }, + "TablesUsed": [ + "main.dual" + ] + } + }, + { + "comment": "select (select id from user order by id limit 1) from user_extra", + "query": "select (select id from user order by id limit 1) from user_extra", + "plan": { "QueryType": "SELECT", "Original": "select (select id from user order by id limit 1) from user_extra", "Instructions": { @@ -4641,47 +2755,7 @@ { "comment": "yeah, it does not make sense, but it's valid", "query": "select exists(select 1) from user where id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select exists(select 1) from user where id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from dual where 1 != 1", - "Query": "select 1 from dual limit 1", - "Table": "dual" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select :__sq_has_values1 from `user` where 1 != 1", - "Query": "select :__sq_has_values1 from `user` where id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select exists(select 1) from user where id = 5", "Instructions": { @@ -4708,22 +2782,7 @@ { "comment": "json schema validation functions", "query": "SELECT JSON_SCHEMA_VALID('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"'), JSON_SCHEMA_VALIDATION_REPORT('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT JSON_SCHEMA_VALID('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"'), JSON_SCHEMA_VALIDATION_REPORT('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_schema_valid('{\\\"type\\\":\\\"string\\\",\\\"pattern\\\":\\\"(\\\"}', '\\\"abc\\\"'), json_schema_validation_report('{\\\"type\\\":\\\"string\\\",\\\"pattern\\\":\\\"(\\\"}', '\\\"abc\\\"') from dual where 1 != 1", - "Query": "select json_schema_valid('{\\\"type\\\":\\\"string\\\",\\\"pattern\\\":\\\"(\\\"}', '\\\"abc\\\"'), json_schema_validation_report('{\\\"type\\\":\\\"string\\\",\\\"pattern\\\":\\\"(\\\"}', '\\\"abc\\\"') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT JSON_SCHEMA_VALID('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"'), JSON_SCHEMA_VALIDATION_REPORT('{\"type\":\"string\",\"pattern\":\"(\"}', '\"abc\"')", "Instructions": { @@ -4745,22 +2804,7 @@ { "comment": "json search functions", "query": "SELECT JSON_CONTAINS('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', '1'), JSON_CONTAINS_PATH('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', 'one', '$.a', '$.e'), JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'), JSON_UNQUOTE(JSON_EXTRACT('[\"a\",\"b\"]', '$[1]')), JSON_KEYS('{\"a\": 1, \"b\": {\"c\": 30}}'), JSON_OVERLAPS(\"[1,3,5,7]\", \"[2,5,7]\"), JSON_SEARCH('[\"abc\"]', 'one', 'abc'), JSON_VALUE('{\"fname\": \"Joe\", \"lname\": \"Palmer\"}', '$.fname'), JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT JSON_CONTAINS('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', '1'), JSON_CONTAINS_PATH('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', 'one', '$.a', '$.e'), JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'), JSON_UNQUOTE(JSON_EXTRACT('[\"a\",\"b\"]', '$[1]')), JSON_KEYS('{\"a\": 1, \"b\": {\"c\": 30}}'), JSON_OVERLAPS(\"[1,3,5,7]\", \"[2,5,7]\"), JSON_SEARCH('[\"abc\"]', 'one', 'abc'), JSON_VALUE('{\"fname\": \"Joe\", \"lname\": \"Palmer\"}', '$.fname'), JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_contains('{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": {\\\"d\\\": 4}}', '1'), json_contains_path('{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": {\\\"d\\\": 4}}', 'one', '$.a', '$.e'), json_extract('[10, 20, [30, 40]]', '$[1]'), json_unquote(json_extract('[\\\"a\\\",\\\"b\\\"]', '$[1]')), json_keys('{\\\"a\\\": 1, \\\"b\\\": {\\\"c\\\": 30}}'), json_overlaps('[1,3,5,7]', '[2,5,7]'), json_search('[\\\"abc\\\"]', 'one', 'abc'), json_value('{\\\"fname\\\": \\\"Joe\\\", \\\"lname\\\": \\\"Palmer\\\"}', '$.fname'), json_array(4, 5) member of ('[[3,4],[4,5]]') from dual where 1 != 1", - "Query": "select json_contains('{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": {\\\"d\\\": 4}}', '1'), json_contains_path('{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": {\\\"d\\\": 4}}', 'one', '$.a', '$.e'), json_extract('[10, 20, [30, 40]]', '$[1]'), json_unquote(json_extract('[\\\"a\\\",\\\"b\\\"]', '$[1]')), json_keys('{\\\"a\\\": 1, \\\"b\\\": {\\\"c\\\": 30}}'), json_overlaps('[1,3,5,7]', '[2,5,7]'), json_search('[\\\"abc\\\"]', 'one', 'abc'), json_value('{\\\"fname\\\": \\\"Joe\\\", \\\"lname\\\": \\\"Palmer\\\"}', '$.fname'), json_array(4, 5) member of ('[[3,4],[4,5]]') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT JSON_CONTAINS('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', '1'), JSON_CONTAINS_PATH('{\"a\": 1, \"b\": 2, \"c\": {\"d\": 4}}', 'one', '$.a', '$.e'), JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'), JSON_UNQUOTE(JSON_EXTRACT('[\"a\",\"b\"]', '$[1]')), JSON_KEYS('{\"a\": 1, \"b\": {\"c\": 30}}'), JSON_OVERLAPS(\"[1,3,5,7]\", \"[2,5,7]\"), JSON_SEARCH('[\"abc\"]', 'one', 'abc'), JSON_VALUE('{\"fname\": \"Joe\", \"lname\": \"Palmer\"}', '$.fname'), JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]')", "Instructions": { @@ -4782,22 +2826,7 @@ { "comment": "Json extract and json unquote shorthands", "query": "SELECT a->\"$[4]\", a->>\"$[3]\" FROM user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT a->\"$[4]\", a->>\"$[3]\" FROM user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select a -> '$[4]', a ->> '$[3]' from `user` where 1 != 1", - "Query": "select a -> '$[4]', a ->> '$[3]' from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT a->\"$[4]\", a->>\"$[3]\" FROM user", "Instructions": { @@ -4819,22 +2848,7 @@ { "comment": "groupe by with non aggregated columns and table alias", "query": "select u.id, u.age from user u group by u.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id, u.age from user u group by u.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, u.age from `user` as u where 1 != 1 group by u.id", - "Query": "select u.id, u.age from `user` as u group by u.id", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id, u.age from user u group by u.id", "Instructions": { @@ -4856,22 +2870,7 @@ { "comment": "Functions that return JSON value attributes", "query": "select JSON_DEPTH('{}'), JSON_LENGTH('{\"a\": 1, \"b\": {\"c\": 30}}', '$.b'), JSON_TYPE(JSON_EXTRACT('{\"a\": [10, true]}', '$.a')), JSON_VALID('{\"a\": 1}')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select JSON_DEPTH('{}'), JSON_LENGTH('{\"a\": 1, \"b\": {\"c\": 30}}', '$.b'), JSON_TYPE(JSON_EXTRACT('{\"a\": [10, true]}', '$.a')), JSON_VALID('{\"a\": 1}')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_depth('{}'), json_length('{\\\"a\\\": 1, \\\"b\\\": {\\\"c\\\": 30}}', '$.b'), json_type(json_extract('{\\\"a\\\": [10, true]}', '$.a')), json_valid('{\\\"a\\\": 1}') from dual where 1 != 1", - "Query": "select json_depth('{}'), json_length('{\\\"a\\\": 1, \\\"b\\\": {\\\"c\\\": 30}}', '$.b'), json_type(json_extract('{\\\"a\\\": [10, true]}', '$.a')), json_valid('{\\\"a\\\": 1}') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select JSON_DEPTH('{}'), JSON_LENGTH('{\"a\": 1, \"b\": {\"c\": 30}}', '$.b'), JSON_TYPE(JSON_EXTRACT('{\"a\": [10, true]}', '$.a')), JSON_VALID('{\"a\": 1}')", "Instructions": { @@ -4893,22 +2892,7 @@ { "comment": "Json array functions", "query": "select JSON_ARRAY_APPEND('{\"a\": 1}', '$', 'z'), JSON_ARRAY_INSERT('[\"a\", {\"b\": [1, 2]}, [3, 4]]', '$[0]', 'x', '$[2][1]', 'y'), JSON_INSERT('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', CAST('[true, false]' AS JSON))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select JSON_ARRAY_APPEND('{\"a\": 1}', '$', 'z'), JSON_ARRAY_INSERT('[\"a\", {\"b\": [1, 2]}, [3, 4]]', '$[0]', 'x', '$[2][1]', 'y'), JSON_INSERT('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', CAST('[true, false]' AS JSON))", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_array_append('{\\\"a\\\": 1}', '$', 'z'), json_array_insert('[\\\"a\\\", {\\\"b\\\": [1, 2]}, [3, 4]]', '$[0]', 'x', '$[2][1]', 'y'), json_insert('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', cast('[true, false]' as JSON)) from dual where 1 != 1", - "Query": "select json_array_append('{\\\"a\\\": 1}', '$', 'z'), json_array_insert('[\\\"a\\\", {\\\"b\\\": [1, 2]}, [3, 4]]', '$[0]', 'x', '$[2][1]', 'y'), json_insert('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', cast('[true, false]' as JSON)) from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select JSON_ARRAY_APPEND('{\"a\": 1}', '$', 'z'), JSON_ARRAY_INSERT('[\"a\", {\"b\": [1, 2]}, [3, 4]]', '$[0]', 'x', '$[2][1]', 'y'), JSON_INSERT('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', CAST('[true, false]' AS JSON))", "Instructions": { @@ -4930,22 +2914,7 @@ { "comment": "Json merge functions", "query": "select JSON_MERGE('[1, 2]', '[true, false]'), JSON_MERGE_PATCH('{\"name\": \"x\"}', '{\"id\": 47}'), JSON_MERGE_PRESERVE('[1, 2]', '{\"id\": 47}')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select JSON_MERGE('[1, 2]', '[true, false]'), JSON_MERGE_PATCH('{\"name\": \"x\"}', '{\"id\": 47}'), JSON_MERGE_PRESERVE('[1, 2]', '{\"id\": 47}')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_merge('[1, 2]', '[true, false]'), json_merge_patch('{\\\"name\\\": \\\"x\\\"}', '{\\\"id\\\": 47}'), json_merge_preserve('[1, 2]', '{\\\"id\\\": 47}') from dual where 1 != 1", - "Query": "select json_merge('[1, 2]', '[true, false]'), json_merge_patch('{\\\"name\\\": \\\"x\\\"}', '{\\\"id\\\": 47}'), json_merge_preserve('[1, 2]', '{\\\"id\\\": 47}') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select JSON_MERGE('[1, 2]', '[true, false]'), JSON_MERGE_PATCH('{\"name\": \"x\"}', '{\"id\": 47}'), JSON_MERGE_PRESERVE('[1, 2]', '{\"id\": 47}')", "Instructions": { @@ -4967,22 +2936,7 @@ { "comment": "JSON modifier functions", "query": "select JSON_REMOVE('[1, [2, 3], 4]', '$[1]'), JSON_REPLACE('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_SET('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_UNQUOTE('\"abc\"')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select JSON_REMOVE('[1, [2, 3], 4]', '$[1]'), JSON_REPLACE('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_SET('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_UNQUOTE('\"abc\"')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select json_remove('[1, [2, 3], 4]', '$[1]'), json_replace('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), json_set('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), json_unquote('\\\"abc\\\"') from dual where 1 != 1", - "Query": "select json_remove('[1, [2, 3], 4]', '$[1]'), json_replace('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), json_set('{ \\\"a\\\": 1, \\\"b\\\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), json_unquote('\\\"abc\\\"') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select JSON_REMOVE('[1, [2, 3], 4]', '$[1]'), JSON_REPLACE('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_SET('{ \"a\": 1, \"b\": [2, 3]}', '$.a', 10, '$.c', '[true, false]'), JSON_UNQUOTE('\"abc\"')", "Instructions": { @@ -5004,47 +2958,7 @@ { "comment": "Reference with a subquery which can be merged", "query": "select exists(select id from user where id = 4)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select exists(select id from user where id = 4)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where id = 4 limit 1", - "Table": "`user`", - "Values": [ - "INT64(4)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select :__sq_has_values1 from dual where 1 != 1", - "Query": "select :__sq_has_values1 from dual", - "Table": "dual" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select exists(select id from user where id = 4)", "Instructions": { @@ -5071,49 +2985,7 @@ { "comment": "Reference with a subquery which cannot be merged", "query": "select exists(select * from user)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select exists(select * from user)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` limit :__upper_limit", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select :__sq_has_values1 from dual where 1 != 1", - "Query": "select :__sq_has_values1 from dual", - "Table": "dual" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select exists(select * from user)", "Instructions": { @@ -5156,28 +3028,13 @@ "TablesUsed": [ "main.dual", "user.user" - ] - } - }, - { - "comment": "insert function not requiring any table", - "query": "select insert('Quadratic', 3, 4, 'What')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select insert('Quadratic', 3, 4, 'What')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select insert('Quadratic', 3, 4, 'What') from dual where 1 != 1", - "Query": "select insert('Quadratic', 3, 4, 'What') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + ] + } + }, + { + "comment": "insert function not requiring any table", + "query": "select insert('Quadratic', 3, 4, 'What')", + "plan": { "QueryType": "SELECT", "Original": "select insert('Quadratic', 3, 4, 'What')", "Instructions": { @@ -5199,22 +3056,7 @@ { "comment": "insert function using column names as arguments", "query": "select insert(tcol1, id, 3, tcol2) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select insert(tcol1, id, 3, tcol2) from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select insert(tcol1, id, 3, tcol2) from `user` where 1 != 1", - "Query": "select insert(tcol1, id, 3, tcol2) from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select insert(tcol1, id, 3, tcol2) from user", "Instructions": { @@ -5236,22 +3078,7 @@ { "comment": "gtid functions", "query": "select gtid_subset('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'), gtid_subtract('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select gtid_subset('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'), gtid_subtract('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select gtid_subset('3E11FA47-71CA-11E1-9E33-C80AA9429562:23', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'), gtid_subtract('3E11FA47-71CA-11E1-9E33-C80AA9429562:23', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57') from dual where 1 != 1", - "Query": "select gtid_subset('3E11FA47-71CA-11E1-9E33-C80AA9429562:23', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'), gtid_subtract('3E11FA47-71CA-11E1-9E33-C80AA9429562:23', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57') from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select gtid_subset('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'), gtid_subtract('3E11FA47-71CA-11E1-9E33-C80AA9429562:23','3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')", "Instructions": { @@ -5273,70 +3100,7 @@ { "comment": "Predicate in apply join which is merged", "query": "select user.col, user_metadata.user_id from user join user_extra on user.col = user_extra.col join user_metadata on user_extra.user_id = user_metadata.user_id where user.textcol1 = 'alice@gmail.com'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user.col, user_metadata.user_id from user join user_extra on user.col = user_extra.col join user_metadata on user_extra.user_id = user_metadata.user_id where user.textcol1 = 'alice@gmail.com'", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "user_extra_user_id": 1 - }, - "TableName": "`user`_user_extra_user_metadata", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "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 `user`.col from `user` where `user`.textcol1 = 'alice@gmail.com'", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_extra.user_id from user_extra where 1 != 1", - "Query": "select user_extra.user_id from user_extra where user_extra.col = :user_col", - "Table": "user_extra" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_metadata.user_id from user_metadata where 1 != 1", - "Query": "select user_metadata.user_id from user_metadata where user_metadata.user_id = :user_extra_user_id", - "Table": "user_metadata", - "Values": [ - ":user_extra_user_id" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.col, user_metadata.user_id from user join user_extra on user.col = user_extra.col join user_metadata on user_extra.user_id = user_metadata.user_id where user.textcol1 = 'alice@gmail.com'", "Instructions": { @@ -5382,26 +3146,7 @@ { "comment": "Join across multiple tables, with conditions on different vindexes, but mergeable through join predicates", "query": "SELECT user.id FROM user INNER JOIN music_extra ON user.id = music_extra.user_id INNER JOIN music ON music_extra.user_id = music.user_id WHERE user.id = 123 and music.id = 456", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT user.id FROM user INNER JOIN music_extra ON user.id = music_extra.user_id INNER JOIN music ON music_extra.user_id = music.user_id WHERE user.id = 123 and music.id = 456", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id from `user` join music_extra on `user`.id = music_extra.user_id join music on music_extra.user_id = music.user_id where 1 != 1", - "Query": "select `user`.id from `user` join music_extra on `user`.id = music_extra.user_id join music on music_extra.user_id = music.user_id where `user`.id = 123 and music.id = 456", - "Table": "`user`, music_extra, music", - "Values": [ - "INT64(123)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT user.id FROM user INNER JOIN music_extra ON user.id = music_extra.user_id INNER JOIN music ON music_extra.user_id = music.user_id WHERE user.id = 123 and music.id = 456", "Instructions": { @@ -5429,61 +3174,7 @@ { "comment": "SQL_CALC_FOUND_ROWS with vindex lookup", "query": "select SQL_CALC_FOUND_ROWS id, name from user where name = 'aa' order by id limit 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select SQL_CALC_FOUND_ROWS id, name from user where name = 'aa' order by id limit 2", - "Instructions": { - "OperatorType": "SQL_CALC_FOUND_ROWS", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(2)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, `name`, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|2) ASC", - "Query": "select id, `name`, weight_string(id) from `user` where `name` = 'aa' order by id asc limit :__upper_limit", - "ResultColumns": 2, - "Table": "`user`", - "Values": [ - "VARCHAR(\"aa\")" - ], - "Vindex": "name_user_map" - } - ] - }, - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) from `user` where 1 != 1", - "Query": "select count(*) from `user` where `name` = 'aa'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"aa\")" - ], - "Vindex": "name_user_map" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select SQL_CALC_FOUND_ROWS id, name from user where name = 'aa' order by id limit 2", "Instructions": { @@ -5594,22 +3285,7 @@ { "comment": "`None` route being merged with another route via join predicate on Vindex columns", "query": "SELECT `music`.id FROM `music` INNER JOIN `user` ON music.user_id = user.id WHERE music.user_id IN (NULL) AND user.id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT `music`.id FROM `music` INNER JOIN `user` ON music.user_id = user.id WHERE music.user_id IN (NULL) AND user.id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music join `user` on music.user_id = `user`.id where 1 != 1", - "Query": "select music.id from music join `user` on music.user_id = `user`.id where music.user_id in (null) and `user`.id = 5", - "Table": "music, `user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT `music`.id FROM `music` INNER JOIN `user` ON music.user_id = user.id WHERE music.user_id IN (NULL) AND user.id = 5", "Instructions": { @@ -5626,127 +3302,39 @@ "TablesUsed": [ "user.music", "user.user" - ] - } - }, - { - "comment": "Treating single value tuples as `EqualUnique` routes", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (5)) AND music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (5)) AND music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(5))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id = 5 and :__sq_has_values1 = 1 and music.id in ::__sq1", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (5)) AND music.user_id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.id in (select music.id from music where music.user_id in (5)) and music.user_id = 5", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "Subquery with `IN` condition using columns with matching lookup vindexes", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3))", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(1), INT64(2), INT64(3))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + ] + } + }, + { + "comment": "Treating single value tuples as `EqualUnique` routes", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (5)) AND music.user_id = 5", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (5)) AND music.user_id = 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where music.id in (select music.id from music where music.user_id in (5)) and music.user_id = 5", + "Table": "music", + "Values": [ + "INT64(5)" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "Subquery with `IN` condition using columns with matching lookup vindexes", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3))", + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3))", "Instructions": { @@ -5772,51 +3360,7 @@ { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes, with derived table", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) _inner)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) _inner)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select music.id from music where 1 != 1) as _inner where 1 != 1", - "Query": "select * from (select music.id from music where music.user_id in ::__vals) as _inner", - "Table": "music", - "Values": [ - "(INT64(1), INT64(2), INT64(3))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) _inner)", "Instructions": { @@ -5842,47 +3386,7 @@ { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes, with inner scatter query", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.foo = 'bar') AND music.user_id IN (3, 4, 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.foo = 'bar') AND music.user_id IN (3, 4, 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.foo = 'bar'", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals and :__sq_has_values1 = 1 and music.id in ::__sq1", - "Table": "music", - "Values": [ - "(INT64(3), INT64(4), INT64(5))" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.foo = 'bar') AND music.user_id IN (3, 4, 5)", "Instructions": { @@ -5908,51 +3412,7 @@ { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) and music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) and music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(1), INT64(2), INT64(3))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id = 5 and :__sq_has_values1 = 1 and music.id in ::__sq1", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) and music.user_id = 5", "Instructions": { @@ -5978,47 +3438,7 @@ { "comment": "Subquery with `IN` condition using columns with matching lookup vindexes, but not a top level predicate", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) OR music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) OR music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(1), INT64(2), INT64(3))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__sq1 or music.user_id = 5", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (1, 2, 3)) OR music.user_id = 5", "Instructions": { @@ -6040,47 +3460,7 @@ { "comment": "`IN` comparison on Vindex with `None` subquery, as routing predicate", "query": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in (null)", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id = 5 and :__sq_has_values1 = 1 and music.id in ::__sq1", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", "Instructions": { @@ -6092,53 +3472,17 @@ }, "FieldQuery": "select music.id from music where 1 != 1", "Query": "select music.id from music where music.id in (select music.id from music where music.user_id in (null)) and music.user_id = 5", - "Table": "music" - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "`IN` comparison on Vindex with `None` subquery, as non-routing predicate", - "query": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in (null)", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__sq1 or music.user_id = 5", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "Table": "music" + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "`IN` comparison on Vindex with `None` subquery, as non-routing predicate", + "query": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5", + "plan": { "QueryType": "SELECT", "Original": "SELECT `music`.id FROM `music` WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5", "Instructions": { @@ -6160,47 +3504,7 @@ { "comment": "Mergeable scatter subquery", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop')", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.genre = 'pop'", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop')", "Instructions": { @@ -6222,47 +3526,7 @@ { "comment": "Mergeable scatter subquery with `GROUP BY` on unique vindex column", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' GROUP BY music.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' GROUP BY music.id)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1 group by music.id", - "Query": "select music.id from music where music.genre = 'pop' group by music.id", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' GROUP BY music.id)", "Instructions": { @@ -6284,8 +3548,7 @@ { "comment": "Unmergeable scatter subquery with `GROUP BY` on-non vindex column", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' GROUP BY music.genre)", - "v3-plan": "VT12001: unsupported: in scatter query: GROUP BY column must reference column in SELECT list", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' GROUP BY music.genre)", "Instructions": { @@ -6320,188 +3583,19 @@ { "OperatorType": "Route", "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "Unmergeable scatter subquery with LIMIT", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' LIMIT 10)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' LIMIT 10)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.genre = 'pop' limit :__upper_limit", - "Table": "music" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' LIMIT 10)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.genre = 'pop' limit :__upper_limit", - "Table": "music" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "Mergeable subquery with `MAX` aggregate and grouped by unique vindex", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6) GROUP BY music.user_id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6) GROUP BY music.user_id)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select max(music.id) from music where 1 != 1 group by music.user_id", - "Query": "select max(music.id) from music where music.user_id in ::__vals group by music.user_id", - "Table": "music", - "Values": [ - "(INT64(5), INT64(6))" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6) GROUP BY music.user_id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.id in (select max(music.id) from music where music.user_id in ::__vals group by music.user_id)", - "Table": "music", - "Values": [ - "(INT64(5), INT64(6))" - ], - "Vindex": "user_index" + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", + "Table": "music", + "Values": [ + "::__sq1" + ], + "Vindex": "music_user_map" + } + ] }, "TablesUsed": [ "user.music" @@ -6509,11 +3603,11 @@ } }, { - "comment": "Unmergeable subquery with `MAX` aggregate", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6))", - "v3-plan": { + "comment": "Unmergeable scatter subquery with LIMIT", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' LIMIT 10)", + "plan": { "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6))", + "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.genre = 'pop' LIMIT 10)", "Instructions": { "OperatorType": "Subquery", "Variant": "PulloutIn", @@ -6523,24 +3617,19 @@ ], "Inputs": [ { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "max(0)", + "OperatorType": "Limit", + "Count": "INT64(10)", "Inputs": [ { "OperatorType": "Route", - "Variant": "IN", + "Variant": "Scatter", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select max(music.id) from music where 1 != 1", - "Query": "select max(music.id) from music where music.user_id in ::__vals", - "Table": "music", - "Values": [ - "(INT64(5), INT64(6))" - ], - "Vindex": "user_index" + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where music.genre = 'pop' limit :__upper_limit", + "Table": "music" } ] }, @@ -6560,9 +3649,42 @@ "Vindex": "music_user_map" } ] - } - }, - "gen4-plan": { + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "Mergeable subquery with `MAX` aggregate and grouped by unique vindex", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6) GROUP BY music.user_id)", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6) GROUP BY music.user_id)", + "Instructions": { + "OperatorType": "Route", + "Variant": "IN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where music.id in (select max(music.id) from music where music.user_id in ::__vals group by music.user_id)", + "Table": "music", + "Values": [ + "(INT64(5), INT64(6))" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "Unmergeable subquery with `MAX` aggregate", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6))", + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id IN (5, 6))", "Instructions": { @@ -6620,51 +3742,7 @@ { "comment": "Mergeable subquery with `MAX` aggregate with `EqualUnique` route operator", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select max(music.id) from music where 1 != 1", - "Query": "select max(music.id) from music where music.user_id = 5", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5)", "Instructions": { @@ -6715,51 +3793,7 @@ { "comment": "Mergeable subquery with `LIMIT` due to `EqualUnique` route", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5 LIMIT 10)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5 LIMIT 10)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select max(music.id) from music where 1 != 1", - "Query": "select max(music.id) from music where music.user_id = 5 limit 10", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT MAX(music.id) FROM music WHERE music.user_id = 5 LIMIT 10)", "Instructions": { @@ -6810,143 +3844,33 @@ { "comment": "Mergeable subquery with multiple levels of derived statements", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id = 5 LIMIT 10) subquery_for_limit) subquery_for_limit)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id = 5 LIMIT 10) subquery_for_limit) subquery_for_limit)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select * from (select music.id from music where 1 != 1) as subquery_for_limit where 1 != 1) as subquery_for_limit where 1 != 1", - "Query": "select * from (select * from (select music.id from music where music.user_id = 5 limit 10) as subquery_for_limit) as subquery_for_limit", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id = 5 LIMIT 10) subquery_for_limit) subquery_for_limit)", "Instructions": { "OperatorType": "Route", "Variant": "EqualUnique", "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.id in (select subquery_for_limit.id from (select subquery_for_limit.id from (select music.id from music where music.user_id = 5 limit 10) as subquery_for_limit) as subquery_for_limit)", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "Mergeable subquery with multiple levels of derived statements, using a single value `IN` predicate", - "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5) LIMIT 10) subquery_for_limit) subquery_for_limit)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5) LIMIT 10) subquery_for_limit) subquery_for_limit)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals limit :__upper_limit", - "Table": "music", - "Values": [ - "(INT64(5))" - ], - "Vindex": "user_index" - } - ] - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where music.id in (select subquery_for_limit.id from (select subquery_for_limit.id from (select music.id from music where music.user_id = 5 limit 10) as subquery_for_limit) as subquery_for_limit)", + "Table": "music", + "Values": [ + "INT64(5)" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "Mergeable subquery with multiple levels of derived statements, using a single value `IN` predicate", + "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5) LIMIT 10) subquery_for_limit) subquery_for_limit)", + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5) LIMIT 10) subquery_for_limit) subquery_for_limit)", "Instructions": { @@ -6972,73 +3896,7 @@ { "comment": "Unmergeable subquery with multiple levels of derived statements, using a multi value `IN` predicate", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5, 6) LIMIT 10) subquery_for_limit) subquery_for_limit)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5, 6) LIMIT 10) subquery_for_limit) subquery_for_limit)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in ::__vals limit :__upper_limit", - "Table": "music", - "Values": [ - "(INT64(5), INT64(6))" - ], - "Vindex": "user_index" - } - ] - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5, 6) LIMIT 10) subquery_for_limit) subquery_for_limit)", "Instructions": { @@ -7103,69 +3961,7 @@ { "comment": "Unmergeable subquery with multiple levels of derived statements", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music LIMIT 10) subquery_for_limit) subquery_for_limit)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music LIMIT 10) subquery_for_limit) subquery_for_limit)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music limit :__upper_limit", - "Table": "music" - } - ] - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music LIMIT 10) subquery_for_limit) subquery_for_limit)", "Instructions": { @@ -7226,47 +4022,7 @@ { "comment": "`None` subquery as top level predicate - outer query changes from `Scatter` to `None` on merge", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL))", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL))", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in (null)", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__vals", - "Table": "music", - "Values": [ - "::__sq1" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL))", "Instructions": { @@ -7288,47 +4044,7 @@ { "comment": "`None` subquery as top level predicate - outer query changes from `EqualUnique` to `None` on merge", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in (null)", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id = 5 and :__sq_has_values1 = 1 and music.id in ::__sq1", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) AND music.user_id = 5", "Instructions": { @@ -7350,106 +4066,29 @@ { "comment": "`None` subquery nested inside `OR` expression - outer query keeps routing information", "query": "SELECT music.id FROM music WHERE (music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music WHERE (music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "None", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.user_id in (null)", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where :__sq_has_values1 = 1 and music.id in ::__sq1 or music.user_id = 5", - "Table": "music" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music WHERE (music.id IN (SELECT music.id FROM music WHERE music.user_id IN (NULL)) OR music.user_id = 5)", "Instructions": { "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.id in (select music.id from music where music.user_id in (null)) or music.user_id = 5", - "Table": "music" - }, - "TablesUsed": [ - "user.music" - ] - } - }, - { - "comment": "Joining with a subquery that uses an aggregate column and an `EqualUnique` route can be merged together", - "query": "SELECT music.id FROM music INNER JOIN (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other ON other.maxt = music.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music INNER JOIN (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other ON other.maxt = music.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "music_id": 0 - }, - "TableName": "music_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music", - "Table": "music" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from (select max(id) as maxt from music where 1 != 1) as other where 1 != 1", - "Query": "select 1 from (select max(id) as maxt from music where music.user_id = 5) as other where other.maxt = :music_id", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select music.id from music where 1 != 1", + "Query": "select music.id from music where music.id in (select music.id from music where music.user_id in (null)) or music.user_id = 5", + "Table": "music" + }, + "TablesUsed": [ + "user.music" + ] + } + }, + { + "comment": "Joining with a subquery that uses an aggregate column and an `EqualUnique` route can be merged together", + "query": "SELECT music.id FROM music INNER JOIN (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other ON other.maxt = music.id", + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music INNER JOIN (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other ON other.maxt = music.id", "Instructions": { @@ -7475,22 +4114,7 @@ { "comment": "Joining with a subquery that uses an `EqualUnique` route can be merged", "query": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id = 5) other ON other.id = music.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id = 5) other ON other.id = music.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music join (select id from music where 1 != 1) as other on other.id = music.id where 1 != 1", - "Query": "select music.id from music join (select id from music where music.user_id = 5) as other on other.id = music.id", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id = 5) other ON other.id = music.id", "Instructions": { @@ -7516,22 +4140,7 @@ { "comment": "Joining with a subquery that has an `IN` route can be merged", "query": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id IN (5, 6, 7)) other ON other.id = music.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id IN (5, 6, 7)) other ON other.id = music.id", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music join (select id from music where 1 != 1) as other on other.id = music.id where 1 != 1", - "Query": "select music.id from music join (select id from music where music.user_id in (5, 6, 7)) as other on other.id = music.id", - "Table": "music" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM music INNER JOIN (SELECT id FROM music WHERE music.user_id IN (5, 6, 7)) other ON other.id = music.id", "Instructions": { @@ -7557,8 +4166,7 @@ { "comment": "limit on the vtgate has to be executed on the LHS of a join", "query": "select id from user join (select user_id from user_extra limit 10) ue on user.id = ue.user_id", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user join (select user_id from user_extra limit 10) ue on user.id = ue.user_id", "Instructions": { @@ -7613,8 +4221,7 @@ { "comment": "select user.a, t.b from user join (select id, count(*) b, req from user_extra group by req, id) as t on user.id = t.id", "query": "select user.a, t.b from user join (select id, count(*) b, req from user_extra group by req, id) as t on user.id = t.id", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user.a, t.b from user join (select id, count(*) b, req from user_extra group by req, id) as t on user.id = t.id", "Instructions": { @@ -7686,58 +4293,12 @@ { "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", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": "VT12001: unsupported: JOIN between derived tables" + "plan": "VT12001: unsupported: JOIN between derived tables" }, { "comment": "SELECT music.id FROM (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other JOIN music ON other.maxt = music.id", "query": "SELECT music.id FROM (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other JOIN music ON other.maxt = music.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT music.id FROM (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other JOIN music ON other.maxt = music.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "other_maxt": 0 - }, - "TableName": "music_music", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select other.maxt from (select max(id) as maxt from music where 1 != 1) as other where 1 != 1", - "Query": "select other.maxt from (select max(id) as maxt from music where music.user_id = 5) as other", - "Table": "music", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select music.id from music where 1 != 1", - "Query": "select music.id from music where music.id = :other_maxt", - "Table": "music", - "Values": [ - ":other_maxt" - ], - "Vindex": "music_user_map" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT music.id FROM (SELECT MAX(id) as maxt FROM music WHERE music.user_id = 5) other JOIN music ON other.maxt = music.id", "Instructions": { @@ -7763,22 +4324,7 @@ { "comment": "Earlier columns are in scope in subqueries https://github.com/vitessio/vitess/issues/11246", "query": "SELECT 1 as x, (SELECT x)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT 1 as x, (SELECT x)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 as x, (select x from dual where 1 != 1) from dual where 1 != 1", - "Query": "select 1 as x, (select x from dual) from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT 1 as x, (SELECT x)", "Instructions": { @@ -7800,22 +4346,7 @@ { "comment": "(OR 1 = 0) doesn't cause unnecessary scatter", "query": "select * from user where id = 1 or 1 = 0", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 1 or 1 = 0", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 1 or 1 = 0", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 1 or 1 = 0", "Instructions": { @@ -7841,22 +4372,7 @@ { "comment": "(OR 2 < 1) doesn't cause unnecessary scatter", "query": "select * from user where id = 1 or 2 < 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user where id = 1 or 2 < 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 1 or 2 < 1", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user where id = 1 or 2 < 1", "Instructions": { @@ -7882,22 +4398,7 @@ { "comment": "query with a derived table and dual table in unsharded keyspace", "query": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded_a as t1 join (select trim((select max(`name`) from unsharded_a where 1 != 1)) as `name` from dual where 1 != 1) as t2 where 1 != 1", - "Query": "select * from unsharded_a as t1 join (select trim((select max(`name`) from unsharded_a)) as `name` from dual) as t2 where t1.`name` >= t2.`name` order by t1.`name` asc limit 1", - "Table": "unsharded_a, dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", "Instructions": { @@ -7920,8 +4421,7 @@ { "comment": "subquery having join table on clause, using column reference of outer select table", "query": "select (select 1 from user u1 join user u2 on u1.id = u2.id and u1.id = u3.id) subquery from user u3 where u3.id = 1", - "v3-plan": "VT03019: column u3.id not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select (select 1 from user u1 join user u2 on u1.id = u2.id and u1.id = u3.id) subquery from user u3 where u3.id = 1", "Instructions": { @@ -7947,22 +4447,7 @@ { "comment": "allow last_insert_id with argument", "query": "select last_insert_id(id) from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select last_insert_id(id) from user", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select last_insert_id(id) from `user` where 1 != 1", - "Query": "select last_insert_id(id) from `user`", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select last_insert_id(id) from user", "Instructions": { @@ -7984,22 +4469,7 @@ { "comment": "merge subquery using MAX and join into single route", "query": "select 1 from user join music_extra on user.id = music_extra.user_id where music_extra.music_id = (select max(music_id) from music_extra where user_id = user.id)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user join music_extra on user.id = music_extra.user_id where music_extra.music_id = (select max(music_id) from music_extra where user_id = user.id)", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` join music_extra on `user`.id = music_extra.user_id where 1 != 1", - "Query": "select 1 from `user` join music_extra on `user`.id = music_extra.user_id where music_extra.music_id = (select max(music_id) from music_extra where user_id = `user`.id)", - "Table": "`user`, music_extra" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user join music_extra on user.id = music_extra.user_id where music_extra.music_id = (select max(music_id) from music_extra where user_id = user.id)", "Instructions": { @@ -8022,26 +4492,7 @@ { "comment": "Query with non-plannable lookup vindex", "query": "SELECT * FROM user_metadata WHERE user_metadata.non_planable = 'foo'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * FROM user_metadata WHERE user_metadata.non_planable = 'foo'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from user_metadata where 1 != 1", - "Query": "select * from user_metadata where user_metadata.non_planable = 'foo'", - "Table": "user_metadata", - "Values": [ - "VARCHAR(\"foo\")" - ], - "Vindex": "non_planable_user_map" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * FROM user_metadata WHERE user_metadata.non_planable = 'foo'", "Instructions": { @@ -8067,52 +4518,7 @@ { "comment": "join query with lookup and join on different vindex column", "query": "select u.id from user u, user_metadata um where u.name = 'foo' and u.id = um.user_id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id from user u, user_metadata um where u.name = 'foo' and u.id = um.user_id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u_id": 0 - }, - "TableName": "`user`_user_metadata", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id from `user` as u where 1 != 1", - "Query": "select u.id from `user` as u where u.`name` = 'foo'", - "Table": "`user`", - "Values": [ - "VARCHAR(\"foo\")" - ], - "Vindex": "name_user_map" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_metadata as um where 1 != 1", - "Query": "select 1 from user_metadata as um where um.user_id = :u_id", - "Table": "user_metadata", - "Values": [ - ":u_id" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id from user u, user_metadata um where u.name = 'foo' and u.id = um.user_id", "Instructions": { @@ -8164,26 +4570,7 @@ { "comment": "pick email as vindex lookup", "query": "select * from customer where email = 'a@mail.com'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from customer where email = 'a@mail.com'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from customer where 1 != 1", - "Query": "select * from customer where email = 'a@mail.com'", - "Table": "customer", - "Values": [ - "VARCHAR(\"a@mail.com\")" - ], - "Vindex": "unq_lkp_vdx" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from customer where email = 'a@mail.com'", "Instructions": { @@ -8234,26 +4621,7 @@ { "comment": "phone is in backfill vindex - not selected for vindex lookup", "query": "select * from customer where phone = 123456", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from customer where phone = 123456", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from customer where 1 != 1", - "Query": "select * from customer where phone = 123456", - "Table": "customer", - "Values": [ - "INT64(123456)" - ], - "Vindex": "unq_lkp_bf_vdx" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from customer where phone = 123456", "Instructions": { @@ -8275,26 +4643,7 @@ { "comment": "email vindex is costly than phone vindex - but phone vindex is backfiling hence ignored", "query": "select * from customer where email = 'a@mail.com' and phone = 123456", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from customer where email = 'a@mail.com' and phone = 123456", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from customer where 1 != 1", - "Query": "select * from customer where email = 'a@mail.com' and phone = 123456", - "Table": "customer", - "Values": [ - "INT64(123456)" - ], - "Vindex": "unq_lkp_bf_vdx" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from customer where email = 'a@mail.com' and phone = 123456", "Instructions": { @@ -8345,26 +4694,7 @@ { "comment": "predicate order changed: email vindex is costly than phone vindex - but phone vindex is backfiling hence ignored", "query": "select * from customer where phone = 123456 and email = 'a@mail.com'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from customer where phone = 123456 and email = 'a@mail.com'", - "Instructions": { - "OperatorType": "Route", - "Variant": "Equal", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from customer where 1 != 1", - "Query": "select * from customer where phone = 123456 and email = 'a@mail.com'", - "Table": "customer", - "Values": [ - "INT64(123456)" - ], - "Vindex": "unq_lkp_bf_vdx" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from customer where phone = 123456 and email = 'a@mail.com'", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases_with_default.json b/go/vt/vtgate/planbuilder/testdata/select_cases_with_default.json index 5817157752b..02fd7330a8f 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases_with_default.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases_with_default.json @@ -2,47 +2,7 @@ { "comment": "EXISTS subquery when the default ks is different than the inner query", "query": "select exists(select * from user where id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select exists(select * from user where id = 5)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutExists", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where id = 5 limit 1", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "second_user", - "Sharded": true - }, - "FieldQuery": "select :__sq_has_values1 from dual where 1 != 1", - "Query": "select :__sq_has_values1 from dual", - "Table": "dual" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select exists(select * from user where id = 5)", "Instructions": { @@ -66,4 +26,4 @@ ] } } -] \ No newline at end of file +] diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases_with_user_as_default.json b/go/vt/vtgate/planbuilder/testdata/select_cases_with_user_as_default.json index 822ed6c2307..6f1145b345e 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases_with_user_as_default.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases_with_user_as_default.json @@ -2,26 +2,7 @@ { "comment": "EXISTS subquery", "query": "select exists(select * from user where id = 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select exists(select * from user where id = 5)", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select exists (select 1 from `user` where 1 != 1) from dual where 1 != 1", - "Query": "select exists (select 1 from `user` where id = 5 limit 1) from dual", - "Table": "dual", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select exists(select * from user where id = 5)", "Instructions": { @@ -45,4 +26,4 @@ ] } } -] \ No newline at end of file +] diff --git a/go/vt/vtgate/planbuilder/testdata/symtab_cases.json b/go/vt/vtgate/planbuilder/testdata/symtab_cases.json index 9dc83122ce0..db9fe66d41e 100644 --- a/go/vt/vtgate/planbuilder/testdata/symtab_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/symtab_cases.json @@ -2,44 +2,7 @@ { "comment": "Tests in this file are for testing symtab functionality\n#\n# Column names need not be qualified if they are predefined in vschema and unambiguous.", "query": "select predef2, predef3 from user join unsharded on predef2 = predef3", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select predef2, predef3 from user join unsharded on predef2 = predef3", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "predef2": 0 - }, - "TableName": "`user`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select predef2 from `user` where 1 != 1", - "Query": "select predef2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select predef3 from unsharded where 1 != 1", - "Query": "select predef3 from unsharded where predef3 = :predef2", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select predef2, predef3 from user join unsharded on predef2 = predef3", "Instructions": { @@ -84,7 +47,6 @@ { "comment": "predef1 is in both user and unsharded. So, it's ambiguous.", "query": "select predef1, predef3 from user join unsharded on predef1 = predef3", - "v3-plan": "VT03019: column predef1 not found", - "gen4-plan": "Column 'predef1' in field list is ambiguous" + "plan": "Column 'predef1' in field list is ambiguous" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/sysschema_default.json b/go/vt/vtgate/planbuilder/testdata/sysschema_default.json index eec3c4709b9..0d2bbfa4adc 100644 --- a/go/vt/vtgate/planbuilder/testdata/sysschema_default.json +++ b/go/vt/vtgate/planbuilder/testdata/sysschema_default.json @@ -2,22 +2,7 @@ { "comment": "max_allowed_packet", "query": "select @@max_allowed_packet from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select @@max_allowed_packet from dual", - "Instructions": { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select @@max_allowed_packet from dual where 1 != 1", - "Query": "select @@max_allowed_packet from dual", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select @@max_allowed_packet from dual", "Instructions": { @@ -39,23 +24,7 @@ { "comment": "unqualified table name", "query": "select t.table_schema,t.table_name,c.column_name,c.column_type from tables t join columns c on c.table_schema = t.table_schema and c.table_name = t.table_name where t.table_schema = 'user' and c.table_schema = 'user' order by t.table_schema,t.table_name,c.column_name", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select t.table_schema,t.table_name,c.column_name,c.column_type from tables t join columns c on c.table_schema = t.table_schema and c.table_name = t.table_name where t.table_schema = 'user' and c.table_schema = 'user' order by t.table_schema,t.table_name,c.column_name", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select t.table_schema, t.table_name, c.column_name, c.column_type from information_schema.`tables` as t join information_schema.`columns` as c on c.table_schema = t.table_schema and c.table_name = t.table_name where 1 != 1", - "Query": "select t.table_schema, t.table_name, c.column_name, c.column_type from information_schema.`tables` as t join information_schema.`columns` as c on c.table_schema = t.table_schema and c.table_name = t.table_name where t.table_schema = :__vtschemaname /* VARCHAR */ and c.table_schema = :__vtschemaname /* VARCHAR */ order by t.table_schema asc, t.table_name asc, c.column_name asc", - "SysTableTableSchema": "[VARCHAR(\"user\"), VARCHAR(\"user\")]", - "Table": "information_schema.`tables`, information_schema.`columns`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select t.table_schema,t.table_name,c.column_name,c.column_type from tables t join columns c on c.table_schema = t.table_schema and c.table_name = t.table_name where t.table_schema = 'user' and c.table_schema = 'user' order by t.table_schema,t.table_name,c.column_name", "Instructions": { @@ -75,23 +44,7 @@ { "comment": "system schema query as a subquery", "query": "SELECT (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1);", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1);", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select (select 1 from information_schema.schemata where 1 != 1) from dual where 1 != 1", - "Query": "select (select 1 from information_schema.schemata where schema_name = :__vtschemaname /* VARCHAR */ limit 1) from dual", - "SysTableTableSchema": "[VARCHAR(\"MyDatabase\")]", - "Table": "dual" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1);", "Instructions": { @@ -114,23 +67,7 @@ { "comment": "system schema query as a derived table", "query": "SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x", - "Instructions": { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from (select 1 from information_schema.schemata where 1 != 1) as x where 1 != 1", - "Query": "select * from (select 1 from information_schema.schemata where schema_name = :__vtschemaname /* VARCHAR */ limit 1) as x", - "SysTableTableSchema": "[VARCHAR(\"MyDatabase\")]", - "Table": "information_schema.schemata" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/tpcc_cases.json b/go/vt/vtgate/planbuilder/testdata/tpcc_cases.json index 51be1f7522c..331a9cdfa13 100644 --- a/go/vt/vtgate/planbuilder/testdata/tpcc_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/tpcc_cases.json @@ -2,26 +2,7 @@ { "comment": "TPC-C select join customer1 and warehouse1", "query": "SELECT c_discount, c_last, c_credit, w_tax FROM customer1 AS c JOIN warehouse1 AS w ON c_w_id=w_id WHERE w_id = 1 AND c_d_id = 15 AND c_id = 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_discount, c_last, c_credit, w_tax FROM customer1 AS c JOIN warehouse1 AS w ON c_w_id=w_id WHERE w_id = 1 AND c_d_id = 15 AND c_id = 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_discount, c_last, c_credit, w_tax from customer1 as c join warehouse1 as w on c_w_id = w_id where 1 != 1", - "Query": "select c_discount, c_last, c_credit, w_tax from customer1 as c join warehouse1 as w on c_w_id = w_id where w_id = 1 and c_d_id = 15 and c_id = 10", - "Table": "customer1, warehouse1", - "Values": [ - "INT64(1)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_discount, c_last, c_credit, w_tax FROM customer1 AS c JOIN warehouse1 AS w ON c_w_id=w_id WHERE w_id = 1 AND c_d_id = 15 AND c_id = 10", "Instructions": { @@ -48,26 +29,7 @@ { "comment": "TPC-C select district1 for update", "query": "SELECT d_next_o_id, d_tax FROM district1 WHERE d_w_id = 15 AND d_id = 95 FOR UPDATE", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT d_next_o_id, d_tax FROM district1 WHERE d_w_id = 15 AND d_id = 95 FOR UPDATE", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select d_next_o_id, d_tax from district1 where 1 != 1", - "Query": "select d_next_o_id, d_tax from district1 where d_w_id = 15 and d_id = 95 for update", - "Table": "district1", - "Values": [ - "INT64(15)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT d_next_o_id, d_tax FROM district1 WHERE d_w_id = 15 AND d_id = 95 FOR UPDATE", "Instructions": { @@ -93,29 +55,7 @@ { "comment": "TPC-C update district1 unique", "query": "UPDATE district1 SET d_next_o_id = 56 WHERE d_id = 9842 AND d_w_id= 8546", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE district1 SET d_next_o_id = 56 WHERE d_id = 9842 AND d_w_id= 8546", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update district1 set d_next_o_id = 56 where d_id = 9842 and d_w_id = 8546", - "Table": "district1", - "Values": [ - "INT64(8546)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.district1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE district1 SET d_next_o_id = 56 WHERE d_id = 9842 AND d_w_id= 8546", "Instructions": { @@ -191,26 +131,7 @@ { "comment": "TPC-C select unique item1", "query": "SELECT i_price, i_name, i_data FROM item1 WHERE i_id = 9654", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT i_price, i_name, i_data FROM item1 WHERE i_id = 9654", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select i_price, i_name, i_data from item1 where 1 != 1", - "Query": "select i_price, i_name, i_data from item1 where i_id = 9654", - "Table": "item1", - "Values": [ - "INT64(9654)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT i_price, i_name, i_data FROM item1 WHERE i_id = 9654", "Instructions": { @@ -236,26 +157,7 @@ { "comment": "TPC-C select stock1 for update", "query": "SELECT s_quantity, s_data, s_dist_01 s_dist FROM stock1 WHERE s_i_id = 2198 AND s_w_id = 89 FOR UPDATE", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT s_quantity, s_data, s_dist_01 s_dist FROM stock1 WHERE s_i_id = 2198 AND s_w_id = 89 FOR UPDATE", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select s_quantity, s_data, s_dist_01 as s_dist from stock1 where 1 != 1", - "Query": "select s_quantity, s_data, s_dist_01 as s_dist from stock1 where s_i_id = 2198 and s_w_id = 89 for update", - "Table": "stock1", - "Values": [ - "INT64(89)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT s_quantity, s_data, s_dist_01 s_dist FROM stock1 WHERE s_i_id = 2198 AND s_w_id = 89 FOR UPDATE", "Instructions": { @@ -281,29 +183,7 @@ { "comment": "TPC-C update stock1", "query": "UPDATE stock1 SET s_quantity = 894 WHERE s_i_id = 156 AND s_w_id= 6", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE stock1 SET s_quantity = 894 WHERE s_i_id = 156 AND s_w_id= 6", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update stock1 set s_quantity = 894 where s_i_id = 156 and s_w_id = 6", - "Table": "stock1", - "Values": [ - "INT64(6)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.stock1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE stock1 SET s_quantity = 894 WHERE s_i_id = 156 AND s_w_id= 6", "Instructions": { @@ -354,29 +234,7 @@ { "comment": "TPC-C update warehouse1 unique", "query": "UPDATE warehouse1 SET w_ytd = w_ytd + 946879 WHERE w_id = 3", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE warehouse1 SET w_ytd = w_ytd + 946879 WHERE w_id = 3", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update warehouse1 set w_ytd = w_ytd + 946879 where w_id = 3", - "Table": "warehouse1", - "Values": [ - "INT64(3)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.warehouse1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE warehouse1 SET w_ytd = w_ytd + 946879 WHERE w_id = 3", "Instructions": { @@ -402,26 +260,7 @@ { "comment": "TPC-C select warehouse1 unique", "query": "SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse1 WHERE w_id = 998", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse1 WHERE w_id = 998", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select w_street_1, w_street_2, w_city, w_state, w_zip, w_name from warehouse1 where 1 != 1", - "Query": "select w_street_1, w_street_2, w_city, w_state, w_zip, w_name from warehouse1 where w_id = 998", - "Table": "warehouse1", - "Values": [ - "INT64(998)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse1 WHERE w_id = 998", "Instructions": { @@ -447,29 +286,7 @@ { "comment": "TPC-C update district1 unique", "query": "UPDATE district1 SET d_ytd = d_ytd + 2 WHERE d_w_id = 89 AND d_id= 9", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE district1 SET d_ytd = d_ytd + 2 WHERE d_w_id = 89 AND d_id= 9", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update district1 set d_ytd = d_ytd + 2 where d_w_id = 89 and d_id = 9", - "Table": "district1", - "Values": [ - "INT64(89)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.district1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE district1 SET d_ytd = d_ytd + 2 WHERE d_w_id = 89 AND d_id= 9", "Instructions": { @@ -495,26 +312,7 @@ { "comment": "TPC-C select district1 unique", "query": "SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district1 WHERE d_w_id = 896 AND d_id = 9", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district1 WHERE d_w_id = 896 AND d_id = 9", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select d_street_1, d_street_2, d_city, d_state, d_zip, d_name from district1 where 1 != 1", - "Query": "select d_street_1, d_street_2, d_city, d_state, d_zip, d_name from district1 where d_w_id = 896 and d_id = 9", - "Table": "district1", - "Values": [ - "INT64(896)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district1 WHERE d_w_id = 896 AND d_id = 9", "Instructions": { @@ -540,26 +338,7 @@ { "comment": "TPC-C select aggr from customer1", "query": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 5 AND c_d_id= 1 AND c_last='last'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 5 AND c_d_id= 1 AND c_last='last'", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select count(c_id) as namecnt from customer1 where 1 != 1", - "Query": "select count(c_id) as namecnt from customer1 where c_w_id = 5 and c_d_id = 1 and c_last = 'last'", - "Table": "customer1", - "Values": [ - "INT64(5)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 5 AND c_d_id= 1 AND c_last='last'", "Instructions": { @@ -585,26 +364,7 @@ { "comment": "TPC-C select customer1 order by", "query": "SELECT c_id FROM customer1 WHERE c_w_id = 8 AND c_d_id = 5 AND c_last='item_last' ORDER BY c_first", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_id FROM customer1 WHERE c_w_id = 8 AND c_d_id = 5 AND c_last='item_last' ORDER BY c_first", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_id from customer1 where 1 != 1", - "Query": "select c_id from customer1 where c_w_id = 8 and c_d_id = 5 and c_last = 'item_last' order by c_first asc", - "Table": "customer1", - "Values": [ - "INT64(8)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_id FROM customer1 WHERE c_w_id = 8 AND c_d_id = 5 AND c_last='item_last' ORDER BY c_first", "Instructions": { @@ -630,26 +390,7 @@ { "comment": "TPC-C select for update customer1 unique", "query": "SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since FROM customer1 WHERE c_w_id = 8965 AND c_d_id = 1 AND c_id = 9 FOR UPDATE", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since FROM customer1 WHERE c_w_id = 8965 AND c_d_id = 1 AND c_id = 9 FOR UPDATE", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since from customer1 where 1 != 1", - "Query": "select c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since from customer1 where c_w_id = 8965 and c_d_id = 1 and c_id = 9 for update", - "Table": "customer1", - "Values": [ - "INT64(8965)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since FROM customer1 WHERE c_w_id = 8965 AND c_d_id = 1 AND c_id = 9 FOR UPDATE", "Instructions": { @@ -675,26 +416,7 @@ { "comment": "TPC-C select customer1 unique", "query": "SELECT c_data FROM customer1 WHERE c_w_id = 32 AND c_d_id=68 AND c_id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_data FROM customer1 WHERE c_w_id = 32 AND c_d_id=68 AND c_id = 5", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_data from customer1 where 1 != 1", - "Query": "select c_data from customer1 where c_w_id = 32 and c_d_id = 68 and c_id = 5", - "Table": "customer1", - "Values": [ - "INT64(32)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_data FROM customer1 WHERE c_w_id = 32 AND c_d_id=68 AND c_id = 5", "Instructions": { @@ -720,12 +442,12 @@ { "comment": "TPC-C update customer1 unique and float value", "query": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301, c_data='i am data' WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", - "v3-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301, c_data='i am data' WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", "Instructions": { "OperatorType": "Update", - "Variant": "Equal", + "Variant": "EqualUnique", "Keyspace": { "Name": "main", "Sharded": true @@ -741,56 +463,12 @@ "TablesUsed": [ "main.customer1" ] - }, - "gen4-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301, c_data='i am data' WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", - "Instructions": { - "OperatorType": "Update", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update customer1 set c_balance = 508.98, c_ytd_payment = 48941.980301, c_data = 'i am data' where c_w_id = 20 and c_d_id = 387 and c_id = 98", - "Table": "customer1", - "Values": [ - "INT64(20)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.customer1" - ] - } - }, - { - "comment": "TPC-C update customer1 unique and float value", - "query": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301 WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301 WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update customer1 set c_balance = 508.98, c_ytd_payment = 48941.980301 where c_w_id = 20 and c_d_id = 387 and c_id = 98", - "Table": "customer1", - "Values": [ - "INT64(20)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.customer1" - ] - }, - "gen4-plan": { + } + }, + { + "comment": "TPC-C update customer1 unique and float value", + "query": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301 WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", + "plan": { "QueryType": "UPDATE", "Original": "UPDATE customer1 SET c_balance=508.98, c_ytd_payment=48941.980301 WHERE c_w_id = 20 AND c_d_id=387 AND c_id=98", "Instructions": { @@ -841,26 +519,7 @@ { "comment": "TPC-C select aggr customer1", "query": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 870 AND c_d_id= 780 AND c_last='last'", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 870 AND c_d_id= 780 AND c_last='last'", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select count(c_id) as namecnt from customer1 where 1 != 1", - "Query": "select count(c_id) as namecnt from customer1 where c_w_id = 870 and c_d_id = 780 and c_last = 'last'", - "Table": "customer1", - "Values": [ - "INT64(870)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT count(c_id) namecnt FROM customer1 WHERE c_w_id = 870 AND c_d_id= 780 AND c_last='last'", "Instructions": { @@ -886,26 +545,7 @@ { "comment": "TPC-C select order by customer1", "query": "SELECT c_balance, c_first, c_middle, c_id FROM customer1 WHERE c_w_id = 840 AND c_d_id= 1 AND c_last='test' ORDER BY c_first", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_balance, c_first, c_middle, c_id FROM customer1 WHERE c_w_id = 840 AND c_d_id= 1 AND c_last='test' ORDER BY c_first", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_balance, c_first, c_middle, c_id from customer1 where 1 != 1", - "Query": "select c_balance, c_first, c_middle, c_id from customer1 where c_w_id = 840 and c_d_id = 1 and c_last = 'test' order by c_first asc", - "Table": "customer1", - "Values": [ - "INT64(840)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_balance, c_first, c_middle, c_id FROM customer1 WHERE c_w_id = 840 AND c_d_id= 1 AND c_last='test' ORDER BY c_first", "Instructions": { @@ -931,26 +571,7 @@ { "comment": "TPC-C select unique customer1", "query": "SELECT c_balance, c_first, c_middle, c_last FROM customer1 WHERE c_w_id = 15 AND c_d_id=5169 AND c_id=1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT c_balance, c_first, c_middle, c_last FROM customer1 WHERE c_w_id = 15 AND c_d_id=5169 AND c_id=1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select c_balance, c_first, c_middle, c_last from customer1 where 1 != 1", - "Query": "select c_balance, c_first, c_middle, c_last from customer1 where c_w_id = 15 and c_d_id = 5169 and c_id = 1", - "Table": "customer1", - "Values": [ - "INT64(15)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT c_balance, c_first, c_middle, c_last FROM customer1 WHERE c_w_id = 15 AND c_d_id=5169 AND c_id=1", "Instructions": { @@ -976,26 +597,7 @@ { "comment": "TPC-C select order by orders1", "query": "SELECT o_id, o_carrier_id, o_entry_d FROM orders1 WHERE o_w_id = 9894 AND o_d_id = 3 AND o_c_id = 159 ORDER BY o_id DESC", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT o_id, o_carrier_id, o_entry_d FROM orders1 WHERE o_w_id = 9894 AND o_d_id = 3 AND o_c_id = 159 ORDER BY o_id DESC", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select o_id, o_carrier_id, o_entry_d from orders1 where 1 != 1", - "Query": "select o_id, o_carrier_id, o_entry_d from orders1 where o_w_id = 9894 and o_d_id = 3 and o_c_id = 159 order by o_id desc", - "Table": "orders1", - "Values": [ - "INT64(9894)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT o_id, o_carrier_id, o_entry_d FROM orders1 WHERE o_w_id = 9894 AND o_d_id = 3 AND o_c_id = 159 ORDER BY o_id DESC", "Instructions": { @@ -1021,26 +623,7 @@ { "comment": "TPC-C select order_line1", "query": "SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line1 WHERE ol_w_id = 92 AND ol_d_id = 5 AND ol_o_id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line1 WHERE ol_w_id = 92 AND ol_d_id = 5 AND ol_o_id = 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d from order_line1 where 1 != 1", - "Query": "select ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d from order_line1 where ol_w_id = 92 and ol_d_id = 5 and ol_o_id = 1", - "Table": "order_line1", - "Values": [ - "INT64(92)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line1 WHERE ol_w_id = 92 AND ol_d_id = 5 AND ol_o_id = 1", "Instructions": { @@ -1066,26 +649,7 @@ { "comment": "TPC-C select for update new_orders1", "query": "SELECT no_o_id FROM new_orders1 WHERE no_d_id = 689 AND no_w_id = 15 ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT no_o_id FROM new_orders1 WHERE no_d_id = 689 AND no_w_id = 15 ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select no_o_id from new_orders1 where 1 != 1", - "Query": "select no_o_id from new_orders1 where no_d_id = 689 and no_w_id = 15 order by no_o_id asc limit 1 for update", - "Table": "new_orders1", - "Values": [ - "INT64(15)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT no_o_id FROM new_orders1 WHERE no_d_id = 689 AND no_w_id = 15 ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE", "Instructions": { @@ -1111,29 +675,7 @@ { "comment": "TPC-C delete new_orders1", "query": "DELETE FROM new_orders1 WHERE no_o_id = 2218 AND no_d_id = 358 AND no_w_id = 98465", - "v3-plan": { - "QueryType": "DELETE", - "Original": "DELETE FROM new_orders1 WHERE no_o_id = 2218 AND no_d_id = 358 AND no_w_id = 98465", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from new_orders1 where no_o_id = 2218 and no_d_id = 358 and no_w_id = 98465", - "Table": "new_orders1", - "Values": [ - "INT64(98465)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.new_orders1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "DELETE FROM new_orders1 WHERE no_o_id = 2218 AND no_d_id = 358 AND no_w_id = 98465", "Instructions": { @@ -1159,26 +701,7 @@ { "comment": "TPC-C select unique orders1", "query": "SELECT o_c_id FROM orders1 WHERE o_id = 6 AND o_d_id = 1983 AND o_w_id = 894605", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT o_c_id FROM orders1 WHERE o_id = 6 AND o_d_id = 1983 AND o_w_id = 894605", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select o_c_id from orders1 where 1 != 1", - "Query": "select o_c_id from orders1 where o_id = 6 and o_d_id = 1983 and o_w_id = 894605", - "Table": "orders1", - "Values": [ - "INT64(894605)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT o_c_id FROM orders1 WHERE o_id = 6 AND o_d_id = 1983 AND o_w_id = 894605", "Instructions": { @@ -1204,29 +727,7 @@ { "comment": "TPC-C update orders1 unique", "query": "UPDATE orders1 SET o_carrier_id = 9 WHERE o_id = 56 AND o_d_id = 98 AND o_w_id = 897", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE orders1 SET o_carrier_id = 9 WHERE o_id = 56 AND o_d_id = 98 AND o_w_id = 897", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update orders1 set o_carrier_id = 9 where o_id = 56 and o_d_id = 98 and o_w_id = 897", - "Table": "orders1", - "Values": [ - "INT64(897)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.orders1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE orders1 SET o_carrier_id = 9 WHERE o_id = 56 AND o_d_id = 98 AND o_w_id = 897", "Instructions": { @@ -1252,29 +753,7 @@ { "comment": "TPC-C update order_line1", "query": "UPDATE order_line1 SET ol_delivery_d = NOW() WHERE ol_o_id = 235 AND ol_d_id = 315 AND ol_w_id = 8", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE order_line1 SET ol_delivery_d = NOW() WHERE ol_o_id = 235 AND ol_d_id = 315 AND ol_w_id = 8", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update order_line1 set ol_delivery_d = now() where ol_o_id = 235 and ol_d_id = 315 and ol_w_id = 8", - "Table": "order_line1", - "Values": [ - "INT64(8)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.order_line1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE order_line1 SET ol_delivery_d = NOW() WHERE ol_o_id = 235 AND ol_d_id = 315 AND ol_w_id = 8", "Instructions": { @@ -1300,26 +779,7 @@ { "comment": "TPC-C select sum order_line1", "query": "SELECT SUM(ol_amount) sm FROM order_line1 WHERE ol_o_id = 680 AND ol_d_id = 201 AND ol_w_id = 87", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT SUM(ol_amount) sm FROM order_line1 WHERE ol_o_id = 680 AND ol_d_id = 201 AND ol_w_id = 87", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select sum(ol_amount) as sm from order_line1 where 1 != 1", - "Query": "select sum(ol_amount) as sm from order_line1 where ol_o_id = 680 and ol_d_id = 201 and ol_w_id = 87", - "Table": "order_line1", - "Values": [ - "INT64(87)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT SUM(ol_amount) sm FROM order_line1 WHERE ol_o_id = 680 AND ol_d_id = 201 AND ol_w_id = 87", "Instructions": { @@ -1345,29 +805,7 @@ { "comment": "TPC-C update customer1", "query": "UPDATE customer1 SET c_balance = c_balance + 988.01, c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = 6 AND c_d_id = 5 AND c_w_id = 160", - "v3-plan": { - "QueryType": "UPDATE", - "Original": "UPDATE customer1 SET c_balance = c_balance + 988.01, c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = 6 AND c_d_id = 5 AND c_w_id = 160", - "Instructions": { - "OperatorType": "Update", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "update customer1 set c_balance = c_balance + 988.01, c_delivery_cnt = c_delivery_cnt + 1 where c_id = 6 and c_d_id = 5 and c_w_id = 160", - "Table": "customer1", - "Values": [ - "INT64(160)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.customer1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "UPDATE", "Original": "UPDATE customer1 SET c_balance = c_balance + 988.01, c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = 6 AND c_d_id = 5 AND c_w_id = 160", "Instructions": { @@ -1393,26 +831,7 @@ { "comment": "TPC-C select unique district1", "query": "SELECT d_next_o_id FROM district1 WHERE d_id = 6 AND d_w_id= 21", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT d_next_o_id FROM district1 WHERE d_id = 6 AND d_w_id= 21", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select d_next_o_id from district1 where 1 != 1", - "Query": "select d_next_o_id from district1 where d_id = 6 and d_w_id = 21", - "Table": "district1", - "Values": [ - "INT64(21)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT d_next_o_id FROM district1 WHERE d_id = 6 AND d_w_id= 21", "Instructions": { @@ -1438,26 +857,7 @@ { "comment": "TPC-C select count distinct stock1 join order_line1", "query": "SELECT COUNT(DISTINCT(s.s_i_id)) FROM stock1 AS s JOIN order_line1 AS ol ON ol.ol_w_id=s.s_w_id AND ol.ol_i_id=s.s_i_id WHERE ol.ol_w_id = 12 AND ol.ol_d_id = 1908 AND ol.ol_o_id < 30 AND ol.ol_o_id >= 15 AND s.s_w_id= 12 AND s.s_quantity < 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT COUNT(DISTINCT(s.s_i_id)) FROM stock1 AS s JOIN order_line1 AS ol ON ol.ol_w_id=s.s_w_id AND ol.ol_i_id=s.s_i_id WHERE ol.ol_w_id = 12 AND ol.ol_d_id = 1908 AND ol.ol_o_id < 30 AND ol.ol_o_id >= 15 AND s.s_w_id= 12 AND s.s_quantity < 10", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select count(distinct s.s_i_id) from stock1 as s join order_line1 as ol on ol.ol_w_id = s.s_w_id and ol.ol_i_id = s.s_i_id where 1 != 1", - "Query": "select count(distinct s.s_i_id) from stock1 as s join order_line1 as ol on ol.ol_w_id = s.s_w_id and ol.ol_i_id = s.s_i_id where ol.ol_w_id = 12 and ol.ol_d_id = 1908 and ol.ol_o_id < 30 and ol.ol_o_id >= 15 and s.s_w_id = 12 and s.s_quantity < 10", - "Table": "stock1, order_line1", - "Values": [ - "INT64(12)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT COUNT(DISTINCT(s.s_i_id)) FROM stock1 AS s JOIN order_line1 AS ol ON ol.ol_w_id=s.s_w_id AND ol.ol_i_id=s.s_i_id WHERE ol.ol_w_id = 12 AND ol.ol_d_id = 1908 AND ol.ol_o_id < 30 AND ol.ol_o_id >= 15 AND s.s_w_id= 12 AND s.s_quantity < 10", "Instructions": { @@ -1484,26 +884,7 @@ { "comment": "TPC-C select distinct order_line1", "query": "SELECT DISTINCT ol_i_id FROM order_line1 WHERE ol_w_id = 1 AND ol_d_id = 156 AND ol_o_id < 500 AND ol_o_id >= 56", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT DISTINCT ol_i_id FROM order_line1 WHERE ol_w_id = 1 AND ol_d_id = 156 AND ol_o_id < 500 AND ol_o_id >= 56", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select ol_i_id from order_line1 where 1 != 1", - "Query": "select distinct ol_i_id from order_line1 where ol_w_id = 1 and ol_d_id = 156 and ol_o_id < 500 and ol_o_id >= 56", - "Table": "order_line1", - "Values": [ - "INT64(1)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT DISTINCT ol_i_id FROM order_line1 WHERE ol_w_id = 1 AND ol_d_id = 156 AND ol_o_id < 500 AND ol_o_id >= 56", "Instructions": { @@ -1529,26 +910,7 @@ { "comment": "TPC-C", "query": "SELECT count(*) FROM stock1 WHERE s_w_id = 1 AND s_i_id = 8 AND s_quantity < 1000", - "v3-plan": { - "QueryType": "SELECT", - "Original": "SELECT count(*) FROM stock1 WHERE s_w_id = 1 AND s_i_id = 8 AND s_quantity < 1000", - "Instructions": { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select count(*) from stock1 where 1 != 1", - "Query": "select count(*) from stock1 where s_w_id = 1 and s_i_id = 8 and s_quantity < 1000", - "Table": "stock1", - "Values": [ - "INT64(1)" - ], - "Vindex": "hash" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "SELECT count(*) FROM stock1 WHERE s_w_id = 1 AND s_i_id = 8 AND s_quantity < 1000", "Instructions": { @@ -1574,56 +936,7 @@ { "comment": "TPC-C select with subquery,aggr,distinct,having,limit", "query": "select o.o_id,o.o_d_id from orders1 o, (select o_c_id,o_w_id,o_d_id,count(distinct o_w_id),o_id from orders1 where o_w_id=1 and o_id > 2100 and o_id < 11153 group by o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t where t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select o.o_id,o.o_d_id from orders1 o, (select o_c_id,o_w_id,o_d_id,count(distinct o_w_id),o_id from orders1 where o_w_id=1 and o_id > 2100 and o_id < 11153 group by o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t where t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "JoinVars": { - "o_o_c_id": 3, - "o_o_d_id": 1, - "o_o_w_id": 2 - }, - "TableName": "orders1_orders1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select o.o_id, o.o_d_id, o.o_w_id, o.o_c_id from orders1 as o where 1 != 1", - "Query": "select o.o_id, o.o_d_id, o.o_w_id, o.o_c_id from orders1 as o", - "Table": "orders1" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select 1 from (select o_c_id, o_w_id, o_d_id, count(distinct o_w_id), o_id from orders1 where 1 != 1 group by o_c_id, o_d_id, o_w_id) as t where 1 != 1", - "Query": "select 1 from (select o_c_id, o_w_id, o_d_id, count(distinct o_w_id), o_id from orders1 where o_w_id = 1 and o_id > 2100 and o_id < 11153 group by o_c_id, o_d_id, o_w_id having count(distinct o_id) > 1 limit 1) as t where t.o_w_id = :o_o_w_id and t.o_d_id = :o_o_d_id and t.o_c_id = :o_o_c_id", - "Table": "orders1", - "Values": [ - "INT64(1)" - ], - "Vindex": "hash" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select o.o_id,o.o_d_id from orders1 o, (select o_c_id,o_w_id,o_d_id,count(distinct o_w_id),o_id from orders1 where o_w_id=1 and o_id > 2100 and o_id < 11153 group by o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t where t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1", "Instructions": { @@ -1649,29 +962,7 @@ { "comment": "TPC-C delete order_line1", "query": "DELETE FROM order_line1 where ol_w_id=178 AND ol_d_id=1 AND ol_o_id=84", - "v3-plan": { - "QueryType": "DELETE", - "Original": "DELETE FROM order_line1 where ol_w_id=178 AND ol_d_id=1 AND ol_o_id=84", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from order_line1 where ol_w_id = 178 and ol_d_id = 1 and ol_o_id = 84", - "Table": "order_line1", - "Values": [ - "INT64(178)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.order_line1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "DELETE FROM order_line1 where ol_w_id=178 AND ol_d_id=1 AND ol_o_id=84", "Instructions": { @@ -1697,29 +988,7 @@ { "comment": "TPC-C delete orders1", "query": "DELETE FROM orders1 where o_w_id=1 AND o_d_id=3 and o_id=384", - "v3-plan": { - "QueryType": "DELETE", - "Original": "DELETE FROM orders1 where o_w_id=1 AND o_d_id=3 and o_id=384", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from orders1 where o_w_id = 1 and o_d_id = 3 and o_id = 384", - "Table": "orders1", - "Values": [ - "INT64(1)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.orders1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "DELETE FROM orders1 where o_w_id=1 AND o_d_id=3 and o_id=384", "Instructions": { @@ -1745,29 +1014,7 @@ { "comment": "TPC-C delete history1", "query": "DELETE FROM history1 where h_w_id=75 AND h_d_id=102 LIMIT 10", - "v3-plan": { - "QueryType": "DELETE", - "Original": "DELETE FROM history1 where h_w_id=75 AND h_d_id=102 LIMIT 10", - "Instructions": { - "OperatorType": "Delete", - "Variant": "Equal", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "TargetTabletType": "PRIMARY", - "Query": "delete from history1 where h_w_id = 75 and h_d_id = 102 limit 10", - "Table": "history1", - "Values": [ - "INT64(75)" - ], - "Vindex": "hash" - }, - "TablesUsed": [ - "main.history1" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DELETE", "Original": "DELETE FROM history1 where h_w_id=75 AND h_d_id=102 LIMIT 10", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json index eb24df0b0b8..5f0e6f93840 100644 --- a/go/vt/vtgate/planbuilder/testdata/tpch_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/tpch_cases.json @@ -2,20 +2,17 @@ { "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", - "v3-plan": "VT12001: unsupported: in scatter query: complex aggregate expression", - "gen4-plan": "VT12001: unsupported: in scatter query: aggregation function 'avg(l_quantity) as avg_qty'" + "plan": "VT12001: unsupported: in scatter query: aggregation function 'avg(l_quantity) as avg_qty'" }, { "comment": "TPC-H query 2", "query": "select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment from part, supplier, partsupp, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey and p_size = 15 and p_type like '%BRASS' and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'EUROPE' and ps_supplycost = ( select min(ps_supplycost) from partsupp, supplier, nation, region where p_partkey = ps_partkey and s_suppkey = ps_suppkey and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'EUROPE' ) order by s_acctbal desc, n_name, s_name, p_partkey limit 10", - "v3-plan": "VT03019: column p_partkey not found", - "gen4-plan": "VT12001: unsupported: cross-shard correlated subquery" + "plan": "VT12001: unsupported: cross-shard correlated subquery" }, { "comment": "TPC-H query 3", "query": "select l_orderkey, sum(l_extendedprice * (1 - l_discount)) as revenue, o_orderdate, o_shippriority from customer, orders, lineitem where c_mktsegment = 'BUILDING' and c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate < date('1995-03-15') and l_shipdate > date('1995-03-15') group by l_orderkey, o_orderdate, o_shippriority order by revenue desc, o_orderdate limit 10", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select l_orderkey, sum(l_extendedprice * (1 - l_discount)) as revenue, o_orderdate, o_shippriority from customer, orders, lineitem where c_mktsegment = 'BUILDING' and c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate < date('1995-03-15') and l_shipdate > date('1995-03-15') group by l_orderkey, o_orderdate, o_shippriority order by revenue desc, o_orderdate limit 10", "Instructions": { @@ -146,8 +143,7 @@ { "comment": "TPC-H query 4", "query": "select o_orderpriority, count(*) as order_count from orders where o_orderdate >= date('1993-07-01') and o_orderdate < date('1993-07-01') + interval '3' month and exists ( select * from lineitem where l_orderkey = o_orderkey and l_commitdate < l_receiptdate ) group by o_orderpriority order by o_orderpriority", - "v3-plan": "VT03019: column o_orderkey not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select o_orderpriority, count(*) as order_count from orders where o_orderdate >= date('1993-07-01') and o_orderdate < date('1993-07-01') + interval '3' month and exists ( select * from lineitem where l_orderkey = o_orderkey and l_commitdate < l_receiptdate ) group by o_orderpriority order by o_orderpriority", "Instructions": { @@ -237,10 +233,9 @@ } }, { - "comment": "TPC-H query 5 - Gen4 produces plan but the plan output is flaky", + "comment": "TPC-H query 5", "query": "select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue from customer, orders, lineitem, supplier, nation, region where c_custkey = o_custkey and l_orderkey = o_orderkey and l_suppkey = s_suppkey and c_nationkey = s_nationkey and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'ASIA' and o_orderdate >= date('1994-01-01') and o_orderdate < date('1994-01-01') + interval '1' year group by n_name order by revenue desc", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select n_name, sum(l_extendedprice * (1 - l_discount)) as revenue from customer, orders, lineitem, supplier, nation, region where c_custkey = o_custkey and l_orderkey = o_orderkey and l_suppkey = s_suppkey and c_nationkey = s_nationkey and s_nationkey = n_nationkey and n_regionkey = r_regionkey and r_name = 'ASIA' and o_orderdate >= date('1994-01-01') and o_orderdate < date('1994-01-01') + interval '1' year group by n_name order by revenue desc", "Instructions": { @@ -494,29 +489,7 @@ { "comment": "TPC-H query 6", "query": "select sum(l_extendedprice * l_discount) as revenue from lineitem where l_shipdate >= date('1994-01-01') and l_shipdate < date('1994-01-01') + interval '1' year and l_discount between 0.06 - 0.01 and 0.06 + 0.01 and l_quantity < 24", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select sum(l_extendedprice * l_discount) as revenue from lineitem where l_shipdate >= date('1994-01-01') and l_shipdate < date('1994-01-01') + interval '1' year and l_discount between 0.06 - 0.01 and 0.06 + 0.01 and l_quantity < 24", - "Instructions": { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum(0)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select sum(l_extendedprice * l_discount) as revenue from lineitem where 1 != 1", - "Query": "select sum(l_extendedprice * l_discount) as revenue from lineitem where l_shipdate >= date('1994-01-01') and l_shipdate < date('1994-01-01') + interval '1' year and l_discount between 0.06 - 0.01 and 0.06 + 0.01 and l_quantity < 24", - "Table": "lineitem" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(l_extendedprice * l_discount) as revenue from lineitem where l_shipdate >= date('1994-01-01') and l_shipdate < date('1994-01-01') + interval '1' year and l_discount between 0.06 - 0.01 and 0.06 + 0.01 and l_quantity < 24", "Instructions": { @@ -545,8 +518,7 @@ { "comment": "TPC-H query 7", "query": "select supp_nation, cust_nation, l_year, sum(volume) as revenue from (select n1.n_name as supp_nation, n2.n_name as cust_nation, extract(year from l_shipdate) as l_year, l_extendedprice * (1 - l_discount) as volume from supplier, lineitem, orders, customer, nation n1, nation n2 where s_suppkey = l_suppkey and o_orderkey = l_orderkey and c_custkey = o_custkey and s_nationkey = n1.n_nationkey and c_nationkey = n2.n_nationkey and ((n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE')) and l_shipdate between date('1995-01-01') and date('1996-12-31')) as shipping group by supp_nation, cust_nation, l_year order by supp_nation, cust_nation, l_year", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select supp_nation, cust_nation, l_year, sum(volume) as revenue from (select n1.n_name as supp_nation, n2.n_name as cust_nation, extract(year from l_shipdate) as l_year, l_extendedprice * (1 - l_discount) as volume from supplier, lineitem, orders, customer, nation n1, nation n2 where s_suppkey = l_suppkey and o_orderkey = l_orderkey and c_custkey = o_custkey and s_nationkey = n1.n_nationkey and c_nationkey = n2.n_nationkey and ((n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE')) and l_shipdate between date('1995-01-01') and date('1996-12-31')) as shipping group by supp_nation, cust_nation, l_year order by supp_nation, cust_nation, l_year", "Instructions": { @@ -774,20 +746,17 @@ { "comment": "TPC-H query 8", "query": "select o_year, sum(case when nation = 'BRAZIL' then volume else 0 end) / sum(volume) as mkt_share from ( select extract(year from o_orderdate) as o_year, l_extendedprice * (1 - l_discount) as volume, n2.n_name as nation from part, supplier, lineitem, orders, customer, nation n1, nation n2, region where p_partkey = l_partkey and s_suppkey = l_suppkey and l_orderkey = o_orderkey and o_custkey = c_custkey and c_nationkey = n1.n_nationkey and n1.n_regionkey = r_regionkey and r_name = 'AMERICA' and s_nationkey = n2.n_nationkey and o_orderdate between date '1995-01-01' and date('1996-12-31') and p_type = 'ECONOMY ANODIZED STEEL' ) as all_nations group by o_year order by o_year", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: in scatter query: complex aggregate expression" + "plan": "VT12001: unsupported: in scatter query: complex aggregate expression" }, { "comment": "TPC-H query 9", "query": "select nation, o_year, sum(amount) as sum_profit from ( select n_name as nation, extract(year from o_orderdate) as o_year, l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount from part, supplier, lineitem, partsupp, orders, nation where s_suppkey = l_suppkey and ps_suppkey = l_suppkey and ps_partkey = l_partkey and p_partkey = l_partkey and o_orderkey = l_orderkey and s_nationkey = n_nationkey and p_name like '%green%' ) as profit group by nation, o_year order by nation, o_year desc", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: aggregation on columns from different sources" + "plan": "VT12001: unsupported: aggregation on columns from different sources" }, { "comment": "TPC-H query 10", "query": "select c_custkey, c_name, sum(l_extendedprice * (1 - l_discount)) as revenue, c_acctbal, n_name, c_address, c_phone, c_comment from customer, orders, lineitem, nation where c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate >= date('1993-10-01') and o_orderdate < date('1993-10-01') + interval '3' month and l_returnflag = 'R' and c_nationkey = n_nationkey group by c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment order by revenue desc limit 20", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select c_custkey, c_name, sum(l_extendedprice * (1 - l_discount)) as revenue, c_acctbal, n_name, c_address, c_phone, c_comment from customer, orders, lineitem, nation where c_custkey = o_custkey and l_orderkey = o_orderkey and o_orderdate >= date('1993-10-01') and o_orderdate < date('1993-10-01') + interval '3' month and l_returnflag = 'R' and c_nationkey = n_nationkey group by c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment order by revenue desc limit 20", "Instructions": { @@ -997,14 +966,12 @@ { "comment": "TPC-H query 11", "query": "select ps_partkey, sum(ps_supplycost * ps_availqty) as value from partsupp, supplier, nation where ps_suppkey = s_suppkey and s_nationkey = n_nationkey and n_name = 'GERMANY' group by ps_partkey having sum(ps_supplycost * ps_availqty) > ( select sum(ps_supplycost * ps_availqty) * 0.00001000000 from partsupp, supplier, nation where ps_suppkey = s_suppkey and s_nationkey = n_nationkey and n_name = 'GERMANY' ) order by value desc", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: in scatter query: complex aggregate expression" + "plan": "VT12001: unsupported: in scatter query: complex aggregate expression" }, { "comment": "TPC-H query 12", "query": "select l_shipmode, sum(case when o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH' then 1 else 0 end) as high_line_count, sum(case when o_orderpriority <> '1-URGENT' and o_orderpriority <> '2-HIGH' then 1 else 0 end) as low_line_count from orders, lineitem where o_orderkey = l_orderkey and l_shipmode in ('MAIL', 'SHIP') and l_commitdate < l_receiptdate and l_shipdate < l_commitdate and l_receiptdate >= date('1994-01-01') and l_receiptdate < date('1994-01-01') + interval '1' year group by l_shipmode order by l_shipmode", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select l_shipmode, sum(case when o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH' then 1 else 0 end) as high_line_count, sum(case when o_orderpriority <> '1-URGENT' and o_orderpriority <> '2-HIGH' then 1 else 0 end) as low_line_count from orders, lineitem where o_orderkey = l_orderkey and l_shipmode in ('MAIL', 'SHIP') and l_commitdate < l_receiptdate and l_shipdate < l_commitdate and l_receiptdate >= date('1994-01-01') and l_receiptdate < date('1994-01-01') + interval '1' year group by l_shipmode order by l_shipmode", "Instructions": { @@ -1099,8 +1066,7 @@ { "comment": "TPC-H query 14", "query": "select 100.00 * sum(case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) else 0 end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue from lineitem, part where l_partkey = p_partkey and l_shipdate >= date('1995-09-01') and l_shipdate < date('1995-09-01') + interval '1' month", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 100.00 * sum(case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) else 0 end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue from lineitem, part where l_partkey = p_partkey and l_shipdate >= date('1995-09-01') and l_shipdate < date('1995-09-01') + interval '1' month", "Instructions": { @@ -1164,80 +1130,9 @@ } }, { - "comment": "TPC-H query 15 view\n#\"with revenue0(supplier_no, total_revenue) as (select l_suppkey, sum(l_extendedprice * (1 - l_discount)) from lineitem where l_shipdate >= date('1996-01-01') and l_shipdate < date('1996-01-01') + interval '3' month group by l_suppkey )\"\n#\"syntax error at position 236\"\n#Gen4 plan same as above\n# TPC-H query 15", + "comment": "TPC-H query 15", "query": "select s_suppkey, s_name, s_address, s_phone, total_revenue from supplier, revenue0 where s_suppkey = supplier_no and total_revenue = ( select max(total_revenue) from revenue0 ) order by s_suppkey", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select s_suppkey, s_name, s_address, s_phone, total_revenue from supplier, revenue0 where s_suppkey = supplier_no and total_revenue = ( select max(total_revenue) from revenue0 ) order by s_suppkey", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "max(0)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select max(total_revenue) from revenue0 where 1 != 1", - "Query": "select max(total_revenue) from revenue0", - "Table": "revenue0" - } - ] - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,L:2,L:3,R:0", - "JoinVars": { - "s_suppkey": 0 - }, - "TableName": "supplier_revenue0", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select s_suppkey, s_name, s_address, s_phone, weight_string(s_suppkey) from supplier where 1 != 1", - "OrderBy": "(0|4) ASC", - "Query": "select s_suppkey, s_name, s_address, s_phone, weight_string(s_suppkey) from supplier order by s_suppkey asc", - "ResultColumns": 4, - "Table": "supplier" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "main", - "Sharded": true - }, - "FieldQuery": "select total_revenue from revenue0 where 1 != 1", - "Query": "select total_revenue from revenue0 where supplier_no = :s_suppkey and total_revenue = :__sq1", - "Table": "revenue0", - "Values": [ - ":s_suppkey" - ], - "Vindex": "hash" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select s_suppkey, s_name, s_address, s_phone, total_revenue from supplier, revenue0 where s_suppkey = supplier_no and total_revenue = ( select max(total_revenue) from revenue0 ) order by s_suppkey", "Instructions": { @@ -1290,20 +1185,17 @@ { "comment": "TPC-H query 16", "query": "select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt from partsupp, part where p_partkey = ps_partkey and p_brand <> 'Brand#45' and p_type not like 'MEDIUM POLISHED%' and p_size in (49, 14, 23, 45, 19, 3, 36, 9) and ps_suppkey not in ( select s_suppkey from supplier where s_comment like '%Customer%Complaints%' ) group by p_brand, p_type, p_size order by supplier_cnt desc, p_brand, p_type, p_size", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: using aggregation on top of a *planbuilder.pulloutSubquery plan" + "plan": "VT12001: unsupported: using aggregation on top of a *planbuilder.pulloutSubquery plan" }, { "comment": "TPC-H query 17", "query": "select sum(l_extendedprice) / 7.0 as avg_yearly from lineitem, part where p_partkey = l_partkey and p_brand = 'Brand#23' and p_container = 'MED BOX' and l_quantity < ( select 0.2 * avg(l_quantity) from lineitem where l_partkey = p_partkey )", - "v3-plan": "VT03019: column p_partkey not found", - "gen4-plan": "VT12001: unsupported: cross-shard correlated subquery" + "plan": "VT12001: unsupported: cross-shard correlated subquery" }, { "comment": "TPC-H query 18", "query": "select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem where o_orderkey in ( select l_orderkey from lineitem group by l_orderkey having sum(l_quantity) > 300 ) and c_custkey = o_custkey and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate limit 100", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) from customer, orders, lineitem where o_orderkey in ( select l_orderkey from lineitem group by l_orderkey having sum(l_quantity) > 300 ) and c_custkey = o_custkey and o_orderkey = l_orderkey group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice order by o_totalprice desc, o_orderdate limit 100", "Instructions": { @@ -1448,8 +1340,7 @@ { "comment": "TPC-H query 19", "query": "select sum(l_extendedprice* (1 - l_discount)) as revenue from lineitem, part where ( p_partkey = l_partkey and p_brand = 'Brand#12' and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') and l_quantity >= 1 and l_quantity <= 1 + 10 and p_size between 1 and 5 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#23' and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') and l_quantity >= 10 and l_quantity <= 10 + 10 and p_size between 1 and 10 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#34' and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') and l_quantity >= 20 and l_quantity <= 20 + 10 and p_size between 1 and 15 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' )", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select sum(l_extendedprice* (1 - l_discount)) as revenue from lineitem, part where ( p_partkey = l_partkey and p_brand = 'Brand#12' and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') and l_quantity >= 1 and l_quantity <= 1 + 10 and p_size between 1 and 5 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#23' and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') and l_quantity >= 10 and l_quantity <= 10 + 10 and p_size between 1 and 10 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' ) or ( p_partkey = l_partkey and p_brand = 'Brand#34' and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') and l_quantity >= 20 and l_quantity <= 20 + 10 and p_size between 1 and 15 and l_shipmode in ('AIR', 'AIR REG') and l_shipinstruct = 'DELIVER IN PERSON' )", "Instructions": { @@ -1512,14 +1403,12 @@ { "comment": "TPC-H query 20", "query": "select s_name, s_address from supplier, nation where s_suppkey in ( select ps_suppkey from partsupp where ps_partkey in ( select p_partkey from part where p_name like 'forest%' ) and ps_availqty > ( select 0.5 * sum(l_quantity) from lineitem where l_partkey = ps_partkey and l_suppkey = ps_suppkey and l_shipdate >= date('1994-01-01') and l_shipdate < date('1994-01-01') + interval '1' year ) ) and s_nationkey = n_nationkey and n_name = 'CANADA' order by s_name", - "v3-plan": "VT03019: column ps_partkey not found", - "gen4-plan": "VT12001: unsupported: cross-shard correlated subquery" + "plan": "VT12001: unsupported: cross-shard correlated subquery" }, { "comment": "TPC-H query 21", "query": "select s_name, count(*) as numwait from supplier, lineitem l1, orders, nation where s_suppkey = l1.l_suppkey and o_orderkey = l1.l_orderkey and o_orderstatus = 'F' and l1.l_receiptdate > l1.l_commitdate and exists ( select * from lineitem l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey ) and not exists ( select * from lineitem l3 where l3.l_orderkey = l1.l_orderkey and l3.l_suppkey <> l1.l_suppkey and l3.l_receiptdate > l3.l_commitdate ) and s_nationkey = n_nationkey and n_name = 'SAUDI ARABIA' group by s_name order by numwait desc, s_name limit 100", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select s_name, count(*) as numwait from supplier, lineitem l1, orders, nation where s_suppkey = l1.l_suppkey and o_orderkey = l1.l_orderkey and o_orderstatus = 'F' and l1.l_receiptdate > l1.l_commitdate and exists ( select * from lineitem l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey ) and not exists ( select * from lineitem l3 where l3.l_orderkey = l1.l_orderkey and l3.l_suppkey <> l1.l_suppkey and l3.l_receiptdate > l3.l_commitdate ) and s_nationkey = n_nationkey and n_name = 'SAUDI ARABIA' group by s_name order by numwait desc, s_name limit 100", "Instructions": { @@ -1661,7 +1550,6 @@ { "comment": "TPC-H query 22", "query": "select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal from ( select substring(c_phone from 1 for 2) as cntrycode, c_acctbal from customer where substring(c_phone from 1 for 2) in ('13', '31', '23', '29', '30', '18', '17') and c_acctbal > ( select avg(c_acctbal) from customer where c_acctbal > 0.00 and substring(c_phone from 1 for 2) in ('13', '31', '23', '29', '30', '18', '17') ) and not exists ( select * from orders where o_custkey = c_custkey ) ) as custsale group by cntrycode order by cntrycode", - "v3-plan": "VT03019: column c_custkey not found", - "gen4-plan": "VT12001: unsupported: EXISTS sub-queries are only supported with AND clause" + "plan": "VT12001: unsupported: EXISTS sub-queries are only supported with AND clause" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index ed836bf207b..d7b259a4747 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -2,22 +2,7 @@ { "comment": "union all between two scatter selects", "query": "select id from user union all select id from music", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user union all select id from music", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1 union all select id from music where 1 != 1", - "Query": "select id from `user` union all select id from music", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user union all select id from music", "Instructions": { @@ -40,43 +25,7 @@ { "comment": "union distinct between two scatter selects", "query": "select id from user union select id from music", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user union select id from music", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music", - "Table": "music" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user union select id from music", "Instructions": { @@ -108,46 +57,7 @@ { "comment": "union all between two SelectEqualUnique", "query": "select id from user where id = 1 union all select id from user where id = 5", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 1 union all select id from user where id = 5", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 5", - "Table": "`user`", - "Values": [ - "INT64(5)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 1 union all select id from user where id = 5", "Instructions": { @@ -193,54 +103,7 @@ { "comment": "almost dereks query - two queries with order by and limit being scattered to two different sets of tablets", "query": "(SELECT id FROM user ORDER BY id DESC LIMIT 1) UNION ALL (SELECT id FROM music ORDER BY id DESC LIMIT 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(SELECT id FROM user ORDER BY id DESC LIMIT 1) UNION ALL (SELECT id FROM music ORDER BY id DESC LIMIT 1)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) DESC", - "Query": "select id, weight_string(id) from `user` order by id desc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Limit", - "Count": "INT64(1)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from music where 1 != 1", - "OrderBy": "(0|1) DESC", - "Query": "select id, weight_string(id) from music order by id desc limit :__upper_limit", - "ResultColumns": 1, - "Table": "music" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(SELECT id FROM user ORDER BY id DESC LIMIT 1) UNION ALL (SELECT id FROM music ORDER BY id DESC LIMIT 1)", "Instructions": { @@ -295,22 +158,7 @@ { "comment": "Union all", "query": "select col1, col2 from user union all select col1, col2 from user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1, col2 from user union all select col1, col2 from user_extra", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2 from `user` where 1 != 1 union all select col1, col2 from user_extra where 1 != 1", - "Query": "select col1, col2 from `user` union all select col1, col2 from user_extra", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1, col2 from user union all select col1, col2 from user_extra", "Instructions": { @@ -333,22 +181,7 @@ { "comment": "union operations in subqueries (FROM)", "query": "select * from (select * from user union all select * from user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from (select * from user union all select * from user_extra) as t", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from (select * from `user` where 1 != 1 union all select * from user_extra where 1 != 1) as t where 1 != 1", - "Query": "select * from (select * from `user` union all select * from user_extra) as t", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select * from user union all select * from user_extra) as t", "Instructions": { @@ -371,22 +204,7 @@ { "comment": "union operations in derived table, without star expression (FROM)¡", "query": "select col1,col2 from (select col1, col2 from user union all select col1, col2 from user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col1,col2 from (select col1, col2 from user union all select col1, col2 from user_extra) as t", - "Instructions": { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col1, col2 from (select col1, col2 from `user` where 1 != 1 union all select col1, col2 from user_extra where 1 != 1) as t where 1 != 1", - "Query": "select col1, col2 from (select col1, col2 from `user` union all select col1, col2 from user_extra) as t", - "Table": "`user`" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col1,col2 from (select col1, col2 from user union all select col1, col2 from user_extra) as t", "Instructions": { @@ -409,54 +227,7 @@ { "comment": "union all between two scatter selects, with order by", "query": "(select id from user order by id limit 5) union all (select id from music order by id desc limit 5)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from user order by id limit 5) union all (select id from music order by id desc limit 5)", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id, weight_string(id) from `user` order by id asc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from music where 1 != 1", - "OrderBy": "(0|1) DESC", - "Query": "select id, weight_string(id) from music order by id desc limit :__upper_limit", - "ResultColumns": 1, - "Table": "music" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from user order by id limit 5) union all (select id from music order by id desc limit 5)", "Instructions": { @@ -511,42 +282,7 @@ { "comment": "union all on scatter and single route", "query": "select id from user where id = 1 union select id from user where id = 1 union all select id from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id = 1 union select id from user where id = 1 union all select id from user", - "Instructions": { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1 union select id from `user` where 1 != 1", - "Query": "select id from `user` where id = 1 union select id from `user` where id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id = 1 union select id from user where id = 1 union all select id from user", "Instructions": { @@ -588,11 +324,15 @@ { "comment": "union of information_schema with normal table", "query": "select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS union select user_name from unsharded", - "v3-plan": { + "plan": { "QueryType": "SELECT", "Original": "select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS union select user_name from unsharded", "Instructions": { "OperatorType": "Distinct", + "Collations": [ + "(0:1)" + ], + "ResultColumns": 1, "Inputs": [ { "OperatorType": "Concatenate", @@ -604,8 +344,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS where 1 != 1", - "Query": "select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS", + "FieldQuery": "select CHARACTER_SET_NAME, weight_string(CHARACTER_SET_NAME) from information_schema.CHARACTER_SETS where 1 != 1", + "Query": "select distinct CHARACTER_SET_NAME, weight_string(CHARACTER_SET_NAME) from information_schema.CHARACTER_SETS", "Table": "information_schema.CHARACTER_SETS" }, { @@ -615,48 +355,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select user_name from unsharded where 1 != 1", - "Query": "select user_name from unsharded", - "Table": "unsharded" - } - ] - } - ] - } - }, - "gen4-plan": { - "QueryType": "SELECT", - "Original": "select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS union select user_name from unsharded", - "Instructions": { - "OperatorType": "Distinct", - "Collations": [ - "(0:1)" - ], - "ResultColumns": 1, - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select CHARACTER_SET_NAME, weight_string(CHARACTER_SET_NAME) from information_schema.CHARACTER_SETS where 1 != 1", - "Query": "select distinct CHARACTER_SET_NAME, weight_string(CHARACTER_SET_NAME) from information_schema.CHARACTER_SETS", - "Table": "information_schema.CHARACTER_SETS" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select user_name, weight_string(user_name) from unsharded where 1 != 1", - "Query": "select distinct user_name, weight_string(user_name) from unsharded", + "FieldQuery": "select user_name, weight_string(user_name) from unsharded where 1 != 1", + "Query": "select distinct user_name, weight_string(user_name) from unsharded", "Table": "unsharded" } ] @@ -671,43 +371,7 @@ { "comment": "union of information_schema with normal table", "query": "select * from unsharded union select * from information_schema.CHARACTER_SETS", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from unsharded union select * from information_schema.CHARACTER_SETS", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from unsharded where 1 != 1", - "Query": "select * from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from information_schema.CHARACTER_SETS where 1 != 1", - "Query": "select * from information_schema.CHARACTER_SETS", - "Table": "information_schema.CHARACTER_SETS" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from unsharded union select * from information_schema.CHARACTER_SETS", "Instructions": { @@ -750,64 +414,7 @@ { "comment": "multi-shard union", "query": "(select id from user union select id from music) union select 1 from dual", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from user union select id from music) union select 1 from dual", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from music where 1 != 1", - "Query": "select id from music", - "Table": "music" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from dual where 1 != 1", - "Query": "select 1 from dual", - "Table": "dual" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from user union select id from music) union select 1 from dual", "Instructions": { @@ -856,170 +463,17 @@ { "comment": "multi-shard union", "query": "select 1 from music union (select id from user union all select name from unsharded)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from music union (select id from user union all select name from unsharded)", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select 1 from music", - "Table": "music" - }, - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select `name` from unsharded where 1 != 1", - "Query": "select `name` from unsharded", - "Table": "unsharded" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": "VT12001: unsupported: nesting of UNIONs on the right-hand side" + "plan": "VT12001: unsupported: nesting of UNIONs on the right-hand side" }, { "comment": "multi-shard union", "query": "select 1 from music union (select id from user union select name from unsharded)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from music union (select id from user union select name from unsharded)", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select 1 from music", - "Table": "music" - }, - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select `name` from unsharded where 1 != 1", - "Query": "select `name` from unsharded", - "Table": "unsharded" - } - ] - } - ] - } - ] - } - ] - } - }, - "gen4-plan": "VT12001: unsupported: nesting of UNIONs on the right-hand side" + "plan": "VT12001: unsupported: nesting of UNIONs on the right-hand side" }, { "comment": "union with the same target shard because of vindex", "query": "select * from music where id = 1 union select * from user where id = 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from music where id = 1 union select * from user where id = 1", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from music where 1 != 1", - "Query": "select * from music where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "music_user_map" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user` where id = 1", - "Table": "`user`", - "Values": [ - "INT64(1)" - ], - "Vindex": "user_index" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from music where id = 1 union select * from user where id = 1", "Instructions": { @@ -1071,51 +525,7 @@ { "comment": "union with different target shards", "query": "select 1 from music where id = 1 union select 1 from music where id = 2", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from music where id = 1 union select 1 from music where id = 2", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select 1 from music where id = 1", - "Table": "music", - "Values": [ - "INT64(1)" - ], - "Vindex": "music_user_map" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from music where 1 != 1", - "Query": "select 1 from music where id = 2", - "Table": "music", - "Values": [ - "INT64(2)" - ], - "Vindex": "music_user_map" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from music where id = 1 union select 1 from music where id = 2", "Instructions": { @@ -1169,47 +579,7 @@ { "comment": "multiple select statement have inner order by with union - TODO (systay) no need to send down ORDER BY if we are going to loose it with UNION DISTINCT", "query": "(select id from user order by 1 desc) union (select id from user order by 1 asc)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select id from user order by 1 desc) union (select id from user order by 1 asc)", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) DESC", - "Query": "select id, weight_string(id) from `user` order by 1 desc", - "ResultColumns": 1, - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id, weight_string(id) from `user` order by 1 asc", - "ResultColumns": 1, - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from user order by 1 desc) union (select id from user order by 1 asc)", "Instructions": { @@ -1242,43 +612,7 @@ { "comment": "multiple unions", "query": "select 1 union select null union select 1.0 union select '1' union select 2 union select 2.0 from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 union select null union select 1.0 union select '1' union select 2 union select 2.0 from user", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from dual where 1 != 1 union select null from dual where 1 != 1 union select 1.0 from dual where 1 != 1 union select '1' from dual where 1 != 1 union select 2 from dual where 1 != 1", - "Query": "select 1 from dual union select null from dual union select 1.0 from dual union select '1' from dual union select 2 from dual", - "Table": "dual" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 2.0 from `user` where 1 != 1", - "Query": "select 2.0 from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 union select null union select 1.0 union select '1' union select 2 union select 2.0 from user", "Instructions": { @@ -1325,62 +659,7 @@ { "comment": "union distinct between a scatter query and a join (other side)", "query": "(select user.id, user.name from user join user_extra where user_extra.extra = 'asdf') union select 'b','c' from user", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select user.id, user.name from user join user_extra where user_extra.extra = 'asdf') union select 'b','c' from user", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.`name` from `user` where 1 != 1", - "Query": "select `user`.id, `user`.`name` from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.extra = 'asdf'", - "Table": "user_extra" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 'b', 'c' from `user` where 1 != 1", - "Query": "select 'b', 'c' from `user`", - "Table": "`user`" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select user.id, user.name from user join user_extra where user_extra.extra = 'asdf') union select 'b','c' from user", "Instructions": { @@ -1448,62 +727,7 @@ { "comment": "union distinct between a scatter query and a join (other side)", "query": "select 'b','c' from user union (select user.id, user.name from user join user_extra where user_extra.extra = 'asdf')", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 'b','c' from user union (select user.id, user.name from user join user_extra where user_extra.extra = 'asdf')", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 'b', 'c' from `user` where 1 != 1", - "Query": "select 'b', 'c' from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.id, `user`.`name` from `user` where 1 != 1", - "Query": "select `user`.id, `user`.`name` from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra where user_extra.extra = 'asdf'", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 'b','c' from user union (select user.id, user.name from user join user_extra where user_extra.extra = 'asdf')", "Instructions": { @@ -1571,57 +795,7 @@ { "comment": "unmergable because we are using aggregation", "query": "select count(*) as s from user union select count(*) as s from music", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select count(*) as s from user union select count(*) as s from music", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) as s from `user` where 1 != 1", - "Query": "select count(*) as s from `user`", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Aggregate", - "Variant": "Scalar", - "Aggregates": "sum_count(0) AS count", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select count(*) as s from music where 1 != 1", - "Query": "select count(*) as s from music", - "Table": "music" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select count(*) as s from user union select count(*) as s from music", "Instructions": { @@ -1682,72 +856,7 @@ { "comment": "Union in derived table with first SELECT being an UNION", "query": "select * from ((select id from user union select id+1 from user) union select user_id from user_extra) as t", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from ((select id from user union select id+1 from user) union select user_id from user_extra) as t", - "Instructions": { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id + 1 from `user` where 1 != 1", - "Query": "select id + 1 from `user`", - "Table": "`user`" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select user_id from user_extra where 1 != 1", - "Query": "select user_id from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from ((select id from user union select id+1 from user) union select user_id from user_extra) as t", "Instructions": { @@ -1784,10 +893,9 @@ } }, { - "comment": "gen4 optimises away ORDER BY when it's safe to do", + "comment": "optimises away ORDER BY when it's safe to do", "query": "(select id from user union select id from music order by id) union select 1 from unsharded", - "v3-plan": "VT12001: unsupported: ORDER BY on top of UNION", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select id from user union select id from music order by id) union select 1 from unsharded", "Instructions": { @@ -1836,49 +944,7 @@ { "comment": "push down the ::upper_limit to the sources, since we are doing DISTINCT on them, it's safe", "query": "select id from user union select 3 limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user union select 3 limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Reference", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 3 from dual where 1 != 1", - "Query": "select 3 from dual", - "Table": "dual" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user union select 3 limit 10", "Instructions": { @@ -1932,22 +998,7 @@ { "comment": "silly query that should be collapsed into a single unsharded UNION route", "query": "(select 1 from unsharded union select 1 from unsharded union all select 1 from unsharded order by 1) union select 1 from unsharded union all select 1 from unsharded order by 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(select 1 from unsharded union select 1 from unsharded union all select 1 from unsharded order by 1) union select 1 from unsharded union all select 1 from unsharded order by 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "(select 1 from unsharded where 1 != 1 union select 1 from unsharded where 1 != 1 union all select 1 from unsharded where 1 != 1) union select 1 from unsharded where 1 != 1 union all select 1 from unsharded where 1 != 1", - "Query": "(select 1 from unsharded union select 1 from unsharded union all select 1 from unsharded order by 1 asc) union select 1 from unsharded union all select 1 from unsharded order by 1 asc", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(select 1 from unsharded union select 1 from unsharded union all select 1 from unsharded order by 1) union select 1 from unsharded union all select 1 from unsharded order by 1", "Instructions": { @@ -1967,87 +1018,9 @@ } }, { - "comment": "UNION that needs to be reordered to be merged more aggressively. Gen4 is able to get it down to 2 routes", + "comment": "UNION that needs to be reordered to be merged more aggressively - able to get it down to 2 routes", "query": "select col from unsharded union select id from user union select col2 from unsharded union select col from user_extra", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select col from unsharded union select id from user union select col2 from unsharded union select col from user_extra", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col from unsharded where 1 != 1", - "Query": "select col from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user`", - "Table": "`user`" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select col2 from unsharded where 1 != 1", - "Query": "select col2 from unsharded", - "Table": "unsharded" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from user_extra where 1 != 1", - "Query": "select col from user_extra", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select col from unsharded union select id from user union select col2 from unsharded union select col from user_extra", "Instructions": { @@ -2096,88 +1069,7 @@ { "comment": "derived table with union", "query": "select tbl2.id FROM ((select id from user order by id limit 5) union all (select id from user order by id desc limit 5)) as tbl1 INNER JOIN user as tbl2 ON tbl1.id = tbl2.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select tbl2.id FROM ((select id from user order by id limit 5) union all (select id from user order by id desc limit 5)) as tbl1 INNER JOIN user as tbl2 ON tbl1.id = tbl2.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "tbl1_id": 0 - }, - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "SimpleProjection", - "Columns": [ - 0 - ], - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select id, weight_string(id) from `user` order by id asc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Limit", - "Count": "INT64(5)", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1", - "OrderBy": "(0|1) DESC", - "Query": "select id, weight_string(id) from `user` order by id desc limit :__upper_limit", - "ResultColumns": 1, - "Table": "`user`" - } - ] - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select tbl2.id from `user` as tbl2 where 1 != 1", - "Query": "select tbl2.id from `user` as tbl2 where tbl2.id = :tbl1_id", - "Table": "`user`", - "Values": [ - ":tbl1_id" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select tbl2.id FROM ((select id from user order by id limit 5) union all (select id from user order by id desc limit 5)) as tbl1 INNER JOIN user as tbl2 ON tbl1.id = tbl2.id", "Instructions": { @@ -2275,26 +1167,22 @@ { "comment": "different number of columns", "query": "select id, 42 from user where id = 1 union all select id from user where id = 5", - "v3-plan": "The used SELECT statements have a different number of columns (errno 1222) (sqlstate 21000) during query: select id, 42 from `user` where id = 1 union all select id from `user` where id = 5", - "gen4-plan": "The used SELECT statements have a different number of columns: 2, 1" + "plan": "The used SELECT statements have a different number of columns: 2, 1" }, { "comment": "union with invalid order by clause with table qualifier", "query": "select id from user union select 3 order by user.id", - "v3-plan": "VT12001: unsupported: ORDER BY on top of UNION", - "gen4-plan": "Table `user` from one of the SELECTs cannot be used in global ORDER clause" + "plan": "Table `user` from one of the SELECTs cannot be used in global ORDER clause" }, { "comment": "union with invalid order by clause with table qualifier", "query": "select id from user union select 3 order by id", - "v3-plan": "VT12001: unsupported: ORDER BY on top of UNION", - "gen4-plan": "VT13001: [BUG] ORDER BY in complex query *planbuilder.distinct" + "plan": "VT13001: [BUG] ORDER BY in complex query *planbuilder.distinct" }, { "comment": "select 1 from (select id+42 as foo from user union select 1+id as foo from unsharded) as t", "query": "select 1 from (select id+42 as foo from user union select 1+id as foo from unsharded) as t", - "v3-plan": "VT12001: unsupported: expression on results of a cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from (select id+42 as foo from user union select 1+id as foo from unsharded) as t", "Instructions": { @@ -2349,8 +1237,7 @@ { "comment": "systable union query in derived table with constraint on outside (without star projection)", "query": "select * from (select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `COLUMN_NAME` = 'primary'", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `COLUMN_NAME` = 'primary'", "Instructions": { @@ -2371,8 +1258,7 @@ { "comment": "pushes predicate on both sides of UNION", "query": "select * from (select name, id as foo from user union select 'extra', user_id from user_extra) X where X.foo = 3", - "v3-plan": "VT12001: unsupported: filtering on results of cross-shard subquery", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select name, id as foo from user union select 'extra', user_id from user_extra) X where X.foo = 3", "Instructions": { @@ -2399,8 +1285,7 @@ { "comment": "systable union query in derived table with constraint on outside (star projection)", "query": "select * from (select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `constraint_name` = 'primary'", - "v3-plan": "VT03019: column constraint_name not found", - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from (select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `constraint_name` = 'primary'", "Instructions": { @@ -2421,22 +1306,7 @@ { "comment": "unknown columns are OK as long as the whole query is unsharded", "query": "(SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'FAILED' ORDER BY buildNumber DESC LIMIT 1) AS last_failed) UNION ALL (SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'SUCCEEDED' ORDER BY buildNumber DESC LIMIT 1) AS last_succeeded) ORDER BY buildNumber DESC LIMIT 1", - "v3-plan": { - "QueryType": "SELECT", - "Original": "(SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'FAILED' ORDER BY buildNumber DESC LIMIT 1) AS last_failed) UNION ALL (SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'SUCCEEDED' ORDER BY buildNumber DESC LIMIT 1) AS last_succeeded) ORDER BY buildNumber DESC LIMIT 1", - "Instructions": { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select * from (select * from unsharded where 1 != 1) as last_failed where 1 != 1 union all select * from (select * from unsharded where 1 != 1) as last_succeeded where 1 != 1", - "Query": "select * from (select * from unsharded where branchId = 203622 and buildNumber <= 113893 and state = 'FAILED' order by buildNumber desc limit 1) as last_failed union all select * from (select * from unsharded where branchId = 203622 and buildNumber <= 113893 and state = 'SUCCEEDED' order by buildNumber desc limit 1) as last_succeeded order by buildNumber desc limit 1", - "Table": "unsharded" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "(SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'FAILED' ORDER BY buildNumber DESC LIMIT 1) AS last_failed) UNION ALL (SELECT * FROM (SELECT * FROM unsharded WHERE branchId = 203622 AND buildNumber <= 113893 AND state = 'SUCCEEDED' ORDER BY buildNumber DESC LIMIT 1) AS last_succeeded) ORDER BY buildNumber DESC LIMIT 1", "Instructions": { @@ -2458,62 +1328,7 @@ { "comment": "union of unsharded route with sharded join with involvement of weight string", "query": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative", - "Instructions": { - "OperatorType": "Distinct", - "Inputs": [ - { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select id, foo, bar from unsharded where 1 != 1", - "Query": "select id, foo, bar from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "TableName": "`user`_authoritative", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `user`.intcol, `user`.textcol2 from `user` where 1 != 1", - "Query": "select `user`.intcol, `user`.textcol2 from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select authoritative.col2 from authoritative where 1 != 1", - "Query": "select authoritative.col2 from authoritative", - "Table": "authoritative" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index cc020dac2af..0610202bead 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -27,8 +27,7 @@ { "comment": "scatter order by with * expression", "query": "select * from user order by id", - "v3-plan": "VT12001: unsupported: in scatter query: ORDER BY must reference a column in the SELECT list: id asc", - "gen4-plan": "VT12001: unsupported: '*' expression in cross-shard query" + "plan": "VT12001: unsupported: '*' expression in cross-shard query" }, { "comment": "natural join", @@ -38,14 +37,12 @@ { "comment": "join with USING construct", "query": "select * from user join user_extra using(id)", - "v3-plan": "VT12001: unsupported: JOIN with USING(column_list) clause for complex queries", - "gen4-plan": "can't handle JOIN USING without authoritative tables" + "plan": "can't handle JOIN USING without authoritative tables" }, { "comment": "join with USING construct with 3 tables", "query": "select user.id from user join user_extra using(id) join music using(id2)", - "v3-plan": "VT12001: unsupported: JOIN with USING(column_list) clause for complex queries", - "gen4-plan": "can't handle JOIN USING without authoritative tables" + "plan": "can't handle JOIN USING without authoritative tables" }, { "comment": "natural left join", @@ -65,56 +62,47 @@ { "comment": "Group by column number, used with non-aliased expression (duplicated code)", "query": "select * from user group by 1", - "v3-plan": "VT12001: unsupported: '*' expression in cross-shard query", - "gen4-plan": "cannot use column offsets in group statement when using `*`" + "plan": "cannot use column offsets in group statement when using `*`" }, { "comment": "Multi-value aggregates not supported", "query": "select count(a,b) from user", - "v3-plan": "VT12001: unsupported: only one expression is allowed inside aggregates: count(a, b)", - "gen4-plan": "VT03001: aggregate functions take a single argument 'count(a, b)'" + "plan": "VT03001: aggregate functions take a single argument 'count(a, b)'" }, { "comment": "subqueries not supported in group by", "query": "select id from user group by id, (select id from user_extra)", - "v3-plan": "VT12001: unsupported: subqueries disallowed in sqlparser.GroupBy", - "gen4-plan": "VT12001: unsupported: subqueries in GROUP BY" + "plan": "VT12001: unsupported: subqueries in GROUP BY" }, { "comment": "subqueries in delete", "query": "delete from user where col = (select id from unsharded)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": "VT12001: unsupported: subqueries in DML" + "plan": "VT12001: unsupported: subqueries in DML" }, { "comment": "sharded subqueries in unsharded delete", "query": "delete from unsharded where col = (select id from user)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": "VT12001: unsupported: subqueries in DML" + "plan": "VT12001: unsupported: subqueries in DML" }, { "comment": "sharded delete with limit clasue", "query": "delete from user_extra limit 10", - "v3-plan": "VT12001: unsupported: multi-shard delete with LIMIT", - "gen4-plan": "VT12001: unsupported: multi shard DELETE with LIMIT" + "plan": "VT12001: unsupported: multi shard DELETE with LIMIT" }, { "comment": "sharded subquery in unsharded subquery in unsharded delete", "query": "delete from unsharded where col = (select id from unsharded where id = (select id from user))", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": "VT12001: unsupported: subqueries in DML" + "plan": "VT12001: unsupported: subqueries in DML" }, { "comment": "sharded join unsharded subqueries in unsharded delete", "query": "delete from unsharded where col = (select id from unsharded join user on unsharded.id = user.id)", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": "VT12001: unsupported: subqueries in DML" + "plan": "VT12001: unsupported: subqueries in DML" }, { "comment": "scatter update with limit clause", "query": "update user_extra set val = 1 where (name = 'foo' or id = 1) limit 1", - "v3-plan": "VT12001: unsupported: multi-shard update with LIMIT", - "gen4-plan": "VT12001: unsupported: multi shard UPDATE with LIMIT" + "plan": "VT12001: unsupported: multi shard UPDATE with LIMIT" }, { "comment": "multi delete multi table", @@ -124,68 +112,57 @@ { "comment": "update changes primary vindex column", "query": "update user set id = 1 where id = 1", - "v3-plan": "VT12001: unsupported: you cannot update primary vindex columns; invalid update on vindex: user_index", - "gen4-plan": "VT12001: unsupported: you cannot UPDATE primary vindex columns; invalid update on vindex: user_index" + "plan": "VT12001: unsupported: you cannot UPDATE primary vindex columns; invalid update on vindex: user_index" }, { "comment": "update change in multicol vindex column", "query": "update multicol_tbl set colc = 5, colb = 4 where cola = 1 and colb = 2", - "v3-plan": "VT12001: unsupported: you cannot update primary vindex columns; invalid update on vindex: multicolIdx", - "gen4-plan": "VT12001: unsupported: you cannot UPDATE primary vindex columns; invalid update on vindex: multicolIdx" + "plan": "VT12001: unsupported: you cannot UPDATE primary vindex columns; invalid update on vindex: multicolIdx" }, { "comment": "update changes non lookup vindex column", "query": "update user_metadata set md5 = 1 where user_id = 1", - "v3-plan": "VT12001: unsupported: you can only update lookup vindexes; invalid update on vindex: user_md5_index", - "gen4-plan": "VT12001: unsupported: you can only UPDATE lookup vindexes; invalid update on vindex: user_md5_index" + "plan": "VT12001: unsupported: you can only UPDATE lookup vindexes; invalid update on vindex: user_md5_index" }, { "comment": "update with complex set clause", "query": "update music set id = id + 1 where id = 1", - "v3-plan": "VT12001: unsupported: only values are supported: invalid update on column: `id` with expr: [id + 1]", - "gen4-plan": "VT12001: unsupported: only values are supported; invalid update on column: `id` with expr: [id + 1]" + "plan": "VT12001: unsupported: only values are supported; invalid update on column: `id` with expr: [id + 1]" }, { "comment": "update by primary keyspace id, changing one vindex column, limit without order clause", "query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 limit 10", - "v3-plan": "VT12001: unsupported: need to provide ORDER BY clause when using LIMIT; invalid update on vindex: email_user_map", - "gen4-plan": "VT12001: unsupported: you need to provide the ORDER BY clause when using LIMIT; invalid update on vindex: email_user_map" + "plan": "VT12001: unsupported: you need to provide the ORDER BY clause when using LIMIT; invalid update on vindex: email_user_map" }, { "comment": "update with derived table", "query": "update (select id from user) as u set id = 4", - "v3-plan": "VT12001: unsupported: sharded subqueries in DML", - "gen4-plan": "The target table u of the UPDATE is not updatable" + "plan": "The target table u of the UPDATE is not updatable" }, { "comment": "join in update tables", "query": "update user join user_extra on user.id = user_extra.id set user.name = 'foo'", - "v3-plan": "VT12001: unsupported: multi-shard or vindex write statement", - "gen4-plan": "VT12001: unsupported: unaliased multiple tables in update" + "plan": "VT12001: unsupported: unaliased multiple tables in update" }, { "comment": "multiple tables in update", "query": "update user as u, user_extra as ue set u.name = 'foo' where u.id = ue.id", - "v3-plan": "VT12001: unsupported: multi-shard or vindex write statement", - "gen4-plan": "VT12001: unsupported: multiple (2) tables in update" + "plan": "VT12001: unsupported: multiple (2) tables in update" }, { "comment": "unsharded insert, unqualified names and auto-inc combined", "query": "insert into unsharded_auto select col from unsharded", - "v3-plan": "VT12001: unsupported: auto-increment and SELECT in INSERT", - "gen4-plan": "VT09004: INSERT should contain column list or the table should have authoritative columns in vschema" + "plan": "VT09004: INSERT should contain column list or the table should have authoritative columns in vschema" }, { "comment": "unsharded insert, no col list with auto-inc", "query": "insert into unsharded_auto values(1,1)", - "v3-plan": "VT13001: [BUG] column list required for tables with auto-inc columns", - "gen4-plan": "VT09004: INSERT should contain column list or the table should have authoritative columns in vschema" + "plan": "VT09004: INSERT should contain column list or the table should have authoritative columns in vschema" }, { "comment": "unsharded insert, col list does not match values", "query": "insert into unsharded_auto(id, val) values(1)", - "v3-plan": "VT13001: [BUG] column list does not match values", - "gen4-plan": "VT03006: column count does not match value count at row 1" + "plan": "VT03006: column count does not match value count at row 1" }, { "comment": "sharded upsert can't change vindex", @@ -295,20 +272,17 @@ { "comment": "select get_lock with non-dual table", "query": "select get_lock('xyz', 10) from user", - "v3-plan": "VT12001: unsupported: get_lock('xyz', 10) is allowed only with dual", - "gen4-plan": "get_lock('xyz', 10) allowed only with dual" + "plan": "get_lock('xyz', 10) allowed only with dual" }, { "comment": "select is_free_lock with non-dual table", "query": "select is_free_lock('xyz') from user", - "v3-plan": "VT12001: unsupported: is_free_lock('xyz') is allowed only with dual", - "gen4-plan": "is_free_lock('xyz') allowed only with dual" + "plan": "is_free_lock('xyz') allowed only with dual" }, { "comment": "union with SQL_CALC_FOUND_ROWS", "query": "(select sql_calc_found_rows id from user where id = 1 limit 1) union select id from user where id = 1", - "v3-plan": "VT12001: unsupported: SQL_CALC_FOUND_ROWS not supported with UNION", - "gen4-plan": "VT12001: unsupported: SQL_CALC_FOUND_ROWS not supported with union" + "plan": "VT12001: unsupported: SQL_CALC_FOUND_ROWS not supported with union" }, { "comment": "set with DEFAULT - vitess aware", @@ -328,8 +302,7 @@ { "comment": "create view with Cannot auto-resolve for cross-shard joins", "query": "create view user.view_a as select col from user join user_extra", - "v3-plan": "VT03019: column col not found", - "gen4-plan": "Column 'col' in field list is ambiguous" + "plan": "Column 'col' in field list is ambiguous" }, { "comment": "create view with join that cannot be served in each shard separately", @@ -364,8 +337,7 @@ { "comment": "avg function on scatter query", "query": "select avg(id) from user", - "v3-plan": "VT12001: unsupported: in scatter query: complex aggregate expression", - "gen4-plan": "VT12001: unsupported: in scatter query: aggregation function 'avg(id)'" + "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", @@ -378,10 +350,9 @@ "plan": "VT12001: unsupported: cross-shard correlated subquery" }, { - "comment": "Gen4 does a rewrite of 'order by 2' that becomes 'order by id', leading to ambiguous binding.", + "comment": "rewrite of 'order by 2' that becomes 'order by id', leading to ambiguous binding.", "query": "select a.id, b.id from user as a, user_extra as b union select 1, 2 order by 2", - "v3-plan": "VT12001: unsupported: ORDER BY on top of UNION", - "gen4-plan": "Column 'id' in field list is ambiguous" + "plan": "Column 'id' in field list is ambiguous" }, { "comment": "unsupported with clause in delete statement", @@ -406,8 +377,7 @@ { "comment": "aggregation on union", "query": "select sum(col) from (select col from user union all select col from unsharded) t", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: using aggregation on top of a *planbuilder.concatenateGen4 plan" + "plan": "VT12001: unsupported: using aggregation on top of a *planbuilder.concatenate plan" }, { "comment": "insert having subquery in row values", @@ -422,8 +392,7 @@ { "comment": "json_table expressions", "query": "SELECT * FROM JSON_TABLE('[ {\"c1\": null} ]','$[*]' COLUMNS( c1 INT PATH '$.c1' ERROR ON ERROR )) as jt", - "v3-plan": "VT12001: unsupported: JSON_TABLE expressions", - "gen4-plan": "VT12001: unsupported: json_table expressions" + "plan": "VT12001: unsupported: json_table expressions" }, { "comment": "mix lock with other expr", @@ -463,7 +432,6 @@ { "comment": "aggregation on top of aggregation not supported", "query": "select distinct count(*) from user, (select distinct count(*) from user) X", - "v3-plan": "VT12001: unsupported: cross-shard query with aggregates", - "gen4-plan": "VT12001: unsupported: aggregation on top of aggregation not supported" + "plan": "VT12001: unsupported: aggregation on top of aggregation not supported" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/vexplain_cases.json b/go/vt/vtgate/planbuilder/testdata/vexplain_cases.json index bd828fe2dbf..630e59f3526 100644 --- a/go/vt/vtgate/planbuilder/testdata/vexplain_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/vexplain_cases.json @@ -17,28 +17,7 @@ { "comment": "vexplain queries", "query": "vexplain QUERIES select * from user", - "v3-plan": { - "QueryType": "EXPLAIN", - "Original": "vexplain QUERIES select * from user", - "Instructions": { - "OperatorType": "VEXPLAIN", - "Type": "queries", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "EXPLAIN", "Original": "vexplain QUERIES select * from user", "Instructions": { @@ -66,28 +45,7 @@ { "comment": "vexplain table", "query": "vexplain ALL select * from user", - "v3-plan": { - "QueryType": "EXPLAIN", - "Original": "vexplain ALL select * from user", - "Instructions": { - "OperatorType": "VEXPLAIN", - "Type": "all", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select * from `user` where 1 != 1", - "Query": "select * from `user`", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "EXPLAIN", "Original": "vexplain ALL select * from user", "Instructions": { diff --git a/go/vt/vtgate/planbuilder/testdata/view_cases.json b/go/vt/vtgate/planbuilder/testdata/view_cases.json index 5b5e76fe9ed..decc6a117cf 100644 --- a/go/vt/vtgate/planbuilder/testdata/view_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/view_cases.json @@ -26,22 +26,7 @@ { "comment": "create view with authoritative columns", "query": "create view user.view_ac as select * from authoritative", - "v3-plan": { - "QueryType": "DDL", - "Original": "create view user.view_ac as select * from authoritative", - "Instructions": { - "OperatorType": "DDL", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "Query": "create view view_ac as select * from authoritative" - }, - "TablesUsed": [ - "user.view_ac" - ] - }, - "gen4-plan": { + "plan": { "QueryType": "DDL", "Original": "create view user.view_ac as select * from authoritative", "Instructions": { @@ -107,4 +92,4 @@ "query": "drop view main.a, main.b, main.a", "plan": "VT03013: not unique table/alias: 'a'" } -] \ No newline at end of file +] diff --git a/go/vt/vtgate/planbuilder/testdata/vindex_func_cases.json b/go/vt/vtgate/planbuilder/testdata/vindex_func_cases.json index fa5198db7a9..320b5ae7bac 100644 --- a/go/vt/vtgate/planbuilder/testdata/vindex_func_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/vindex_func_cases.json @@ -2,33 +2,7 @@ { "comment": "vindex func read all cols", "query": "select id, keyspace_id, range_start, range_end, hex_keyspace_id, shard from user_index where id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, keyspace_id, range_start, range_end, hex_keyspace_id, shard from user_index where id = :id", - "Instructions": { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "Fields": { - "hex_keyspace_id": "VARBINARY", - "id": "VARBINARY", - "keyspace_id": "VARBINARY", - "range_end": "VARBINARY", - "range_start": "VARBINARY", - "shard": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, keyspace_id, range_start, range_end, hex_keyspace_id, shard from user_index where id = :id", "Instructions": { @@ -61,33 +35,7 @@ { "comment": "vindex func select *", "query": "select * from user_index where id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select * from user_index where id = :id", - "Instructions": { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "Fields": { - "hex_keyspace_id": "VARBINARY", - "id": "VARBINARY", - "keyspace_id": "VARBINARY", - "range_end": "VARBINARY", - "range_start": "VARBINARY", - "shard": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select * from user_index where id = :id", "Instructions": { @@ -120,26 +68,7 @@ { "comment": "vindex func read with id repeated", "query": "select id, keyspace_id, id from user_index where id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, keyspace_id, id from user_index where id = :id", - "Instructions": { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1, - 0 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, keyspace_id, id from user_index where id = :id", "Instructions": { @@ -179,26 +108,7 @@ { "comment": "disambiguated vindex reference", "query": "select id, keyspace_id, id from second_user.hash_dup where id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id, keyspace_id, id from second_user.hash_dup where id = :id", - "Instructions": { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1, - 0 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "hash_dup" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id, keyspace_id, id from second_user.hash_dup where id = :id", "Instructions": { @@ -233,42 +143,7 @@ { "comment": "You can even join with a vindexFunc primitive", "query": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "_unsharded", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 1 - ], - "Fields": { - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id", "Instructions": { @@ -311,42 +186,7 @@ { "comment": "Join vindexFunc on RHS", "query": "select user_index.keyspace_id, unsharded.id from unsharded join user_index where user_index.id = :id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_index.keyspace_id, unsharded.id from unsharded join user_index where user_index.id = :id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0,L:0", - "TableName": "unsharded_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded", - "Table": "unsharded" - }, - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 1 - ], - "Fields": { - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_index.keyspace_id, unsharded.id from unsharded join user_index where user_index.id = :id", "Instructions": { @@ -389,47 +229,7 @@ { "comment": "Join with vindexFunc on a column of it, already present in select list", "query": "select user_index.id, user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_index.id, user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_index_id": 0 - }, - "TableName": "_unsharded", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 0, - 1 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.id = :user_index_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_index.id, user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", "Instructions": { @@ -477,47 +277,7 @@ { "comment": "Join with vindexFunc on a column of it, already present at the end of the select list", "query": "select user_index.keyspace_id, user_index.id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_index.keyspace_id, user_index.id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1,R:0", - "JoinVars": { - "user_index_id": 1 - }, - "TableName": "_unsharded", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 1, - 0 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.id = :user_index_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_index.keyspace_id, user_index.id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", "Instructions": { @@ -565,47 +325,7 @@ { "comment": "Join with vindexFunc on a column of it, not present in select list", "query": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "user_index_id": 1 - }, - "TableName": "_unsharded", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 1, - 0 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.id = :user_index_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select user_index.keyspace_id, unsharded.id from user_index join unsharded where user_index.id = :id and unsharded.id = user_index.id", "Instructions": { @@ -653,47 +373,7 @@ { "comment": "Join with aliased table name", "query": "select ui.keyspace_id, unsharded.id from user_index ui join unsharded where ui.id = :id and unsharded.id = ui.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select ui.keyspace_id, unsharded.id from user_index ui join unsharded where ui.id = :id and unsharded.id = ui.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "ui_id": 1 - }, - "TableName": "_unsharded", - "Inputs": [ - { - "OperatorType": "VindexFunc", - "Variant": "VindexMap", - "Columns": [ - 1, - 0 - ], - "Fields": { - "id": "VARBINARY", - "keyspace_id": "VARBINARY" - }, - "Value": ":id", - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.id from unsharded where 1 != 1", - "Query": "select unsharded.id from unsharded where unsharded.id = :ui_id", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select ui.keyspace_id, unsharded.id from user_index ui join unsharded where ui.id = :id and unsharded.id = ui.id", "Instructions": { @@ -741,7 +421,6 @@ { "comment": "select none from user_index where id = :id", "query": "select none from user_index where id = :id", - "v3-plan": "VT03019: column `none` not found", - "gen4-plan": "column '`none`' not found in table 'user_index'" + "plan": "column '`none`' not found in table 'user_index'" } ] diff --git a/go/vt/vtgate/planbuilder/testdata/wireup_cases.json b/go/vt/vtgate/planbuilder/testdata/wireup_cases.json index b9984923292..376f9455cf8 100644 --- a/go/vt/vtgate/planbuilder/testdata/wireup_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/wireup_cases.json @@ -2,44 +2,7 @@ { "comment": "join on having clause", "query": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0,L:0,R:1", - "JoinVars": { - "uid": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id as uid from `user` as u where 1 != 1", - "Query": "select u.id as uid from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.col, e.id as eid from user_extra as e where 1 != 1", - "Query": "select e.col, e.id as eid from user_extra as e having eid = :uid", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid", "Instructions": { @@ -88,44 +51,7 @@ { "comment": "bind var already in use", "query": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid and e.col = :uid", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid and e.col = :uid", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0,L:0,R:1", - "JoinVars": { - "uid1": 0 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id as uid from `user` as u where 1 != 1", - "Query": "select u.id as uid from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.col, e.id as eid from user_extra as e where 1 != 1", - "Query": "select e.col, e.id as eid from user_extra as e having eid = :uid1 and e.col = :uid", - "Table": "user_extra" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select e.col, u.id uid, e.id eid from user u join user_extra e having uid = eid and e.col = :uid", "Instructions": { @@ -174,63 +100,7 @@ { "comment": "wire-up join with join, going left", "query": "select u1.id from user u1 join user u2 join user u3 where u3.col = u1.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 join user u3 where u3.col = u1.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id, u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.id, u1.col from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u3 where 1 != 1", - "Query": "select 1 from `user` as u3 where u3.col = :u1_col", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 join user u3 where u3.col = u1.col", "Instructions": { @@ -293,63 +163,7 @@ { "comment": "wire-up join with join, going left, then right", "query": "select u1.id from user u1 join user u2 join user u3 where u3.col = u2.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 join user u3 where u3.col = u2.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u2_col": 1 - }, - "TableName": "`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id from `user` as u1 where 1 != 1", - "Query": "select u1.id from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u2.col from `user` as u2 where 1 != 1", - "Query": "select u2.col from `user` as u2", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u3 where 1 != 1", - "Query": "select 1 from `user` as u3 where u3.col = :u2_col", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 join user u3 where u3.col = u2.col", "Instructions": { @@ -411,66 +225,7 @@ { "comment": "wire-up join with join, reuse existing result from a lower join", "query": "select u1.id from user u1 join user u2 on u2.col = u1.col join user u3 where u3.col = u1.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 on u2.col = u1.col join user u3 where u3.col = u1.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id, u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.id, u1.col from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2 where u2.col = :u1_col", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u3 where 1 != 1", - "Query": "select 1 from `user` as u3 where u3.col = :u1_col", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 on u2.col = u1.col join user u3 where u3.col = u1.col", "Instructions": { @@ -536,89 +291,7 @@ { "comment": "wire-up join with join, reuse existing result from a lower join.\n# You need two levels of join nesting to test this: when u3 requests\n# col from u1, the u1-u2 joins exports the column to u2-u3. When\n# u4 requests it, it should be reused from the u1-u2 join.", "query": "select u1.id from user u1 join user u2 join user u3 on u3.id = u1.col join user u4 where u4.col = u1.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 join user u3 on u3.id = u1.col join user u4 where u4.col = u1.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,L:1", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id, u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.id, u1.col from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2", - "Table": "`user`" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u3 where 1 != 1", - "Query": "select 1 from `user` as u3 where u3.id = :u1_col", - "Table": "`user`", - "Values": [ - ":u1_col" - ], - "Vindex": "user_index" - } - ] - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u4 where 1 != 1", - "Query": "select 1 from `user` as u4 where u4.col = :u1_col", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 join user u3 on u3.id = u1.col join user u4 where u4.col = u1.col", "Instructions": { @@ -707,70 +380,7 @@ { "comment": "Test reuse of join var already being supplied to the right of a node.", "query": "select u1.id from user u1 join (user u2 join user u3) where u2.id = u1.col and u3.id = u1.col", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join (user u2 join user u3) where u2.id = u1.col and u3.id = u1.col", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "JoinVars": { - "u1_col": 1 - }, - "TableName": "`user`_`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id, u1.col from `user` as u1 where 1 != 1", - "Query": "select u1.id, u1.col from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2 where u2.id = :u1_col", - "Table": "`user`", - "Values": [ - ":u1_col" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u3 where 1 != 1", - "Query": "select 1 from `user` as u3 where u3.id = :u1_col", - "Table": "`user`", - "Values": [ - ":u1_col" - ], - "Vindex": "user_index" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join (user u2 join user u3) where u2.id = u1.col and u3.id = u1.col", "Instructions": { @@ -844,44 +454,7 @@ { "comment": "Join on weird columns.", "query": "select `weird``name`.a, unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select `weird``name`.a, unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "weird_name_a_b_c": 1 - }, - "TableName": "`weird``name`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `weird``name`.a, `weird``name`.`a``b*c` from `weird``name` where 1 != 1", - "Query": "select `weird``name`.a, `weird``name`.`a``b*c` from `weird``name`", - "Table": "`weird``name`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.b from unsharded where 1 != 1", - "Query": "select unsharded.b from unsharded where unsharded.id = :weird_name_a_b_c", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select `weird``name`.a, unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", "Instructions": { @@ -926,48 +499,11 @@ "user.weird`name" ] } - }, - { - "comment": "Join on weird column (col is not in select)", - "query": "select unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "R:0", - "JoinVars": { - "weird_name_a_b_c": 0 - }, - "TableName": "`weird``name`_unsharded", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select `weird``name`.`a``b*c` from `weird``name` where 1 != 1", - "Query": "select `weird``name`.`a``b*c` from `weird``name`", - "Table": "`weird``name`" - }, - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select unsharded.b from unsharded where 1 != 1", - "Query": "select unsharded.b from unsharded where unsharded.id = :weird_name_a_b_c", - "Table": "unsharded" - } - ] - } - }, - "gen4-plan": { + }, + { + "comment": "Join on weird column (col is not in select)", + "query": "select unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", + "plan": { "QueryType": "SELECT", "Original": "select unsharded.b from `weird``name` join unsharded on `weird``name`.`a``b*c` = unsharded.id", "Instructions": { @@ -1016,50 +552,7 @@ { "comment": "wire-up with limit primitive", "query": "select u.id, e.id from user u join user_extra e where e.id = u.col limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id, e.id from user u join user_extra e where e.id = u.col limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "u_col": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, u.col from `user` as u where 1 != 1", - "Query": "select u.id, u.col from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.id from user_extra as e where 1 != 1", - "Query": "select e.id from user_extra as e where e.id = :u_col", - "Table": "user_extra" - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id, e.id from user u join user_extra e where e.id = u.col limit 10", "Instructions": { @@ -1110,75 +603,7 @@ { "comment": "Wire-up in subquery", "query": "select 1 from user where id in (select u.id, e.id from user u join user_extra e where e.id = u.col limit 10)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select 1 from user where id in (select u.id, e.id from user u join user_extra e where e.id = u.col limit 10)", - "Instructions": { - "OperatorType": "Subquery", - "Variant": "PulloutIn", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "u_col": 1 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, u.col from `user` as u where 1 != 1", - "Query": "select u.id, u.col from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.id from user_extra as e where 1 != 1", - "Query": "select e.id from user_extra as e where e.id = :u_col", - "Table": "user_extra" - } - ] - } - ] - }, - { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` where 1 != 1", - "Query": "select 1 from `user` where :__sq_has_values1 = 1 and id in ::__vals", - "Table": "`user`", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select 1 from user where id in (select u.id, e.id from user u join user_extra e where e.id = u.col limit 10)", "Instructions": { @@ -1254,71 +679,7 @@ { "comment": "Wire-up in underlying primitive after pullout", "query": "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10", - "Instructions": { - "OperatorType": "Limit", - "Count": "INT64(10)", - "Inputs": [ - { - "OperatorType": "Subquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq_has_values1", - "__sq1" - ], - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user`", - "Table": "`user`" - }, - { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0,L:1", - "JoinVars": { - "u_col": 2 - }, - "TableName": "`user`_user_extra", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u.id, :__sq1, u.col from `user` as u where 1 != 1", - "Query": "select u.id, :__sq1, u.col from `user` as u", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select e.id from user_extra as e where 1 != 1", - "Query": "select e.id from user_extra as e where e.id = :u_col", - "Table": "user_extra" - } - ] - } - ] - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10", "Instructions": { @@ -1389,26 +750,7 @@ { "comment": "Invalid value in IN clause", "query": "select id from user where id in (18446744073709551616, 1)", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select id from user where id in (18446744073709551616, 1)", - "Instructions": { - "OperatorType": "Route", - "Variant": "IN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from `user` where 1 != 1", - "Query": "select id from `user` where id in ::__vals", - "Table": "`user`", - "Values": [ - "(DECIMAL(18446744073709551616), INT64(1))" - ], - "Vindex": "user_index" - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select id from user where id in (18446744073709551616, 1)", "Instructions": { @@ -1434,45 +776,7 @@ { "comment": "Invalid value in IN clause from LHS of join", "query": "select u1.id from user u1 join user u2 where u1.id = 18446744073709551616", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 where u1.id = 18446744073709551616", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id from `user` as u1 where 1 != 1", - "Query": "select u1.id from `user` as u1 where u1.id = 18446744073709551616", - "Table": "`user`", - "Values": [ - "DECIMAL(18446744073709551616)" - ], - "Vindex": "user_index" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2", - "Table": "`user`" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 where u1.id = 18446744073709551616", "Instructions": { @@ -1517,45 +821,7 @@ { "comment": "Invalid value in IN clause from RHS of join", "query": "select u1.id from user u1 join user u2 where u2.id = 18446744073709551616", - "v3-plan": { - "QueryType": "SELECT", - "Original": "select u1.id from user u1 join user u2 where u2.id = 18446744073709551616", - "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_`user`", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select u1.id from `user` as u1 where 1 != 1", - "Query": "select u1.id from `user` as u1", - "Table": "`user`" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select 1 from `user` as u2 where 1 != 1", - "Query": "select 1 from `user` as u2 where u2.id = 18446744073709551616", - "Table": "`user`", - "Values": [ - "DECIMAL(18446744073709551616)" - ], - "Vindex": "user_index" - } - ] - } - }, - "gen4-plan": { + "plan": { "QueryType": "SELECT", "Original": "select u1.id from user u1 join user u2 where u2.id = 18446744073709551616", "Instructions": { @@ -1598,11 +864,11 @@ } }, { - "comment": "derived table with column aliases not supported by v3, but planner is overridden with hint", - "query": "select /*vt+ PLANNER=gen4 */ u.a from (select id as b, name from user) u(a, n) where u.n = 1", + "comment": "derived table with column aliases", + "query": "select u.a from (select id as b, name from user) u(a, n) where u.n = 1", "plan": { "QueryType": "SELECT", - "Original": "select /*vt+ PLANNER=gen4 */ u.a from (select id as b, name from user) u(a, n) where u.n = 1", + "Original": "select u.a from (select id as b, name from user) u(a, n) where u.n = 1", "Instructions": { "OperatorType": "VindexLookup", "Variant": "Equal", @@ -1638,7 +904,7 @@ "Sharded": true }, "FieldQuery": "select u.a from (select id as b, `name` from `user` where 1 != 1) as u(a, n) where 1 != 1", - "Query": "select /*vt+ PLANNER=gen4 */ u.a from (select id as b, `name` from `user` where `name` = 1) as u(a, n)", + "Query": "select u.a from (select id as b, `name` from `user` where `name` = 1) as u(a, n)", "Table": "`user`" } ] @@ -1648,11 +914,6 @@ ] } }, - { - "comment": "derived table with column aliases not supported by v3, but planner is overridden with hint", - "query": "select /*vt+ PLANNER=v3 */ u.a from (select id as b, name from user) u(a, n) where u.n = 1", - "plan": "VT12001: unsupported: column aliases in derived table" - }, { "comment": "Three-way join using the left2right. The normal gen4 planner would merge m1 and m2 first, but the left to right doesnt", "query": "select /*vt+ PLANNER=left2right */ user.col from user join unsharded as m1 join unsharded as m2", diff --git a/go/vt/vtgate/planbuilder/union.go b/go/vt/vtgate/planbuilder/union.go deleted file mode 100644 index 22dba1aa236..00000000000 --- a/go/vt/vtgate/planbuilder/union.go +++ /dev/null @@ -1,146 +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 planbuilder - -import ( - "fmt" - - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - "vitess.io/vitess/go/vt/vterrors" - - "vitess.io/vitess/go/mysql" - - "vitess.io/vitess/go/vt/sqlparser" -) - -func buildUnionPlan(string) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - union := stmt.(*sqlparser.Union) - if union.With != nil { - return nil, vterrors.VT12001("WITH expression in UNION statement") - } - err := checkUnsupportedExpressions(union) - if err != nil { - return nil, err - } - // For unions, create a pb with anonymous scope. - pb := newPrimitiveBuilder(vschema, newJointab(reservedVars)) - if err := pb.processUnion(union, reservedVars, nil); err != nil { - return nil, err - } - if err := pb.plan.Wireup(pb.plan, pb.jt); err != nil { - return nil, err - } - return newPlanResult(pb.plan.Primitive()), nil - } -} - -func (pb *primitiveBuilder) processUnion(union *sqlparser.Union, reservedVars *sqlparser.ReservedVars, outer *symtab) error { - if err := pb.processPart(union.Left, reservedVars, outer); err != nil { - return err - } - - rpb := newPrimitiveBuilder(pb.vschema, pb.jt) - if err := rpb.processPart(union.Right, reservedVars, outer); err != nil { - return err - } - err := unionRouteMerge(pb.plan, rpb.plan, union) - if err != nil { - // we are merging between two routes - let's check if we can see so that we have the same amount of columns on both sides of the union - lhsCols := len(pb.plan.ResultColumns()) - rhsCols := len(rpb.plan.ResultColumns()) - if lhsCols != rhsCols { - return &mysql.SQLError{ - Num: mysql.ERWrongNumberOfColumnsInSelect, - State: "21000", - Message: "The used SELECT statements have a different number of columns", - Query: sqlparser.String(union), - } - } - - pb.plan = &concatenate{ - lhs: pb.plan, - rhs: rpb.plan, - } - - if union.Distinct { - pb.plan = newDistinctV3(pb.plan) - } - } - pb.st.Outer = outer - - if err := setLock(pb.plan, union.Lock); err != nil { - return err - } - - if err := pb.pushOrderBy(union.OrderBy); err != nil { - return err - } - return pb.pushLimit(union.Limit) -} - -func (pb *primitiveBuilder) processPart(part sqlparser.SelectStatement, reservedVars *sqlparser.ReservedVars, outer *symtab) error { - switch part := part.(type) { - case *sqlparser.Union: - return pb.processUnion(part, reservedVars, outer) - case *sqlparser.Select: - if part.SQLCalcFoundRows { - return vterrors.VT12001("SQL_CALC_FOUND_ROWS not supported with UNION") - } - return pb.processSelect(part, reservedVars, outer, "") - } - return vterrors.VT13001(fmt.Sprintf("unexpected SELECT type: %T", part)) -} - -// TODO (systay) we never use this as an actual error. we should rethink the return type -func unionRouteMerge(left, right logicalPlan, us *sqlparser.Union) error { - lroute, ok := left.(*route) - if !ok { - return vterrors.VT12001("SELECT of UNION is non-trivial") - } - rroute, ok := right.(*route) - if !ok { - return vterrors.VT12001("SELECT of UNION is non-trivial") - } - mergeSuccess := lroute.MergeUnion(rroute, us.Distinct) - if !mergeSuccess { - return vterrors.VT12001("execute UNION as a single route") - } - - lroute.Select = &sqlparser.Union{Left: lroute.Select, Right: us.Right, Distinct: us.Distinct} - - return nil -} - -// planLock pushes "FOR UPDATE", "LOCK IN SHARE MODE" down to all routes -func setLock(in logicalPlan, lock sqlparser.Lock) error { - _, err := visit(in, func(plan logicalPlan) (bool, logicalPlan, error) { - switch node := in.(type) { - case *route: - node.Select.SetLock(lock) - return false, node, nil - case *sqlCalcFoundRows, *vindexFunc: - return false, nil, vterrors.VT13001(fmt.Sprintf("unreachable %T.locking", in)) - } - return true, plan, nil - }) - if err != nil { - return err - } - return nil -} diff --git a/go/vt/vtgate/planbuilder/update.go b/go/vt/vtgate/planbuilder/update.go new file mode 100644 index 00000000000..d57853a5bd6 --- /dev/null +++ b/go/vt/vtgate/planbuilder/update.go @@ -0,0 +1,101 @@ +/* +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 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" + "vitess.io/vitess/go/vt/vtgate/semantics" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +func gen4UpdateStmtPlanner( + version querypb.ExecuteOptions_PlannerVersion, + updStmt *sqlparser.Update, + reservedVars *sqlparser.ReservedVars, + vschema plancontext.VSchema, +) (*planResult, error) { + if updStmt.With != nil { + return nil, vterrors.VT12001("WITH expression in UPDATE statement") + } + + ksName := "" + if ks, _ := vschema.DefaultKeyspace(); ks != nil { + ksName = ks.Name + } + semTable, err := semantics.Analyze(updStmt, ksName, vschema) + if err != nil { + return nil, err + } + // record any warning as planner warning. + vschema.PlannerWarning(semTable.Warning) + + err = rewriteRoutedTables(updStmt, vschema) + if err != nil { + return nil, err + } + + if ks, tables := semTable.SingleUnshardedKeyspace(); ks != nil { + plan := updateUnshardedShortcut(updStmt, ks, tables) + plan = pushCommentDirectivesOnPlan(plan, updStmt) + return newPlanResult(plan.Primitive(), operators.QualifiedTables(ks, tables)...), nil + } + + if semTable.NotUnshardedErr != nil { + return nil, semTable.NotUnshardedErr + } + + err = queryRewrite(semTable, reservedVars, updStmt) + if err != nil { + return nil, err + } + + ctx := plancontext.NewPlanningContext(reservedVars, semTable, vschema, version) + + op, err := operators.PlanQuery(ctx, updStmt) + if err != nil { + return nil, err + } + + plan, err := transformToLogicalPlan(ctx, op, true) + if err != nil { + return nil, err + } + + plan = pushCommentDirectivesOnPlan(plan, updStmt) + + setLockOnAllSelect(plan) + + if err := plan.Wireup(ctx); err != nil { + return nil, err + } + + return newPlanResult(plan.Primitive(), operators.TablesUsed(op)...), nil +} + +func updateUnshardedShortcut(stmt *sqlparser.Update, ks *vindexes.Keyspace, tables []*vindexes.Table) logicalPlan { + edml := engine.NewDML() + edml.Keyspace = ks + edml.Table = tables + edml.Opcode = engine.Unsharded + edml.Query = generateQuery(stmt) + return &primitiveWrapper{prim: &engine.Update{DML: edml}} +} diff --git a/go/vt/vtgate/planbuilder/update_planner.go b/go/vt/vtgate/planbuilder/update_planner.go deleted file mode 100644 index cf9e8288745..00000000000 --- a/go/vt/vtgate/planbuilder/update_planner.go +++ /dev/null @@ -1,165 +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 planbuilder - -import ( - "fmt" - - "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/vindexes" -) - -// buildUpdatePlan returns a stmtPlanner that builds the instructions for an UPDATE statement. -func buildUpdatePlan(string) stmtPlanner { - return func(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { - upd := stmt.(*sqlparser.Update) - if upd.With != nil { - return nil, vterrors.VT12001("WITH expression in UPDATE statement") - } - err := checkUnsupportedExpressions(upd) - if err != nil { - return nil, err - } - dml, tables, ksidVindex, err := buildDMLPlan(vschema, "update", stmt, reservedVars, upd.TableExprs, upd.Where, upd.OrderBy, upd.Limit, upd.Comments, upd.Exprs) - if err != nil { - return nil, err - } - eupd := &engine.Update{DML: dml} - - if dml.Opcode == engine.Unsharded { - return newPlanResult(eupd, tables...), nil - } - eupdTable, err := eupd.GetSingleTable() - if err != nil { - return nil, err - } - cvv, ovq, err := buildChangedVindexesValues(upd, eupdTable, ksidVindex.Columns) - if err != nil { - return nil, err - } - eupd.ChangedVindexValues = cvv - eupd.OwnedVindexQuery = ovq - if len(eupd.ChangedVindexValues) != 0 { - eupd.KsidVindex = ksidVindex.Vindex - eupd.KsidLength = len(ksidVindex.Columns) - } - return newPlanResult(eupd, tables...), nil - } -} - -// buildChangedVindexesValues adds to the plan all the lookup vindexes that are changing. -// Updates can only be performed to secondary lookup vindexes with no complex expressions -// in the set clause. -func buildChangedVindexesValues(update *sqlparser.Update, table *vindexes.Table, ksidCols []sqlparser.IdentifierCI) (map[string]*engine.VindexValues, string, error) { - changedVindexes := make(map[string]*engine.VindexValues) - buf, offset := initialQuery(ksidCols, table) - for i, vindex := range table.ColumnVindexes { - vindexValueMap := make(map[string]evalengine.Expr) - first := true - for _, vcol := range vindex.Columns { - // Searching in order of columns in colvindex. - found := false - for _, assignment := range update.Exprs { - if !vcol.Equal(assignment.Name.Name) { - continue - } - if found { - return nil, "", vterrors.VT03015(assignment.Name.Name) - } - found = true - pv, err := extractValueFromUpdate(assignment) - if err != nil { - return nil, "", err - } - vindexValueMap[vcol.String()] = pv - if first { - buf.Myprintf(", %v", assignment) - first = false - } else { - buf.Myprintf(" and %v", assignment) - } - } - } - if len(vindexValueMap) == 0 { - // Vindex not changing, continue - continue - } - - if update.Limit != nil && len(update.OrderBy) == 0 { - return nil, "", vterrors.VT12001(fmt.Sprintf("need to provide ORDER BY clause when using LIMIT; invalid update on vindex: %v", vindex.Name)) - } - if i == 0 { - return nil, "", 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, "", vterrors.VT12001(fmt.Sprintf("you can only update lookup vindexes; invalid update on vindex: %v", vindex.Name)) - } - changedVindexes[vindex.Name] = &engine.VindexValues{ - PvMap: vindexValueMap, - Offset: offset, - } - offset++ - } - if len(changedVindexes) == 0 { - return nil, "", nil - } - // generate rest of the owned vindex query. - aTblExpr, ok := update.TableExprs[0].(*sqlparser.AliasedTableExpr) - if !ok { - return nil, "", 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(), nil -} - -func initialQuery(ksidCols []sqlparser.IdentifierCI, table *vindexes.Table) (*sqlparser.TrackedBuffer, int) { - buf := sqlparser.NewTrackedBuffer(nil) - offset := 0 - for _, col := range ksidCols { - if offset == 0 { - buf.Myprintf("select %v", col) - } else { - buf.Myprintf(", %v", col) - } - offset++ - } - for _, cv := range table.Owned { - for _, column := range cv.Columns { - buf.Myprintf(", %v", column) - offset++ - } - } - return buf, offset -} - -// extractValueFromUpdate given an UpdateExpr attempts to extracts the Value -// it's holding. At the moment it only supports: StrVal, HexVal, IntVal, ValArg. -// If a complex expression is provided (e.g set name = name + 1), the update will be rejected. -func extractValueFromUpdate(upd *sqlparser.UpdateExpr) (evalengine.Expr, error) { - pv, err := evalengine.Translate(upd.Expr, nil) - if err != nil || sqlparser.IsSimpleTuple(upd.Expr) { - err := vterrors.VT12001(fmt.Sprintf("only values are supported: invalid update on column: `%s` with expr: [%s]", upd.Name.Name.String(), sqlparser.String(upd.Expr))) - return nil, err - } - return pv, nil -} diff --git a/go/vt/vtgate/planbuilder/vindex_func.go b/go/vt/vtgate/planbuilder/vindex_func.go index e72a35e7814..9b575030c61 100644 --- a/go/vt/vtgate/planbuilder/vindex_func.go +++ b/go/vt/vtgate/planbuilder/vindex_func.go @@ -25,11 +25,9 @@ import ( "vitess.io/vitess/go/vt/vterrors" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/vindexes" - - querypb "vitess.io/vitess/go/vt/proto/query" ) var _ logicalPlan = (*vindexFunc)(nil) @@ -41,9 +39,6 @@ type vindexFunc struct { // the tableID field is only used by the gen4 planner tableID semantics.TableSet - // resultColumns represent the columns returned by this route. - resultColumns []*resultColumn - // eVindexFunc is the primitive being built. eVindexFunc *engine.VindexFunc } @@ -57,89 +52,16 @@ var colnames = []string{ "shard", } -func newVindexFunc(alias sqlparser.TableName, vindex vindexes.SingleColumn) (*vindexFunc, *symtab) { - vf := &vindexFunc{ - order: 1, - eVindexFunc: &engine.VindexFunc{ - Vindex: vindex, - }, - } - - // Create a 'table' that represents the vindex. - t := &table{ - alias: alias, - origin: vf, - } - - for _, colName := range colnames { - t.addColumn(sqlparser.NewIdentifierCI(colName), &column{origin: vf}) - } - t.isAuthoritative = true - - st := newSymtab() - // AddTable will not fail because symtab is empty. - _ = st.AddTable(t) - return vf, st -} - -// Order implements the logicalPlan interface -func (vf *vindexFunc) Order() int { - return vf.order -} - -// Reorder implements the logicalPlan interface -func (vf *vindexFunc) Reorder(order int) { - vf.order = order + 1 -} - // Primitive implements the logicalPlan interface func (vf *vindexFunc) Primitive() engine.Primitive { return vf.eVindexFunc } -// ResultColumns implements the logicalPlan interface -func (vf *vindexFunc) ResultColumns() []*resultColumn { - return vf.resultColumns -} - -// Wireup implements the logicalPlan interface -func (vf *vindexFunc) Wireup(logicalPlan, *jointab) error { - return nil -} - // WireupGen4 implements the logicalPlan interface -func (vf *vindexFunc) WireupGen4(*plancontext.PlanningContext) error { +func (vf *vindexFunc) Wireup(*plancontext.PlanningContext) error { return nil } -// SupplyVar implements the logicalPlan interface -func (vf *vindexFunc) SupplyVar(from, to int, col *sqlparser.ColName, varname string) { - // vindexFunc is an atomic primitive. So, SupplyVar cannot be - // called on it. - panic("BUG: vindexFunc is an atomic node.") -} - -// SupplyCol implements the logicalPlan interface -func (vf *vindexFunc) SupplyCol(col *sqlparser.ColName) (rc *resultColumn, colNumber int) { - c := col.Metadata.(*column) - for i, rc := range vf.resultColumns { - if rc.column == c { - return rc, i - } - } - - vf.resultColumns = append(vf.resultColumns, &resultColumn{column: c}) - vf.eVindexFunc.Fields = append(vf.eVindexFunc.Fields, &querypb.Field{ - Name: col.Name.String(), - Type: querypb.Type_VARBINARY, - }) - - // columns that reference vindexFunc will have their colNumber set. - // Let's use it here. - vf.eVindexFunc.Cols = append(vf.eVindexFunc.Cols, c.colNumber) - return rc, len(vf.resultColumns) - 1 -} - // SupplyProjection pushes the given aliased expression into the fields and cols slices of the // vindexFunc engine primitive. The method returns the offset of the new expression in the columns // list. @@ -180,11 +102,6 @@ func (err UnsupportedSupplyWeightString) Error() string { return fmt.Sprintf("cannot do collation on %s", err.Type) } -// SupplyWeightString implements the logicalPlan interface -func (vf *vindexFunc) SupplyWeightString(colNumber int, alsoAddToGroupBy bool) (weightcolNumber int, err error) { - return 0, UnsupportedSupplyWeightString{Type: "vindex function"} -} - // Rewrite implements the logicalPlan interface func (vf *vindexFunc) Rewrite(inputs ...logicalPlan) error { if len(inputs) != 0 { diff --git a/go/vt/vtgate/planbuilder/vindex_op.go b/go/vt/vtgate/planbuilder/vindex_op.go index bfd064d6921..5d16f05c88b 100644 --- a/go/vt/vtgate/planbuilder/vindex_op.go +++ b/go/vt/vtgate/planbuilder/vindex_op.go @@ -39,9 +39,8 @@ func transformVindexPlan(ctx *plancontext.PlanningContext, op *operators.Vindex) return nil, err } plan := &vindexFunc{ - order: 1, - tableID: op.Solved, - resultColumns: nil, + order: 1, + tableID: op.Solved, eVindexFunc: &engine.VindexFunc{ Opcode: op.OpCode, Vindex: single, diff --git a/go/vt/vtgate/vindexes/lookup_test.go b/go/vt/vtgate/vindexes/lookup_test.go index 9b01770218a..1051a394787 100644 --- a/go/vt/vtgate/vindexes/lookup_test.go +++ b/go/vt/vtgate/vindexes/lookup_test.go @@ -19,12 +19,11 @@ package vindexes import ( "context" "errors" + "strings" "testing" "vitess.io/vitess/go/test/utils" - "strings" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 558befe7ce0..1eb8aaebfc1 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -469,7 +469,7 @@ func (vtg *VTGate) Gateway() *TabletGateway { return vtg.gw } -// Execute executes a non-streaming query. This is a V3 function. +// Execute executes a non-streaming query. func (vtg *VTGate) Execute(ctx context.Context, session *vtgatepb.Session, sql string, bindVariables map[string]*querypb.BindVariable) (newSession *vtgatepb.Session, qr *sqltypes.Result, err error) { // In this context, we don't care if we can't fully parse destination destKeyspace, destTabletType, _, _ := vtg.executor.ParseDestinationTarget(session.TargetString) @@ -498,7 +498,7 @@ func (vtg *VTGate) Execute(ctx context.Context, session *vtgatepb.Session, sql s return session, nil, err } -// ExecuteBatch executes a batch of queries. This is a V3 function. +// ExecuteBatch executes a batch of queries. func (vtg *VTGate) ExecuteBatch(ctx context.Context, session *vtgatepb.Session, sqlList []string, bindVariablesList []map[string]*querypb.BindVariable) (*vtgatepb.Session, []sqltypes.QueryResponse, error) { // In this context, we don't care if we can't fully parse destination destKeyspace, destTabletType, _, _ := vtg.executor.ParseDestinationTarget(session.TargetString) @@ -526,9 +526,8 @@ func (vtg *VTGate) ExecuteBatch(ctx context.Context, session *vtgatepb.Session, return session, qrl, nil } -// StreamExecute executes a streaming query. This is a V3 function. -// Note we guarantee the callback will not be called concurrently -// by multiple go routines. +// StreamExecute executes a streaming query. +// Note we guarantee the callback will not be called concurrently by multiple go routines. func (vtg *VTGate) StreamExecute(ctx context.Context, session *vtgatepb.Session, sql string, bindVariables map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) (*vtgatepb.Session, error) { // In this context, we don't care if we can't fully parse destination destKeyspace, destTabletType, _, _ := vtg.executor.ParseDestinationTarget(session.TargetString) diff --git a/go/vt/vtgate/vtgateconn/vtgateconn.go b/go/vt/vtgate/vtgateconn/vtgateconn.go index 5a6c5ae6b94..ae0da3fdf43 100644 --- a/go/vt/vtgate/vtgateconn/vtgateconn.go +++ b/go/vt/vtgate/vtgateconn/vtgateconn.go @@ -62,7 +62,7 @@ type VTGateConn struct { impl Impl } -// Session returns a VTGateSession that can be used to access V3 functions. +// Session returns a VTGateSession that can be used to access execution functions. func (conn *VTGateConn) Session(targetString string, options *querypb.ExecuteOptions) *VTGateSession { return &VTGateSession{ session: &vtgatepb.Session{ @@ -111,7 +111,7 @@ func (conn *VTGateConn) VStream(ctx context.Context, tabletType topodatapb.Table return conn.impl.VStream(ctx, tabletType, vgtid, filter, flags) } -// VTGateSession exposes the V3 API to the clients. +// VTGateSession exposes the Vitess Execution API to the clients. // The object maintains client-side state and is comparable to a native MySQL connection. // For example, if you enable autocommit on a Session object, all subsequent calls will respect this. // Functions within an object must not be called concurrently. @@ -163,13 +163,13 @@ func (sn *VTGateSession) Prepare(ctx context.Context, query string, bindVars map // Impl defines the interface for a vtgate client protocol // implementation. It can be used concurrently across goroutines. type Impl interface { - // Execute executes a non-streaming query on vtgate. This is a V3 function. + // Execute executes a non-streaming query on vtgate. Execute(ctx context.Context, session *vtgatepb.Session, query string, bindVars map[string]*querypb.BindVariable) (*vtgatepb.Session, *sqltypes.Result, error) - // ExecuteBatch executes a non-streaming queries on vtgate. This is a V3 function. + // ExecuteBatch executes a non-streaming queries on vtgate. ExecuteBatch(ctx context.Context, session *vtgatepb.Session, queryList []string, bindVarsList []map[string]*querypb.BindVariable) (*vtgatepb.Session, []sqltypes.QueryResponse, error) - // StreamExecute executes a streaming query on vtgate. This is a V3 function. + // StreamExecute executes a streaming query on vtgate. StreamExecute(ctx context.Context, session *vtgatepb.Session, query string, bindVars map[string]*querypb.BindVariable, processResponse func(*vtgatepb.StreamExecuteResponse)) (sqltypes.ResultStream, error) // Prepare returns the fields information for the query as part of supporting prepare statements. diff --git a/go/vt/vtgate/vtgateconn/vtgateconn_test.go b/go/vt/vtgate/vtgateconn/vtgateconn_test.go index 8bada5b406c..523492328e9 100644 --- a/go/vt/vtgate/vtgateconn/vtgateconn_test.go +++ b/go/vt/vtgate/vtgateconn/vtgateconn_test.go @@ -17,9 +17,8 @@ limitations under the License. package vtgateconn import ( - "testing" - "context" + "testing" ) func TestRegisterDialer(t *testing.T) { diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 3a095eb8b2d..c7d048b3377 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -89,7 +89,7 @@ type Config struct { Charset string // PlannerVersion is the planner version to use for the vtgate. - // Choose between V3, V3Insert, Gen4, Gen4Greedy and Gen4Fallback + // Choose between Gen4, Gen4Greedy and Gen4Left2Right PlannerVersion string // ExtraMyCnf are the extra .CNF files to be added to the MySQL config