vitess.io/vitess@v0.16.2/go/vt/vtgate/engine/primitive.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package engine
    18  
    19  import (
    20  	"context"
    21  
    22  	"vitess.io/vitess/go/mysql/collations"
    23  	"vitess.io/vitess/go/sqltypes"
    24  	"vitess.io/vitess/go/vt/key"
    25  	"vitess.io/vitess/go/vt/sqlparser"
    26  	"vitess.io/vitess/go/vt/srvtopo"
    27  	"vitess.io/vitess/go/vt/vtgate/vindexes"
    28  
    29  	binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
    30  	querypb "vitess.io/vitess/go/vt/proto/query"
    31  	vtgatepb "vitess.io/vitess/go/vt/proto/vtgate"
    32  )
    33  
    34  const (
    35  	// SeqVarName is a reserved bind var name for sequence values.
    36  	SeqVarName = "__seq"
    37  	// ListVarName is a reserved bind var name for list vars.
    38  	// This is used for sending different IN clause values
    39  	// to different shards.
    40  	ListVarName = "__vals"
    41  )
    42  
    43  type (
    44  	// VCursor defines the interface the engine will use
    45  	// to execute routes.
    46  	VCursor interface {
    47  		GetKeyspace() string
    48  		// MaxMemoryRows returns the maxMemoryRows flag value.
    49  		MaxMemoryRows() int
    50  
    51  		// ExceedsMaxMemoryRows returns a boolean indicating whether
    52  		// the maxMemoryRows value has been exceeded. Returns false
    53  		// if the max memory rows override directive is set to true
    54  		ExceedsMaxMemoryRows(numRows int) bool
    55  
    56  		// V3 functions.
    57  		Execute(ctx context.Context, method string, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error)
    58  		AutocommitApproval() bool
    59  
    60  		// Execute the given primitive
    61  		ExecutePrimitive(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error)
    62  		// Execute the given primitive in a new autocommit session
    63  		ExecutePrimitiveStandalone(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error)
    64  
    65  		// Execute the given primitive
    66  		StreamExecutePrimitive(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error
    67  		// Execute the given primitive in a new autocommit session
    68  		StreamExecutePrimitiveStandalone(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(result *sqltypes.Result) error) error
    69  
    70  		// Shard-level functions.
    71  		ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error)
    72  		ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error)
    73  		StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error
    74  
    75  		// Keyspace ID level functions.
    76  		ExecuteKeyspaceID(ctx context.Context, keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError, autocommit bool) (*sqltypes.Result, error)
    77  
    78  		// Resolver methods, from key.Destination to srvtopo.ResolvedShard.
    79  		// Will replace all of the Topo functions.
    80  		ResolveDestinations(ctx context.Context, keyspace string, ids []*querypb.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error)
    81  
    82  		ResolveDestinationsMultiCol(ctx context.Context, keyspace string, ids [][]sqltypes.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][][]sqltypes.Value, error)
    83  
    84  		ExecuteVSchema(ctx context.Context, keyspace string, vschemaDDL *sqlparser.AlterVschema) error
    85  
    86  		Session() SessionActions
    87  
    88  		ConnCollation() collations.ID
    89  
    90  		ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShard, query *querypb.BoundQuery, lockFuncType sqlparser.LockingFuncType) (*sqltypes.Result, error)
    91  
    92  		InTransactionAndIsDML() bool
    93  
    94  		LookupRowLockShardSession() vtgatepb.CommitOrder
    95  
    96  		FindRoutedTable(tablename sqlparser.TableName) (*vindexes.Table, error)
    97  
    98  		// GetDBDDLPlugin gets the configured plugin for DROP/CREATE DATABASE
    99  		GetDBDDLPluginName() string
   100  
   101  		// KeyspaceAvailable returns true when a keyspace is visible from vtgate
   102  		KeyspaceAvailable(ks string) bool
   103  
   104  		MessageStream(ctx context.Context, rss []*srvtopo.ResolvedShard, tableName string, callback func(*sqltypes.Result) error) error
   105  
   106  		VStream(ctx context.Context, rss []*srvtopo.ResolvedShard, filter *binlogdatapb.Filter, gtid string, callback func(evs []*binlogdatapb.VEvent) error) error
   107  
   108  		// ShowExec takes in show command and use executor to execute the query, they are used when topo access is involved.
   109  		ShowExec(ctx context.Context, command sqlparser.ShowCommandType, filter *sqlparser.ShowFilter) (*sqltypes.Result, error)
   110  		// SetExec takes in k,v pair and use executor to set them in topo metadata.
   111  		SetExec(ctx context.Context, name string, value string) error
   112  
   113  		// CanUseSetVar returns true if system_settings can use SET_VAR hint.
   114  		CanUseSetVar() bool
   115  
   116  		// ReleaseLock releases all the held advisory locks.
   117  		ReleaseLock(ctx context.Context) error
   118  	}
   119  
   120  	// SessionActions gives primitives ability to interact with the session state
   121  	SessionActions interface {
   122  		// RecordWarning stores the given warning in the current session
   123  		RecordWarning(warning *querypb.QueryWarning)
   124  
   125  		SetTarget(target string) error
   126  
   127  		SetUDV(key string, value any) error
   128  
   129  		SetSysVar(name string, expr string)
   130  
   131  		// NeedsReservedConn marks this session as needing a dedicated connection to underlying database
   132  		NeedsReservedConn()
   133  
   134  		// InReservedConn provides whether this session is using reserved connection
   135  		InReservedConn() bool
   136  
   137  		// ShardSession returns shard info about open connections
   138  		ShardSession() []*srvtopo.ResolvedShard
   139  
   140  		SetAutocommit(ctx context.Context, autocommit bool) error
   141  		SetClientFoundRows(context.Context, bool) error
   142  		SetSkipQueryPlanCache(context.Context, bool) error
   143  		SetSQLSelectLimit(int64) error
   144  		SetTransactionMode(vtgatepb.TransactionMode)
   145  		SetWorkload(querypb.ExecuteOptions_Workload)
   146  		SetPlannerVersion(querypb.ExecuteOptions_PlannerVersion)
   147  		SetConsolidator(querypb.ExecuteOptions_Consolidator)
   148  		SetFoundRows(uint64)
   149  
   150  		SetDDLStrategy(string)
   151  		GetDDLStrategy() string
   152  
   153  		GetSessionUUID() string
   154  
   155  		SetSessionEnableSystemSettings(context.Context, bool) error
   156  		GetSessionEnableSystemSettings() bool
   157  
   158  		GetSystemVariables(func(k string, v string))
   159  		HasSystemVariables() bool
   160  
   161  		// SetReadAfterWriteGTID sets the GTID that the user expects a replica to have caught up with before answering a query
   162  		SetReadAfterWriteGTID(string)
   163  		SetReadAfterWriteTimeout(float64)
   164  		SetSessionTrackGTIDs(bool)
   165  
   166  		// HasCreatedTempTable will mark the session as having created temp tables
   167  		HasCreatedTempTable()
   168  		GetWarnings() []*querypb.QueryWarning
   169  
   170  		// AnyAdvisoryLockTaken returns true of any advisory lock is taken
   171  		AnyAdvisoryLockTaken() bool
   172  		// AddAdvisoryLock adds advisory lock to the session
   173  		AddAdvisoryLock(name string)
   174  		// RemoveAdvisoryLock removes advisory lock from the session
   175  		RemoveAdvisoryLock(name string)
   176  
   177  		// VExplainLogging enables logging of all interactions to the tablets so
   178  		// VEXPLAIN QUERIES/ALL can report what's being done
   179  		VExplainLogging()
   180  
   181  		// GetVExplainLogs retrieves the vttablet interaction logs
   182  		GetVExplainLogs() []ExecuteEntry
   183  
   184  		// SetCommitOrder sets the commit order for the shard session in respect of the type of vindex lookup.
   185  		// This is used to select the right shard session to perform the vindex lookup query.
   186  		SetCommitOrder(co vtgatepb.CommitOrder)
   187  
   188  		// GetQueryTimeout gets the query timeout and takes in the query timeout from comments
   189  		GetQueryTimeout(queryTimeoutFromComment int) int
   190  
   191  		// SetQueryTimeout sets the query timeout
   192  		SetQueryTimeout(queryTimeout int64)
   193  
   194  		// InTransaction returns true if the session has already opened transaction or
   195  		// will start a transaction on the query execution.
   196  		InTransaction() bool
   197  	}
   198  
   199  	// Match is used to check if a Primitive matches
   200  	Match func(node Primitive) bool
   201  
   202  	// Primitive is the building block of the engine execution plan. They form a tree structure, where the leaves typically
   203  	// issue queries to one or more vttablet.
   204  	// During execution, the Primitive's pass Result objects up the tree structure, until reaching the root,
   205  	// and its result is passed to the client.
   206  	Primitive interface {
   207  		RouteType() string
   208  		GetKeyspaceName() string
   209  		GetTableName() string
   210  		GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error)
   211  		NeedsTransaction() bool
   212  
   213  		TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error)
   214  		TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error
   215  
   216  		// Inputs is a slice containing the inputs to this Primitive
   217  		Inputs() []Primitive
   218  
   219  		// description is the description, sans the inputs, of this Primitive.
   220  		// to get the plan description with all children, use PrimitiveToPlanDescription()
   221  		description() PrimitiveDescription
   222  	}
   223  
   224  	// noInputs default implementation for Primitives that are leaves
   225  	noInputs struct{}
   226  
   227  	// noTxNeeded is a default implementation for Primitives that don't need transaction handling
   228  	noTxNeeded struct{}
   229  
   230  	// txNeeded is a default implementation for Primitives that need transaction handling
   231  	txNeeded struct{}
   232  
   233  	// Gen4Comparer interfaces all Primitive used to compare Gen4 with other planners (V3, MySQL, ...).
   234  	Gen4Comparer interface {
   235  		Primitive
   236  		GetGen4Primitive() Primitive
   237  	}
   238  )
   239  
   240  // Find will return the first Primitive that matches the evaluate function. If no match is found, nil will be returned
   241  func Find(isMatch Match, start Primitive) Primitive {
   242  	if isMatch(start) {
   243  		return start
   244  	}
   245  	for _, input := range start.Inputs() {
   246  		result := Find(isMatch, input)
   247  		if result != nil {
   248  			return result
   249  		}
   250  	}
   251  	return nil
   252  }
   253  
   254  // Exists traverses recursively down the Primitive tree structure, and returns true when Match returns true
   255  func Exists(m Match, p Primitive) bool {
   256  	return Find(m, p) != nil
   257  }
   258  
   259  // Inputs implements no inputs
   260  func (noInputs) Inputs() []Primitive {
   261  	return nil
   262  }
   263  
   264  func (noTxNeeded) NeedsTransaction() bool {
   265  	return false
   266  }
   267  
   268  func (txNeeded) NeedsTransaction() bool {
   269  	return true
   270  }