Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A mysterious Packet sometimes hang around #43

Open
theobat opened this issue Oct 20, 2021 · 1 comment
Open

A mysterious Packet sometimes hang around #43

theobat opened this issue Oct 20, 2021 · 1 comment

Comments

@theobat
Copy link

theobat commented Oct 20, 2021

Hi, thanks for the overall good lib.
I created an insert function which essentially look like :

-- column & table names have been changed but they are irrelevant
insert into table_x values (?, ?);  insert into table_x_revision (id, table_x_id, aaa_id, bbb_id, xxx, yyy,      zzz, ddd, eee)      values (?, ?, ?, ?, ?, ?, ?, ?, ?); 

I execute it through the prepared statement API within a transaction with the following parameters :

[MySQLText "f0aa2688-2ea4-4d97-835b-cddf12812861",MySQLText "2b52b38c-fba7-4411-97aa-5d7ac5fdd8d1",MySQLText "2b52b38c-fba7-4411-97aa-5d7ac5fdd8d1",MySQLText "f0aa2688-2ea4-4d97-835b-cddf12812861",MySQLInt32U 3,MySQLInt32U 4,MySQLDateTime 2022-02-01 10:00:00,MySQLText "qsdqsd",MySQLText "Whaaaat ?",MySQLText "okqoskdoqskd",MySQLText "qlskjdlqjsdlkjqsd"]

And I get a perfectly correct answer, no trouble :

OK {okAffectedRows = 1, okLastInsertID = 0, okStatus = 11, okWarningCnt = 0}

Then, I try to select something from the table :

SELECT id FROM table_x

Following the same prepared statement API.
And this fails :

 DecodePacketFailed "" 7 "not enough bytes

I then tried a few things including getting the stack trace, which shows it's failing at the preparation level (Callstack=CallStack (from HasCallStack):\n getFromPacket, called at ./Database/MySQL/Base.hs:220:49 in mysql-haskell-0.8.4.3-FIXFr1SSHmQ8ubCZpHozx2:Database.MySQL.Base") It seems anything using the prepared statement after the initial insert fails with the same message.
It seems like a simple unexhausted InputStream from the previous query is showing up in the next query, and it pollutes the statement preparation in

-- in prepareStmt in Base.hs
        StmtPrepareOK stid colCnt paramCnt _ <- getFromPacket getStmtPrepareOK p

Now I don't know why the initial query leeked somehow, but it seems like it should rather throw an UnconsumedResultSet anyway. It seems like the OK type is not consuming the entire InputStream Packet. I managed to workaround the problem for now by using

    _ <- timeout 1 $ readPacket is -- eof but isERR and isEOF are both false

Before preparing a statement, but while it works, it seems highly dubious (the timeout is required otherwise if there are no packet to get, it hangs forever).

The packet in excess look like this :

Packet {pLen = 7, pSeqN = 2, pBody = "\NUL\SOH\NUL\v\NUL\NUL\NUL"}
"010b000" -- The bytestring shown in hexadecimal

I'm not sure what the proper fix should be, I suppose there's something missing equivalent to the skipToEof function for the OK returning functions like execute. But I didn't manage to create it properly, maybe you can help me find out the missing pieces ?

@theobat
Copy link
Author

theobat commented Oct 20, 2021

An interesting aspect but I don't have the time right now to investigate is whether a bunch of the following flags are enabled on my server :

https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html

Namely :

if capabilities & CLIENT_PROTOCOL_41 {
} elseif capabilities & CLIENT_TRANSACTIONS {
if capabilities & CLIENT_SESSION_TRACK {
if status_flags & SERVER_SESSION_STATE_CHANGED {
} else {

The Get Packet function does not seem to take these into account which might be the source of the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant