-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
dependencies.go
299 lines (230 loc) · 11.2 KB
/
dependencies.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
// Copyright 2021 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package scbuildstmt
import (
"context"
"github.com/cockroachdb/cockroach/pkg/security/username"
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/catpb"
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scpb"
"github.com/cockroachdb/cockroach/pkg/sql/sem/catid"
"github.com/cockroachdb/cockroach/pkg/sql/sem/eval"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
)
// BuildCtx wraps BuilderState and exposes various convenience methods for the
// benefit of the scbuildstmts package.
//
// All methods except those in Context and Dependencies may panic instead of
// explicitly returning errors.
type BuildCtx interface {
context.Context
ClusterAndSessionInfo
SchemaFeatureChecker
BuilderState
EventLogState
TreeAnnotator
TreeContextBuilder
Telemetry
// Add adds an absent element to the BuilderState, targeting PUBLIC.
Add(element scpb.Element)
// AddTransient adds an absent element to the BuilderState, targeting
// TRANSIENT_ABSENT.
AddTransient(element scpb.Element)
// Drop sets the ABSENT target on an existing element in the BuilderState.
Drop(element scpb.Element)
// WithNewSourceElementID wraps BuilderStateWithNewSourceElementID in a
// BuildCtx return type.
WithNewSourceElementID() BuildCtx
}
// ClusterAndSessionInfo provides general cluster and session info.
type ClusterAndSessionInfo interface {
// ClusterSettings returns the current cluster settings, as in execCfg.
ClusterSettings() *cluster.Settings
// SessionData returns the current session data, as in execCtx.
SessionData() *sessiondata.SessionData
}
// BuilderState encapsulates the state of the planned schema changes, hiding
// its internal state to anything that ends up using it and only allowing
// state changes via the provided methods.
type BuilderState interface {
scpb.ElementStatusIterator
ElementReferences
NameResolver
PrivilegeChecker
TableHelpers
// QueryByID returns all elements sharing the given descriptor ID.
QueryByID(descID catid.DescID) ElementResultSet
// Ensure ensures the presence of the given element in the BuilderState with
// the given statuses and metadata.
Ensure(current scpb.Status, target scpb.TargetStatus, elem scpb.Element, meta scpb.TargetMetadata)
}
// EventLogState encapsulates the state of the metadata to decorate the eventlog
// with.
type EventLogState interface {
// TargetMetadata returns the current scpb.TargetMetadata for this state.
TargetMetadata() scpb.TargetMetadata
// IncrementSubWorkID increments the current subwork ID used for tracking
// when a statement does operations on multiple objects or in multiple
// commands.
IncrementSubWorkID()
// EventLogStateWithNewSourceElementID returns an EventLogState with an
// incremented source element ID
EventLogStateWithNewSourceElementID() EventLogState
}
// TreeContextBuilder exposes convenient tree-package context builder methods.
type TreeContextBuilder interface {
// SemaCtx returns a new tree.SemaContext.
SemaCtx() *tree.SemaContext
// EvalCtx returns a new eval.Context.
EvalCtx() *eval.Context
}
// TreeAnnotator provides interfaces to be able to modify the AST safely,
// by providing a copy and support for adding annotations.
type TreeAnnotator interface {
// SetUnresolvedNameAnnotation sets an annotation on an unresolved object name.
SetUnresolvedNameAnnotation(unresolvedName *tree.UnresolvedObjectName, ann interface{})
// MarkNameAsNonExistent indicates that a table name is non-existent
// in the AST, which will cause it to skip full namespace resolution
// validation.
MarkNameAsNonExistent(name *tree.TableName)
}
// Telemetry allows incrementing schema change telemetry counters.
type Telemetry interface {
// IncrementSchemaChangeAlterCounter increments the selected ALTER telemetry
// counter.
IncrementSchemaChangeAlterCounter(counterType string, extra ...string)
// IncrementSchemaChangeDropCounter increments the selected DROP telemetry
// counter.
IncrementSchemaChangeDropCounter(counterType string)
// IncrementSchemaChangeAddColumnTypeCounter increments telemetry counters for
// different types added as columns.
IncrementSchemaChangeAddColumnTypeCounter(typeName string)
// IncrementSchemaChangeAddColumnQualificationCounter increments telemetry
// counters for different qualifications (default expressions) on a newly
// added column.
IncrementSchemaChangeAddColumnQualificationCounter(qualification string)
// IncrementUserDefinedSchemaCounter increments the selected user-defined
// schema telemetry counter.
IncrementUserDefinedSchemaCounter(counterType sqltelemetry.UserDefinedSchemaTelemetryType)
// IncrementEnumCounter increments the selected enum telemetry counter.
IncrementEnumCounter(counterType sqltelemetry.EnumTelemetryType)
// IncrementDropOwnedByCounter increments the DROP OWNED BY telemetry counter.
IncrementDropOwnedByCounter()
}
// SchemaFeatureChecker checks if a schema change feature is allowed by the
// database administrator.
type SchemaFeatureChecker interface {
// CheckFeature returns if the feature name specified is allowed or disallowed,
// by the database administrator.
CheckFeature(ctx context.Context, featureName tree.SchemaFeatureName) error
}
// PrivilegeChecker checks an element's privileges.
type PrivilegeChecker interface {
// HasOwnership returns true iff the current user owns the element.
HasOwnership(e scpb.Element) bool
// CheckPrivilege panics if the current user does not have the specified
// privilege for the element.
CheckPrivilege(e scpb.Element, privilege privilege.Kind)
// CheckMemberOf returns true iff the current user has membership in the
// specified role.
IsMemberOf(member username.SQLUsername) bool
}
// TableHelpers has methods useful for creating new table elements.
type TableHelpers interface {
// NextTableColumnID returns the ID that should be used for any new column
// added to this table.
NextTableColumnID(table *scpb.Table) catid.ColumnID
// NextColumnFamilyID returns the ID that should be used for any new column
// family added to this table.
NextColumnFamilyID(table *scpb.Table) catid.FamilyID
// NextTableIndexID returns the ID that should be used for any new index added
// to this table.
NextTableIndexID(table *scpb.Table) catid.IndexID
// NextViewIndexID returns the ID that should be used for any new index added
// to this materialized view.
NextViewIndexID(view *scpb.View) catid.IndexID
// IndexPartitioningDescriptor creates a new partitioning descriptor
// for the secondary index element, or panics.
IndexPartitioningDescriptor(
index *scpb.Index,
partBy *tree.PartitionBy,
) catpb.PartitioningDescriptor
// ResolveTypeRef resolves a type reference.
ResolveTypeRef(typeref tree.ResolvableTypeReference) scpb.TypeT
// WrapExpression constructs an expression wrapper given an AST.
WrapExpression(parentID catid.DescID, expr tree.Expr) *scpb.Expression
// ComputedColumnExpression returns a validated computed column expression
// and its type.
// TODO(postamar): make this more low-level instead of consuming an AST
ComputedColumnExpression(tbl *scpb.Table, d *tree.ColumnTableDef) tree.Expr
// IsTableEmpty returns if the table is empty or not.
IsTableEmpty(tbl *scpb.Table) bool
}
// ElementResultSet wraps the results of an element query.
type ElementResultSet interface {
scpb.ElementStatusIterator
// IsEmpty returns true iff there are no elements in the result set.
IsEmpty() bool
// Filter returns a subset of this result set according to the predicate.
Filter(predicate func(current scpb.Status, target scpb.TargetStatus, e scpb.Element) bool) ElementResultSet
}
// ElementReferences looks up an element's forward and backward references.
type ElementReferences interface {
// ForwardReferences returns the set of elements to which we have forward
// references in the given element. This includes the current element.
ForwardReferences(e scpb.Element) ElementResultSet
// BackReferences returns the set of elements to which we have back-references
// in the descriptor backing the given element. Back-references also include
// children, in the case of databases and schemas.
BackReferences(id catid.DescID) ElementResultSet
}
// ResolveParams specifies the behavior of the methods in the
// NameResolver interface.
type ResolveParams struct {
// IsExistenceOptional iff true causes the method to return nil when the
// descriptor cannot be found, instead of panicking.
IsExistenceOptional bool
// RequiredPrivilege defines the privilege required for the resolved
// descriptor.
RequiredPrivilege privilege.Kind
}
// NameResolver looks up elements in the catalog by name, and vice-versa.
type NameResolver interface {
// NamePrefix returns the name prefix for the descriptor backing the given
// element. This is constructed on a best-effort basis.
NamePrefix(e scpb.Element) tree.ObjectNamePrefix
// ResolveDatabase retrieves a database by name and returns its elements.
ResolveDatabase(name tree.Name, p ResolveParams) ElementResultSet
// ResolveSchema retrieves a schema by name and returns its elements.
ResolveSchema(name tree.ObjectNamePrefix, p ResolveParams) ElementResultSet
// ResolveEnumType retrieves a type by name and returns its elements.
ResolveEnumType(name *tree.UnresolvedObjectName, p ResolveParams) ElementResultSet
// ResolveRelation retrieves a relation by name and returns its elements.
ResolveRelation(name *tree.UnresolvedObjectName, p ResolveParams) ElementResultSet
// ResolveTable retrieves a table by name and returns its elements.
ResolveTable(name *tree.UnresolvedObjectName, p ResolveParams) ElementResultSet
// ResolveSequence retrieves a sequence by name and returns its elements.
ResolveSequence(name *tree.UnresolvedObjectName, p ResolveParams) ElementResultSet
// ResolveView retrieves a view by name and returns its elements.
ResolveView(name *tree.UnresolvedObjectName, p ResolveParams) ElementResultSet
// ResolveIndex retrieves an index by name and returns its elements.
ResolveIndex(relationID catid.DescID, indexName tree.Name, p ResolveParams) ElementResultSet
// ResolveTableIndexBestEffort retrieves a table which contains the target
// index and returns its elements. Name of database, schema or table may be
// missing. It panics if require=true but index is not found.
ResolveTableIndexBestEffort(tableIndexName *tree.TableIndexName, p ResolveParams, required bool) ElementResultSet
// ResolveColumn retrieves a column by name and returns its elements.
ResolveColumn(relationID catid.DescID, columnName tree.Name, p ResolveParams) ElementResultSet
// ResolveConstraint retrieves a constraint by name and returns its elements.
ResolveConstraint(relationID catid.DescID, constraintName tree.Name, p ResolveParams) ElementResultSet
}