@@ -33,6 +33,7 @@ import (
33
33
"context"
34
34
"crypto/tls"
35
35
"crypto/x509"
36
+ "encoding/binary"
36
37
"errors"
37
38
"fmt"
38
39
"io"
@@ -952,6 +953,28 @@ func TestWriteCoalescing_WriteAfterClose(t *testing.T) {
952
953
}
953
954
}
954
955
956
+ func TestSkipMetadata (t * testing.T ) {
957
+ ctx , cancel := context .WithCancel (context .Background ())
958
+ defer cancel ()
959
+
960
+ srv := NewTestServer (t , protoVersion4 , ctx )
961
+ defer srv .Stop ()
962
+
963
+ db , err := newTestSession (protoVersion4 , srv .Address )
964
+ if err != nil {
965
+ t .Fatalf ("NewCluster: %v" , err )
966
+ }
967
+ defer db .Close ()
968
+
969
+ if err := db .Query ("select nometadata" ).Exec (); err != nil {
970
+ t .Fatalf ("expected no error got: %v" , err )
971
+ }
972
+
973
+ if err := db .Query ("select metadata" ).Exec (); err != nil {
974
+ t .Fatalf ("expected no error got: %v" , err )
975
+ }
976
+ }
977
+
955
978
type recordingFrameHeaderObserver struct {
956
979
t * testing.T
957
980
mu sync.Mutex
@@ -1264,6 +1287,99 @@ func (srv *TestServer) process(conn net.Conn, reqFrame *framer) {
1264
1287
case opError :
1265
1288
respFrame .writeHeader (0 , opError , head .stream )
1266
1289
respFrame .buf = append (respFrame .buf , reqFrame .buf ... )
1290
+ case opPrepare :
1291
+ query := reqFrame .readLongString ()
1292
+ name := strings .TrimPrefix (query , "select " )
1293
+ if n := strings .Index (name , " " ); n > 0 {
1294
+ name = name [:n ]
1295
+ }
1296
+ switch strings .ToLower (name ) {
1297
+ case "nometadata" :
1298
+ respFrame .writeHeader (0 , opResult , head .stream )
1299
+ respFrame .writeInt (resultKindPrepared )
1300
+ // <id>
1301
+ respFrame .writeShortBytes (binary .BigEndian .AppendUint64 (nil , 1 ))
1302
+ // <metadata>
1303
+ respFrame .writeInt (0 ) // <flags>
1304
+ respFrame .writeInt (0 ) // <columns_count>
1305
+ if srv .protocol >= protoVersion4 {
1306
+ respFrame .writeInt (0 ) // <pk_count>
1307
+ }
1308
+ // <result_metadata>
1309
+ respFrame .writeInt (int32 (flagNoMetaData )) // <flags>
1310
+ respFrame .writeInt (0 )
1311
+ case "metadata" :
1312
+ respFrame .writeHeader (0 , opResult , head .stream )
1313
+ respFrame .writeInt (resultKindPrepared )
1314
+ // <id>
1315
+ respFrame .writeShortBytes (binary .BigEndian .AppendUint64 (nil , 2 ))
1316
+ // <metadata>
1317
+ respFrame .writeInt (0 ) // <flags>
1318
+ respFrame .writeInt (0 ) // <columns_count>
1319
+ if srv .protocol >= protoVersion4 {
1320
+ respFrame .writeInt (0 ) // <pk_count>
1321
+ }
1322
+ // <result_metadata>
1323
+ respFrame .writeInt (int32 (flagGlobalTableSpec )) // <flags>
1324
+ respFrame .writeInt (1 ) // <columns_count>
1325
+ // <global_table_spec>
1326
+ respFrame .writeString ("keyspace" )
1327
+ respFrame .writeString ("table" )
1328
+ // <col_spec_0>
1329
+ respFrame .writeString ("col0" ) // <name>
1330
+ respFrame .writeShort (uint16 (TypeBoolean )) // <type>
1331
+ default :
1332
+ respFrame .writeHeader (0 , opError , head .stream )
1333
+ respFrame .writeInt (0 )
1334
+ respFrame .writeString ("unsupported query: " + name )
1335
+ }
1336
+ case opExecute :
1337
+ b := reqFrame .readShortBytes ()
1338
+ id := binary .BigEndian .Uint64 (b )
1339
+ // <query_parameters>
1340
+ reqFrame .readConsistency () // <consistency>
1341
+ var flags byte
1342
+ if srv .protocol > protoVersion4 {
1343
+ ui := reqFrame .readInt ()
1344
+ flags = byte (ui )
1345
+ } else {
1346
+ flags = reqFrame .readByte ()
1347
+ }
1348
+ switch id {
1349
+ case 1 :
1350
+ if flags & flagSkipMetaData != 0 {
1351
+ respFrame .writeHeader (0 , opError , head .stream )
1352
+ respFrame .writeInt (0 )
1353
+ respFrame .writeString ("skip metadata unexpected" )
1354
+ } else {
1355
+ respFrame .writeHeader (0 , opResult , head .stream )
1356
+ respFrame .writeInt (resultKindRows )
1357
+ // <metadata>
1358
+ respFrame .writeInt (0 ) // <flags>
1359
+ respFrame .writeInt (0 ) // <columns_count>
1360
+ // <rows_count>
1361
+ respFrame .writeInt (0 )
1362
+ }
1363
+ case 2 :
1364
+ if flags & flagSkipMetaData != 0 {
1365
+ respFrame .writeHeader (0 , opResult , head .stream )
1366
+ respFrame .writeInt (resultKindRows )
1367
+ // <metadata>
1368
+ respFrame .writeInt (0 ) // <flags>
1369
+ respFrame .writeInt (0 ) // <columns_count>
1370
+ // <rows_count>
1371
+ respFrame .writeInt (0 )
1372
+ } else {
1373
+ respFrame .writeHeader (0 , opError , head .stream )
1374
+ respFrame .writeInt (0 )
1375
+ respFrame .writeString ("skip metadata expected" )
1376
+ }
1377
+ default :
1378
+ respFrame .writeHeader (0 , opError , head .stream )
1379
+ respFrame .writeInt (ErrCodeUnprepared )
1380
+ respFrame .writeString ("unprepared" )
1381
+ respFrame .writeShortBytes (binary .BigEndian .AppendUint64 (nil , id ))
1382
+ }
1267
1383
default :
1268
1384
respFrame .writeHeader (0 , opError , head .stream )
1269
1385
respFrame .writeInt (0 )
0 commit comments