Skip to content

A mysterious Packet sometimes hang around #43

@theobat

Description

@theobat

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 ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions