joao-r-reis commented on code in PR #1822:
URL:
https://github.com/apache/cassandra-gocql-driver/pull/1822#discussion_r1817075992
##########
conn.go:
##########
@@ -1430,6 +1529,34 @@ func (c *Conn) executeQuery(ctx context.Context, qry
*Query) *Iter {
case *resultVoidFrame:
return &Iter{framer: framer}
case *resultRowsFrame:
+ if x.meta.newMetadataID != nil {
+ // Updating the result metadata id in prepared stmt
+ //
+ // If a RESULT/Rows message reports
+ // changed resultset metadata with the
Metadata_changed flag, the reported new
+ // resultset metadata must be used in subsequent
executions
+
+ stmtCacheKey :=
c.session.stmtsLRU.keyFor(c.host.HostID(), c.currentKeyspace, qry.stmt)
+ oldInflight, ok := c.session.stmtsLRU.get(stmtCacheKey)
+ if !ok {
+ // We didn't find the stmt in the cache, so we
just re-prepare it
+ return c.executeQuery(ctx, qry)
+ }
+
+ newInflight := &inflightPrepare{
+ done: make(chan struct{}),
+ preparedStatment: &preparedStatment{
+ id:
oldInflight.preparedStatment.id,
+ resultMetadataID: x.meta.newMetadataID,
+ request:
oldInflight.preparedStatment.request,
+ response: x.meta,
+ },
+ }
+
+ c.session.stmtsLRU.add(stmtCacheKey, newInflight)
+ return c.executeQuery(ctx, qry)
Review Comment:
ok I found a way to trigger the `NEW_METADATA_ID` flag in the response but
you basically have to add temporary code to make the driver NOT update the
prepared entry when it receives an UNPREPARED, this is obviously not how it
should work but it's a way to at least do some manual testing to make sure this
flow is working properly.
In `Conn.executeQuery` replace the whole `case *RequestErrUnprepared` block
with this:
```
case *RequestErrUnprepared:
stmtCacheKey := c.session.stmtsLRU.keyFor(c.host.HostID(),
c.currentKeyspace, qry.stmt)
prep := &writePrepareFrame{
statement: qry.stmt,
}
if c.version > protoVersion4 {
prep.keyspace = qry.keyspace
}
framer, err := c.exec(c.ctx, prep, qry.trace)
if err != nil {
c.session.stmtsLRU.remove(stmtCacheKey)
return &Iter{err: x, framer: framer}
}
_, err = framer.parseFrame()
if err != nil {
c.session.stmtsLRU.remove(stmtCacheKey)
return &Iter{err: x, framer: framer}
}
return c.executeQuery(ctx, qry)
```
This will cause gocql to send an `EXECUTE` with the old result metadata ID
even after the RE-PREPARE which will then cause C* to return `ROWS` with the
new metadata.
--
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]