-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
internal_executor.go
275 lines (245 loc) · 10.3 KB
/
internal_executor.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
// Copyright 2016 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 sqlutil
import (
"context"
"github.com/cockroachdb/cockroach/pkg/kv"
"github.com/cockroachdb/cockroach/pkg/sql/catalog"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
)
// InternalExecutor is meant to be used by layers below SQL in the system that
// nevertheless want to execute SQL queries (presumably against system tables).
// It is extracted in this "sqlutil" package to avoid circular references and
// is implemented by *sql.InternalExecutor.
type InternalExecutor interface {
// Exec executes the supplied SQL statement and returns the number of rows
// affected (not like the full results; see QueryIterator()). If no user has
// been previously set through SetSessionData, the statement is executed as
// the root user.
//
// If txn is not nil, the statement will be executed in the respective txn.
//
// Exec is deprecated because it may transparently execute a query as root.
// Use ExecEx instead.
Exec(
ctx context.Context, opName string, txn *kv.Txn, statement string, params ...interface{},
) (int, error)
// ExecEx is like Exec, but allows the caller to override some session data
// fields.
//
// The fields set in session that are set override the respective fields if
// they have previously been set through SetSessionData().
ExecEx(
ctx context.Context,
opName string,
txn *kv.Txn,
o sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) (int, error)
// QueryRow executes the supplied SQL statement and returns a single row, or
// nil if no row is found, or an error if more that one row is returned.
//
// QueryRow is deprecated. Use QueryRowEx() instead.
QueryRow(
ctx context.Context, opName string, txn *kv.Txn, statement string, qargs ...interface{},
) (tree.Datums, error)
// QueryRowEx is like QueryRow, but allows the caller to override some
// session data fields.
//
// The fields set in session that are set override the respective fields if
// they have previously been set through SetSessionData().
QueryRowEx(
ctx context.Context,
opName string,
txn *kv.Txn,
session sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) (tree.Datums, error)
// QueryRowExWithCols is like QueryRowEx, additionally returning the
// computed ResultColumns of the input query.
QueryRowExWithCols(
ctx context.Context,
opName string,
txn *kv.Txn,
session sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) (tree.Datums, colinfo.ResultColumns, error)
// QueryBuffered executes the supplied SQL statement and returns the
// resulting rows (meaning all of them are buffered at once). If no user has
// been previously set through SetSessionData, the statement is executed as
// the root user.
//
// If txn is not nil, the statement will be executed in the respective txn.
//
// QueryBuffered is deprecated because it may transparently execute a query
// as root. Use QueryBufferedEx instead.
QueryBuffered(
ctx context.Context,
opName string,
txn *kv.Txn,
stmt string,
qargs ...interface{},
) ([]tree.Datums, error)
// QueryBufferedEx executes the supplied SQL statement and returns the
// resulting rows (meaning all of them are buffered at once).
//
// If txn is not nil, the statement will be executed in the respective txn.
//
// The fields set in session that are set override the respective fields if
// they have previously been set through SetSessionData().
QueryBufferedEx(
ctx context.Context,
opName string,
txn *kv.Txn,
session sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) ([]tree.Datums, error)
// QueryIterator executes the query, returning an iterator that can be used
// to get the results. If the call is successful, the returned iterator
// *must* be closed.
//
// QueryIterator is deprecated because it may transparently execute a query
// as root. Use QueryIteratorEx instead.
QueryIterator(
ctx context.Context,
opName string,
txn *kv.Txn,
stmt string,
qargs ...interface{},
) (InternalRows, error)
// QueryIteratorEx executes the query, returning an iterator that can be
// used to get the results. If the call is successful, the returned iterator
// *must* be closed.
QueryIteratorEx(
ctx context.Context,
opName string,
txn *kv.Txn,
session sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) (InternalRows, error)
// QueryBufferedExWithCols is like QueryBufferedEx, additionally returning the computed
// ResultColumns of the input query.
QueryBufferedExWithCols(
ctx context.Context,
opName string,
txn *kv.Txn,
session sessiondata.InternalExecutorOverride,
stmt string,
qargs ...interface{},
) ([]tree.Datums, colinfo.ResultColumns, error)
// WithSyntheticDescriptors sets the synthetic descriptors before running the
// the provided closure and resets them afterward. Used for queries/statements
// that need to use in-memory synthetic descriptors different from descriptors
// written to disk. These descriptors override all other descriptors on the
// immutable resolution path.
//
// Warning: Not safe for concurrent use from multiple goroutines. This API is
// flawed in that the internal executor is meant to function as a stateless
// wrapper, and creates a new connExecutor and descs.Collection on each query/
// statement, so these descriptors should really be specified at a per-query/
// statement level. See #34304.
WithSyntheticDescriptors(
descs []catalog.Descriptor, run func() error,
) error
}
// InternalRows is an iterator interface that's exposed by the internal
// executor. It provides access to the rows from a query.
type InternalRows interface {
// Next advances the iterator by one row, returning false if there are no
// more rows in this iterator or if an error is encountered (the latter is
// then returned).
//
// The iterator is automatically closed when false is returned, consequent
// calls to Next will return the same values as when the iterator was
// closed.
Next(context.Context) (bool, error)
// Cur returns the row at the current position of the iterator. The row is
// safe to hold onto (meaning that calling Next() or Close() will not
// invalidate it).
Cur() tree.Datums
// RowsAffected() returns the count of rows affected by the statement.
// This is only guaranteed to be accurate after Next() has returned
// false (no more rows).
RowsAffected() int
// Close closes this iterator, releasing any resources it held open. Close
// is idempotent and *must* be called once the caller is done with the
// iterator.
Close() error
// Types returns the types of the columns returned by this iterator. The
// returned array is guaranteed to correspond 1:1 with the tree.Datums rows
// returned by Cur().
//
// WARNING: this method is safe to call anytime *after* the first call to
// Next() (including after Close() was called).
Types() colinfo.ResultColumns
}
// InternalExecutorFactory is an interface that allow the creation of an
// internal executor, and run sql statement without a txn with the internal
// executor.
type InternalExecutorFactory interface {
// NewInternalExecutor constructs a new internal executor.
// TODO (janexing): this should be deprecated soon.
NewInternalExecutor(sd *sessiondata.SessionData) InternalExecutor
// RunWithoutTxn is to create an internal executor without binding to a txn,
// and run the passed function with this internal executor.
RunWithoutTxn(ctx context.Context, run func(ctx context.Context, ie InternalExecutor) error) error
// TxnWithExecutor enables callers to run transactions with a *Collection such that all
// retrieved immutable descriptors are properly leased and all mutable
// descriptors are handled. The function deals with verifying the two version
// invariant and retrying when it is violated. Callers need not worry that they
// write mutable descriptors multiple times. The call will explicitly wait for
// the leases to drain on old versions of descriptors modified or deleted in the
// transaction; callers do not need to call lease.WaitForOneVersion.
// It also enables using internal executor to run sql queries in a txn manner.
//
// The passed transaction is pre-emptively anchored to the system config key on
// the system tenant.
TxnWithExecutor(context.Context, *kv.DB, *sessiondata.SessionData, func(context.Context, *kv.Txn, InternalExecutor) error, ...TxnOption) error
}
// InternalExecFn is the type of functions that operates using an internalExecutor.
type InternalExecFn func(ctx context.Context, txn *kv.Txn, ie InternalExecutor) error
// HistoricalInternalExecTxnRunner is like historicalTxnRunner except it only
// passes the fn the exported InternalExecutor instead of the whole unexported
// extendedEvalContenxt, so it can be implemented outside pkg/sql.
type HistoricalInternalExecTxnRunner func(ctx context.Context, fn InternalExecFn) error
// TxnOption is used to configure a Txn or TxnWithExecutor.
type TxnOption interface {
Apply(*TxnConfig)
}
// TxnConfig is the config to be set for txn.
type TxnConfig struct {
steppingEnabled bool
}
// GetSteppingEnabled return the steppingEnabled setting from the txn config.
func (tc *TxnConfig) GetSteppingEnabled() bool {
return tc.steppingEnabled
}
type txnOptionFn func(options *TxnConfig)
// Apply is to apply the txn config.
func (f txnOptionFn) Apply(options *TxnConfig) { f(options) }
var steppingEnabled = txnOptionFn(func(o *TxnConfig) {
o.steppingEnabled = true
})
// SteppingEnabled creates a TxnOption to determine whether the underlying
// transaction should have stepping enabled. If stepping is enabled, the
// transaction will implicitly use lower admission priority. However, the
// user will need to remember to Step the Txn to make writes visible. The
// InternalExecutor will automatically (for better or for worse) step the
// transaction when executing each statement.
func SteppingEnabled() TxnOption {
return steppingEnabled
}