Skip to content

Commit e37ea6b

Browse files
committed
sql: make sure to close mem acc of prepared stmt in case of an error
Previously, it was possible that we would not close the memory account created for a prepared statement when an error is encountered. This was the case because we would not include the prepared stmt into the prep stmts namespace, so it would just get lost. However, up until recently this was not an issue since we mistakenly cleared that memory account when creating the prepared statement. Release note: None
1 parent 2dd8e76 commit e37ea6b

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

pkg/sql/conn_executor_prepare.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,14 @@ func (ex *connExecutor) addPreparedStmt(
105105
}
106106

107107
if len(prepared.TypeHints) > pgwirebase.MaxPreparedStatementArgs {
108+
prepared.memAcc.Close(ctx)
108109
return nil, pgwirebase.NewProtocolViolationErrorf(
109110
"more than %d arguments to prepared statement: %d",
110111
pgwirebase.MaxPreparedStatementArgs, len(prepared.TypeHints))
111112
}
112113

113114
if err := prepared.memAcc.Grow(ctx, int64(len(name))); err != nil {
115+
prepared.memAcc.Close(ctx)
114116
return nil, err
115117
}
116118
ex.extraTxnState.prepStmtsNamespace.prepStmts[name] = prepared
@@ -135,16 +137,13 @@ func (ex *connExecutor) addPreparedStmt(
135137
//
136138
// placeholderHints may contain partial type information for placeholders.
137139
// prepare will populate the missing types. It can be nil.
138-
//
139-
// The PreparedStatement is returned (or nil if there are no results). The
140-
// returned PreparedStatement needs to be close()d once its no longer in use.
141140
func (ex *connExecutor) prepare(
142141
ctx context.Context,
143142
stmt Statement,
144143
placeholderHints tree.PlaceholderTypes,
145144
rawTypeHints []oid.Oid,
146145
origin PreparedStatementOrigin,
147-
) (*PreparedStatement, error) {
146+
) (_ *PreparedStatement, retErr error) {
148147

149148
prepared := &PreparedStatement{
150149
memAcc: ex.sessionMon.MakeBoundAccount(),
@@ -153,6 +152,12 @@ func (ex *connExecutor) prepare(
153152
createdAt: timeutil.Now(),
154153
origin: origin,
155154
}
155+
defer func() {
156+
// Make sure to close the memory account if an error is returned.
157+
if retErr != nil {
158+
prepared.memAcc.Close(ctx)
159+
}
160+
}()
156161

157162
if stmt.AST == nil {
158163
return prepared, nil

0 commit comments

Comments
 (0)