github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opaque.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sql 12 13 import ( 14 "context" 15 "reflect" 16 17 "github.com/cockroachdb/cockroach/pkg/sql/opt" 18 "github.com/cockroachdb/cockroach/pkg/sql/opt/optbuilder" 19 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 20 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 21 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 22 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 23 "github.com/cockroachdb/errors" 24 ) 25 26 type opaqueMetadata struct { 27 info string 28 plan planNode 29 } 30 31 var _ opt.OpaqueMetadata = &opaqueMetadata{} 32 33 func (o *opaqueMetadata) ImplementsOpaqueMetadata() {} 34 func (o *opaqueMetadata) String() string { return o.info } 35 36 func buildOpaque( 37 ctx context.Context, semaCtx *tree.SemaContext, evalCtx *tree.EvalContext, stmt tree.Statement, 38 ) (opt.OpaqueMetadata, sqlbase.ResultColumns, error) { 39 p := evalCtx.Planner.(*planner) 40 41 // Opaque statements handle their own scalar arguments, with no help from the 42 // optimizer. As such, they cannot contain subqueries. 43 scalarProps := &semaCtx.Properties 44 defer scalarProps.Restore(*scalarProps) 45 scalarProps.Require(stmt.StatementTag(), tree.RejectSubqueries) 46 47 var plan planNode 48 var err error 49 switch n := stmt.(type) { 50 case *tree.AlterIndex: 51 plan, err = p.AlterIndex(ctx, n) 52 case *tree.AlterTable: 53 plan, err = p.AlterTable(ctx, n) 54 case *tree.AlterType: 55 plan, err = p.AlterType(ctx, n) 56 case *tree.AlterRole: 57 plan, err = p.AlterRole(ctx, n) 58 case *tree.AlterSequence: 59 plan, err = p.AlterSequence(ctx, n) 60 case *tree.CommentOnColumn: 61 plan, err = p.CommentOnColumn(ctx, n) 62 case *tree.CommentOnDatabase: 63 plan, err = p.CommentOnDatabase(ctx, n) 64 case *tree.CommentOnIndex: 65 plan, err = p.CommentOnIndex(ctx, n) 66 case *tree.CommentOnTable: 67 plan, err = p.CommentOnTable(ctx, n) 68 case *tree.CreateDatabase: 69 plan, err = p.CreateDatabase(ctx, n) 70 case *tree.CreateIndex: 71 plan, err = p.CreateIndex(ctx, n) 72 case *tree.CreateSchema: 73 plan, err = p.CreateSchema(ctx, n) 74 case *tree.CreateType: 75 plan, err = p.CreateType(ctx, n) 76 case *tree.CreateRole: 77 plan, err = p.CreateRole(ctx, n) 78 case *tree.CreateSequence: 79 plan, err = p.CreateSequence(ctx, n) 80 case *tree.CreateStats: 81 plan, err = p.CreateStatistics(ctx, n) 82 case *tree.Deallocate: 83 plan, err = p.Deallocate(ctx, n) 84 case *tree.Discard: 85 plan, err = p.Discard(ctx, n) 86 case *tree.DropDatabase: 87 plan, err = p.DropDatabase(ctx, n) 88 case *tree.DropIndex: 89 plan, err = p.DropIndex(ctx, n) 90 case *tree.DropRole: 91 plan, err = p.DropRole(ctx, n) 92 case *tree.DropTable: 93 plan, err = p.DropTable(ctx, n) 94 case *tree.DropType: 95 plan, err = p.DropType(ctx, n) 96 case *tree.DropView: 97 plan, err = p.DropView(ctx, n) 98 case *tree.DropSequence: 99 plan, err = p.DropSequence(ctx, n) 100 case *tree.Grant: 101 plan, err = p.Grant(ctx, n) 102 case *tree.GrantRole: 103 plan, err = p.GrantRole(ctx, n) 104 case *tree.RenameColumn: 105 plan, err = p.RenameColumn(ctx, n) 106 case *tree.RenameDatabase: 107 plan, err = p.RenameDatabase(ctx, n) 108 case *tree.RenameIndex: 109 plan, err = p.RenameIndex(ctx, n) 110 case *tree.RenameTable: 111 plan, err = p.RenameTable(ctx, n) 112 case *tree.Revoke: 113 plan, err = p.Revoke(ctx, n) 114 case *tree.RevokeRole: 115 plan, err = p.RevokeRole(ctx, n) 116 case *tree.Scatter: 117 plan, err = p.Scatter(ctx, n) 118 case *tree.Scrub: 119 plan, err = p.Scrub(ctx, n) 120 case *tree.SetClusterSetting: 121 plan, err = p.SetClusterSetting(ctx, n) 122 case *tree.SetZoneConfig: 123 plan, err = p.SetZoneConfig(ctx, n) 124 case *tree.SetVar: 125 plan, err = p.SetVar(ctx, n) 126 case *tree.SetTransaction: 127 plan, err = p.SetTransaction(ctx, n) 128 case *tree.SetSessionAuthorizationDefault: 129 plan, err = p.SetSessionAuthorizationDefault() 130 case *tree.SetSessionCharacteristics: 131 plan, err = p.SetSessionCharacteristics(n) 132 case *tree.ShowClusterSetting: 133 plan, err = p.ShowClusterSetting(ctx, n) 134 case *tree.ShowHistogram: 135 plan, err = p.ShowHistogram(ctx, n) 136 case *tree.ShowTableStats: 137 plan, err = p.ShowTableStats(ctx, n) 138 case *tree.ShowTraceForSession: 139 plan, err = p.ShowTrace(ctx, n) 140 case *tree.ShowZoneConfig: 141 plan, err = p.ShowZoneConfig(ctx, n) 142 case *tree.ShowFingerprints: 143 plan, err = p.ShowFingerprints(ctx, n) 144 case *tree.Truncate: 145 plan, err = p.Truncate(ctx, n) 146 case tree.CCLOnlyStatement: 147 plan, err = p.maybePlanHook(ctx, stmt) 148 if plan == nil && err == nil { 149 return nil, nil, pgerror.Newf(pgcode.CCLRequired, 150 "a CCL binary is required to use this statement type: %T", stmt) 151 } 152 default: 153 return nil, nil, errors.AssertionFailedf("unknown opaque statement %T", stmt) 154 } 155 if err != nil { 156 return nil, nil, err 157 } 158 res := &opaqueMetadata{ 159 info: stmt.StatementTag(), 160 plan: plan, 161 } 162 return res, planColumns(plan), nil 163 } 164 165 func init() { 166 for _, stmt := range []tree.Statement{ 167 &tree.AlterIndex{}, 168 &tree.AlterTable{}, 169 &tree.AlterType{}, 170 &tree.AlterSequence{}, 171 &tree.AlterRole{}, 172 &tree.CommentOnColumn{}, 173 &tree.CommentOnDatabase{}, 174 &tree.CommentOnIndex{}, 175 &tree.CommentOnTable{}, 176 &tree.CreateDatabase{}, 177 &tree.CreateIndex{}, 178 &tree.CreateSchema{}, 179 &tree.CreateSequence{}, 180 &tree.CreateStats{}, 181 &tree.CreateType{}, 182 &tree.CreateRole{}, 183 &tree.Deallocate{}, 184 &tree.Discard{}, 185 &tree.DropDatabase{}, 186 &tree.DropIndex{}, 187 &tree.DropTable{}, 188 &tree.DropType{}, 189 &tree.DropView{}, 190 &tree.DropRole{}, 191 &tree.DropSequence{}, 192 &tree.Grant{}, 193 &tree.GrantRole{}, 194 &tree.RenameColumn{}, 195 &tree.RenameDatabase{}, 196 &tree.RenameIndex{}, 197 &tree.RenameTable{}, 198 &tree.Revoke{}, 199 &tree.RevokeRole{}, 200 &tree.Scatter{}, 201 &tree.Scrub{}, 202 &tree.SetClusterSetting{}, 203 &tree.SetZoneConfig{}, 204 &tree.SetVar{}, 205 &tree.SetTransaction{}, 206 &tree.SetSessionAuthorizationDefault{}, 207 &tree.SetSessionCharacteristics{}, 208 &tree.ShowClusterSetting{}, 209 &tree.ShowHistogram{}, 210 &tree.ShowTableStats{}, 211 &tree.ShowTraceForSession{}, 212 &tree.ShowZoneConfig{}, 213 &tree.ShowFingerprints{}, 214 &tree.Truncate{}, 215 216 // CCL statements (without Export which has an optimizer operator). 217 &tree.Backup{}, 218 &tree.ShowBackup{}, 219 &tree.Restore{}, 220 &tree.CreateChangefeed{}, 221 &tree.Import{}, 222 } { 223 typ := optbuilder.OpaqueReadOnly 224 if tree.CanModifySchema(stmt) { 225 typ = optbuilder.OpaqueDDL 226 } else if tree.CanWriteData(stmt) { 227 typ = optbuilder.OpaqueMutation 228 } 229 optbuilder.RegisterOpaque(reflect.TypeOf(stmt), typ, buildOpaque) 230 } 231 }