Skip to content

Commit

Permalink
sql: allow DEALLOCATE ALL with a prepared statement
Browse files Browse the repository at this point in the history
PR #48842 added logic to exhaust portals after executing them. This had
issues when the portal being executed closes itself, which happens when
using DEALLOCATE in a prepared statement. Now we check if the portal
still exists before exhausting it.

There is no release note as this fixes a bug that only exists in
unreleased versions.

Release note: None
  • Loading branch information
rafiss authored and yuzefovich committed Aug 20, 2020
1 parent b8a4990 commit 65add86
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
6 changes: 5 additions & 1 deletion pkg/sql/conn_executor_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ func (ex *connExecutor) execPortal(
// Note that the portal is considered exhausted regardless of
// the fact whether an error occurred or not - if it did, we
// still don't want to re-execute the portal from scratch.
ex.exhaustPortal(portalName)
// The current statement may have just closed and deleted the portal,
// so only exhaust it if it still exists.
if _, ok := ex.extraTxnState.prepStmtsNamespace.portals[portalName]; ok {
ex.exhaustPortal(portalName)
}
}
default:
ev, payload, err = ex.execStmt(stmtCtx, curStmt, stmtRes, pinfo)
Expand Down
52 changes: 52 additions & 0 deletions pkg/sql/pgwire/testdata/pgtest/pgjdbc
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
# deallocate_test checks that we can run DEALLOCATE ALL using a prepared
# statement. See #52915.
send
Query {"String": "DROP TABLE IF EXISTS deallocate_test"}
----

until ignore=NoticeResponse
ReadyForQuery
----
{"Type":"CommandComplete","CommandTag":"DROP TABLE"}
{"Type":"ReadyForQuery","TxStatus":"I"}

send
Query {"String": "CREATE TABLE deallocate_test (a INT)"}
----

until
ReadyForQuery
----
{"Type":"CommandComplete","CommandTag":"CREATE TABLE"}
{"Type":"ReadyForQuery","TxStatus":"I"}

# 80 = ASCII 'P' for Portal
send
Parse {"Name": "s1", "Query": "DEALLOCATE ALL"}
Bind {"DestinationPortal": "p1", "PreparedStatement": "s1"}
Describe {"ObjectType": 80, "Name": "p1"}
Execute {"Portal": "p1"}
Sync
----

until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"NoData"}
{"Type":"CommandComplete","CommandTag":"DEALLOCATE ALL"}
{"Type":"ReadyForQuery","TxStatus":"I"}

send
Query {"String": "DISCARD ALL"}
----

until
ReadyForQuery
----
{"Type":"ParameterStatus","Name":"application_name","Value":""}
{"Type":"ParameterStatus","Name":"TimeZone","Value":"UTC"}
{"Type":"CommandComplete","CommandTag":"DISCARD"}
{"Type":"ReadyForQuery","TxStatus":"I"}

# Send a simple query in the middle of extended protocol, which is apparently
# allowed. (See #41511, #33693)
send
Expand Down

0 comments on commit 65add86

Please sign in to comment.