@@ -33,6 +33,7 @@ import (
3333 "context"
3434 "crypto/tls"
3535 "crypto/x509"
36+ "encoding/binary"
3637 "errors"
3738 "fmt"
3839 "io"
@@ -952,6 +953,28 @@ func TestWriteCoalescing_WriteAfterClose(t *testing.T) {
952953 }
953954}
954955
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+
955978type recordingFrameHeaderObserver struct {
956979 t * testing.T
957980 mu sync.Mutex
@@ -1264,6 +1287,99 @@ func (srv *TestServer) process(conn net.Conn, reqFrame *framer) {
12641287 case opError :
12651288 respFrame .writeHeader (0 , opError , head .stream )
12661289 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+ }
12671383 default :
12681384 respFrame .writeHeader (0 , opError , head .stream )
12691385 respFrame .writeInt (0 )
0 commit comments