Skip to content

Commit bc1ba00

Browse files
olavloitebhatt4982renovate-bot
authored
chore: move connection variables to connection state (#494)
* chore: add generic transactional connection state Adds data structures for generic transactional connection state. These structures will be used to keep all connection state in one place, making it easier to add new connection variables. This also adds support for transactional connection state; Changes that are made during a transaction are only persisted if the transaction is committed. It also allows for setting temporary (local) values during a transaction. This change is the first step in a multi-step process for moving all connection variables into a generic structure. Following changes will move the other connection variables into this structure, and will add support for executing `set local ...` statements. * chore: move connection variables to connection state Move individual connection variables to the generic connection state. * chore: fix formatting * chore: parse SET/SHOW statements with simple parser (#495) * chore: parse SET/SHOW statements with simple parser Parse SET/SHOW statements using the simple parser. Any connection variable that is not covered by a regular expression client-side statement, will be picked up by this simple parser. In a following step, all regex-based client-side statements will be removed, and the parsing will happen using the simple parser. This further simplifies and unifies all client-side statement parsing and handling, and makes all connection variables transactional. * chore: fix formatting * chore: use a callback to supply tx opts (#496) * chore: use a callback to supply tx opts Use a callback to supply transaction options, so changes to the connection variables at the start of a transaction (before it has actually been activated) are also included in the transaction. This is necessary to support SET LOCAL statements that have an impact on the actual transaction, such as the following example script: ``` BEGIN TRANSACTION; SET LOCAL ISOLATION_LEVEL='repeatable_read'; UPDATE my_table SET my_col=1 WHERE id=1; COMMIT; ``` This change depends on googleapis/google-cloud-go#12779 * fix: update all dependencies (#492) * fix: update all dependencies * chore: go mod tidy and update tests Update tests to match the behavior of using multiplexed sessions by default for all operations. --------- Co-authored-by: Knut Olav Løite <koloite@gmail.com> * feat: use a single multiplexed session for all operations (#500) The Spanner database/sql driver now uses a single multiplexed session for all operations. Setting a value for MinSessions and MaxSessions is therefore no longer necessary for workloads that have a significantly higher or lower usage than can normally be served by the default session pool. One multiplexed session can execute any number of both read-only and read/write transactions concurrently. See https://cloud.google.com/spanner/docs/sessions#multiplexed_sessions for more information on multiplexed sessions. * chore: fix some flaky test cases (#499) * chore: replace ExecOptions for connection variables (#497) * chore: replace ExecOptions for connection variables Replaces all ExecOptions with actual connection variables, and makes the ExecOptions field a real temporary field that is only used when the application passes in an ExecOptions instance as an argument for a statement. * feat: use a single multiplexed session for all operations (#500) The Spanner database/sql driver now uses a single multiplexed session for all operations. Setting a value for MinSessions and MaxSessions is therefore no longer necessary for workloads that have a significantly higher or lower usage than can normally be served by the default session pool. One multiplexed session can execute any number of both read-only and read/write transactions concurrently. See https://cloud.google.com/spanner/docs/sessions#multiplexed_sessions for more information on multiplexed sessions. * chore: fix some flaky test cases (#499) * feat: create/drop database statements (#502) Support CREATE DATABASE and DROP DATABASE statements. --------- Co-authored-by: Mend Renovate <bot@renovateapp.com> --------- Co-authored-by: Sanjeev Bhatt <bhatt4982@gmail.com> Co-authored-by: Mend Renovate <bot@renovateapp.com> --------- Co-authored-by: Sanjeev Bhatt <bhatt4982@gmail.com> Co-authored-by: Mend Renovate <bot@renovateapp.com>
1 parent c0781a7 commit bc1ba00

27 files changed

+3357
-704
lines changed

batch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ type batch struct {
2727
tp batchType
2828
statements []spanner.Statement
2929
returnValues []int64
30-
options ExecOptions
30+
options *ExecOptions
3131
automatic bool
3232
}

benchmarks/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ require (
3535
github.com/go-logr/logr v1.4.3 // indirect
3636
github.com/go-logr/stdr v1.2.2 // indirect
3737
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
38+
github.com/golang/protobuf v1.5.4 // indirect
3839
github.com/google/s2a-go v0.1.9 // indirect
3940
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
4041
github.com/googleapis/gax-go/v2 v2.15.0 // indirect

client_side_statement.go

Lines changed: 17 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import (
4848
type statementExecutor struct {
4949
}
5050

51-
func (s *statementExecutor) ShowCommitTimestamp(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
51+
func (s *statementExecutor) ShowCommitTimestamp(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
5252
ts, err := c.CommitTimestamp()
5353
var commitTs *time.Time
5454
if err == nil {
@@ -61,103 +61,71 @@ func (s *statementExecutor) ShowCommitTimestamp(_ context.Context, c *conn, _ st
6161
return createRows(it, opts), nil
6262
}
6363

64-
func (s *statementExecutor) ShowRetryAbortsInternally(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
64+
func (s *statementExecutor) ShowRetryAbortsInternally(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
6565
it, err := createBooleanIterator("RetryAbortsInternally", c.RetryAbortsInternally())
6666
if err != nil {
6767
return nil, err
6868
}
6969
return createRows(it, opts), nil
7070
}
7171

72-
func (s *statementExecutor) ShowAutoBatchDml(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
72+
func (s *statementExecutor) ShowAutoBatchDml(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
7373
it, err := createBooleanIterator("AutoBatchDml", c.AutoBatchDml())
7474
if err != nil {
7575
return nil, err
7676
}
7777
return createRows(it, opts), nil
7878
}
7979

80-
func (s *statementExecutor) ShowAutoBatchDmlUpdateCount(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
80+
func (s *statementExecutor) ShowAutoBatchDmlUpdateCount(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
8181
it, err := createInt64Iterator("AutoBatchDmlUpdateCount", c.AutoBatchDmlUpdateCount())
8282
if err != nil {
8383
return nil, err
8484
}
8585
return createRows(it, opts), nil
8686
}
8787

88-
func (s *statementExecutor) ShowAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, opts ExecOptions, _ string, _ []driver.NamedValue) (driver.Rows, error) {
88+
func (s *statementExecutor) ShowAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, opts *ExecOptions, _ string, _ []driver.NamedValue) (driver.Rows, error) {
8989
it, err := createBooleanIterator("AutoBatchDmlUpdateCountVerification", c.AutoBatchDmlUpdateCountVerification())
9090
if err != nil {
9191
return nil, err
9292
}
9393
return createRows(it, opts), nil
9494
}
9595

96-
func (s *statementExecutor) ShowAutocommitDmlMode(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
96+
func (s *statementExecutor) ShowAutocommitDmlMode(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
9797
it, err := createStringIterator("AutocommitDMLMode", c.AutocommitDMLMode().String())
9898
if err != nil {
9999
return nil, err
100100
}
101101
return createRows(it, opts), nil
102102
}
103103

104-
func (s *statementExecutor) ShowReadOnlyStaleness(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
104+
func (s *statementExecutor) ShowReadOnlyStaleness(_ context.Context, c *conn, _ string, opts *ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
105105
it, err := createStringIterator("ReadOnlyStaleness", c.ReadOnlyStaleness().String())
106106
if err != nil {
107107
return nil, err
108108
}
109109
return createRows(it, opts), nil
110110
}
111111

112-
func (s *statementExecutor) ShowExcludeTxnFromChangeStreams(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
113-
it, err := createBooleanIterator("ExcludeTxnFromChangeStreams", c.ExcludeTxnFromChangeStreams())
114-
if err != nil {
115-
return nil, err
116-
}
117-
return createRows(it, opts), nil
118-
}
119-
120-
func (s *statementExecutor) ShowMaxCommitDelay(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
121-
it, err := createStringIterator("MaxCommitDelay", c.MaxCommitDelay().String())
122-
if err != nil {
123-
return nil, err
124-
}
125-
return createRows(it, opts), nil
126-
}
127-
128-
func (s *statementExecutor) ShowTransactionTag(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
129-
it, err := createStringIterator("TransactionTag", c.TransactionTag())
130-
if err != nil {
131-
return nil, err
132-
}
133-
return createRows(it, opts), nil
134-
}
135-
136-
func (s *statementExecutor) ShowStatementTag(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
137-
it, err := createStringIterator("StatementTag", c.StatementTag())
138-
if err != nil {
139-
return nil, err
140-
}
141-
return createRows(it, opts), nil
142-
}
143-
144-
func (s *statementExecutor) StartBatchDdl(_ context.Context, c *conn, _ string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
112+
func (s *statementExecutor) StartBatchDdl(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
145113
return c.startBatchDDL()
146114
}
147115

148-
func (s *statementExecutor) StartBatchDml(_ context.Context, c *conn, _ string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
116+
func (s *statementExecutor) StartBatchDml(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
149117
return c.startBatchDML( /* automatic = */ false)
150118
}
151119

152-
func (s *statementExecutor) RunBatch(ctx context.Context, c *conn, _ string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
120+
func (s *statementExecutor) RunBatch(ctx context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
153121
return c.runBatch(ctx)
154122
}
155123

156-
func (s *statementExecutor) AbortBatch(_ context.Context, c *conn, _ string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
124+
func (s *statementExecutor) AbortBatch(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
157125
return c.abortBatch()
158126
}
159127

160-
func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
128+
func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
161129
if params == "" {
162130
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for RetryAbortsInternally"))
163131
}
@@ -168,19 +136,19 @@ func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn,
168136
return c.setRetryAbortsInternally(retry)
169137
}
170138

171-
func (s *statementExecutor) SetAutoBatchDml(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
139+
func (s *statementExecutor) SetAutoBatchDml(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
172140
return setBoolVariable("AutoBatchDml", func(value bool) (driver.Result, error) {
173141
return driver.ResultNoRows, c.SetAutoBatchDml(value)
174142
}, params)
175143
}
176144

177-
func (s *statementExecutor) SetAutoBatchDmlUpdateCount(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
145+
func (s *statementExecutor) SetAutoBatchDmlUpdateCount(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
178146
return setInt64Variable("AutoBatchDmlUpdateCount", func(value int64) (driver.Result, error) {
179147
return driver.ResultNoRows, c.SetAutoBatchDmlUpdateCount(value)
180148
}, params)
181149
}
182150

183-
func (s *statementExecutor) SetAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
151+
func (s *statementExecutor) SetAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
184152
return setBoolVariable("AutoBatchDmlUpdateCountVerification", func(value bool) (driver.Result, error) {
185153
return driver.ResultNoRows, c.SetAutoBatchDmlUpdateCountVerification(value)
186154
}, params)
@@ -208,7 +176,7 @@ func setInt64Variable(name string, f func(value int64) (driver.Result, error), p
208176
return f(value)
209177
}
210178

211-
func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
179+
func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
212180
if params == "" {
213181
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for AutocommitDMLMode"))
214182
}
@@ -224,63 +192,13 @@ func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, par
224192
return c.setAutocommitDMLMode(mode)
225193
}
226194

227-
func (s *statementExecutor) SetExcludeTxnFromChangeStreams(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
228-
if params == "" {
229-
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for ExcludeTxnFromChangeStreams"))
230-
}
231-
exclude, err := strconv.ParseBool(params)
232-
if err != nil {
233-
return nil, spanner.ToSpannerError(status.Errorf(codes.InvalidArgument, "invalid boolean value: %s", params))
234-
}
235-
return c.setExcludeTxnFromChangeStreams(exclude)
236-
}
237-
238-
var maxCommitDelayRegexp = regexp.MustCompile(`(?i)^\s*('(?P<duration>(\d{1,19})(s|ms|us|ns))'|(?P<number>\d{1,19})|(?P<null>NULL))\s*$`)
239-
240-
func (s *statementExecutor) SetMaxCommitDelay(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
241-
duration, err := parseDuration(maxCommitDelayRegexp, "max_commit_delay", params)
242-
if err != nil {
243-
return nil, err
244-
}
245-
return c.setMaxCommitDelay(duration)
246-
}
247-
248-
func (s *statementExecutor) SetTransactionTag(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
249-
tag, err := parseTag(params)
250-
if err != nil {
251-
return nil, err
252-
}
253-
return c.setTransactionTag(tag)
254-
}
255-
256-
func (s *statementExecutor) SetStatementTag(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
257-
tag, err := parseTag(params)
258-
if err != nil {
259-
return nil, err
260-
}
261-
return c.setStatementTag(tag)
262-
}
263-
264-
func parseTag(params string) (string, error) {
265-
if params == "" {
266-
return "", spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for tag"))
267-
}
268-
tag := strings.TrimSpace(params)
269-
if !(strings.HasPrefix(tag, "'") && strings.HasSuffix(tag, "'")) {
270-
return "", spanner.ToSpannerError(status.Error(codes.InvalidArgument, "missing single quotes around tag"))
271-
}
272-
tag = strings.TrimLeft(tag, "'")
273-
tag = strings.TrimRight(tag, "'")
274-
return tag, nil
275-
}
276-
277195
var strongRegexp = regexp.MustCompile("(?i)'STRONG'")
278196
var exactStalenessRegexp = regexp.MustCompile(`(?i)'(?P<type>EXACT_STALENESS)[\t ]+(?P<duration>(\d{1,19})(s|ms|us|ns))'`)
279197
var maxStalenessRegexp = regexp.MustCompile(`(?i)'(?P<type>MAX_STALENESS)[\t ]+(?P<duration>(\d{1,19})(s|ms|us|ns))'`)
280198
var readTimestampRegexp = regexp.MustCompile(`(?i)'(?P<type>READ_TIMESTAMP)[\t ]+(?P<timestamp>(\d{4})-(\d{2})-(\d{2})([Tt](\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?)([Zz]|([+-])(\d{2}):(\d{2})))'`)
281199
var minReadTimestampRegexp = regexp.MustCompile(`(?i)'(?P<type>MIN_READ_TIMESTAMP)[\t ]+(?P<timestamp>(\d{4})-(\d{2})-(\d{2})([Tt](\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?)([Zz]|([+-])(\d{2}):(\d{2})))'`)
282200

283-
func (s *statementExecutor) SetReadOnlyStaleness(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
201+
func (s *statementExecutor) SetReadOnlyStaleness(_ context.Context, c *conn, params string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
284202
if params == "" {
285203
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for ReadOnlyStaleness"))
286204
}

0 commit comments

Comments
 (0)