Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 49 additions & 62 deletions go/cmd/vtexplain/vtexplain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package main

import (
"flag"
"fmt"
"os"

Expand All @@ -28,62 +27,50 @@ import (
"vitess.io/vitess/go/vt/vtexplain"
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"

"github.com/spf13/pflag"

querypb "vitess.io/vitess/go/vt/proto/query"
// Include deprecation warnings for soon-to-be-unsupported flag invocations.
_flag "vitess.io/vitess/go/internal/flag"
)

var (
sqlFlag = flag.String("sql", "", "A list of semicolon-delimited SQL commands to analyze")
sqlFileFlag = flag.String("sql-file", "", "Identifies the file that contains the SQL commands to analyze")
schemaFlag = flag.String("schema", "", "The SQL table schema")
schemaFileFlag = flag.String("schema-file", "", "Identifies the file that contains the SQL table schema")
vschemaFlag = flag.String("vschema", "", "Identifies the VTGate routing schema")
vschemaFileFlag = flag.String("vschema-file", "", "Identifies the VTGate routing schema file")
ksShardMapFlag = flag.String("ks-shard-map", "", "JSON map of keyspace name -> shard name -> ShardReference object. The inner map is the same as the output of FindAllShardsInKeyspace")
ksShardMapFileFlag = flag.String("ks-shard-map-file", "", "File containing json blob of keyspace name -> shard name -> ShardReference object")
numShards = flag.Int("shards", 2, "Number of shards per keyspace. Passing --ks-shard-map/--ks-shard-map-file causes this flag to be ignored.")
executionMode = flag.String("execution-mode", "multi", "The execution mode to simulate -- must be set to multi, legacy-autocommit, or twopc")
replicationMode = flag.String("replication-mode", "ROW", "The replication mode to simulate -- must be set to either ROW or STATEMENT")
normalize = flag.Bool("normalize", false, "Whether to enable vtgate normalization")
outputMode = flag.String("output-mode", "text", "Output in human-friendly text or json")
dbName = flag.String("dbname", "", "Optional database target to override normal routing")
plannerVersionStr = flag.String("planner-version", "", "Sets the query planner version to use when generating the explain output. Valid values are V3 and Gen4")

// vtexplainFlags lists all the flags that should show in usage
vtexplainFlags = []string{
"output-mode",
"planner-version",
"normalize",
"shards",
"replication-mode",
"schema",
"schema-file",
"sql",
"sql-file",
"vschema",
"vschema-file",
"ks-shard-map",
"ks-shard-map-file",
"dbname",
"queryserver-config-passthrough-dmls",
}
sqlFlag string
sqlFileFlag string
schemaFlag string
schemaFileFlag string
vschemaFlag string
vschemaFileFlag string
ksShardMapFlag string
ksShardMapFileFlag string
normalize bool
dbName string
plannerVersionStr string

numShards = 2
replicationMode = "ROW"
executionMode = "multi"
outputMode = "text"
)

func registerFlags(fs *pflag.FlagSet) {
fs.StringVar(&sqlFlag, "sql", sqlFlag, "A list of semicolon-delimited SQL commands to analyze")
fs.StringVar(&sqlFileFlag, "sql-file", sqlFileFlag, "Identifies the file that contains the SQL commands to analyze")
fs.StringVar(&schemaFlag, "schema", schemaFlag, "The SQL table schema")
fs.StringVar(&schemaFileFlag, "schema-file", schemaFileFlag, "Identifies the file that contains the SQL table schema")
fs.StringVar(&vschemaFlag, "vschema", vschemaFlag, "Identifies the VTGate routing schema")
fs.StringVar(&vschemaFileFlag, "vschema-file", vschemaFileFlag, "Identifies the VTGate routing schema file")
fs.StringVar(&ksShardMapFlag, "ks-shard-map", ksShardMapFlag, "JSON map of keyspace name -> shard name -> ShardReference object. The inner map is the same as the output of FindAllShardsInKeyspace")
fs.StringVar(&ksShardMapFileFlag, "ks-shard-map-file", ksShardMapFileFlag, "File containing json blob of keyspace name -> shard name -> ShardReference object")
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")
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")
}

func init() {
logger := logutil.NewConsoleLogger()
flag.CommandLine.SetOutput(logutil.NewLoggerWriter(logger))
_flag.SetUsage(flag.CommandLine, _flag.UsageOptions{
FlagFilter: func(f *flag.Flag) bool {
for _, name := range vtexplainFlags {
if f.Name == name {
return true
}
}

return false
},
})
servenv.OnParse(registerFlags)
}

// getFileParam returns a string containing either flag is not "",
Expand Down Expand Up @@ -123,38 +110,38 @@ func main() {
}

func parseAndRun() error {
plannerVersion, _ := plancontext.PlannerNameToVersion(*plannerVersionStr)
plannerVersion, _ := plancontext.PlannerNameToVersion(plannerVersionStr)
if 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", *plannerVersionStr)
return fmt.Errorf("invalid value specified for planner-version of '%s' -- valid values are V3 and Gen4", plannerVersionStr)
}

sql, err := getFileParam(*sqlFlag, *sqlFileFlag, "sql", true)
sql, err := getFileParam(sqlFlag, sqlFileFlag, "sql", true)
if err != nil {
return err
}

schema, err := getFileParam(*schemaFlag, *schemaFileFlag, "schema", true)
schema, err := getFileParam(schemaFlag, schemaFileFlag, "schema", true)
if err != nil {
return err
}

vschema, err := getFileParam(*vschemaFlag, *vschemaFileFlag, "vschema", true)
vschema, err := getFileParam(vschemaFlag, vschemaFileFlag, "vschema", true)
if err != nil {
return err
}

ksShardMap, err := getFileParam(*ksShardMapFlag, *ksShardMapFileFlag, "ks-shard-map", false)
ksShardMap, err := getFileParam(ksShardMapFlag, ksShardMapFileFlag, "ks-shard-map", false)
if err != nil {
return err
}

opts := &vtexplain.Options{
ExecutionMode: *executionMode,
ExecutionMode: executionMode,
PlannerVersion: plannerVersion,
ReplicationMode: *replicationMode,
NumShards: *numShards,
Normalize: *normalize,
Target: *dbName,
ReplicationMode: replicationMode,
NumShards: numShards,
Normalize: normalize,
Target: dbName,
}

log.V(100).Infof("sql %s\n", sql)
Expand All @@ -172,7 +159,7 @@ func parseAndRun() error {
return err
}

if *outputMode == "text" {
if outputMode == "text" {
fmt.Print(vte.ExplainsAsText(plans))
} else {
fmt.Print(vtexplain.ExplainsAsJSON(plans))
Expand Down