Skip to content

Commit 6667833

Browse files
committed
test: add more tests
1 parent 2de8b88 commit 6667833

File tree

12 files changed

+253
-185
lines changed

12 files changed

+253
-185
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
on:
2+
push:
3+
branches: [ main ]
4+
pull_request:
5+
name: Spanner Lib Tests
6+
jobs:
7+
test:
8+
strategy:
9+
matrix:
10+
go-version: [1.23.x, 1.24.x]
11+
os: [ubuntu-latest, macos-latest, windows-latest]
12+
runs-on: ${{ matrix.os }}
13+
steps:
14+
- name: Install Go
15+
uses: actions/setup-go@v5
16+
with:
17+
go-version: ${{ matrix.go-version }}
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
- name: Run unit tests
21+
working-directory: spannerlib/exported
22+
run: go test -race -short
23+
24+
build-lib:
25+
strategy:
26+
matrix:
27+
go-version: [1.23.x, 1.24.x]
28+
os: [ubuntu-latest, macos-latest, windows-latest]
29+
runs-on: ${{ matrix.os }}
30+
steps:
31+
- name: Install Go
32+
uses: actions/setup-go@v5
33+
with:
34+
go-version: ${{ matrix.go-version }}
35+
- name: Checkout code
36+
uses: actions/checkout@v4
37+
- name: Build shared lib
38+
working-directory: spannerlib
39+
run: go build -o spannerlib.so -buildmode=c-shared

client_side_statement.go

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ import (
1818
"context"
1919
"database/sql/driver"
2020
"fmt"
21-
"io"
2221
"regexp"
2322
"strconv"
2423
"strings"
2524
"time"
2625

2726
"cloud.google.com/go/spanner"
2827
"cloud.google.com/go/spanner/apiv1/spannerpb"
28+
"google.golang.org/api/iterator"
2929
"google.golang.org/grpc/codes"
3030
"google.golang.org/grpc/status"
3131
)
@@ -48,7 +48,7 @@ import (
4848
type statementExecutor struct {
4949
}
5050

51-
func (s *statementExecutor) ShowCommitTimestamp(_ context.Context, c *conn, _ string, _ []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 {
@@ -58,106 +58,106 @@ func (s *statementExecutor) ShowCommitTimestamp(_ context.Context, c *conn, _ st
5858
if err != nil {
5959
return nil, err
6060
}
61-
return &rows{it: it}, nil
61+
return createRows(it, opts), nil
6262
}
6363

64-
func (s *statementExecutor) ShowRetryAbortsInternally(_ context.Context, c *conn, _ string, _ []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
}
69-
return &rows{it: it}, nil
69+
return createRows(it, opts), nil
7070
}
7171

72-
func (s *statementExecutor) ShowAutoBatchDml(_ context.Context, c *conn, _ string, _ []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
}
77-
return &rows{it: it}, nil
77+
return createRows(it, opts), nil
7878
}
7979

80-
func (s *statementExecutor) ShowAutoBatchDmlUpdateCount(_ context.Context, c *conn, _ string, _ []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
}
85-
return &rows{it: it}, nil
85+
return createRows(it, opts), nil
8686
}
8787

88-
func (s *statementExecutor) ShowAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, _ 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
}
93-
return &rows{it: it}, nil
93+
return createRows(it, opts), nil
9494
}
9595

96-
func (s *statementExecutor) ShowAutocommitDmlMode(_ context.Context, c *conn, _ string, _ []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
}
101-
return &rows{it: it}, nil
101+
return createRows(it, opts), nil
102102
}
103103

104-
func (s *statementExecutor) ShowReadOnlyStaleness(_ context.Context, c *conn, _ string, _ []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
}
109-
return &rows{it: it}, nil
109+
return createRows(it, opts), nil
110110
}
111111

