@@ -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 (
4848type 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
238238var 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 ]+(
280280var 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})))'` )
281281var 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
429440func (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