Skip to content

Fix prepared statement #734

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

Merged
merged 5 commits into from
Jan 13, 2018

Conversation

methane
Copy link
Member

@methane methane commented Jan 8, 2018

When there are many args and maxAllowedPacket is not enough,
writeExecutePacket() attempted to use STMT_LONG_DATA even for
0byte string.
But writeCommandLongData() doesn't support 0byte data. So it
caused to send malfold packet.

This commit loosen threshold for using STMT_LONG_DATA.

fixes #730

Checklist

  • Code compiles correctly
  • Created tests which fail without the change (if possible)
  • All tests passing
  • Extended the README / documentation, if necessary
  • Added myself / the copyright holder to the AUTHORS file

When there are many args and maxAllowedPacket is not enough,
writeExecutePacket() attempted to use STMT_LONG_DATA even for
0byte string.
But writeCommandLongData() doesn't support 0byte data. So it
caused to send malfold packet.

This commit loosen threshold for using STMT_LONG_DATA.
packets.go Outdated
longDataSize := mc.maxAllowedPacket / stmt.paramCount
if longDataSize < 16 {
longDataSize = 16
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, 16byte is too short?

@julienschmidt
Copy link
Member

Can we have a test for this? It seems like you were able to confirm the bug report somehow.

@julienschmidt julienschmidt added this to the v1.4 milestone Jan 10, 2018
@methane
Copy link
Member Author

methane commented Jan 10, 2018

I confirmed 475ca26 fails without this patch,
when max_allowed_packet is MySQL default (4194304).

packets.go Outdated
@@ -912,6 +912,12 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
const minPktLen = 4 + 1 + 4 + 1 + 4
mc := stmt.mc

// Determine threshould dynamically to avoid packet size shortage as possible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/threshould/threshold/

What do you mean by the "as possible"? When possible? As much as possible?
Are there still cases where the driver sends too short packets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by the "as possible"? When possible? As much as possible?

Sorry, I'm not English speaker. I meant it's OK for most realistic use cases,
although there can be edge cases.

Are there still cases where the driver sends too short packets?

No, always send more than 64 bytes.
"shortage" meant there is chance which stmt_exec packet is bigger than
max_allowed_packet.
For example, user can set very small max_allowed_packet. In such case,
packet can be bigger than max_allowed_packet even when all data is sent
with STMT_LONG_DATA.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not good English writer. Could you rewrite this comment?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just remove the "as possible"

@julienschmidt julienschmidt merged commit 2cc627a into go-sql-driver:master Jan 13, 2018
bLamarche413 pushed a commit to bLamarche413/mysql that referenced this pull request Mar 23, 2018
* Fix prepared statement

When there are many args and maxAllowedPacket is not enough,
writeExecutePacket() attempted to use STMT_LONG_DATA even for
0byte string.
But writeCommandLongData() doesn't support 0byte data. So it
caused to send malfold packet.

This commit loosen threshold for using STMT_LONG_DATA.

* Change minimum size of LONG_DATA to 64byte

* Add test which reproduce issue 730

* TestPreparedManyCols test only numParams = 65535 case

* s/as possible//
@methane methane deleted the fix-zerobyte-longdata branch November 13, 2018 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"Error 1210: Incorrect arguments to mysqld_stmt_execute" with empty strings and 65535 placeholders
2 participants