112-
func (s *statementExecutor) ShowExcludeTxnFromChangeStreams(_ context.Context, c *conn, _ string, _ []driver.NamedValue) (driver.Rows, error) {
112+
func (s *statementExecutor) ShowExcludeTxnFromChangeStreams(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
113113
it, err := createBooleanIterator("ExcludeTxnFromChangeStreams", c.ExcludeTxnFromChangeStreams())
114114
if err != nil {
115115
return nil, err
116116
}
117-
return &rows{it: it}, nil
117+
return createRows(it, opts), nil
118118
}
119119

120-
func (s *statementExecutor) ShowMaxCommitDelay(_ context.Context, c *conn, _ string, _ []driver.NamedValue) (driver.Rows, error) {
120+
func (s *statementExecutor) ShowMaxCommitDelay(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
121121
it, err := createStringIterator("MaxCommitDelay", c.MaxCommitDelay().String())
122122
if err != nil {
123123
return nil, err
124124
}
125-
return &rows{it: it}, nil
125+
return createRows(it, opts), nil
126126
}
127127

128-
func (s *statementExecutor) ShowTransactionTag(_ context.Context, c *conn, _ string, _ []driver.NamedValue) (driver.Rows, error) {
128+
func (s *statementExecutor) ShowTransactionTag(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
129129
it, err := createStringIterator("TransactionTag", c.TransactionTag())
130130
if err != nil {
131131
return nil, err
132132
}
133-
return &rows{it: it}, nil
133+
return createRows(it, opts), nil
134134
}
135135

136-
func (s *statementExecutor) ShowStatementTag(_ context.Context, c *conn, _ string, _ []driver.NamedValue) (driver.Rows, error) {
136+
func (s *statementExecutor) ShowStatementTag(_ context.Context, c *conn, _ string, opts ExecOptions, _ []driver.NamedValue) (driver.Rows, error) {
137137
it, err := createStringIterator("StatementTag", c.StatementTag())
138138
if err != nil {
139139
return nil, err
140140
}
141-
return &rows{it: it}, nil
141+
return createRows(it, opts), nil
142142
}
143143

144-
func (s *statementExecutor) StartBatchDdl(_ context.Context, c *conn, _ string, _ []driver.NamedValue) (driver.Result, error) {
144+
func (s *statementExecutor) StartBatchDdl(_ context.Context, c *conn, _ string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
145145
return c.startBatchDDL()
146146
}
147147

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

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

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

160-
func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
160+
func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
161161
if params == "" {
162162
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for RetryAbortsInternally"))
163163
}
@@ -168,19 +168,19 @@ func (s *statementExecutor) SetRetryAbortsInternally(_ context.Context, c *conn,
168168
return c.setRetryAbortsInternally(retry)
169169
}
170170

171-
func (s *statementExecutor) SetAutoBatchDml(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
171+
func (s *statementExecutor) SetAutoBatchDml(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
172172
return setBoolVariable("AutoBatchDml", func(value bool) (driver.Result, error) {
173173
return driver.ResultNoRows, c.SetAutoBatchDml(value)
174174
}, params)
175175
}
176176

177-
func (s *statementExecutor) SetAutoBatchDmlUpdateCount(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
177+
func (s *statementExecutor) SetAutoBatchDmlUpdateCount(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
178178
return setInt64Variable("AutoBatchDmlUpdateCount", func(value int64) (driver.Result, error) {
179179
return driver.ResultNoRows, c.SetAutoBatchDmlUpdateCount(value)
180180
}, params)
181181
}
182182

183-
func (s *statementExecutor) SetAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
183+
func (s *statementExecutor) SetAutoBatchDmlUpdateCountVerification(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
184184
return setBoolVariable("AutoBatchDmlUpdateCountVerification", func(value bool) (driver.Result, error) {
185185
return driver.ResultNoRows, c.SetAutoBatchDmlUpdateCountVerification(value)
186186
}, params)
@@ -208,7 +208,7 @@ func setInt64Variable(name string, f func(value int64) (driver.Result, error), p
208208
return f(value)
209209
}
210210

211-
func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
211+
func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
212212
if params == "" {
213213
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for AutocommitDMLMode"))
214214
}
@@ -224,7 +224,7 @@ func (s *statementExecutor) SetAutocommitDmlMode(_ context.Context, c *conn, par
224224
return c.setAutocommitDMLMode(mode)
225225
}
226226

227-
func (s *statementExecutor) SetExcludeTxnFromChangeStreams(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
227+
func (s *statementExecutor) SetExcludeTxnFromChangeStreams(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
228228
if params == "" {
229229
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for ExcludeTxnFromChangeStreams"))
230230
}
@@ -237,23 +237,23 @@ func (s *statementExecutor) SetExcludeTxnFromChangeStreams(_ context.Context, c
237237

238238
var maxCommitDelayRegexp = regexp.MustCompile(`(?i)^\s*('(?P<duration>(\d{1,19})(s|ms|us|ns))'|(?P<number>\d{1,19})|(?P<null>NULL))\s*$`)
239239

240-
func (s *statementExecutor) SetMaxCommitDelay(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
240+
func (s *statementExecutor) SetMaxCommitDelay(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
241241
duration, err := parseDuration(maxCommitDelayRegexp, "max_commit_delay", params)
242242
if err != nil {
243243
return nil, err
244244
}
245245
return c.setMaxCommitDelay(duration)
246246
}
247247

248-
func (s *statementExecutor) SetTransactionTag(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
248+
func (s *statementExecutor) SetTransactionTag(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
249249
tag, err := parseTag(params)
250250
if err != nil {
251251
return nil, err
252252
}
253253
return c.setTransactionTag(tag)
254254
}
255255

256-
func (s *statementExecutor) SetStatementTag(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
256+
func (s *statementExecutor) SetStatementTag(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
257257
tag, err := parseTag(params)
258258
if err != nil {
259259
return nil, err
@@ -280,7 +280,7 @@ var maxStalenessRegexp = regexp.MustCompile(`(?i)'(?P<type>MAX_STALENESS)[\t ]+(
280280
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})))'`)
281281
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})))'`)
282282

283-
func (s *statementExecutor) SetReadOnlyStaleness(_ context.Context, c *conn, params string, _ []driver.NamedValue) (driver.Result, error) {
283+
func (s *statementExecutor) SetReadOnlyStaleness(_ context.Context, c *conn, params string, _ ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
284284
if params == "" {
285285
return nil, spanner.ToSpannerError(status.Error(codes.InvalidArgument, "no value given for ReadOnlyStaleness"))
286286
}
@@ -369,6 +369,17 @@ func matchesToMap(re *regexp.Regexp, s string) map[string]string {
369369
return matches
370370
}
371371

372+
func createEmptyIterator() *clientSideIterator {
373+
return &clientSideIterator{
374+
metadata: &spannerpb.ResultSetMetadata{
375+
RowType: &spannerpb.StructType{
376+
Fields: []*spannerpb.StructType_Field{},
377+
},
378+
},
379+
rows: []*spanner.Row{},
380+
}
381+
}
382+
372383
// createBooleanIterator creates a row iterator with a single BOOL column with
373384
// one row. This is used for client side statements that return a result set
374385
// containing a BOOL value.
@@ -428,7 +439,7 @@ type clientSideIterator struct {
428439

429440
func (t *clientSideIterator) Next() (*spanner.Row, error) {
430441
if t.index == len(t.rows) {
431-
return nil, io.EOF
442+
return nil, iterator.Done
432443
}
433444
row := t.rows[t.index]
434445
t.index++

0 commit comments

Comments
 (0)