-
Notifications
You must be signed in to change notification settings - Fork 230
Draft: CONJ-1238 rewriteBatchStatements #202
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
base: main
Are you sure you want to change the base?
Draft: CONJ-1238 rewriteBatchStatements #202
Conversation
… method to capture valuesBracketPositions ( based on code removed in commit 6c2213a )
…t of parameters; encode() will rewrite SQL to supply multiple parameters if possible and rewriteBatchStatements enabled
…n rewriteBatchStatements=true
…alse to test rewriteBatchedStatements
… are never called
thanks for this PR. The only reason to do that :
Con :
|
hi @rusher thanks for the feedback. To address those 'con' points on the pro / con list:
I'm not too familiar with galera so not sure how this is incompatible with it, can you supply some more detail ? ( Is the 2.x connector also incompatible with galera ? ) From a quick google, it looks like galera is based on mariadb servers, which isn't the intended use-case for bringing this connection option back. This option is for users who are connecting to non-mariadb mysql servers, who therefore can't get the benefits of COM_STMT_BULK_EXECUTE.
yep, agree it's limited in the sense that the original
Right, but again the use-case is for users connecting to non-mariadb mysql servers where bulk is not available.
Yes this would be another implementation that would need to be maintained, but hopefully the code isn't too difficult to understand and conforms to existing code conventions. I intentionally kept the Not sure if that addressed all your concerns, let me know if there's anything else I can add that might tip the balance in favour of keeping this connection option. |
This PR reinstates the
rewriteBatchStatements
connection property, which is needed to preserveLAST_INSERT_ID()
behaviour when connecting to non-MariaDB MySQL servers. It also improves performance of the connector back to the level we enjoyed with the old 2.x connector, when connecting to non-MariaDB MySQL servers.Ticket in CONJ issue tracker: https://jira.mariadb.org/browse/CONJ-1238
I've based the changes on this branch on the code that was removed in commit 6c2213a ( on Mar 26, 2021 )
The sourcecode has diverged quite a bit since that commit.
The code in that commit used to perform rewriting by breaking the supplied SQL into multiple
queryParts[]
e.g. the SQL
INSERT INTO TABLE(col1,col2,col3,col4, col5) VALUES (9, ?, 5, ?, 8) ON DUPLICATE KEY UPDATE col2=col2+10
would be split into 5 queryParts:
which allowed it to repeat the VALUES() sections, substituting parameters as it went.
The current 3.x code does not keep a
queryParts[]
array. Instead, it converts the supplied SQLString
into abyte[]
of it's UTF-8 representation, and stores aList<Integer>
ofparamPositions
which are the indexes of any?
positional placeholders within that byte array.To support
rewriteBatchStatements
functionality, this branch extends ClientParser class so that whenrewriteBatchStatements
is set totrue
and the SQL is in the required format, it can also capture the indexes of the opening and closing parenthesis around theVALUES()
clause of the SQL. These byte indexes are stored invaluesBracketPositions
.The QueryWithParametersPacket class, which normally sends queries containing parameters, has been extended so that instead of containing a single
Parameters
object ( containing a list ofParameter
objects ) it contains aList<Parameters>
.The QueryWithParametersPacket
encode()
method has been modified so that instead of iterating overparamPositions
once, it can iterate over it multiple times provided it has been supplied multipleParameters
, and hasvaluesBracketPositions
.This new form of QueryWithParametersPacket is created by ClientPreparedStatement if the conditions for rewriting are present.
It constructs multiple QueryWithParametersPackets in a new
getBatchPackets()
method, which also determines how many parameters can fit into a single packet. In order to determine how to split the parameters across packets, a newByteCountingWriter
class has been created, which performs no I/O, but only counts the number of bytes consumed by a parameter if it had been included in a packet.This seems to be how the old code used to demarcate packets, although the old code did that demarcation at encode time, which is no longer possible. To write this code I referred back to the ComQuery class from the 2.x branch at commit 7b569cb ( the commit the 3.x code was branched from ): https://github.com/mariadb-corporation/mariadb-connector-j/blob/7b569cb5a791baf36f3a9d0b4811522db8f590cd/src/main/java/org/mariadb/jdbc/internal/com/send/ComQuery.java
I've marked this PR as Draft in order to get some feedback on whether this is the right approach, and for some guidance on what tests might be appropriate. I've reinstated the ClientPrepareResultTest from the old 6c2213a commit, but we probably need some more thorough tests than that.