From 625ea7ddc3e9091f6fc5faf9c48e09b747577e10 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Tue, 26 Mar 2024 11:51:13 +0200 Subject: [PATCH 1/9] boost: draft for boost executor --- go/vt/sqlparser/analyzer.go | 12 +++--- go/vt/sqlparser/normalizer.go | 26 ++++++++++--- go/vt/vtgate/engine/empty_primitive.go | 51 ++++++++++++++++++++++++++ go/vt/vtgate/executor.go | 29 ++++++++++++++- go/vt/vtgate/planbuilder/builder.go | 8 ++++ 5 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 go/vt/vtgate/engine/empty_primitive.go diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 489b27aa32f..f24c2870899 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -63,9 +63,11 @@ const ( StmtCallProc StmtRevert StmtShowMigrationLogs + + StmtBoost ) -//ASTToStatementType returns a StatementType from an AST stmt +// ASTToStatementType returns a StatementType from an AST stmt func ASTToStatementType(stmt Statement) StatementType { switch stmt.(type) { case *Select, *Union: @@ -121,7 +123,7 @@ func ASTToStatementType(stmt Statement) StatementType { } } -//CanNormalize takes Statement and returns if the statement can be normalized. +// CanNormalize takes Statement and returns if the statement can be normalized. func CanNormalize(stmt Statement) bool { switch stmt.(type) { case *Select, *Union, *Insert, *Update, *Delete, *Set, *CallProc, *Stream: // TODO: we could merge this logic into ASTrewriter @@ -140,7 +142,7 @@ func CachePlan(stmt Statement) bool { return false } -//MustRewriteAST takes Statement and returns true if RewriteAST must run on it for correct execution irrespective of user flags. +// MustRewriteAST takes Statement and returns true if RewriteAST must run on it for correct execution irrespective of user flags. func MustRewriteAST(stmt Statement) bool { switch node := stmt.(type) { case *Set: @@ -301,7 +303,7 @@ func IsDML(sql string) bool { return false } -//IsDMLStatement returns true if the query is an INSERT, UPDATE or DELETE statement. +// IsDMLStatement returns true if the query is an INSERT, UPDATE or DELETE statement. func IsDMLStatement(stmt Statement) bool { switch stmt.(type) { case *Insert, *Update, *Delete: @@ -490,7 +492,7 @@ func NewPlanValue(node Expr) (sqltypes.PlanValue, error) { return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "expression is too complex '%v'", String(node)) } -//IsLockingFunc returns true for all functions that are used to work with mysql advisory locks +// IsLockingFunc returns true for all functions that are used to work with mysql advisory locks func IsLockingFunc(node Expr) bool { switch p := node.(type) { case *FuncExpr: diff --git a/go/vt/sqlparser/normalizer.go b/go/vt/sqlparser/normalizer.go index f76d7363602..ad047ca7e56 100644 --- a/go/vt/sqlparser/normalizer.go +++ b/go/vt/sqlparser/normalizer.go @@ -39,10 +39,12 @@ func Normalize(stmt Statement, reserved *ReservedVars, bindVars map[string]*quer } type normalizer struct { - bindVars map[string]*querypb.BindVariable - reserved *ReservedVars - vals map[string]string - err error + bindVars map[string]*querypb.BindVariable + reserved *ReservedVars + vals map[string]string + columns map[string]string + currentColumn string + err error } func newNormalizer(reserved *ReservedVars, bindVars map[string]*querypb.BindVariable) *normalizer { @@ -50,6 +52,7 @@ func newNormalizer(reserved *ReservedVars, bindVars map[string]*querypb.BindVari bindVars: bindVars, reserved: reserved, vals: make(map[string]string), + columns: make(map[string]string), } } @@ -86,7 +89,10 @@ func (nz *normalizer) WalkSelect(cursor *Cursor) bool { nz.convertLiteralDedup(node, cursor) case *ComparisonExpr: nz.convertComparison(node) - case *ColName, TableName: + case *ColName: + nz.currentColumn = node.Name.String() + return false + case *TableName: // Common node types that never contain Literals or ListArgs but create a lot of object // allocations. return false @@ -134,6 +140,11 @@ func (nz *normalizer) convertLiteralDedup(node *Literal, cursor *Cursor) { nz.bindVars[bvname] = bval } + // Store the column to bind var mapping. + if nz.currentColumn != "" && !ok { + nz.columns[nz.currentColumn] = bvname + } + // Modify the AST node to a bindvar. cursor.Replace(NewArgument(bvname)) } @@ -148,6 +159,11 @@ func (nz *normalizer) convertLiteral(node *Literal, cursor *Cursor) { bvname := nz.reserved.nextUnusedVar() nz.bindVars[bvname] = bval + // Store the column to bind var mapping. + if nz.currentColumn != "" { + nz.columns[nz.currentColumn] = bvname + } + cursor.Replace(NewArgument(bvname)) } diff --git a/go/vt/vtgate/engine/empty_primitive.go b/go/vt/vtgate/engine/empty_primitive.go new file mode 100644 index 00000000000..58385369365 --- /dev/null +++ b/go/vt/vtgate/engine/empty_primitive.go @@ -0,0 +1,51 @@ +package engine + +import ( + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/proto/query" +) + +// EmptyPrimitive represents a no-operation primitive, +// fulfilling the Primitive interface without performing any actions. +type EmptyPrimitive struct { + noInputs + noTxNeeded +} + +func (ep *EmptyPrimitive) Execute(vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool) (*sqltypes.Result, error) { + return &sqltypes.Result{}, nil +} + +func (ep *EmptyPrimitive) StreamExecute(vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + return callback(&sqltypes.Result{}) +} + +func (ep *EmptyPrimitive) GetFields(vcursor VCursor, bindVars map[string]*query.BindVariable) (*sqltypes.Result, error) { + return &sqltypes.Result{}, nil +} + +func (ep *EmptyPrimitive) RouteType() string { + return "Empty" +} + +func (ep *EmptyPrimitive) GetKeyspaceName() string { + return "" +} + +func (ep *EmptyPrimitive) GetTableName() string { + return "" +} + +func (ep *EmptyPrimitive) Inputs() []Primitive { + return nil +} + +func (ep *EmptyPrimitive) NeedsTransaction() bool { + return false +} + +func (ep *EmptyPrimitive) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "Empty", + } +} diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index f458223eb86..5b21e4cfc91 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -398,7 +398,7 @@ func (e *Executor) handleCommit(ctx context.Context, safeSession *SafeSession, l return &sqltypes.Result{}, err } -//Commit commits the existing transactions +// Commit commits the existing transactions func (e *Executor) Commit(ctx context.Context, safeSession *SafeSession) error { return e.txConn.Commit(ctx, safeSession) } @@ -1046,6 +1046,8 @@ func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession switch plan.Type { case sqlparser.StmtBegin, sqlparser.StmtCommit, sqlparser.StmtRollback: return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "OLAP does not supported statement type: %s", plan.Type) + case sqlparser.StmtBoost: + return e.handleBoost(ctx, safeSession, plan, bindVars, callback) } err = e.addNeededBindVars(plan.BindVarNeeds, bindVars, safeSession) @@ -1224,6 +1226,23 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. return plan.(*engine.Plan), nil } + isBoosted := true + + if isBoosted { + plan, err := planbuilder.BuildBoost(query, statement) + if err != nil { + return nil, err + } + + plan.Warnings = vcursor.warnings + vcursor.warnings = nil + + if !skipQueryPlanCache && !sqlparser.SkipQueryPlanCacheDirective(statement) && sqlparser.CachePlan(statement) { + e.plans.Set(planKey, plan) + } + return plan, nil + } + plan, err := planbuilder.BuildFromStmt(query, statement, reservedVars, vcursor, bindVarNeeds, *enableOnlineDDL, *enableDirectDDL) if err != nil { return nil, err @@ -1511,3 +1530,11 @@ func (e *Executor) startVStream(ctx context.Context, rss []*srvtopo.ResolvedShar vs.stream(ctx) return nil } + +// Instead of mysql query, query Redis with custom-built key +func (e *Executor) handleBoost(ctx context.Context, session *SafeSession, plan *engine.Plan, vars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { + + panic("not implemented") + return nil + +} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index c28bf069a1b..24009753429 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -120,6 +120,14 @@ func BuildFromStmt(query string, stmt sqlparser.Statement, reservedVars *sqlpars return plan, nil } +func BuildBoost(query string, stmt sqlparser.Statement) (*engine.Plan, error) { + return &engine.Plan{ + Type: sqlparser.StmtBoost, + Instructions: &engine.EmptyPrimitive{}, + BindVarNeeds: &sqlparser.BindVarNeeds{}, + }, nil +} + func getConfiguredPlanner(vschema ContextVSchema) (selectPlanner, error) { switch vschema.Planner() { case Gen4, Gen4Left2Right, Gen4GreedyOnly: From 10087a05b58e04260981e8d7622cbd70816bed00 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:15:41 +0200 Subject: [PATCH 2/9] boost: move boost config to plan itself --- go/vt/sqlparser/ast_rewriting.go | 15 +++++--- go/vt/sqlparser/normalizer.go | 9 ++--- go/vt/sqlparser/redact_query.go | 2 +- go/vt/sqlparser/utils.go | 2 +- go/vt/vtgate/boost/boost.go | 8 +++++ go/vt/vtgate/engine/primitive.go | 14 ++++---- go/vt/vtgate/executor.go | 53 +++++++++++++++++++---------- go/vt/vtgate/planbuilder/builder.go | 30 ++++++++-------- 8 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 go/vt/vtgate/boost/boost.go diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index 978e14a5d64..978aa83715c 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -18,6 +18,7 @@ package sqlparser import ( "strconv" + "vitess.io/vitess/go/vt/vtgate/boost" querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" @@ -31,7 +32,8 @@ import ( // RewriteASTResult contains the rewritten ast and meta information about it type RewriteASTResult struct { *BindVarNeeds - AST Statement // The rewritten AST + AST Statement // The rewritten AST + Columns boost.Columns } // ReservedVars keeps track of the bind variable names that have already been used @@ -145,17 +147,21 @@ func NewReservedVars(prefix string, known BindVars) *ReservedVars { // PrepareAST will normalize the query func PrepareAST(in Statement, reservedVars *ReservedVars, bindVars map[string]*querypb.BindVariable, parameterize bool, keyspace string) (*RewriteASTResult, error) { + var boostColumns boost.Columns + var err error + if parameterize { - err := Normalize(in, reservedVars, bindVars) + boostColumns, err = Normalize(in, reservedVars, bindVars) if err != nil { return nil, err } } - return RewriteAST(in, keyspace) + + return RewriteAST(in, keyspace, boostColumns) } // RewriteAST rewrites the whole AST, replacing function calls and adding column aliases to queries -func RewriteAST(in Statement, keyspace string) (*RewriteASTResult, error) { +func RewriteAST(in Statement, keyspace string, columns map[string]string) (*RewriteASTResult, error) { er := newExpressionRewriter(keyspace) er.shouldRewriteDatabaseFunc = shouldRewriteDatabaseFunc(in) setRewriter := &setNormalizer{} @@ -172,6 +178,7 @@ func RewriteAST(in Statement, keyspace string) (*RewriteASTResult, error) { r := &RewriteASTResult{ AST: out, BindVarNeeds: er.bindVars, + Columns: columns, } return r, nil } diff --git a/go/vt/sqlparser/normalizer.go b/go/vt/sqlparser/normalizer.go index ad047ca7e56..bfc8af05a6a 100644 --- a/go/vt/sqlparser/normalizer.go +++ b/go/vt/sqlparser/normalizer.go @@ -18,8 +18,8 @@ package sqlparser import ( "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/vtgate/boost" ) // BindVars is a set of reserved bind variables from a SQL statement @@ -32,17 +32,18 @@ type BindVars map[string]struct{} // Within Select constructs, bind vars are deduped. This allows // us to identify vindex equality. Otherwise, every value is // treated as distinct. -func Normalize(stmt Statement, reserved *ReservedVars, bindVars map[string]*querypb.BindVariable) error { + +func Normalize(stmt Statement, reserved *ReservedVars, bindVars map[string]*querypb.BindVariable) (boost.Columns, error) { nz := newNormalizer(reserved, bindVars) _ = Rewrite(stmt, nz.WalkStatement, nil) - return nz.err + return nz.columns, nz.err } type normalizer struct { bindVars map[string]*querypb.BindVariable reserved *ReservedVars vals map[string]string - columns map[string]string + columns boost.Columns currentColumn string err error } diff --git a/go/vt/sqlparser/redact_query.go b/go/vt/sqlparser/redact_query.go index 194ad1ca64d..6362f1cd32e 100644 --- a/go/vt/sqlparser/redact_query.go +++ b/go/vt/sqlparser/redact_query.go @@ -28,7 +28,7 @@ func RedactSQLQuery(sql string) (string, error) { return "", err } - err = Normalize(stmt, NewReservedVars("redacted", reservedVars), bv) + _, err = Normalize(stmt, NewReservedVars("redacted", reservedVars), bv) if err != nil { return "", err } diff --git a/go/vt/sqlparser/utils.go b/go/vt/sqlparser/utils.go index a9ec689aa2e..e2bee2cb959 100644 --- a/go/vt/sqlparser/utils.go +++ b/go/vt/sqlparser/utils.go @@ -40,7 +40,7 @@ func QueryMatchesTemplates(query string, queryTemplates []string) (match bool, e if err != nil { return "", err } - err = Normalize(stmt, NewReservedVars("", reservedVars), bv) + _, err = Normalize(stmt, NewReservedVars("", reservedVars), bv) if err != nil { return "", err } diff --git a/go/vt/vtgate/boost/boost.go b/go/vt/vtgate/boost/boost.go new file mode 100644 index 00000000000..51fcd510503 --- /dev/null +++ b/go/vt/vtgate/boost/boost.go @@ -0,0 +1,8 @@ +package boost + +type Columns map[string]string + +type PlanConfig struct { + IsBoosted bool + BoostColumns Columns +} diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index ab08f72951e..22e75f476d4 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -21,6 +21,7 @@ import ( "encoding/json" "sync/atomic" "time" + "vitess.io/vitess/go/vt/vtgate/boost" "golang.org/x/sync/errgroup" @@ -161,11 +162,12 @@ type ( // each node does its part by combining the results of the // sub-nodes. Plan struct { - Type sqlparser.StatementType // The type of query we have - Original string // Original is the original query. - Instructions Primitive // Instructions contains the instructions needed to fulfil the query. - BindVarNeeds *sqlparser.BindVarNeeds // Stores BindVars needed to be provided as part of expression rewriting - Warnings []*querypb.QueryWarning // Warnings that need to be yielded every time this query runs + Type sqlparser.StatementType // The type of query we have + Original string // Original is the original query. + Instructions Primitive // Instructions contains the instructions needed to fulfil the query. + BindVarNeeds *sqlparser.BindVarNeeds // Stores BindVars needed to be provided as part of expression rewriting + Warnings []*querypb.QueryWarning // Warnings that need to be yielded every time this query runs + BoostPlanConfig *boost.PlanConfig ExecCount uint64 // Count of times this plan was executed ExecTime uint64 // Total execution time @@ -249,7 +251,7 @@ func Exists(m Match, p Primitive) bool { return Find(m, p) != nil } -//MarshalJSON serializes the plan into a JSON representation. +// MarshalJSON serializes the plan into a JSON representation. func (p *Plan) MarshalJSON() ([]byte, error) { var instructions *PrimitiveDescription if p.Instructions != nil { diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 5b21e4cfc91..ce0db297c1a 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -28,6 +28,7 @@ import ( "strings" "sync" "time" + "vitess.io/vitess/go/vt/vtgate/boost" "vitess.io/vitess/go/acl" "vitess.io/vitess/go/cache" @@ -1203,6 +1204,7 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. } ignoreMaxMemoryRows := sqlparser.IgnoreMaxMaxMemoryRowsDirective(stmt) vcursor.SetIgnoreMaxMemoryRows(ignoreMaxMemoryRows) + var boostPlanConfig *boost.PlanConfig // Normalize if possible and retry. if (e.normalize && sqlparser.CanNormalize(stmt)) || sqlparser.MustRewriteAST(stmt) { @@ -1214,6 +1216,7 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. statement = result.AST bindVarNeeds = result.BindVarNeeds query = sqlparser.String(statement) + boostPlanConfig = configForBoost(result.Columns, "x") } if logStats != nil { @@ -1226,24 +1229,7 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. return plan.(*engine.Plan), nil } - isBoosted := true - - if isBoosted { - plan, err := planbuilder.BuildBoost(query, statement) - if err != nil { - return nil, err - } - - plan.Warnings = vcursor.warnings - vcursor.warnings = nil - - if !skipQueryPlanCache && !sqlparser.SkipQueryPlanCacheDirective(statement) && sqlparser.CachePlan(statement) { - e.plans.Set(planKey, plan) - } - return plan, nil - } - - plan, err := planbuilder.BuildFromStmt(query, statement, reservedVars, vcursor, bindVarNeeds, *enableOnlineDDL, *enableDirectDDL) + plan, err := planbuilder.BuildFromStmt(query, statement, reservedVars, vcursor, bindVarNeeds, *enableOnlineDDL, *enableDirectDDL, boostPlanConfig) if err != nil { return nil, err } @@ -1254,9 +1240,40 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. if !skipQueryPlanCache && !sqlparser.SkipQueryPlanCacheDirective(statement) && sqlparser.CachePlan(statement) { e.plans.Set(planKey, plan) } + return plan, nil } +func configForBoost(columns boost.Columns, table string) *boost.PlanConfig { + configColumns := map[string]string{ + "user_id": "1337", + } + + //todo compare sets for ordering + if !keysMatch(columns, configColumns) { + return &boost.PlanConfig{} + } + + return &boost.PlanConfig{ + IsBoosted: true, + BoostColumns: columns, + } +} + +func keysMatch(map1, map2 map[string]string) bool { + if len(map1) != len(map2) { + return false + } + + for k := range map1 { + if _, exists := map2[k]; !exists { + return false + } + } + + return true +} + // skipQueryPlanCache extracts SkipQueryPlanCache from session func skipQueryPlanCache(safeSession *SafeSession) bool { if safeSession == nil || safeSession.Options == nil { diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 24009753429..3857c7ea63c 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -19,6 +19,7 @@ package planbuilder import ( "errors" "sort" + "vitess.io/vitess/go/vt/vtgate/boost" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -93,40 +94,41 @@ func TestBuilder(query string, vschema ContextVSchema) (*engine.Plan, error) { if err != nil { return nil, err } - result, err := sqlparser.RewriteAST(stmt, "") + result, err := sqlparser.RewriteAST(stmt, "", make(map[string]string)) if err != nil { return nil, err } reservedVars := sqlparser.NewReservedVars("vtg", reserved) - return BuildFromStmt(query, result.AST, reservedVars, vschema, result.BindVarNeeds, true, true) + return BuildFromStmt(query, result.AST, reservedVars, vschema, result.BindVarNeeds, true, true, nil) } // ErrPlanNotSupported is an error for plan building not supported var ErrPlanNotSupported = errors.New("plan building not supported") // BuildFromStmt builds a plan based on the AST provided. -func BuildFromStmt(query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema ContextVSchema, bindVarNeeds *sqlparser.BindVarNeeds, enableOnlineDDL, enableDirectDDL bool) (*engine.Plan, error) { +func BuildFromStmt(query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema ContextVSchema, bindVarNeeds *sqlparser.BindVarNeeds, enableOnlineDDL, enableDirectDDL bool, config *boost.PlanConfig) (*engine.Plan, error) { instruction, err := createInstructionFor(query, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) if err != nil { return nil, err } plan := &engine.Plan{ - Type: sqlparser.ASTToStatementType(stmt), - Original: query, - Instructions: instruction, - BindVarNeeds: bindVarNeeds, + Type: sqlparser.ASTToStatementType(stmt), + Original: query, + Instructions: instruction, + BindVarNeeds: bindVarNeeds, + BoostPlanConfig: config, } return plan, nil } -func BuildBoost(query string, stmt sqlparser.Statement) (*engine.Plan, error) { - return &engine.Plan{ - Type: sqlparser.StmtBoost, - Instructions: &engine.EmptyPrimitive{}, - BindVarNeeds: &sqlparser.BindVarNeeds{}, - }, nil -} +//func BuildBoost(query string, stmt sqlparser.Statement) (*engine.Plan, error) { +// return &engine.Plan{ +// Type: sqlparser.StmtBoost, +// Instructions: &engine.EmptyPrimitive{}, +// BindVarNeeds: &sqlparser.BindVarNeeds{}, +// }, nil +//} func getConfiguredPlanner(vschema ContextVSchema) (selectPlanner, error) { switch vschema.Planner() { From 52f399e49a6c313f9b4f67c3a1d2d087e53abc90 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:19:30 +0200 Subject: [PATCH 3/9] boost: remove empty primitive --- go/vt/vtgate/engine/empty_primitive.go | 51 -------------------------- 1 file changed, 51 deletions(-) delete mode 100644 go/vt/vtgate/engine/empty_primitive.go diff --git a/go/vt/vtgate/engine/empty_primitive.go b/go/vt/vtgate/engine/empty_primitive.go deleted file mode 100644 index 58385369365..00000000000 --- a/go/vt/vtgate/engine/empty_primitive.go +++ /dev/null @@ -1,51 +0,0 @@ -package engine - -import ( - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/proto/query" -) - -// EmptyPrimitive represents a no-operation primitive, -// fulfilling the Primitive interface without performing any actions. -type EmptyPrimitive struct { - noInputs - noTxNeeded -} - -func (ep *EmptyPrimitive) Execute(vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool) (*sqltypes.Result, error) { - return &sqltypes.Result{}, nil -} - -func (ep *EmptyPrimitive) StreamExecute(vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - return callback(&sqltypes.Result{}) -} - -func (ep *EmptyPrimitive) GetFields(vcursor VCursor, bindVars map[string]*query.BindVariable) (*sqltypes.Result, error) { - return &sqltypes.Result{}, nil -} - -func (ep *EmptyPrimitive) RouteType() string { - return "Empty" -} - -func (ep *EmptyPrimitive) GetKeyspaceName() string { - return "" -} - -func (ep *EmptyPrimitive) GetTableName() string { - return "" -} - -func (ep *EmptyPrimitive) Inputs() []Primitive { - return nil -} - -func (ep *EmptyPrimitive) NeedsTransaction() bool { - return false -} - -func (ep *EmptyPrimitive) description() PrimitiveDescription { - return PrimitiveDescription{ - OperatorType: "Empty", - } -} From 1c2152760771e0bdaff844dc59a180cf421e82a8 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:20:31 +0200 Subject: [PATCH 4/9] boost: comment old approach --- Makefile | 2 +- go/vt/vtgate/executor.go | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 91120cfa11b..fd32c914e59 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ export CGO_CFLAGS := -O1 embed_config: cd go/vt/mysqlctl go run github.com/GeertJohan/go.rice/rice embed-go - go build . + go build -gcflags="-l=4" . # build the vitess binaries with dynamic dependency on libc build-dyn: diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index ce0db297c1a..c92f92e7676 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1047,8 +1047,8 @@ func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession switch plan.Type { case sqlparser.StmtBegin, sqlparser.StmtCommit, sqlparser.StmtRollback: return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "OLAP does not supported statement type: %s", plan.Type) - case sqlparser.StmtBoost: - return e.handleBoost(ctx, safeSession, plan, bindVars, callback) + //case sqlparser.StmtBoost: + // return e.handleBoost(ctx, safeSession, plan, bindVars, callback) } err = e.addNeededBindVars(plan.BindVarNeeds, bindVars, safeSession) @@ -1548,10 +1548,11 @@ func (e *Executor) startVStream(ctx context.Context, rss []*srvtopo.ResolvedShar return nil } -// Instead of mysql query, query Redis with custom-built key -func (e *Executor) handleBoost(ctx context.Context, session *SafeSession, plan *engine.Plan, vars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { - - panic("not implemented") - return nil - -} +// +//// Instead of mysql query, query Redis with custom-built key +//func (e *Executor) handleBoost(ctx context.Context, session *SafeSession, plan *engine.Plan, vars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { +// +// panic("not implemented") +// return nil +// +//} From 75f3099df499ad3157c3d9a8793836c57fe2d6ca Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:53:34 +0200 Subject: [PATCH 5/9] boost: cleanup --- go/vt/sqlparser/analyzer.go | 2 -- go/vt/vtgate/executor.go | 11 ----------- go/vt/vtgate/planbuilder/builder.go | 8 -------- 3 files changed, 21 deletions(-) diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index f24c2870899..e86006a9893 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -63,8 +63,6 @@ const ( StmtCallProc StmtRevert StmtShowMigrationLogs - - StmtBoost ) // ASTToStatementType returns a StatementType from an AST stmt diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index c92f92e7676..d061a5d6932 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1047,8 +1047,6 @@ func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession switch plan.Type { case sqlparser.StmtBegin, sqlparser.StmtCommit, sqlparser.StmtRollback: return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "OLAP does not supported statement type: %s", plan.Type) - //case sqlparser.StmtBoost: - // return e.handleBoost(ctx, safeSession, plan, bindVars, callback) } err = e.addNeededBindVars(plan.BindVarNeeds, bindVars, safeSession) @@ -1547,12 +1545,3 @@ func (e *Executor) startVStream(ctx context.Context, rss []*srvtopo.ResolvedShar vs.stream(ctx) return nil } - -// -//// Instead of mysql query, query Redis with custom-built key -//func (e *Executor) handleBoost(ctx context.Context, session *SafeSession, plan *engine.Plan, vars map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { -// -// panic("not implemented") -// return nil -// -//} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 3857c7ea63c..5478e4fbc38 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -122,14 +122,6 @@ func BuildFromStmt(query string, stmt sqlparser.Statement, reservedVars *sqlpars return plan, nil } -//func BuildBoost(query string, stmt sqlparser.Statement) (*engine.Plan, error) { -// return &engine.Plan{ -// Type: sqlparser.StmtBoost, -// Instructions: &engine.EmptyPrimitive{}, -// BindVarNeeds: &sqlparser.BindVarNeeds{}, -// }, nil -//} - func getConfiguredPlanner(vschema ContextVSchema) (selectPlanner, error) { switch vschema.Planner() { case Gen4, Gen4Left2Right, Gen4GreedyOnly: From fa63dac961224ab287338f3322d44d8e040d1766 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:54:37 +0200 Subject: [PATCH 6/9] boost: cleanup --- go/vt/vtgate/executor.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index d061a5d6932..0b5bc069483 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1214,7 +1214,7 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. statement = result.AST bindVarNeeds = result.BindVarNeeds query = sqlparser.String(statement) - boostPlanConfig = configForBoost(result.Columns, "x") + boostPlanConfig = configForBoost(result.Columns, "") } if logStats != nil { @@ -1242,6 +1242,7 @@ func (e *Executor) getPlan(vcursor *vcursorImpl, sql string, comments sqlparser. return plan, nil } +// TODO func configForBoost(columns boost.Columns, table string) *boost.PlanConfig { configColumns := map[string]string{ "user_id": "1337", From 4815333ea06c61cbf3cb2ac547d8b4156f17b7ae Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:57:31 +0200 Subject: [PATCH 7/9] boost: comments --- go/vt/vtgate/plan_execute.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/plan_execute.go b/go/vt/vtgate/plan_execute.go index 3865ffabad3..e4a93375b56 100644 --- a/go/vt/vtgate/plan_execute.go +++ b/go/vt/vtgate/plan_execute.go @@ -120,7 +120,13 @@ func (e *Executor) newExecute(ctx context.Context, safeSession *SafeSession, sql e.executePlan(ctx, plan, vcursor, bindVars, execStart)) } - return e.executePlan(ctx, plan, vcursor, bindVars, execStart)(logStats, safeSession) + // Check if boosted and hit Redis + + statementTypeResult, sqlResult, err := e.executePlan(ctx, plan, vcursor, bindVars, execStart)(logStats, safeSession) + + // Maybe store in Redis here if boosted, but cache miss + + return statementTypeResult, sqlResult, err } func (e *Executor) startTxIfNecessary(ctx context.Context, safeSession *SafeSession) error { From fed89f17f5059fc0061f585b7f482bcb343a2a94 Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 10:58:27 +0200 Subject: [PATCH 8/9] boost: cleanup --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fd32c914e59..91120cfa11b 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ export CGO_CFLAGS := -O1 embed_config: cd go/vt/mysqlctl go run github.com/GeertJohan/go.rice/rice embed-go - go build -gcflags="-l=4" . + go build . # build the vitess binaries with dynamic dependency on libc build-dyn: From 1dded547e2044f5d9b8d84ad97ba48f1a3e5a57c Mon Sep 17 00:00:00 2001 From: Zygimantas Benetis Date: Wed, 27 Mar 2024 11:03:48 +0200 Subject: [PATCH 9/9] boost: comment --- go/vt/vtgate/plan_execute.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/vt/vtgate/plan_execute.go b/go/vt/vtgate/plan_execute.go index e4a93375b56..f19c392809f 100644 --- a/go/vt/vtgate/plan_execute.go +++ b/go/vt/vtgate/plan_execute.go @@ -121,6 +121,7 @@ func (e *Executor) newExecute(ctx context.Context, safeSession *SafeSession, sql } // Check if boosted and hit Redis + // plan.BoostPlanConfig.IsBoosted == true statementTypeResult, sqlResult, err := e.executePlan(ctx, plan, vcursor, bindVars, execStart)(logStats, safeSession)