forked from dolthub/go-mysql-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tables.go
374 lines (332 loc) · 16.9 KB
/
tables.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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
// Copyright 2022 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sql
import "fmt"
// Table is a SQL table.
type Table interface {
Nameable
fmt.Stringer
// Schema returns the table's schema.
Schema() Schema
// Collation returns the table's collation.
Collation() CollationID
// Partitions returns the table's partitions in an iterator.
Partitions(*Context) (PartitionIter, error)
// PartitionRows returns the rows in the given partition, which was returned by Partitions.
PartitionRows(*Context, Partition) (RowIter, error)
}
// TableFunction is a node that is generated by a function and can be used as a table factor in many SQL queries.
type TableFunction interface {
Node
Expressioner
Databaser
Nameable
// NewInstance calls the table function with the arguments provided, producing a Node
NewInstance(ctx *Context, db Database, args []Expression) (Node, error)
}
// TemporaryTable allows tables to declare that they are temporary (created by CREATE TEMPORARY TABLE).
// Only used for validation of certain DDL operations -- in almost all respects TemporaryTables are indistinguishable
// from persisted tables to the engine.
type TemporaryTable interface {
// IsTemporary should return true if the table is temporary to the session
IsTemporary() bool
}
// TableWrapper is a node that wraps the real table. This is needed because wrappers cannot implement some methods the
// table may implement. This interface is used in analysis and planning and is not expected to be implemented by
// integrators.
type TableWrapper interface {
// Underlying returns the underlying table.
Underlying() Table
}
// FilteredTable is a table that can filter its result rows from RowIter using filter expressions that would otherwise
// be applied by a separate Filter node.
type FilteredTable interface {
Table
// Filters returns the filter expressions that have been applied to this table.
Filters() []Expression
// HandledFilters returns the subset of the filter expressions given that this table can apply.
HandledFilters(filters []Expression) []Expression
// WithFilters returns a table with the given filter expressions applied.
WithFilters(ctx *Context, filters []Expression) Table
}
// ProjectedTable is a table that can return only a subset of its columns from RowIter. This provides a very large
// efficiency gain during table scans. Tables that implement this interface must return only the projected columns
// in future calls to Schema.
type ProjectedTable interface {
Table
// WithProjections returns a version of this table with only the subset of columns named. Calls to Schema must
// only include these columns. A zero-length slice of column names is valid and indicates that rows from this table
// should be spooled, but no columns should be returned. A nil slice will never be provided.
WithProjections(colNames []string) Table
// Projections returns the names of the column projections applied to this table, or nil if no projection is applied
// and all columns of the schema will be returned.
Projections() []string
}
// IndexAddressable is a table that can be scanned through a primary index
type IndexAddressable interface {
// IndexedAccess returns a table that can perform scans constrained to
// an IndexLookup on the index given, or nil if the index cannot support
// the lookup expression.
IndexedAccess(IndexLookup) IndexedTable
// GetIndexes returns an array of this table's Indexes
GetIndexes(ctx *Context) ([]Index, error)
}
// IndexAddressableTable is a table that can be accessed through an index
type IndexAddressableTable interface {
Table
IndexAddressable
}
// IndexedTable is a table with an index chosen for range scans
type IndexedTable interface {
Table
// LookupPartitions returns partitions scanned by the given IndexLookup
LookupPartitions(*Context, IndexLookup) (PartitionIter, error)
}
// IndexAlterableTable represents a table that supports index modification operations.
type IndexAlterableTable interface {
Table
// CreateIndex creates an index for this table, using the provided parameters.
// Returns an error if the index name already exists, or an index with the same columns already exists.
CreateIndex(ctx *Context, indexDef IndexDef) error
// DropIndex removes an index from this table, if it exists.
// Returns an error if the removal failed or the index does not exist.
DropIndex(ctx *Context, indexName string) error
// RenameIndex renames an existing index to another name that is not already taken by another index on this table.
RenameIndex(ctx *Context, fromIndexName string, toIndexName string) error
}
// ForeignKeyTable is a table that declares foreign key constraints, and can be referenced by other tables' foreign
// key constraints.
type ForeignKeyTable interface {
IndexAddressableTable
// CreateIndexForForeignKey creates an index for this table, using the provided parameters. Indexes created through
// this function are specifically ones generated for use with a foreign key. Returns an error if the index name
// already exists, or an index on the same columns already exists.
CreateIndexForForeignKey(ctx *Context, indexDef IndexDef) error
// GetDeclaredForeignKeys returns the foreign key constraints that are declared by this table.
GetDeclaredForeignKeys(ctx *Context) ([]ForeignKeyConstraint, error)
// GetReferencedForeignKeys returns the foreign key constraints that are referenced by this table.
GetReferencedForeignKeys(ctx *Context) ([]ForeignKeyConstraint, error)
// AddForeignKey adds the given foreign key constraint to the table. Returns an error if the foreign key name
// already exists on any other table within the database.
AddForeignKey(ctx *Context, fk ForeignKeyConstraint) error
// DropForeignKey removes a foreign key from the table.
DropForeignKey(ctx *Context, fkName string) error
// UpdateForeignKey updates the given foreign key constraint. May range from updated table names to setting the
// IsResolved boolean.
UpdateForeignKey(ctx *Context, fkName string, fk ForeignKeyConstraint) error
// GetForeignKeyEditor returns a ForeignKeyEditor for this table.
GetForeignKeyEditor(ctx *Context) ForeignKeyEditor
}
// ForeignKeyEditor is a TableEditor that is addressable via IndexLookup.
type ForeignKeyEditor interface {
TableEditor
IndexAddressable
}
// CheckTable is a table that declares check constraints.
type CheckTable interface {
Table
// GetChecks returns the check constraints on this table.
GetChecks(ctx *Context) ([]CheckDefinition, error)
}
// CheckAlterableTable represents a table that supports check constraints.
type CheckAlterableTable interface {
Table
// CreateCheck creates an check constraint for this table, using the provided parameters.
// Returns an error if the constraint name already exists.
CreateCheck(ctx *Context, check *CheckDefinition) error
// DropCheck removes a check constraint from the database.
DropCheck(ctx *Context, chName string) error
}
// PrimaryKeyTable is a table with a primary key.
type PrimaryKeyTable interface {
// PrimaryKeySchema returns this table's PrimaryKeySchema
PrimaryKeySchema() PrimaryKeySchema
}
// PrimaryKeyAlterableTable represents a table that supports primary key changes.
type PrimaryKeyAlterableTable interface {
Table
// CreatePrimaryKey creates a primary key for this table, using the provided parameters.
// Returns an error if the new primary key set is not compatible with the current table data.
CreatePrimaryKey(ctx *Context, columns []IndexColumn) error
// DropPrimaryKey drops a primary key on a table. Returns an error if that table does not have a key.
DropPrimaryKey(ctx *Context) error
}
// EditOpenerCloser is the base interface for table editors, and deals with statement boundaries.
type EditOpenerCloser interface {
// StatementBegin is called before the first operation of a statement. Integrators should mark the state of the data
// in some way that it may be returned to in the case of an error.
StatementBegin(ctx *Context)
// DiscardChanges is called if a statement encounters an error, and all current changes since the statement beginning
// should be discarded.
DiscardChanges(ctx *Context, errorEncountered error) error
// StatementComplete is called after the last operation of the statement, indicating that it has successfully completed.
// The mark set in StatementBegin may be removed, and a new one should be created on the next StatementBegin.
StatementComplete(ctx *Context) error
}
// InsertableTable is a table that can process insertion of new rows.
type InsertableTable interface {
Table
// Inserter returns an Inserter for this table. The Inserter will get one call to Insert() for each row to be
// inserted, and will end with a call to Close() to finalize the insert operation.
Inserter(*Context) RowInserter
}
// RowInserter is an insert cursor that can insert one or more values to a table.
type RowInserter interface {
EditOpenerCloser
// Insert inserts the row given, returning an error if it cannot. Insert will be called once for each row to process
// for the insert operation, which may involve many rows. After all rows in an operation have been processed, Close
// is called.
Insert(*Context, Row) error
// Close finalizes the insert operation, persisting its result.
Closer
}
// DeletableTable is a table that can delete rows.
type DeletableTable interface {
Table
// Deleter returns a RowDeleter for this table. The RowDeleter will get one call to Delete for each row to be deleted,
// and will end with a call to Close() to finalize the delete operation.
Deleter(*Context) RowDeleter
}
// RowDeleter is a delete cursor that can delete one or more rows from a table.
type RowDeleter interface {
EditOpenerCloser
// Delete deletes the given row. Returns ErrDeleteRowNotFound if the row was not found. Delete will be called once for
// each row to process for the delete operation, which may involve many rows. After all rows have been processed,
// Close is called.
Delete(*Context, Row) error
// Closer finalizes the delete operation, persisting the result.
Closer
}
// TruncateableTable is a table that can process the deletion of all rows either via a TRUNCATE TABLE statement or a
// DELETE statement without a WHERE clause. This is usually much faster that deleting rows one at a time.
type TruncateableTable interface {
Table
// Truncate removes all rows from the table. If the table also implements DeletableTable and it is determined that
// truncate would be equivalent to a DELETE which spans the entire table, then this function will be called instead.
// Returns the number of rows that were removed.
Truncate(*Context) (int, error)
}
// AutoIncrementTable is a table that supports AUTO_INCREMENT. Getter and Setter methods access the table's
// AUTO_INCREMENT sequence. These methods should only be used for tables with and AUTO_INCREMENT column in their schema.
type AutoIncrementTable interface {
Table
// PeekNextAutoIncrementValue returns the next AUTO_INCREMENT value without incrementing the current
// auto_increment counter.
PeekNextAutoIncrementValue(ctx *Context) (uint64, error)
// GetNextAutoIncrementValue gets the next AUTO_INCREMENT value. In the case that a table with an autoincrement
// column is passed in a row with the autoinc column failed, the next auto increment value must
// update its internal state accordingly and use the insert val at runtime.
// Implementations are responsible for updating their state to provide the correct values.
GetNextAutoIncrementValue(ctx *Context, insertVal interface{}) (uint64, error)
// AutoIncrementSetter returns an AutoIncrementSetter.
AutoIncrementSetter(*Context) AutoIncrementSetter
}
// AutoIncrementSetter provides support for altering a table's
// AUTO_INCREMENT sequence, eg 'ALTER TABLE t AUTO_INCREMENT = 10;'
type AutoIncrementSetter interface {
// SetAutoIncrementValue sets a new AUTO_INCREMENT value.
SetAutoIncrementValue(*Context, uint64) error
// Closer finalizes the set operation, persisting the result.
Closer
}
// AutoIncrementGetter is implemented by tables that support AUTO_INCREMENT to return the next value that will be
// inserted, given a particular insert value provided by the client.
type AutoIncrementGetter interface {
GetNextAutoIncrementValue(ctx *Context, insertVal interface{}) (uint64, error)
}
// AutoIncrementEditor is an interface for tables that support changing the value of auto increment columns.
type AutoIncrementEditor interface {
AutoIncrementSetter
AutoIncrementGetter
}
// ReplaceableTable allows rows to be replaced through a Delete (if applicable) then Insert.
type ReplaceableTable interface {
Table
// Replacer returns a RowReplacer for this table. The RowReplacer will have Insert and optionally Delete called once
// for each row, followed by a call to Close() when all rows have been processed.
Replacer(ctx *Context) RowReplacer
}
// RowReplacer is a combination of RowDeleter and RowInserter.
type RowReplacer interface {
EditOpenerCloser
RowInserter
RowDeleter
}
// UpdatableTable is a table that can process updates of existing rows via update statements.
type UpdatableTable interface {
Table
// Updater returns a RowUpdater for this table. The RowUpdater will have Update called once for each row to be
// updated, followed by a call to Close() when all rows have been processed.
Updater(ctx *Context) RowUpdater
}
// RowUpdater is an update cursor that can update one or more rows in a table.
type RowUpdater interface {
EditOpenerCloser
// Update the given row. Provides both the old and new rows.
Update(ctx *Context, old Row, new Row) error
// Closer finalizes the update operation, persisting the result.
Closer
}
// TableEditor is the combination of interfaces that allow any table edit operation:
// i.e. INSERT, UPDATE, DELETE, REPLACE
type TableEditor interface {
RowReplacer
RowUpdater
}
// RewritableTable is an extension to Table that makes it simpler for integrators to adapt to schema changes that must
// rewrite every row of the table. In this case, rows are streamed from the existing table in the old schema,
// transformed / updated appropriately, and written with the new format.
type RewritableTable interface {
Table
AlterableTable
// ShouldRewriteTable returns whether this table should be rewritten because of a schema change. The old and new
// versions of the schema and modified column are provided. For some operations, one or both of |oldColumn| or
// |newColumn| may be nil.
// The engine may decide to rewrite tables regardless in some cases, such as when a new non-nullable column is added.
ShouldRewriteTable(ctx *Context, oldSchema, newSchema PrimaryKeySchema, oldColumn, newColumn *Column) bool
// RewriteInserter returns a RowInserter for the new schema. Rows from the current table, with the old schema, will
// be streamed from the table and passed to this RowInserter. Implementor tables must still return rows in the
// current schema until the rewrite operation completes. |Close| will be called on RowInserter when all rows have
// been inserted.
RewriteInserter(ctx *Context, oldSchema, newSchema PrimaryKeySchema, oldColumn, newColumn *Column, idxCols []IndexColumn) (RowInserter, error)
}
// AlterableTable should be implemented by tables that can receive ALTER TABLE statements to modify their schemas.
type AlterableTable interface {
Table
UpdatableTable
// AddColumn adds a column to this table as given. If non-nil, order specifies where in the schema to add the column.
AddColumn(ctx *Context, column *Column, order *ColumnOrder) error
// DropColumn drops the column with the name given.
DropColumn(ctx *Context, columnName string) error
// ModifyColumn modifies the column with the name given, replacing with the new column definition provided (which may
// include a name change). If non-nil, order specifies where in the schema to move the column.
ModifyColumn(ctx *Context, columnName string, column *Column, order *ColumnOrder) error
}
// UnresolvedTable is a Table that is either unresolved or deferred for until an asOf resolution.
// Used by the analyzer during planning, and is not expected to be implemented by integrators.
type UnresolvedTable interface {
Nameable
// Database returns the database name
Database() string
// WithAsOf returns a copy of this versioned table with its AsOf
// field set to the given value. Analogous to WithChildren.
WithAsOf(asOf Expression) (Node, error)
// AsOf returns this table's asof expression.
AsOf() Expression
}
// Table2 is an experimental future interface alternative to Table to provide faster access.
type Table2 interface {
Table
PartitionRows2(ctx *Context, part Partition) (RowIter2, error)
}