@@ -147,8 +147,9 @@ void print_backtrace(void);
147147
148148#define NEXT_IMMEDIATE (new_st ) do { async_state_machine = new_st; goto handler_again; } while (0 )
149149
150- PgSQL_Connection::PgSQL_Connection () {
150+ PgSQL_Connection::PgSQL_Connection (bool is_client_conn ) {
151151 proxy_debug (PROXY_DEBUG_MYSQL_CONNPOOL, 4 , " Creating new PgSQL_Connection %p\n " , this );
152+ is_client_connection = is_client_conn;
152153 pgsql_conn = NULL ;
153154 result_type = 0 ;
154155 pgsql_result = NULL ;
@@ -215,13 +216,6 @@ PgSQL_Connection::~PgSQL_Connection() {
215216 delete query_result_reuse;
216217 query_result_reuse = NULL ;
217218 }
218- for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
219- if (variables[i].value ) {
220- free (variables[i].value );
221- variables[i].value = NULL ;
222- var_hash[i] = 0 ;
223- }
224- }
225219
226220 if (connected_host_details.hostname ) {
227221 free (connected_host_details.hostname );
@@ -233,6 +227,21 @@ PgSQL_Connection::~PgSQL_Connection() {
233227 }
234228
235229 if (options.init_connect ) free (options.init_connect );
230+
231+ for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; ++i) {
232+ if (variables[i].value ) {
233+ free (variables[i].value );
234+ variables[i].value = NULL ;
235+ var_hash[i] = 0 ;
236+ }
237+ }
238+
239+ for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; ++i) {
240+ if (startup_parameters[i]) {
241+ free (startup_parameters[i]);
242+ startup_parameters_hash[i] = 0 ;
243+ }
244+ }
236245}
237246
238247void PgSQL_Connection::next_event (PG_ASYNC_ST new_st) {
@@ -756,44 +765,28 @@ void PgSQL_Connection::connect_start() {
756765 // charset validation is already done
757766 pgsql_variables.server_set_hash_and_value (myds->sess , PGSQL_CLIENT_ENCODING, client_charset, client_charset_hash);
758767
759- std::vector<unsigned int > client_options;
760- client_options.reserve (PGSQL_NAME_LAST_LOW_WM + myds->sess ->client_myds ->myconn ->dynamic_variables_idx .size ());
768+ // optimized way to set client parameters on backend connection when creating a new connection
769+ conninfo << " options='" ;
770+ // excluding client_encoding, which is already set above
771+ for (int idx = 1 ; idx < PGSQL_NAME_LAST_LOW_WM; idx++) {
772+ const char * value = pgsql_variables.client_get_value (myds->sess , idx);
773+ const char * escaped_str = escape_string_backslash_spaces (value);
774+ conninfo << " -c " << pgsql_tracked_variables[idx].set_variable_name << " =" << escaped_str << " " ;
775+ if (escaped_str != value)
776+ free ((char *)escaped_str);
761777
762- // excluding PGSQL_CLIENT_ENCODING
763- for (unsigned int idx = 1 ; idx < PGSQL_NAME_LAST_LOW_WM; idx++) {
764- if (pgsql_variables.client_get_hash (myds->sess , idx) == 0 ) continue ;
765- client_options.push_back (idx);
778+ const uint32_t hash = pgsql_variables.client_get_hash (myds->sess , idx);
779+ pgsql_variables.server_set_hash_and_value (myds->sess , idx, value, hash);
766780 }
767781
768- for (uint32_t idx : myds->sess ->client_myds ->myconn ->dynamic_variables_idx ) {
769- assert (pgsql_variables.client_get_hash (myds->sess , idx));
770- client_options.push_back (idx);
771- }
782+ myds->sess ->mybe ->server_myds ->myconn ->copy_pgsql_variables_to_startup_parameters (true );
772783
773- if (client_options.empty () == false ||
774- myds->sess ->untracked_option_parameters .empty () == false ) {
775-
776- // optimized way to set client parameters on backend connection when creating a new connection
777- conninfo << " options='" ;
778- for (int idx : client_options) {
779- const char * value = pgsql_variables.client_get_value (myds->sess , idx);
780- const char * escaped_str = escape_string_backslash_spaces (value);
781- conninfo << " -c " << pgsql_tracked_variables[idx].set_variable_name << " =" << escaped_str << " " ;
782- if (escaped_str != value)
783- free ((char *)escaped_str);
784-
785- const uint32_t hash = pgsql_variables.client_get_hash (myds->sess , idx);
786- pgsql_variables.server_set_hash_and_value (myds->sess , idx, value, hash);
787- }
788-
789- myds->sess ->mybe ->server_myds ->myconn ->reorder_dynamic_variables_idx ();
790-
791- // if there are untracked parameters, the session should lock on the host group
792- if (myds->sess ->untracked_option_parameters .empty () == false ) {
793- conninfo << myds->sess ->untracked_option_parameters ;
794- }
795- conninfo << " '" ;
784+ // if there are untracked parameters, the session should lock on the host group
785+ if (myds->sess ->untracked_option_parameters .empty () == false ) {
786+ conninfo << myds->sess ->untracked_option_parameters ;
796787 }
788+ conninfo << " '" ;
789+
797790 }
798791
799792 /* conninfo << "postgres://";
@@ -1881,16 +1874,19 @@ void PgSQL_Connection::reset() {
18811874 reusable = true ;
18821875 creation_time = monotonic_time ();
18831876
1884- for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
1877+ for (int i = (is_client_connection ? 0 : PGSQL_NAME_LAST_LOW_WM + 1 );
1878+ i < PGSQL_NAME_LAST_HIGH_WM;
1879+ i++) {
18851880 var_hash[i] = 0 ;
18861881 if (variables[i].value ) {
18871882 free (variables[i].value );
18881883 variables[i].value = NULL ;
1889- var_hash[i] = 0 ;
18901884 }
18911885 }
18921886 dynamic_variables_idx.clear ();
18931887
1888+ if (!is_client_connection) copy_startup_parameters_to_pgsql_variables (/* copy_only_critical_param=*/ true );
1889+
18941890 if (options.init_connect ) {
18951891 free (options.init_connect );
18961892 options.init_connect = NULL ;
@@ -2202,3 +2198,68 @@ void PgSQL_Connection::set_error_from_PQerrorMessage() {
22022198 const std::string_view& full_msg = !primary_msg.empty () ? primary_msg : lib_errmsg;
22032199 PgSQL_Error_Helper::fill_error_info (error_info, sqlstate.data (), full_msg.data (), severity.data ());
22042200}
2201+
2202+ std::pair<const char *, uint32_t > PgSQL_Connection::get_startup_parameter_and_hash (enum pgsql_variable_name idx) {
2203+ // within valid range?
2204+ assert (idx >= 0 && idx < PGSQL_NAME_LAST_HIGH_WM);
2205+
2206+ // Attempt to retrieve value from default startup parameters
2207+ if (startup_parameters_hash[idx] != 0 ) {
2208+ assert (startup_parameters[idx]);
2209+ return { startup_parameters[idx], startup_parameters_hash[idx] };
2210+ }
2211+ // fall back to thread-specific default
2212+ return { pgsql_thread___default_variables[idx], 0 };
2213+ }
2214+
2215+ void PgSQL_Connection::copy_pgsql_variables_to_startup_parameters (bool copy_only_critical_param) {
2216+
2217+ // memcpy(startup_parameters_hash, var_hash, sizeof(uint32_t) * PGSQL_NAME_LAST_LOW_WM);
2218+ for (int i = 0 ; i < PGSQL_NAME_LAST_LOW_WM; ++i) {
2219+ assert (var_hash[i]);
2220+ assert (variables[i].value );
2221+ startup_parameters_hash[i] = var_hash[i];
2222+ free (startup_parameters[i]);
2223+ startup_parameters[i] = strdup (variables[i].value );
2224+ }
2225+
2226+ if (copy_only_critical_param) return ;
2227+
2228+ for (int i = PGSQL_NAME_LAST_LOW_WM + 1 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
2229+ if (var_hash[i] != 0 ) {
2230+ startup_parameters_hash[i] = var_hash[i];
2231+ free (startup_parameters[i]);
2232+ startup_parameters[i] = strdup (variables[i].value );
2233+ } else {
2234+ startup_parameters_hash[i] = 0 ;
2235+ free (startup_parameters[i]);
2236+ startup_parameters[i] = nullptr ;
2237+ }
2238+ }
2239+ }
2240+
2241+ void PgSQL_Connection::copy_startup_parameters_to_pgsql_variables (bool copy_only_critical_param) {
2242+
2243+ // memcpy(var_hash, startup_parameters_hash, sizeof(uint32_t) * PGSQL_NAME_LAST_LOW_WM);
2244+ for (int i = 0 ; i < PGSQL_NAME_LAST_LOW_WM; i++) {
2245+ assert (startup_parameters_hash[i]);
2246+ assert (startup_parameters[i]);
2247+ var_hash[i] = startup_parameters_hash[i];
2248+ free (variables[i].value );
2249+ variables[i].value = strdup (startup_parameters[i]);
2250+ }
2251+
2252+ if (copy_only_critical_param) return ;
2253+
2254+ for (int i = PGSQL_NAME_LAST_LOW_WM + 1 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
2255+ if (startup_parameters_hash[i]) {
2256+ var_hash[i] = startup_parameters_hash[i];
2257+ free (variables[i].value );
2258+ variables[i].value = strdup (startup_parameters[i]);
2259+ } else {
2260+ var_hash[i] = 0 ;
2261+ free (variables[i].value );
2262+ variables[i].value = nullptr ;
2263+ }
2264+ }
2265+ }
0 commit comments