Skip to content

Commit 3bd352e

Browse files
committed
Merge Update Keyspace/Table name in prepared Query statement (#1714)
2 parents 1519a00 + 65f29c8 commit 3bd352e

File tree

10 files changed

+166
-29
lines changed

10 files changed

+166
-29
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,4 @@ Lauro Ramos Venancio <[email protected]>
140140
Dmitry Kropachev <[email protected]>
141141
Oliver Boyle <[email protected]>
142142
Jackson Fleming <[email protected]>
143+
Sylwia Szunejko <[email protected]>

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- Added the InstaclustrPasswordAuthenticator to the list of default approved authenticators.
1111
- Added the `com.scylladb.auth.SaslauthdAuthenticator` and `com.scylladb.auth.TransitionalAuthenticator`
1212
to the list of default approved authenticators.
13+
- Added transferring Keyspace and Table names to the Query from the prepared response and updating
14+
information about that every time this information is received
1315
### Changed
1416

1517
### Fixed

cass1batch_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func TestShouldPrepareFunction(t *testing.T) {
5353
}
5454

5555
for _, test := range shouldPrepareTests {
56-
q := &Query{stmt: test.Stmt}
56+
q := &Query{stmt: test.Stmt, routingInfo: &queryRoutingInfo{}}
5757
if got := q.shouldPrepare(); got != test.Result {
5858
t.Fatalf("%q: got %v, expected %v\n", test.Stmt, got, test.Result)
5959
}

conn.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,12 @@ func (c *Conn) executeQuery(ctx context.Context, qry *Query) *Iter {
13781378
params: params,
13791379
customPayload: qry.customPayload,
13801380
}
1381+
1382+
// Set "keyspace" and "table" property in the query if it is present in preparedMetadata
1383+
qry.routingInfo.mu.Lock()
1384+
qry.routingInfo.keyspace = info.request.keyspace
1385+
qry.routingInfo.table = info.request.table
1386+
qry.routingInfo.mu.Unlock()
13811387
} else {
13821388
frame = &writeQueryFrame{
13831389
statement: qry.stmt,

frame.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ type preparedMetadata struct {
918918

919919
// proto v4+
920920
pkeyColumns []int
921+
922+
keyspace string
923+
924+
table string
921925
}
922926

923927
func (r preparedMetadata) String() string {
@@ -952,26 +956,25 @@ func (f *framer) parsePreparedMetadata() preparedMetadata {
952956
return meta
953957
}
954958

955-
var keyspace, table string
956959
globalSpec := meta.flags&flagGlobalTableSpec == flagGlobalTableSpec
957960
if globalSpec {
958-
keyspace = f.readString()
959-
table = f.readString()
961+
meta.keyspace = f.readString()
962+
meta.table = f.readString()
960963
}
961964

962965
var cols []ColumnInfo
963966
if meta.colCount < 1000 {
964967
// preallocate columninfo to avoid excess copying
965968
cols = make([]ColumnInfo, meta.colCount)
966969
for i := 0; i < meta.colCount; i++ {
967-
f.readCol(&cols[i], &meta.resultMetadata, globalSpec, keyspace, table)
970+
f.readCol(&cols[i], &meta.resultMetadata, globalSpec, meta.keyspace, meta.table)
968971
}
969972
} else {
970973
// use append, huge number of columns usually indicates a corrupt frame or
971974
// just a huge row.
972975
for i := 0; i < meta.colCount; i++ {
973976
var col ColumnInfo
974-
f.readCol(&col, &meta.resultMetadata, globalSpec, keyspace, table)
977+
f.readCol(&col, &meta.resultMetadata, globalSpec, meta.keyspace, meta.table)
975978
cols = append(cols, col)
976979
}
977980
}

keyspace_table_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//go:build all || integration
2+
// +build all integration
3+
4+
package gocql
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"testing"
10+
)
11+
12+
// Keyspace_table checks if Query.Keyspace() is updated based on prepared statement
13+
func TestKeyspaceTable(t *testing.T) {
14+
cluster := createCluster()
15+
16+
fallback := RoundRobinHostPolicy()
17+
cluster.PoolConfig.HostSelectionPolicy = TokenAwareHostPolicy(fallback)
18+
19+
session, err := cluster.CreateSession()
20+
if err != nil {
21+
t.Fatal("createSession:", err)
22+
}
23+
24+
cluster.Keyspace = "wrong_keyspace"
25+
26+
keyspace := "test1"
27+
table := "table1"
28+
29+
err = createTable(session, `DROP KEYSPACE IF EXISTS `+keyspace)
30+
if err != nil {
31+
t.Fatal("unable to drop keyspace:", err)
32+
}
33+
34+
err = createTable(session, fmt.Sprintf(`CREATE KEYSPACE %s
35+
WITH replication = {
36+
'class' : 'SimpleStrategy',
37+
'replication_factor' : 1
38+
}`, keyspace))
39+
40+
if err != nil {
41+
t.Fatal("unable to create keyspace:", err)
42+
}
43+
44+
if err := session.control.awaitSchemaAgreement(); err != nil {
45+
t.Fatal(err)
46+
}
47+
48+
err = createTable(session, fmt.Sprintf(`CREATE TABLE %s.%s (pk int, ck int, v int, PRIMARY KEY (pk, ck));
49+
`, keyspace, table))
50+
51+
if err != nil {
52+
t.Fatal("unable to create table:", err)
53+
}
54+
55+
if err := session.control.awaitSchemaAgreement(); err != nil {
56+
t.Fatal(err)
57+
}
58+
59+
ctx := context.Background()
60+
61+
// insert a row
62+
if err := session.Query(`INSERT INTO test1.table1(pk, ck, v) VALUES (?, ?, ?)`,
63+
1, 2, 3).WithContext(ctx).Consistency(One).Exec(); err != nil {
64+
t.Fatal(err)
65+
}
66+
67+
var pk int
68+
69+
/* Search for a specific set of records whose 'pk' column matches
70+
* the value of inserted row. */
71+
qry := session.Query(`SELECT pk FROM test1.table1 WHERE pk = ? LIMIT 1`,
72+
1).WithContext(ctx).Consistency(One)
73+
if err := qry.Scan(&pk); err != nil {
74+
t.Fatal(err)
75+
}
76+
77+
// cluster.Keyspace was set to "wrong_keyspace", but during prepering statement
78+
// Keyspace in Query should be changed to "test" and Table should be changed to table1
79+
assertEqual(t, "qry.Keyspace()", "test1", qry.Keyspace())
80+
assertEqual(t, "qry.Table()", "table1", qry.Table())
81+
}

policies_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestHostPolicy_TokenAware_SimpleStrategy(t *testing.T) {
5454
return nil, errors.New("not initalized")
5555
}
5656

57-
query := &Query{}
57+
query := &Query{routingInfo: &queryRoutingInfo{}}
5858
query.getKeyspace = func() string { return keyspace }
5959

6060
iter := policy.Pick(nil)
@@ -201,7 +201,7 @@ func TestHostPolicy_TokenAware_NilHostInfo(t *testing.T) {
201201
}
202202
policy.SetPartitioner("OrderedPartitioner")
203203

204-
query := &Query{}
204+
query := &Query{routingInfo: &queryRoutingInfo{}}
205205
query.getKeyspace = func() string { return "myKeyspace" }
206206
query.RoutingKey([]byte("20"))
207207

@@ -259,7 +259,7 @@ func TestCOWList_Add(t *testing.T) {
259259

260260
// TestSimpleRetryPolicy makes sure that we only allow 1 + numRetries attempts
261261
func TestSimpleRetryPolicy(t *testing.T) {
262-
q := &Query{}
262+
q := &Query{routingInfo: &queryRoutingInfo{}}
263263

264264
// this should allow a total of 3 tries.
265265
rt := &SimpleRetryPolicy{NumRetries: 2}
@@ -317,7 +317,7 @@ func TestExponentialBackoffPolicy(t *testing.T) {
317317

318318
func TestDowngradingConsistencyRetryPolicy(t *testing.T) {
319319

320-
q := &Query{cons: LocalQuorum}
320+
q := &Query{cons: LocalQuorum, routingInfo: &queryRoutingInfo{}}
321321

322322
rewt0 := &RequestErrWriteTimeout{
323323
Received: 0,
@@ -478,7 +478,7 @@ func TestHostPolicy_TokenAware(t *testing.T) {
478478
return nil, errors.New("not initialized")
479479
}
480480

481-
query := &Query{}
481+
query := &Query{routingInfo: &queryRoutingInfo{}}
482482
query.getKeyspace = func() string { return keyspace }
483483

484484
iter := policy.Pick(nil)
@@ -580,7 +580,7 @@ func TestHostPolicy_TokenAware_NetworkStrategy(t *testing.T) {
580580
return nil, errors.New("not initialized")
581581
}
582582

583-
query := &Query{}
583+
query := &Query{routingInfo: &queryRoutingInfo{}}
584584
query.getKeyspace = func() string { return keyspace }
585585

586586
iter := policy.Pick(nil)
@@ -707,7 +707,7 @@ func TestHostPolicy_TokenAware_RackAware(t *testing.T) {
707707
policyWithFallbackInternal.getKeyspaceName = policyInternal.getKeyspaceName
708708
policyWithFallbackInternal.getKeyspaceMetadata = policyInternal.getKeyspaceMetadata
709709

710-
query := &Query{}
710+
query := &Query{routingInfo: &queryRoutingInfo{}}
711711
query.getKeyspace = func() string { return keyspace }
712712

713713
iter := policy.Pick(nil)

query_executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type ExecutableQuery interface {
1515
speculativeExecutionPolicy() SpeculativeExecutionPolicy
1616
GetRoutingKey() ([]byte, error)
1717
Keyspace() string
18+
Table() string
1819
IsIdempotent() bool
1920

2021
withContext(context.Context) ExecutableQuery

0 commit comments

Comments
 (0)