[MDEV-26906] New capability flag for not sending parameter metadata Created: 2021-10-26  Updated: 2022-01-10  Resolved: 2022-01-10

Status: Closed
Project: MariaDB Server
Component/s: Protocol
Fix Version/s: N/A

Type: Task Priority: Major
Reporter: Georg Richter Assignee: Vladislav Vaintroub
Resolution: Won't Do Votes: 0
Labels: CONNECTOR_RELATED


 Description   

In response to COM_STMT_PREPARE the server sends back metadata (24 bytes) for each parameter in prepared statement. The metadata information is incomplete, has wrong values and cannot be used. Therefore the client api function mysql_stmt_param_metadata always returns a hardcoded NULL.

Proposal:
Add a new extended capability flag MARIADB_CLIENT_SKIP_PARAM_METADATA. If this flag is set/supported both by client and server, the server will send only the number of parameters, but not parameter metadata.



 Comments   
Comment by Oleksandr Byelkin [ 2021-10-26 ]

wlad what you think about it?

Comment by Vladislav Vaintroub [ 2021-10-26 ]

What is the use case?
I think , maybe we fix COM_STMT_PREPARE so that metadata is correct, and can be used?
Otherwise, it seems like micro-optimization, I'd think not worth pursuing. COM_STMT_PREPARE should not be a command that is issued often .

If the question is again about something like execute_direct, I believe prepare+execute like now maybe suboptimal. I believe C/C should move on to more compact EXECUTE IMMEDIATE, but also learn to count parameter holders, aka questionmarks (neither in comments, nor in strings) itself. That is, if C/C still does not want to implement client-side prepared statements.

As for the "can't be used", I beg to differ. In java, parameter metadata can be used, if implemented correctly . See https://docs.oracle.com/javase/7/docs/api/java/sql/ParameterMetaData.html

Comment by Vladislav Vaintroub [ 2021-10-28 ]

As explained by georg over on Slack, the actual thing he wants, without any workarounds, is
COM_EXECUTE_DIRECT, where he provides a string with placeholders, encodes input parameters, gets a result as either OK, or ERROR, or (I guess binary encoded) result set. My understanding is that he does not really want to send 3 commands, to prepare, execute and close the prepared statement . Also, that he does not want to see prepare response, the parameter count, parameter metadata, and result set metadata on one packet, and then the data in additional packet.

This would be an improvement over what is currently done with pipelining.

I think this might perhaps even a better idea to provide a more generic and versatile COM_QUERY variation, where one can specify for example

  • how result set is encoded - binary or text
  • optionally provide parameters, if query has placeholders.
  • and have place/flags for other things - e.g there is an idea that I'm toying with is making result set metadata optional for normal queries, not just prepared, this would be a benefit for clients that do prepare on client-side.

This would cover the COM_EXECUTE_DIRECT needs, too, and in addition, georg's dream of never parsing text protocol might come true as well

Comment by Vladislav Vaintroub [ 2022-01-10 ]

As we discussed, the actual thing you'd like to have is EXECUTE_DIRECT command. If this is so, let's create a different MDEV, about an extended and extendable COM_QUERY_EX which allows to define resultset encoding (binary vs text), and optionally pass query parameters, and other things, rather not spend valuable bits in the protocol for small single-use stuff for C client only.

Comment by Georg Richter [ 2022-01-10 ]

Parameter junk has been sent over the wire for more than 17 years. Where is the problem to disable it, if client doesn't want to receive this garbage?
It it will once contain useful information, the client doesn't need to set a flag anymore.

Comment by Vladislav Vaintroub [ 2022-01-10 ]

The problem is that our protocol would further drift away from MySQL, for no good reason. Really, one can optimize much better if we optionally remove the "def" strings, that take much more space than this proposal.
The junk was not planned for one. It is, in theory, useful information, and clients other than proprietary C API would be well served, once we send good info (clients other than C are JDBC for example, see https://docs.oracle.com/javase/7/docs/api/java/sql/ParameterMetaData.html) . Also, at some point, if you do not really need all that stuff, you could optimize your client exceptionally well, by implementing client-side prepared statements.

Comment by Vladislav Vaintroub [ 2022-01-10 ]

The general problem with those tiny requests, with each one consuming additional capability flag is that you'll soon run out of flags, trying to squeeze everything into existing COM_PREPARE or COM_EXECUTE.
In reality though, the thing you actually wanted was different, and since many years of those 17 you mention, we're trying to implement execute direct, that you would like. You can have a generalized command instead, that can take a query text, and optionally parameters, and optionally (based on a flag) return result set metadata, or not return it, Maybe this command can also take a prepared statement ID, instead of text, based on a flag, and , it can return binary encoded result set based on flag, or text encoded result set. This would be much more useful.

Generated at Thu Feb 08 09:48:50 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.