@@ -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 ;
@@ -179,10 +180,10 @@ PgSQL_Connection::PgSQL_Connection() {
179180 options.init_connect_sent = false ;
180181 userinfo = new PgSQL_Connection_userinfo ();
181182
182- for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
183- variables[i].value = NULL ;
184- var_hash[i] = 0 ;
185- }
183+ // for (int i = 0; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
184+ // variables[i].value = NULL;
185+ // var_hash[i] = 0;
186+ // }
186187
187188 new_result = true ;
188189 is_copy_out = false ;
@@ -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,22 @@ 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[i] = nullptr ;
243+ startup_parameters_hash[i] = 0 ;
244+ }
245+ }
236246}
237247
238248void PgSQL_Connection::next_event (PG_ASYNC_ST new_st) {
@@ -756,44 +766,28 @@ void PgSQL_Connection::connect_start() {
756766 // charset validation is already done
757767 pgsql_variables.server_set_hash_and_value (myds->sess , PGSQL_CLIENT_ENCODING, client_charset, client_charset_hash);
758768
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 ());
769+ // optimized way to set client parameters on backend connection when creating a new connection
770+ conninfo << " options='" ;
771+ // excluding client_encoding, which is already set above
772+ for (int idx = 1 ; idx < PGSQL_NAME_LAST_LOW_WM; idx++) {
773+ const char * value = pgsql_variables.client_get_value (myds->sess , idx);
774+ const char * escaped_str = escape_string_backslash_spaces (value);
775+ conninfo << " -c " << pgsql_tracked_variables[idx].set_variable_name << " =" << escaped_str << " " ;
776+ if (escaped_str != value)
777+ free ((char *)escaped_str);
761778
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);
779+ const uint32_t hash = pgsql_variables.client_get_hash (myds->sess , idx);
780+ pgsql_variables.server_set_hash_and_value (myds->sess , idx, value, hash);
766781 }
767782
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- }
772-
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);
783+ myds->sess ->mybe ->server_myds ->myconn ->copy_pgsql_variables_to_startup_parameters (true );
784784
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 << " '" ;
785+ // if there are untracked parameters, the session should lock on the host group
786+ if (myds->sess ->untracked_option_parameters .empty () == false ) {
787+ conninfo << myds->sess ->untracked_option_parameters ;
796788 }
789+ conninfo << " '" ;
790+
797791 }
798792
799793 /* conninfo << "postgres://";
@@ -1881,16 +1875,19 @@ void PgSQL_Connection::reset() {
18811875 reusable = true ;
18821876 creation_time = monotonic_time ();
18831877
1884- for (int i = 0 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
1878+ for (int i = (is_client_connection ? 0 : PGSQL_NAME_LAST_LOW_WM + 1 );
1879+ i < PGSQL_NAME_LAST_HIGH_WM;
1880+ i++) {
18851881 var_hash[i] = 0 ;
18861882 if (variables[i].value ) {
18871883 free (variables[i].value );
18881884 variables[i].value = NULL ;
1889- var_hash[i] = 0 ;
18901885 }
18911886 }
18921887 dynamic_variables_idx.clear ();
18931888
1889+ if (!is_client_connection) copy_startup_parameters_to_pgsql_variables (/* copy_only_critical_param=*/ true );
1890+
18941891 if (options.init_connect ) {
18951892 free (options.init_connect );
18961893 options.init_connect = NULL ;
@@ -2202,3 +2199,68 @@ void PgSQL_Connection::set_error_from_PQerrorMessage() {
22022199 const std::string_view& full_msg = !primary_msg.empty () ? primary_msg : lib_errmsg;
22032200 PgSQL_Error_Helper::fill_error_info (error_info, sqlstate.data (), full_msg.data (), severity.data ());
22042201}
2202+
2203+ std::pair<const char *, uint32_t > PgSQL_Connection::get_startup_parameter_and_hash (enum pgsql_variable_name idx) {
2204+ // within valid range?
2205+ assert (idx >= 0 && idx < PGSQL_NAME_LAST_HIGH_WM);
2206+
2207+ // Attempt to retrieve value from default startup parameters
2208+ if (startup_parameters_hash[idx] != 0 ) {
2209+ assert (startup_parameters[idx]);
2210+ return { startup_parameters[idx], startup_parameters_hash[idx] };
2211+ }
2212+ assert (!(idx < PGSQL_NAME_LAST_LOW_WM));
2213+ return { " " , 0 };
2214+ }
2215+
2216+ void PgSQL_Connection::copy_pgsql_variables_to_startup_parameters (bool copy_only_critical_param) {
2217+
2218+ // memcpy(startup_parameters_hash, var_hash, sizeof(uint32_t) * PGSQL_NAME_LAST_LOW_WM);
2219+ for (int i = 0 ; i < PGSQL_NAME_LAST_LOW_WM; ++i) {
2220+ assert (var_hash[i]);
2221+ assert (variables[i].value );
2222+ startup_parameters_hash[i] = var_hash[i];
2223+ free (startup_parameters[i]);
2224+ startup_parameters[i] = strdup (variables[i].value );
2225+ }
2226+
2227+ if (copy_only_critical_param) return ;
2228+
2229+ for (int i = PGSQL_NAME_LAST_LOW_WM + 1 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
2230+ if (var_hash[i] != 0 ) {
2231+ startup_parameters_hash[i] = var_hash[i];
2232+ free (startup_parameters[i]);
2233+ startup_parameters[i] = strdup (variables[i].value );
2234+ } else {
2235+ startup_parameters_hash[i] = 0 ;
2236+ free (startup_parameters[i]);
2237+ startup_parameters[i] = nullptr ;
2238+ }
2239+ }
2240+ }
2241+
2242+ void PgSQL_Connection::copy_startup_parameters_to_pgsql_variables (bool copy_only_critical_param) {
2243+
2244+ // memcpy(var_hash, startup_parameters_hash, sizeof(uint32_t) * PGSQL_NAME_LAST_LOW_WM);
2245+ for (int i = 0 ; i < PGSQL_NAME_LAST_LOW_WM; i++) {
2246+ assert (startup_parameters_hash[i]);
2247+ assert (startup_parameters[i]);
2248+ var_hash[i] = startup_parameters_hash[i];
2249+ free (variables[i].value );
2250+ variables[i].value = strdup (startup_parameters[i]);
2251+ }
2252+
2253+ if (copy_only_critical_param) return ;
2254+
2255+ for (int i = PGSQL_NAME_LAST_LOW_WM + 1 ; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
2256+ if (startup_parameters_hash[i]) {
2257+ var_hash[i] = startup_parameters_hash[i];
2258+ free (variables[i].value );
2259+ variables[i].value = strdup (startup_parameters[i]);
2260+ } else {
2261+ var_hash[i] = 0 ;
2262+ free (variables[i].value );
2263+ variables[i].value = nullptr ;
2264+ }
2265+ }
2266+ }
0 commit comments