Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#25577] YSQL: Support unnamed prepared statements bind+execute
Summary: **Issue** Some databases drivers by libpq (C driver) have functionality to prepare an unnamed prepare statement by sending the parse packet only with statement name as empty string. The execution can be delayed. An example mentioning this: ``` PGresult *res = PQprepare(conn, "", "SELECT * FROM my_table WHERE id = $1", 1, NULL); // only prepare the query and send parse message only const char *paramValues[1] = {"1"}; res = PQexecPrepared(conn, "", 1, paramValues, NULL, NULL, 0); // bind + execute ``` With connection manager involved, the server would be detached after `PQprepare` and during detach connection manager issues internal queries like `RESET` and `RESET ALL`. Postgres backend interpret them as unnamed statements and drops the already existing prepared statement plan for `SELECT * FROM my_table WHERE id = $1`. Due to this, when `PQexecPrepared` is done to execute the query, postgres can't find unnamed prepared statement as it was dropped in detach step. ``` Execution failed: ERROR: unnamed prepared statement does not exist ``` **Fix** # We need some way to identify what was the last unnamed prepared statement is issue by client to be prepared via parse message. We can then use that to re-send the parse message it if required. # Whether it is required or not would depend upon if ther server which is routed to perform the transaction have that unnamed prepared statement stored for that client. For point 1, this diff adds these fields in od_client structure. ``` /* * This stores the last pasre message issued by this logical connection * corresponding to the unnamed prepared statement. */ char* yb_unnamed_prep_stmt; int yb_unnamed_prep_stmt_size; ``` Whenever a parse message corresponding to unnamed prepared statement comes, just store the entire message and it's size. This will then be re-sent when processing the bind message if required. For point 2, this diff adds these field in od_server structure. ``` /* * The ID of the logical client that has sent parse message to the backend * corresponding to this server object for an unnamed prepared statement. * This would be cleared after server gets detached. */ od_id_t yb_unnamed_prep_stmt_client_id; ``` During processing the bind packet, we will check if `client->id` is same as `server->yb_unnamed_prep_stmt_client_id`. If true, then no need to resend the parse message. Otherwise it is required. Jira: DB-14831 Test Plan: Jenkins: enable connection manager, all tests Reviewers: skumar, stiwary, vpatibandla, rbarigidad Reviewed By: rbarigidad Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D41078
- Loading branch information