Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tabletserver: SBR deprecation #5940

Merged
merged 18 commits into from
Mar 20, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

func analyzeSelect(sel *sqlparser.Select, tables map[string]*schema.Table) (plan *Plan, err error) {
plan = &Plan{
PlanID: PlanPassSelect,
PlanID: PlanSelect,
Table: lookupTable(sel.From, tables),
FieldQuery: GenerateFieldQuery(sel),
FullQuery: GenerateLimitQuery(sel),
Expand Down Expand Up @@ -62,21 +62,23 @@ func analyzeSelect(sel *sqlparser.Select, tables map[string]*schema.Table) (plan

func analyzeUpdate(upd *sqlparser.Update, tables map[string]*schema.Table) (plan *Plan, err error) {
plan = &Plan{
PlanID: PlanPassDML,
PlanID: PlanUpdate,
Table: lookupTable(upd.TableExprs, tables),
}

// Store the WHERE clause as string for the hot row protection (txserializer).
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("%v", upd.Where)
plan.WhereClause = buf.ParsedQuery()
if upd.Where != nil {
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("%v", upd.Where)
plan.WhereClause = buf.ParsedQuery()
}

if PassthroughDMLs || upd.Limit != nil {
plan.FullQuery = GenerateFullQuery(upd)
return plan, nil
}

plan.PlanID = PlanDMLLimit
plan.PlanID = PlanUpdateLimit
upd.Limit = execLimit
plan.FullQuery = GenerateFullQuery(upd)
upd.Limit = nil
Expand All @@ -85,20 +87,22 @@ func analyzeUpdate(upd *sqlparser.Update, tables map[string]*schema.Table) (plan

func analyzeDelete(del *sqlparser.Delete, tables map[string]*schema.Table) (plan *Plan, err error) {
plan = &Plan{
PlanID: PlanPassDML,
PlanID: PlanDelete,
Table: lookupTable(del.TableExprs, tables),
}

// Store the WHERE clause as string for the hot row protection (txserializer).
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("%v", del.Where)
plan.WhereClause = buf.ParsedQuery()
if del.Where != nil {
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("%v", del.Where)
plan.WhereClause = buf.ParsedQuery()
}

if PassthroughDMLs || del.Limit != nil {
plan.FullQuery = GenerateFullQuery(del)
return plan, nil
}
plan.PlanID = PlanDMLLimit
plan.PlanID = PlanDeleteLimit
del.Limit = execLimit
plan.FullQuery = GenerateFullQuery(del)
del.Limit = nil
Expand All @@ -107,7 +111,7 @@ func analyzeDelete(del *sqlparser.Delete, tables map[string]*schema.Table) (plan

func analyzeInsert(ins *sqlparser.Insert, tables map[string]*schema.Table) (plan *Plan, err error) {
plan = &Plan{
PlanID: PlanPassDML,
PlanID: PlanInsert,
FullQuery: GenerateFullQuery(ins),
}

Expand Down
124 changes: 31 additions & 93 deletions go/vt/vttablet/tabletserver/planbuilder/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package planbuilder

import (
"encoding/json"
"fmt"

"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/vt/sqlparser"
Expand All @@ -30,11 +29,9 @@ import (
)

var (
// ErrTooComplex indicates given sql query is too complex.
ErrTooComplex = vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "Complex")
execLimit = &sqlparser.Limit{Rowcount: sqlparser.NewValArg([]byte(":#maxLimit"))}
execLimit = &sqlparser.Limit{Rowcount: sqlparser.NewValArg([]byte(":#maxLimit"))}

// PassthroughDMLs will return PlanPassDML for all update or delete statements
// PassthroughDMLs will return plans that pass-through the DMLs without changing them.
PassthroughDMLs = false
)

Expand All @@ -43,60 +40,47 @@ var (
// PlanType indicates a query plan type.
type PlanType int

// The following are PlanType values.
sougou marked this conversation as resolved.
Show resolved Hide resolved
const (
// PlanPassSelect is pass through select statements. This is the
// default plan for select statements.
PlanPassSelect PlanType = iota
// PlanSelectLock is for a select that locks.
PlanSelect PlanType = iota
PlanSelectLock
// PlanNextval is for NEXTVAL.
PlanNextval
// PlanPassDML is pass through update & delete statements. This is
// the default plan for update and delete statements.
// If PassthroughDMLs is true, then it is used for all DML statements
// and is valid in all replication modes.
// Otherwise is only allowed in row based replication mode
PlanPassDML
// PlanDMLLimit is an update or delete with a limit.
PlanDMLLimit
// PlanInsertTopic is for inserting into message topics.
PlanSelectImpossible
PlanInsert
PlanInsertTopic
// PlanInsertMessage is for inserting into message tables.
PlanInsertMessage
// PlanSet is for SET statements.
PlanSet
// PlanDDL is for DDL statements.
PlanUpdate
PlanUpdateLimit
PlanDelete
PlanDeleteLimit
PlanDDL
// PlanSelectStream is used for streaming queries.
PlanSelectStream
// PlanOtherRead is for SHOW, DESCRIBE & EXPLAIN statements.
PlanSet
PlanOtherRead
// PlanOtherAdmin is for REPAIR, OPTIMIZE and TRUNCATE statements.
PlanOtherAdmin
// PlanMessageStream is used for streaming messages.
PlanSelectStream
PlanMessageStream
// PlanSelectImpossible is used for where or having clauses that can never be true.
PlanSelectImpossible
// NumPlans stores the total number of plans
NumPlans
)

// Must exactly match order of plan constants.
var planName = [NumPlans]string{
"PASS_SELECT",
"SELECT_LOCK",
"NEXTVAL",
"PASS_DML",
"DML_LIMIT",
"INSERT_TOPIC",
"INSERT_MESSAGE",
"SET",
"Select",
"SelectLock",
"Nextval",
"SelectImpossible",
"Insert",
"InsertTopic",
"InsertMessage",
"Update",
"UpdateLimit",
"Delete",
"DeleteLimit",
"DDL",
"SELECT_STREAM",
"OTHER_READ",
"OTHER_ADMIN",
"MESSAGE_STREAM",
"SELECT_IMPOSSIBLE",
"Set",
"OtherRead",
"OtherAdmin",
"SelectStream",
"MessageStream",
}

func (pt PlanType) String() string {
Expand All @@ -118,7 +102,7 @@ func PlanByName(s string) (pt PlanType, ok bool) {

// IsSelect returns true if PlanType is about a select query.
func (pt PlanType) IsSelect() bool {
return pt == PlanPassSelect || pt == PlanSelectLock || pt == PlanSelectImpossible
return pt == PlanSelect || pt == PlanSelectLock || pt == PlanSelectImpossible
}

// MarshalJSON returns a json string for PlanType.
Expand All @@ -128,56 +112,10 @@ func (pt PlanType) MarshalJSON() ([]byte, error) {

//_______________________________________________

// ReasonType indicates why a query plan fails to build
type ReasonType int

// Reason codes give a hint about why a certain plan was chosen.
const (
ReasonDefault ReasonType = iota
ReasonTable
ReasonTableNoIndex
ReasonPKChange
ReasonComplexExpr
ReasonUpsertSubquery
ReasonUpsertMultiRow
ReasonReplace
ReasonMultiTable
ReasonTopic
NumReasons
)

// Must exactly match order of reason constants.
var reasonName = [NumReasons]string{
"DEFAULT",
"TABLE",
"TABLE_NOINDEX",
"PK_CHANGE",
"COMPLEX_EXPR",
"UPSERT_SUBQUERY",
"UPSERT_MULTI_ROW",
"REPLACE",
"MULTI_TABLE",
"TOPIC",
}

// String returns a string representation of a ReasonType.
func (rt ReasonType) String() string {
return reasonName[rt]
}

// MarshalJSON returns a json string for ReasonType.
func (rt ReasonType) MarshalJSON() ([]byte, error) {
return ([]byte)(fmt.Sprintf("\"%s\"", rt.String())), nil
}

//_______________________________________________

// Plan is built for selects and DMLs.
// Plan contains the parameters for executing a request.
type Plan struct {
PlanID PlanType
Table *schema.Table
// NewName is the new name of the table. Set for DDLs which create or change the table.
NewName sqlparser.TableIdent

// Permissions stores the permissions for the tables accessed in the query.
Permissions []Permission
Expand Down Expand Up @@ -217,7 +155,7 @@ func Build(statement sqlparser.Statement, tables map[string]*schema.Table) (*Pla
switch stmt := statement.(type) {
case *sqlparser.Union:
plan, err = &Plan{
PlanID: PlanPassSelect,
PlanID: PlanSelect,
FieldQuery: GenerateFieldQuery(stmt),
FullQuery: GenerateLimitQuery(stmt),
}, nil
Expand Down
69 changes: 0 additions & 69 deletions go/vt/vttablet/tabletserver/planbuilder/query_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package planbuilder

import (
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vttablet/tabletserver/schema"
)

// GenerateFullQuery generates the full query from the ast.
Expand Down Expand Up @@ -65,71 +64,3 @@ func GenerateLimitQuery(selStmt sqlparser.SelectStatement) *sqlparser.ParsedQuer
buf.Myprintf("%v", selStmt)
return buf.ParsedQuery()
}

// GenerateInsertOuterQuery generates the outer query for inserts.
func GenerateInsertOuterQuery(ins *sqlparser.Insert) *sqlparser.ParsedQuery {
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("%s %v%sinto %v%v values %a",
ins.Action,
ins.Comments,
ins.Ignore,
ins.Table,
ins.Columns,
":#values",
)
return buf.ParsedQuery()
}

// GenerateUpdateOuterQuery generates the outer query for updates.
// If there is no custom formatting needed, formatter can be nil.
func GenerateUpdateOuterQuery(upd *sqlparser.Update, aliased *sqlparser.AliasedTableExpr, formatter sqlparser.NodeFormatter) *sqlparser.ParsedQuery {
buf := sqlparser.NewTrackedBuffer(formatter)
buf.Myprintf("update %v%v set %v where %a%v", upd.Comments, aliased.RemoveHints(), upd.Exprs, ":#pk", upd.OrderBy)
return buf.ParsedQuery()
}

// GenerateDeleteOuterQuery generates the outer query for deletes.
func GenerateDeleteOuterQuery(del *sqlparser.Delete, aliased *sqlparser.AliasedTableExpr) *sqlparser.ParsedQuery {
buf := sqlparser.NewTrackedBuffer(nil)
buf.Myprintf("delete %vfrom %v where %a%v", del.Comments, aliased.RemoveHints(), ":#pk", del.OrderBy)
return buf.ParsedQuery()
}

// GenerateUpdateSubquery generates the subquery for updates.
func GenerateUpdateSubquery(upd *sqlparser.Update, table *schema.Table, aliased *sqlparser.AliasedTableExpr) *sqlparser.ParsedQuery {
return GenerateSubquery(
table,
aliased,
upd.Where,
upd.OrderBy,
upd.Limit,
)
}

// GenerateDeleteSubquery generates the subquery for deletes.
func GenerateDeleteSubquery(del *sqlparser.Delete, table *schema.Table, aliased *sqlparser.AliasedTableExpr) *sqlparser.ParsedQuery {
return GenerateSubquery(
table,
aliased,
del.Where,
del.OrderBy,
del.Limit,
)
}

// GenerateSubquery generates a subquery based on the input parameters.
func GenerateSubquery(table *schema.Table, tableName *sqlparser.AliasedTableExpr, where *sqlparser.Where, order sqlparser.OrderBy, limit *sqlparser.Limit) *sqlparser.ParsedQuery {
buf := sqlparser.NewTrackedBuffer(nil)
if limit == nil {
limit = execLimit
}
buf.WriteString("select ")
prefix := ""
for _, colnum := range table.PKColumns {
buf.Myprintf("%s%v", prefix, table.Columns[colnum].Name)
prefix = ", "
}
buf.Myprintf(" from %v%v%v%v", tableName, where, order, limit)
buf.Myprintf(sqlparser.ForUpdateStr)
return buf.ParsedQuery()
}
Loading