vitess.io/vitess@v0.16.2/go/vt/vtgate/engine/ddl.go (about) 1 /* 2 Copyright 2020 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/sqltypes" 23 "vitess.io/vitess/go/vt/proto/query" 24 vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" 25 "vitess.io/vitess/go/vt/schema" 26 "vitess.io/vitess/go/vt/sqlparser" 27 "vitess.io/vitess/go/vt/vterrors" 28 "vitess.io/vitess/go/vt/vtgate/vindexes" 29 ) 30 31 var _ Primitive = (*DDL)(nil) 32 33 // DDL represents a DDL statement, either normal or online DDL 34 type DDL struct { 35 Keyspace *vindexes.Keyspace 36 SQL string 37 DDL sqlparser.DDLStatement 38 39 NormalDDL *Send 40 OnlineDDL *OnlineDDL 41 42 DirectDDLEnabled bool 43 OnlineDDLEnabled bool 44 45 CreateTempTable bool 46 47 noTxNeeded 48 49 noInputs 50 } 51 52 func (ddl *DDL) description() PrimitiveDescription { 53 other := map[string]any{ 54 "Query": ddl.SQL, 55 } 56 if ddl.CreateTempTable { 57 other["TempTable"] = true 58 } 59 return PrimitiveDescription{ 60 OperatorType: "DDL", 61 Keyspace: ddl.Keyspace, 62 Other: other, 63 } 64 } 65 66 // RouteType implements the Primitive interface 67 func (ddl *DDL) RouteType() string { 68 return "DDL" 69 } 70 71 // GetKeyspaceName implements the Primitive interface 72 func (ddl *DDL) GetKeyspaceName() string { 73 return ddl.Keyspace.Name 74 } 75 76 // GetTableName implements the Primitive interface 77 func (ddl *DDL) GetTableName() string { 78 return ddl.DDL.GetTable().Name.String() 79 } 80 81 // IsOnlineSchemaDDL returns true if the query is an online schema change DDL 82 func (ddl *DDL) isOnlineSchemaDDL() bool { 83 switch ddl.DDL.GetAction() { 84 case sqlparser.CreateDDLAction, sqlparser.DropDDLAction, sqlparser.AlterDDLAction: 85 return !ddl.OnlineDDL.DDLStrategySetting.Strategy.IsDirect() 86 } 87 return false 88 } 89 90 // TryExecute implements the Primitive interface 91 func (ddl *DDL) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool) (result *sqltypes.Result, err error) { 92 if ddl.CreateTempTable { 93 vcursor.Session().HasCreatedTempTable() 94 vcursor.Session().NeedsReservedConn() 95 return vcursor.ExecutePrimitive(ctx, ddl.NormalDDL, bindVars, wantfields) 96 } 97 98 ddlStrategySetting, err := schema.ParseDDLStrategy(vcursor.Session().GetDDLStrategy()) 99 if err != nil { 100 return nil, err 101 } 102 ddl.OnlineDDL.DDLStrategySetting = ddlStrategySetting 103 104 switch { 105 case ddl.isOnlineSchemaDDL(): 106 if !ddl.OnlineDDLEnabled { 107 return nil, schema.ErrOnlineDDLDisabled 108 } 109 return vcursor.ExecutePrimitive(ctx, ddl.OnlineDDL, bindVars, wantfields) 110 default: // non online-ddl 111 if !ddl.DirectDDLEnabled { 112 return nil, schema.ErrDirectDDLDisabled 113 } 114 return vcursor.ExecutePrimitive(ctx, ddl.NormalDDL, bindVars, wantfields) 115 } 116 } 117 118 // TryStreamExecute implements the Primitive interface 119 func (ddl *DDL) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*query.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { 120 results, err := ddl.TryExecute(ctx, vcursor, bindVars, wantfields) 121 if err != nil { 122 return err 123 } 124 return callback(results) 125 } 126 127 // GetFields implements the Primitive interface 128 func (ddl *DDL) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*query.BindVariable) (*sqltypes.Result, error) { 129 return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] GetFields in not reachable") 130 }