Skip to content

Commit 3246e1f

Browse files
committed
Bug #30989042 GETTING CDK ERROR: REPLY BLOCKED BY A PREVIOUS ONE.
Fixes an error in reply processing logic which in case of a reply with multiple rsets could incorrectly deregister cdk reply object after reading the first rset, while more rsets from the server are pending.
1 parent 1ce802c commit 3246e1f

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

common/result.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,23 @@ bool Result_impl::load_cache(row_count_t prefetch_size)
322322
m_cursor->wait();
323323

324324
/*
325-
Cleanup after reading all rows.
325+
Cleanup after reading all rows: close the cursor if whole rset has
326+
been consumed (or error happend, in which case server won't sent more
327+
data).
326328
*/
327329

328330
if (!m_pending_rows || m_reply->entry_count() > 0)
329331
{
330332
m_cursor->close();
331-
m_sess->deregister_result(this);
332333
m_pending_rows = false;
334+
335+
/*
336+
If there are no more rsets in the reply, deregister the result so that
337+
session is unlocked for the next command.
338+
*/
339+
340+
if (m_reply->end_of_reply())
341+
m_sess->deregister_result(this);
333342
}
334343

335344
return !m_result_cache.back().empty();

devapi/tests/bugs-t.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,55 @@ class Bugs : public mysqlx::test::Xplugin
4242
};
4343

4444

45+
TEST_F(Bugs,bug30989042_cdk_reply_error)
46+
{
47+
SKIP_IF_NO_XPLUGIN;
48+
49+
// Create procedure that returns 2 row sets
50+
51+
sql("DROP PROCEDURE IF EXISTS test.p");
52+
sql(
53+
"CREATE PROCEDURE test.p(error INT)"
54+
"BEGIN"
55+
" SELECT 1;"
56+
" IF error = 0 THEN"
57+
" SELECT 2;"
58+
" ELSE"
59+
" SELECT 1/point(1,0);" // trigger error
60+
" END IF;"
61+
"END"
62+
);
63+
64+
auto res = sql("CALL test.p(0)");
65+
66+
// res.count() will consume the first row set, but another
67+
// one is pending.
68+
69+
EXPECT_EQ(1,res.count());
70+
71+
// As we execute new statement, all remaining rows from the previous
72+
// reply should be cached. It was not the case before bug was fixed,
73+
// and the next statement was throwing error, because previous reply
74+
// was not fully consumed.
75+
76+
EXPECT_NO_THROW(sql("select 1"));
77+
78+
// Check that remaining rows from the reply to CALL are cached
79+
// and still available.
80+
81+
EXPECT_TRUE(res.nextResult());
82+
EXPECT_EQ(1,res.count());
83+
84+
// Check that in case of error, it is reported only when moving to
85+
// the next result in the reply (should not be reported while accessing
86+
// the first result).
87+
88+
res = sql("CALL test.p(1)");
89+
EXPECT_EQ(1, res.count());
90+
EXPECT_THROW(res.nextResult(), Error);
91+
}
92+
93+
4594
TEST_F(Bugs, failover_error)
4695
{
4796

0 commit comments

Comments
 (0)