[CONC-461] Can mariadb send CLIENT_DEPRECATE_EOF flag during handshake? Created: 2020-03-10  Updated: 2023-12-06  Resolved: 2021-05-03

Status: Closed
Project: MariaDB Connector/C
Component/s: None
Affects Version/s: 3.1.7
Fix Version/s: N/A

Type: New Feature Priority: Critical
Reporter: Bibek Shrestha Assignee: Georg Richter
Resolution: Won't Do Votes: 0
Labels: Compatibility

Attachments: PNG File Screen Shot 2020-03-10 at 11.47.25 AM.png     PNG File Screen Shot 2020-03-10 at 11.47.36 AM.png    
Issue Links:
Blocks
blocks MXS-1892 Support deprecate eof Closed
Relates
relates to CONC-477 Support all session tracking types Open
relates to MDEV-32102 Permit to have intermediate EOF in re... Open

 Description   

mysql-connector-c send `CLIENT_DEPRECATE_EOF` flag while mariadb does not.
mariadb already supports handling ok packets and I'm curious what the reason is to not support sending this flag during initial handshake.

mariadb-client already parses OK packets when there are no result sets, but due to `CLIENT_DEPRECATE_EOF` set to 0, server does not return OK packets for queries with resultsets.

Why is this relevant?

In the ok packets, mysql sends session tracking information which we'd like to use also when there is resultsets.

Wireshark dump of mariadb-client handshake

Wireshark dump of mysql-client handshake



 Comments   
Comment by Georg Richter [ 2020-07-08 ]

While it is a good idea to deliver session tracking information, it is quite a bad idea to remove the intermediate EOF packet, since applications which use unbuffered result sets will break ( text and binary protocol)

Simple example:

  mysql_real_connect(mysql, "127.0.0.1", NULL, NULL, "test", 0, NULL, CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS);
  if (mysql_errno(mysql))
  {
    printf("Error: %s\n", mysql_error(mysql));
    exit(-1);
  }
 
  mysql_query(mysql, "SELECT 1;SELECT 2");
 
  res= mysql_use_result(mysql);
 
  /* if there are more results, skip first result */
  if (mysql_more_results(mysql))
  {
    mysql_free_result(res);
    mysql_next_result(mysql);
    res= mysql_use_result(mysql);
  }
 
  row= mysql_fetch_row(res);
  printf("Value: %s\n", row[0]);
  mysql_free_result(res);

Output:

without CLIENT_DEPRECATED_EOF:
Value: 2

with CLIENT_DEPRECATED_EOF:
Value: 1

Comment by Bibek Shrestha [ 2020-07-08 ]

As per the docs, this works with unbuffered fetch too. The reason for the bad result above is you're not fetching results as per the docs.

The mysql_use_result docs say:

> When using mysql_use_result(), you must execute mysql_fetch_row() until a NULL value is returned, otherwise, the unfetched rows are returned as part of the result set for your next query. The C API gives the error Commands out of sync; you can't run this command now if you forget to do this!

The following code returns right results with unbuffered fetch for example:

  MYSQL_RES* res;
  MYSQL_ROW row;
 
  mysql_query(mysql, "SELECT 1;SELECT 2");
 
  res= mysql_use_result(mysql);
  while (row= mysql_fetch_row(res)) {
    printf("Value first time: %s\n", row[0]);
  }
  mysql_free_result(res);
 
  if (mysql_more_results(mysql))
  {
    mysql_next_result(mysql);
    res= mysql_use_result(mysql);
    while (row= mysql_fetch_row(res)) {
      printf("Value second time: %s\n", row[0]);
    }
    mysql_free_result(res);
  }

Output:

Value first time: 1
Value second time: 2

I tested this with my PR with CLIENT_DEPRECATE_EOF support in https://github.com/mariadb-corporation/mariadb-connector-c/pull/131.

Comment by Georg Richter [ 2020-07-08 ]

I know that it works when fetching all rows to get the last ok packet, but this will break a lot of applications.
Imho this design is broken, and will not be implemented.

Comment by Georg Richter [ 2020-09-09 ]

See also MySQL bug #100279

Comment by Diego Dupin [ 2021-05-03 ]

Won't do, because breaking existing application

Generated at Thu Feb 08 03:05:29 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.