worryg0d commented on issue #1746:
URL: 
https://github.com/apache/cassandra-gocql-driver/issues/1746#issuecomment-2609405028

   Hello. I guess I successfully reproduced it. I used the code provided by 
@testisnullus and adjusted it a bit to run on Scylla 6.0.
   
   I'm experiencing getting `applied = false` when executing batch 
`ExecuteBatchCAS()` on an empty table, but the data is applied:
   ```
   cqlsh> SELECT * from test.testkv ;
   
    key  | col | ts                  | val
   ------+-----+---------------------+--------------------------
    key1 |   l |                   0 | 0x656e636f6465644c6f636b
    key1 |   d | 1737625396336730945 |           0x76616c756531
   ```
   
   Also, I can't reproduce it on the latest Cassandra. The driver behaves the 
way it should and returns `applied = true` when the data is actually applied 
and `false` otherwise.
   
   My Scylla setup:
   ```shell
   docker run --name scylla-latest --hostname some-scylla -p 9042:9042 -d 
scylladb/scylla --smp 1
   ```
   
   My Cassandra setup:
   ```shell
   docker run --name cassandra-latest -p 9043:9042 -d cassandra
   ```
   
   The code I used to reproduce it:
   ```go
   package main
   
   import (
        "fmt"
        "log"
        "time"
   
        "github.com/gocql/gocql"
   )
   
   type Tx struct {
        session       *gocql.Session
        pendingWrites map[string][]byte
        readTime      time.Time
        table         string
   }
   
   type TxnAborted struct{}
   
   func (e *TxnAborted) Error() string {
        return "Transaction aborted due to write conflict"
   }
   
   func createKeyspace(s *gocql.Session) error {
        //if err := s.Query("CREATE KEYSPACE if not exists test WITH 
replication = {'class': 'NetworkTopologyStrategy', 'replication_factor' : 
1}").Exec(); err != nil {
        //      return fmt.Errorf("error creating keyspace: %w", err)
        //}
   
        // Scylla 6.0 specific code. LWT is not yet supported with tablets
        if err := s.Query("CREATE KEYSPACE if not exists test WITH replication 
= {'class': 'NetworkTopologyStrategy', 'replication_factor' : 1} AND TABLETS = 
{'enabled': false}").Exec(); err != nil {
                return fmt.Errorf("error creating keyspace: %w", err)
        }
   
        return nil
   }
   
   func createTable(s *gocql.Session) error {
        // Table here won't be created because the keyspace is not specified...
        //if err := s.Query("create table if not exists testkv (key text, col 
text, ts bigint, val blob, primary key (key, col, ts)) with clustering order by 
(col desc, ts desc)").Exec(); err != nil {
        //      return fmt.Errorf("error creating table: %w", err)
        //}
   
        if err := s.Query("create table if not exists test.testkv (key text, 
col text, ts bigint, val blob, primary key (key, col, ts)) with clustering 
order by (col desc, ts desc)").Exec(); err != nil {
                return fmt.Errorf("error creating table: %w", err)
        }
   
        return nil
   }
   
   func (tx *Tx) ExecuteBatchTransaction() error {
        b := tx.session.NewBatch(gocql.UnloggedBatch)
   
        for key, val := range tx.pendingWrites {
                b.Entries = append(b.Entries, gocql.BatchEntry{
                        //Stmt: fmt.Sprintf("insert into \"%s\" (key, ts, col, 
val) values (?, 0, 'l', ?) if not exists", tx.table),
                        // DO NOT USE "\"\ for table name
                        Stmt: fmt.Sprintf("insert into %s (key, ts, col, val) 
values (?, 0, 'l', ?) if not exists", tx.table),
                        Args: []any{key, []byte("encodedLock")},
                })
   
                // Insert the data record
                b.Entries = append(b.Entries, gocql.BatchEntry{
                        //Stmt: fmt.Sprintf("insert into \"%s\" (key, ts, col, 
val) values (?, ?, 'd', ?) if not exists", tx.table),
                        Stmt: fmt.Sprintf("insert into %s (key, ts, col, val) 
values (?, ?, 'd', ?) if not exists", tx.table),
                        Args: []any{key, tx.readTime.UnixNano(), val},
                })
        }
   
        //m := make(map[string]any)
        applied, _, err := tx.session.ExecuteBatchCAS(b)
        if err != nil {
                return fmt.Errorf("error in ExecuteBatchCAS: %w", err)
        }
   
        fmt.Println("APPLIED?", applied)
        //fmt.Println("MapExecuteBatchCAS:", m)
   
        if !applied {
                return fmt.Errorf("%w: prewrite not applied (conflict)", 
&TxnAborted{})
        }
   
        fmt.Println(applied)
   
        return nil
   }
   
   func main() {
        // connect to the cluster
        cluster := gocql.NewCluster("localhost:9042") // scylla
        //cluster := gocql.NewCluster("localhost:9043") // cassandra
        cluster.Consistency = gocql.Quorum
        cluster.ProtoVersion = 4
        cluster.ConnectTimeout = time.Second * 10
        // Keyspace is being created when session is already initialized...
        //cluster.Keyspace = "test"
        session, err := cluster.CreateSession()
        if err != nil {
                log.Println(err)
                return
        }
        defer session.Close()
   
        // keyspace "test" is being created here
        err = createKeyspace(session)
        if err != nil {
                fmt.Println("Keyspace failed:", err)
        }
   
        // table "testkv" in ks "test"
        err = createTable(session)
        if err != nil {
                fmt.Println("Table failed:", err)
        }
   
        tx := Tx{
                session:       session,
                pendingWrites: map[string][]byte{"key1": []byte("value1")},
                readTime:      time.Now(),
                // It won't work because keyspace is not specified...
                // Transaction failed: error in ExecuteBatchCAS: No keyspace 
has been specified. USE a keyspace, or explicitly specify keyspace.tablename
                //table: "testkv",
                table: "test.testkv",
        }
   
        err = tx.ExecuteBatchTransaction()
        if err != nil {
                fmt.Println("Transaction failed:", err)
        }
   }
   ```
   
   I'm not a Scylla expert, so I can't say if this is the driver issue or not. 
However, at least there is a way to reproduce it.
   Also, it is reproducable on 
[scylladb/gocql](https://github.com/scylladb/gocql) fork as well.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to