Skip to content

Commit

Permalink
sql: restore invalid prepared statements in session migration
Browse files Browse the repository at this point in the history
A schema change can make an existing prepared statement invalid. Rather
than returning an error when deserializing that invalid statement, now
the error will be returned only when trying to use the statement. This
makes a session migration even more transparent to the end user.

Release note: None
  • Loading branch information
rafiss committed Feb 23, 2022
1 parent 9931810 commit ad02cf5
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
5 changes: 3 additions & 2 deletions pkg/sql/conn_executor_prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ func (ex *connExecutor) prepare(
prepared.PrepareMetadata = querycache.PrepareMetadata{
PlaceholderTypesInfo: tree.PlaceholderTypesInfo{
TypeHints: placeholderHints,
Types: placeholderHints,
},
}
prepared.Statement = stmt.Statement
Expand All @@ -225,13 +226,13 @@ func (ex *connExecutor) prepare(

if txn := ex.state.mu.txn; txn != nil && txn.IsOpen() {
// Use the existing transaction.
if err := prepare(ctx, txn); err != nil {
if err := prepare(ctx, txn); err != nil && origin != PreparedStatementOriginSessionMigration {
return nil, err
}
} else {
// Use a new transaction. This will handle retriable errors here rather
// than bubbling them up to the connExecutor state machine.
if err := ex.server.cfg.DB.Txn(ctx, prepare); err != nil {
if err := ex.server.cfg.DB.Txn(ctx, prepare); err != nil && origin != PreparedStatementOriginSessionMigration {
return nil, err
}
// Prepare with an implicit transaction will end up creating
Expand Down
42 changes: 40 additions & 2 deletions pkg/sql/testdata/session_migration/prepared_statements
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ wire_prepare s2
INSERT INTO t VALUES($1, $2, $3)
----

exec
ALTER TABLE t RENAME TO t2
----

wire_prepare s3
INSERT INTO t2 VALUES($1, $2, $3)
----

exec
ALTER TABLE t2 DROP COLUMN c
----

wire_prepare s4
INSERT INTO t2 VALUES($1, $2)
----

wire_exec s2 1 cat 2022-02-10
----
ERROR: relation "t" does not exist (SQLSTATE 42P01)

wire_exec s3 1 cat 2022-02-10
----
ERROR: INSERT has more expressions than target columns, 3 expressions for 2 targets (SQLSTATE 42601)

query
SELECT * FROM t2
----

let $x
SELECT encode(crdb_internal.serialize_session(), 'hex')
----
Expand Down Expand Up @@ -46,13 +74,23 @@ EXECUTE s1
----
1

# The s2 and s3 statements should experience the same errors that they did
# before the session migration.
wire_exec s2 1 cat 2022-02-10
----
ERROR: relation "t" does not exist (SQLSTATE 42P01)

wire_exec s3 1 cat 2022-02-10
----
ERROR: INSERT has more expressions than target columns, 3 expressions for 2 targets (SQLSTATE 42601)

wire_exec s4 1 cat
----

query
SELECT * FROM t
SELECT * FROM t2
----
1 cat 2022-02-10 00:00:00 +0000 UTC
1 cat

reset
----
Expand Down

0 comments on commit ad02cf5

Please sign in to comment.