Skip to content

Commit

Permalink
add cnf rewriting to system schema queries
Browse files Browse the repository at this point in the history
Signed-off-by: Harshit Gangal <harshit@planetscale.com>
  • Loading branch information
harshit-gangal committed Jul 19, 2021
1 parent 260e67c commit 38f506b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 34 deletions.
14 changes: 5 additions & 9 deletions go/vt/vtgate/engine/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"sort"
"strconv"
"strings"
"time"

"vitess.io/vitess/go/vt/log"
Expand Down Expand Up @@ -800,17 +801,12 @@ func (route *Route) description() PrimitiveDescription {
other["SysTableTableSchema"] = sysTabSchema
}
if len(route.SysTableTableName) != 0 {
idx := 0
sysTableName := "["
var sysTableName []string
for k, v := range route.SysTableTableName {
if idx != 0 {
sysTableName += ", "
}
sysTableName += k + ":" + v.String()
idx++
sysTableName = append(sysTableName, k+":"+v.String())
}
sysTableName += "]"
other["SysTableTableName"] = sysTableName
sort.Strings(sysTableName)
other["SysTableTableName"] = "[" + strings.Join(sysTableName, ", ") + "]"
}
orderBy := GenericJoin(route.OrderBy, orderByToString)
if orderBy != "" {
Expand Down
24 changes: 21 additions & 3 deletions go/vt/vtgate/planbuilder/route_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,28 @@ func gen4Planner(_ string) func(sqlparser.Statement, *sqlparser.ReservedVars, Co
if !ok {
return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "%T not yet supported", stmt)
}
return newBuildSelectPlan(sel, reservedVars, vschema)

getPlan := func(sel *sqlparser.Select) (logicalPlan, error) {
return newBuildSelectPlan(sel, reservedVars, vschema)
}

plan, err := getPlan(sel)
if err != nil {
return nil, err
}

if shouldRetryWithCNFRewriting(plan) {
// by transforming the predicates to CNF, the planner will sometimes find better plans
primitive := rewriteToCNFAndReplan(stmt, getPlan)
if primitive != nil {
return primitive, nil
}
}
return plan.Primitive(), nil
}
}

func newBuildSelectPlan(sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars, vschema ContextVSchema) (engine.Primitive, error) {
func newBuildSelectPlan(sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars, vschema ContextVSchema) (logicalPlan, error) {

directives := sqlparser.ExtractCommentDirectives(sel.Comments)
if len(directives) > 0 {
Expand Down Expand Up @@ -100,7 +117,8 @@ func newBuildSelectPlan(sel *sqlparser.Select, reservedVars *sqlparser.ReservedV
if err := plan.WireupGen4(semTable); err != nil {
return nil, err
}
return plan.Primitive(), nil

return plan, nil
}

func optimizeQuery(opTree abstract.Operator, reservedVars *sqlparser.ReservedVars, semTable *semantics.SemTable, vschema ContextVSchema) (joinTree, error) {
Expand Down
19 changes: 0 additions & 19 deletions go/vt/vtgate/planbuilder/testdata/filter_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1959,25 +1959,6 @@ Gen4 plan same as above
}
}

# able to isolate table_schema value even when hidden inside of ORs
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and other_column = 42) OR (TABLE_SCHEMA = 'ks' and foobar = 'value')"
{
"QueryType": "SELECT",
"Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and other_column = 42) OR (TABLE_SCHEMA = 'ks' and foobar = 'value')",
"Instructions": {
"OperatorType": "Route",
"Variant": "SelectDBA",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1",
"Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and (other_column = 42 or TABLE_SCHEMA = 'ks') and (other_column = 42 or foobar = 'value')",
"SysTableTableSchema": "[VARBINARY(\"ks\")]",
"Table": "INFORMATION_SCHEMA.`TABLES`"
}
}

# solving LIKE query with a CFC prefix vindex
"select c2 from cfc_vindex_col where c1 like 'A%'"
{
Expand Down
26 changes: 23 additions & 3 deletions go/vt/vtgate/planbuilder/testdata/systemtables_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ Gen4 plan same as above
},
"FieldQuery": "select KCU.DELETE_RULE, S.UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC, INFORMATION_SCHEMA.K as S where 1 != 1",
"Query": "select KCU.DELETE_RULE, S.UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC, INFORMATION_SCHEMA.K as S where S.TABLE_SCHEMA = :__vtschemaname and S.TABLE_NAME = :S_TABLE_NAME and KCU.TABLE_SCHEMA = :__vtschemaname and KCU.TABLE_NAME = :KCU_TABLE_NAME and KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc",
"SysTableTableName": "[S_TABLE_NAME:VARBINARY(\"sc\"), KCU_TABLE_NAME:VARBINARY(\"data_type_table\")]",
"SysTableTableName": "[KCU_TABLE_NAME:VARBINARY(\"data_type_table\"), S_TABLE_NAME:VARBINARY(\"sc\")]",
"SysTableTableSchema": "[VARBINARY(\"test\"), VARBINARY(\"test\")]",
"Table": "INFORMATION_SCHEMA.K, INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS"
}
Expand Down Expand Up @@ -345,7 +345,7 @@ Gen4 plan same as above
},
"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, information_schema.key_column_usage as fk where 1 != 1",
"Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc, information_schema.key_column_usage as fk where rc.constraint_schema = database() and rc.table_name = :rc_table_name and fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :fk_table_name and rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name",
"SysTableTableName": "[rc_table_name:VARBINARY(\":vtg1\"), fk_table_name:VARBINARY(\":vtg1\")]",
"SysTableTableName": "[fk_table_name:VARBINARY(\":vtg1\"), rc_table_name:VARBINARY(\":vtg1\")]",
"Table": "information_schema.key_column_usage, information_schema.referential_constraints"
}
}
Expand Down Expand Up @@ -422,7 +422,7 @@ Gen4 plan same as above
},
"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, information_schema.key_column_usage as fk where 1 != 1",
"Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc, information_schema.key_column_usage as fk where rc.constraint_schema = :__vtschemaname and rc.table_name = :rc_table_name and fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname and fk.table_name = :fk_table_name and rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name",
"SysTableTableName": "[rc_table_name:VARBINARY(\"table_name\"), fk_table_name:VARBINARY(\"table_name\")]",
"SysTableTableName": "[fk_table_name:VARBINARY(\"table_name\"), rc_table_name:VARBINARY(\"table_name\")]",
"SysTableTableSchema": "[VARBINARY(\"table_schema\"), VARBINARY(\"table_schema\")]",
"Table": "information_schema.key_column_usage, information_schema.referential_constraints"
}
Expand Down Expand Up @@ -738,3 +738,23 @@ Gen4 plan same as above
}
}
Gen4 plan same as above

# able to isolate table_schema value even when hidden inside of ORs
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and other_column = 42) OR (TABLE_SCHEMA = 'ks' and foobar = 'value')"
{
"QueryType": "SELECT",
"Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_SCHEMA = 'ks' and other_column = 42) OR (TABLE_SCHEMA = 'ks' and foobar = 'value')",
"Instructions": {
"OperatorType": "Route",
"Variant": "SelectDBA",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1",
"Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and (other_column = 42 or TABLE_SCHEMA = 'ks') and (other_column = 42 or foobar = 'value')",
"SysTableTableSchema": "[VARBINARY(\"ks\")]",
"Table": "INFORMATION_SCHEMA.`TABLES`"
}
}
Gen4 plan same as above

0 comments on commit 38f506b

Please sign in to comment.