@@ -17,6 +17,9 @@ package tree
1717import (
1818 "fmt"
1919 "strings"
20+
21+ "github.com/cockroachdb/cockroach/pkg/util/buildutil"
22+ "github.com/cockroachdb/errors"
2023)
2124
2225// Instructions for creating new types: If a type needs to satisfy an
@@ -142,25 +145,36 @@ type Statement interface {
142145 StatementTag () string
143146}
144147
145- // canModifySchema is to be implemented by statements that can modify
146- // the database schema but may have StatementReturnType() != DDL.
147- // See CanModifySchema() below.
148- type canModifySchema interface {
149- modifiesSchema () bool
150- }
151-
152148// CanModifySchema returns true if the statement can modify
153149// the database schema.
154150func CanModifySchema (stmt Statement ) bool {
155151 if stmt == nil {
156152 // Some drivers send empty queries to test the connection.
157153 return false
158154 }
159- if stmt .StatementReturnType () == DDL || stmt .StatementType () == TypeDDL {
155+ if t := stmt .StatementType (); t == TypeDML {
156+ // Return early for the common case of DML, which never modify schema.
157+ if buildutil .CrdbTestBuild {
158+ // Assert this invariant in test builds.
159+ if stmt .StatementReturnType () == DDL {
160+ panic (errors .AssertionFailedf ("DML statement %T has unexpected DDL return type" , stmt ))
161+ }
162+ // Also assert that the special cases are not TypeDML.
163+ switch stmt .(type ) {
164+ case * Discard , * SetZoneConfig :
165+ panic (errors .AssertionFailedf ("%T has unexpected DDL statement type" , stmt ))
166+ }
167+ }
168+ return false
169+ } else if t == TypeDDL || stmt .StatementReturnType () == DDL {
160170 return true
161171 }
162- scm , ok := stmt .(canModifySchema )
163- return ok && scm .modifiesSchema ()
172+ // Special cases for non-DDL statements which modify the schema.
173+ switch stmt .(type ) {
174+ case * Discard , * SetZoneConfig :
175+ return true
176+ }
177+ return false
164178}
165179
166180// CanWriteData returns true if the statement can modify data.
@@ -473,9 +487,6 @@ func (*AlterPolicy) StatementTag() string { return AlterPolicyTag }
473487
474488func (* AlterPolicy ) hiddenFromShowQueries () {}
475489
476- // modifiesSchema implements the canModifySchema interface.
477- func (* AlterPolicy ) modifiesSchema () bool { return true }
478-
479490// StatementReturnType implements the Statement interface.
480491func (* AlterTable ) StatementReturnType () StatementReturnType { return DDL }
481492
@@ -1055,9 +1066,6 @@ func (*CreatePolicy) StatementTag() string { return CreatePolicyTag }
10551066
10561067func (* CreatePolicy ) hiddenFromShowQueries () {}
10571068
1058- // modifiesSchema implements the canModifySchema interface.
1059- func (* CreatePolicy ) modifiesSchema () bool { return true }
1060-
10611069// StatementReturnType implements the Statement interface.
10621070func (n * CreateSchema ) StatementReturnType () StatementReturnType { return DDL }
10631071
@@ -1069,9 +1077,6 @@ func (n *CreateSchema) StatementTag() string {
10691077 return CreateSchemaTag
10701078}
10711079
1072- // modifiesSchema implements the canModifySchema interface.
1073- func (* CreateSchema ) modifiesSchema () bool { return true }
1074-
10751080// StatementReturnType implements the Statement interface.
10761081func (n * CreateTable ) StatementReturnType () StatementReturnType { return DDL }
10771082
@@ -1086,9 +1091,6 @@ func (n *CreateTable) StatementTag() string {
10861091 return "CREATE TABLE"
10871092}
10881093
1089- // modifiesSchema implements the canModifySchema interface.
1090- func (* CreateTable ) modifiesSchema () bool { return true }
1091-
10921094// StatementReturnType implements the Statement interface.
10931095func (* CreateType ) StatementReturnType () StatementReturnType { return DDL }
10941096
@@ -1098,8 +1100,6 @@ func (*CreateType) StatementType() StatementType { return TypeDDL }
10981100// StatementTag implements the Statement interface.
10991101func (* CreateType ) StatementTag () string { return "CREATE TYPE" }
11001102
1101- func (* CreateType ) modifiesSchema () bool { return true }
1102-
11031103// StatementReturnType implements the Statement interface.
11041104func (* CreateRole ) StatementReturnType () StatementReturnType { return DDL }
11051105
@@ -1168,9 +1168,6 @@ func (d *Discard) StatementTag() string {
11681168 return "DISCARD"
11691169}
11701170
1171- // modifiesSchema implements the canModifySchema interface.
1172- func (* Discard ) modifiesSchema () bool { return true }
1173-
11741171// StatementReturnType implements the Statement interface.
11751172func (n * DeclareCursor ) StatementReturnType () StatementReturnType { return Ack }
11761173
@@ -1218,9 +1215,6 @@ func (*DropPolicy) StatementTag() string { return DropPolicyTag }
12181215
12191216func (* DropPolicy ) hiddenFromShowQueries () {}
12201217
1221- // modifiesSchema implements the canModifySchema interface.
1222- func (* DropPolicy ) modifiesSchema () bool { return true }
1223-
12241218// StatementReturnType implements the Statement interface.
12251219func (* DropTable ) StatementReturnType () StatementReturnType { return DDL }
12261220
@@ -2348,9 +2342,6 @@ func (*Truncate) StatementType() StatementType { return TypeDDL }
23482342// StatementTag returns a short string identifying the type of statement.
23492343func (* Truncate ) StatementTag () string { return TruncateTag }
23502344
2351- // modifiesSchema implements the canModifySchema interface.
2352- func (* Truncate ) modifiesSchema () bool { return true }
2353-
23542345// StatementReturnType implements the Statement interface.
23552346func (n * Update ) StatementReturnType () StatementReturnType { return n .Returning .statementReturnType () }
23562347
0 commit comments