vitess.io/vitess@v0.16.2/go/vt/vtgate/engine/online_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 "fmt" 22 23 "vitess.io/vitess/go/sqltypes" 24 "vitess.io/vitess/go/vt/key" 25 querypb "vitess.io/vitess/go/vt/proto/query" 26 vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" 27 "vitess.io/vitess/go/vt/schema" 28 "vitess.io/vitess/go/vt/sqlparser" 29 "vitess.io/vitess/go/vt/vterrors" 30 "vitess.io/vitess/go/vt/vtgate/vindexes" 31 ) 32 33 var _ Primitive = (*OnlineDDL)(nil) 34 35 // OnlineDDL represents the instructions to perform an online schema change via vtctld 36 type OnlineDDL struct { 37 Keyspace *vindexes.Keyspace 38 DDL sqlparser.DDLStatement 39 SQL string 40 DDLStrategySetting *schema.DDLStrategySetting 41 // TargetDestination specifies an explicit target destination to send the query to. 42 TargetDestination key.Destination 43 44 noTxNeeded 45 46 noInputs 47 } 48 49 func (v *OnlineDDL) description() PrimitiveDescription { 50 return PrimitiveDescription{ 51 OperatorType: "OnlineDDL", 52 Keyspace: v.Keyspace, 53 Other: map[string]any{ 54 "query": v.SQL, 55 }, 56 } 57 } 58 59 // RouteType implements the Primitive interface 60 func (v *OnlineDDL) RouteType() string { 61 return "OnlineDDL" 62 } 63 64 // GetKeyspaceName implements the Primitive interface 65 func (v *OnlineDDL) GetKeyspaceName() string { 66 return v.Keyspace.Name 67 } 68 69 // GetTableName implements the Primitive interface 70 func (v *OnlineDDL) GetTableName() string { 71 return v.DDL.GetTable().Name.String() 72 } 73 74 // TryExecute implements the Primitive interface 75 func (v *OnlineDDL) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (result *sqltypes.Result, err error) { 76 result = &sqltypes.Result{ 77 Fields: []*querypb.Field{ 78 { 79 Name: "uuid", 80 Type: sqltypes.VarChar, 81 }, 82 }, 83 Rows: [][]sqltypes.Value{}, 84 } 85 onlineDDLs, err := schema.NewOnlineDDLs(v.GetKeyspaceName(), v.SQL, v.DDL, 86 v.DDLStrategySetting, fmt.Sprintf("vtgate:%s", vcursor.Session().GetSessionUUID()), "", 87 ) 88 if err != nil { 89 return result, err 90 } 91 for _, onlineDDL := range onlineDDLs { 92 // Go directly to tablets, much like Send primitive does 93 s := Send{ 94 Keyspace: v.Keyspace, 95 TargetDestination: v.TargetDestination, 96 Query: onlineDDL.SQL, 97 IsDML: false, 98 SingleShardOnly: false, 99 } 100 if _, err := vcursor.ExecutePrimitive(ctx, &s, bindVars, wantfields); err != nil { 101 return result, err 102 } 103 result.Rows = append(result.Rows, []sqltypes.Value{ 104 sqltypes.NewVarChar(onlineDDL.UUID), 105 }) 106 } 107 return result, err 108 } 109 110 // TryStreamExecute implements the Primitive interface 111 func (v *OnlineDDL) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { 112 results, err := v.TryExecute(ctx, vcursor, bindVars, wantfields) 113 if err != nil { 114 return err 115 } 116 return callback(results) 117 } 118 119 // GetFields implements the Primitive interface 120 func (v *OnlineDDL) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { 121 return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] GetFields is not reachable") 122 }