Skip to content

Commit b035014

Browse files
authored
chore: cache parsed statements and remove regex loading (#512)
Cache parsed statements and remove loading and checking for regex-based statements, as the latter is no an empty list.
1 parent aa9cdda commit b035014

File tree

5 files changed

+102
-317
lines changed

5 files changed

+102
-317
lines changed

client_side_statement.go

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,49 +15,13 @@
1515
package spannerdriver
1616

1717
import (
18-
"context"
19-
"database/sql/driver"
2018
"time"
2119

2220
"cloud.google.com/go/spanner"
2321
"cloud.google.com/go/spanner/apiv1/spannerpb"
2422
"google.golang.org/api/iterator"
2523
)
2624

27-
// statementExecutor is an empty struct that is used to hold the execution methods
28-
// of the different client side statements. This makes it possible to look up the
29-
// methods using reflection, which is not possible if the methods do not belong to
30-
// a struct. The methods all accept the same arguments and return the same types.
31-
// This is to ensure that they can be assigned to a compiled clientSideStatement.
32-
//
33-
// The different methods of statementExecutor are invoked by a connection when one
34-
// of the valid client side statements is executed on a connection. These methods
35-
// are responsible for any argument parsing and translating that might be needed
36-
// before the corresponding method on the connection can be called.
37-
//
38-
// The names of the methods are exactly equal to the naming in the
39-
// client_side_statements.json file. This means that some methods do not adhere
40-
// to the Go style guide, as these method names are equal for all languages that
41-
// implement the Connection API.
42-
type statementExecutor struct {
43-
}
44-
45-
func (s *statementExecutor) StartBatchDdl(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
46-
return c.startBatchDDL()
47-
}
48-
49-
func (s *statementExecutor) StartBatchDml(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
50-
return c.startBatchDML( /* automatic = */ false)
51-
}
52-
53-
func (s *statementExecutor) RunBatch(ctx context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
54-
return c.runBatch(ctx)
55-
}
56-
57-
func (s *statementExecutor) AbortBatch(_ context.Context, c *conn, _ string, _ *ExecOptions, _ []driver.NamedValue) (driver.Result, error) {
58-
return c.abortBatch()
59-
}
60-
6125
func createEmptyIterator() *clientSideIterator {
6226
return &clientSideIterator{
6327
metadata: &spannerpb.ResultSetMetadata{

client_side_statement_test.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,27 @@ import (
3636
func TestStatementExecutor_StartBatchDdl(t *testing.T) {
3737
t.Parallel()
3838

39-
c := &conn{logger: noopLogger, state: createInitialConnectionState(connectionstate.TypeNonTransactional, map[string]connectionstate.ConnectionPropertyValue{})}
40-
s := &statementExecutor{}
39+
parser, _ := newStatementParser(databasepb.DatabaseDialect_GOOGLE_STANDARD_SQL, 1000)
40+
c := &conn{
41+
logger: noopLogger,
42+
state: createInitialConnectionState(connectionstate.TypeNonTransactional, map[string]connectionstate.ConnectionPropertyValue{}),
43+
parser: parser,
44+
}
4145
ctx := context.Background()
4246

4347
if c.InDDLBatch() {
4448
t.Fatal("connection unexpectedly in a DDL batch")
4549
}
46-
if _, err := s.StartBatchDdl(ctx, c, "", &ExecOptions{}, nil); err != nil {
50+
if _, err := c.ExecContext(ctx, "start batch ddl", []driver.NamedValue{}); err != nil {
4751
t.Fatalf("could not start a DDL batch: %v", err)
4852
}
4953
if !c.InDDLBatch() {
5054
t.Fatal("connection unexpectedly not in a DDL batch")
5155
}
52-
if _, err := s.StartBatchDdl(ctx, c, "", &ExecOptions{}, nil); spanner.ErrCode(err) != codes.FailedPrecondition {
56+
if _, err := c.ExecContext(ctx, "start batch ddl", []driver.NamedValue{}); spanner.ErrCode(err) != codes.FailedPrecondition {
5357
t.Fatalf("error mismatch for starting a DDL batch while already in a batch\nGot: %v\nWant: %v", spanner.ErrCode(err), codes.FailedPrecondition)
5458
}
55-
if _, err := s.RunBatch(ctx, c, "", &ExecOptions{}, nil); err != nil {
59+
if _, err := c.ExecContext(ctx, "run batch", []driver.NamedValue{}); err != nil {
5660
t.Fatalf("could not run empty DDL batch: %v", err)
5761
}
5862
if c.InDDLBatch() {
@@ -61,31 +65,35 @@ func TestStatementExecutor_StartBatchDdl(t *testing.T) {
6165

6266
// Starting a DDL batch while the connection is in a transaction is not allowed.
6367
c.tx = &readWriteTransaction{}
64-
if _, err := s.StartBatchDdl(ctx, c, "", &ExecOptions{}, nil); spanner.ErrCode(err) != codes.FailedPrecondition {
68+
if _, err := c.ExecContext(ctx, "start batch ddl", []driver.NamedValue{}); spanner.ErrCode(err) != codes.FailedPrecondition {
6569
t.Fatalf("error mismatch for starting a DDL batch while in a transaction\nGot: %v\nWant: %v", spanner.ErrCode(err), codes.FailedPrecondition)
6670
}
6771
}
6872

6973
func TestStatementExecutor_StartBatchDml(t *testing.T) {
7074
t.Parallel()
7175

72-
c := &conn{logger: noopLogger, state: createInitialConnectionState(connectionstate.TypeNonTransactional, map[string]connectionstate.ConnectionPropertyValue{})}
73-
s := &statementExecutor{}
76+
parser, _ := newStatementParser(databasepb.DatabaseDialect_GOOGLE_STANDARD_SQL, 1000)
77+
c := &conn{
78+
logger: noopLogger,
79+
state: createInitialConnectionState(connectionstate.TypeNonTransactional, map[string]connectionstate.ConnectionPropertyValue{}),
80+
parser: parser,
81+
}
7482
ctx := context.Background()
7583

7684
if c.InDMLBatch() {
7785
t.Fatal("connection unexpectedly in a DML batch")
7886
}
79-
if _, err := s.StartBatchDml(ctx, c, "", &ExecOptions{}, nil); err != nil {
87+
if _, err := c.ExecContext(ctx, "start batch dml", []driver.NamedValue{}); err != nil {
8088
t.Fatalf("could not start a DML batch: %v", err)
8189
}
8290
if !c.InDMLBatch() {
8391
t.Fatal("connection unexpectedly not in a DML batch")
8492
}
85-
if _, err := s.StartBatchDml(ctx, c, "", &ExecOptions{}, nil); spanner.ErrCode(err) != codes.FailedPrecondition {
93+
if _, err := c.ExecContext(ctx, "start batch dml", []driver.NamedValue{}); spanner.ErrCode(err) != codes.FailedPrecondition {
8694
t.Fatalf("error mismatch for starting a DML batch while already in a batch\nGot: %v\nWant: %v", spanner.ErrCode(err), codes.FailedPrecondition)
8795
}
88-
if _, err := s.RunBatch(ctx, c, "", &ExecOptions{}, nil); err != nil {
96+
if _, err := c.ExecContext(ctx, "run batch", []driver.NamedValue{}); err != nil {
8997
t.Fatalf("could not run empty DML batch: %v", err)
9098
}
9199
if c.InDMLBatch() {
@@ -94,13 +102,13 @@ func TestStatementExecutor_StartBatchDml(t *testing.T) {
94102

95103
// Starting a DML batch while the connection is in a read-only transaction is not allowed.
96104
c.tx = &readOnlyTransaction{logger: noopLogger}
97-
if _, err := s.StartBatchDml(ctx, c, "", &ExecOptions{}, nil); spanner.ErrCode(err) != codes.FailedPrecondition {
105+
if _, err := c.ExecContext(ctx, "start batch dml", []driver.NamedValue{}); spanner.ErrCode(err) != codes.FailedPrecondition {
98106
t.Fatalf("error mismatch for starting a DML batch while in a read-only transaction\nGot: %v\nWant: %v", spanner.ErrCode(err), codes.FailedPrecondition)
99107
}
100108

101109
// Starting a DML batch while the connection is in a read/write transaction is allowed.
102110
c.tx = &readWriteTransaction{logger: noopLogger}
103-
if _, err := s.StartBatchDml(ctx, c, "", &ExecOptions{}, nil); err != nil {
111+
if _, err := c.ExecContext(ctx, "start batch dml", []driver.NamedValue{}); err != nil {
104112
t.Fatalf("could not start a DML batch while in a read/write transaction: %v", err)
105113
}
106114
}

client_side_statements_json.go

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)