pg 1.5.9 → 1.6.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data/Gemfile +7 -4
 - data/History.md +26 -0
 - data/README-Windows.rdoc +1 -1
 - data/README.ja.md +3 -3
 - data/README.md +4 -4
 - data/Rakefile +55 -12
 - data/ext/extconf.rb +119 -13
 - data/ext/gvl_wrappers.c +13 -2
 - data/ext/gvl_wrappers.h +33 -0
 - data/ext/pg.c +16 -5
 - data/ext/pg.h +8 -9
 - data/ext/pg_binary_decoder.c +150 -0
 - data/ext/pg_binary_encoder.c +203 -7
 - data/ext/pg_cancel_connection.c +360 -0
 - data/ext/pg_coder.c +3 -5
 - data/ext/pg_connection.c +337 -148
 - data/ext/pg_copy_coder.c +2 -2
 - data/ext/pg_record_coder.c +1 -1
 - data/ext/pg_result.c +9 -11
 - data/ext/pg_text_encoder.c +2 -2
 - data/ext/pg_tuple.c +2 -2
 - data/ext/pg_type_map.c +1 -1
 - data/ext/pg_type_map_all_strings.c +1 -1
 - data/ext/pg_type_map_by_class.c +1 -1
 - data/ext/pg_type_map_by_column.c +1 -1
 - data/ext/pg_type_map_by_mri_type.c +1 -1
 - data/ext/pg_type_map_by_oid.c +1 -1
 - data/ext/pg_type_map_in_ruby.c +1 -1
 - data/lib/pg/basic_type_registry.rb +2 -2
 - data/lib/pg/cancel_connection.rb +30 -0
 - data/lib/pg/connection.rb +182 -126
 - data/lib/pg/version.rb +1 -1
 - data/lib/pg.rb +13 -8
 - data/pg.gemspec +2 -2
 - data.tar.gz.sig +0 -0
 - metadata +9 -5
 - metadata.gz.sig +0 -0
 - data/Rakefile.cross +0 -303
 
    
        data/ext/pg_copy_coder.c
    CHANGED
    
    | 
         @@ -51,7 +51,7 @@ static const rb_data_type_t pg_copycoder_type = { 
     | 
|
| 
       51 
51 
     | 
    
         
             
            		pg_copycoder_mark,
         
     | 
| 
       52 
52 
     | 
    
         
             
            		RUBY_TYPED_DEFAULT_FREE,
         
     | 
| 
       53 
53 
     | 
    
         
             
            		pg_copycoder_memsize,
         
     | 
| 
       54 
     | 
    
         
            -
            		 
     | 
| 
      
 54 
     | 
    
         
            +
            		pg_copycoder_compact,
         
     | 
| 
       55 
55 
     | 
    
         
             
            	},
         
     | 
| 
       56 
56 
     | 
    
         
             
            	&pg_coder_type,
         
     | 
| 
       57 
57 
     | 
    
         
             
            	0,
         
     | 
| 
         @@ -831,7 +831,6 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl 
     | 
|
| 
       831 
831 
     | 
    
         | 
| 
       832 
832 
     | 
    
         
             
            		for( fieldno = 0; fieldno < nfields; fieldno++){
         
     | 
| 
       833 
833 
     | 
    
         
             
            			long input_len;
         
     | 
| 
       834 
     | 
    
         
            -
            			VALUE field_value;
         
     | 
| 
       835 
834 
     | 
    
         | 
| 
       836 
835 
     | 
    
         
             
            			/* read field size */
         
     | 
| 
       837 
836 
     | 
    
         
             
            			if (line_end_ptr - cur_ptr < 4 ) goto length_error;
         
     | 
| 
         @@ -843,6 +842,7 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl 
     | 
|
| 
       843 
842 
     | 
    
         
             
            				/* NULL indicator */
         
     | 
| 
       844 
843 
     | 
    
         
             
            				rb_ary_push(array, Qnil);
         
     | 
| 
       845 
844 
     | 
    
         
             
            			} else {
         
     | 
| 
      
 845 
     | 
    
         
            +
            				VALUE field_value;
         
     | 
| 
       846 
846 
     | 
    
         
             
            				if (line_end_ptr - cur_ptr < input_len ) goto length_error;
         
     | 
| 
       847 
847 
     | 
    
         | 
| 
       848 
848 
     | 
    
         
             
            				/* copy input data to field_str */
         
     | 
    
        data/ext/pg_record_coder.c
    CHANGED
    
    
    
        data/ext/pg_result.c
    CHANGED
    
    | 
         @@ -147,9 +147,7 @@ pgresult_clear( void *_this ) 
     | 
|
| 
       147 
147 
     | 
    
         
             
            	t_pg_result *this = (t_pg_result *)_this;
         
     | 
| 
       148 
148 
     | 
    
         
             
            	if( this->pgresult && !this->autoclear ){
         
     | 
| 
       149 
149 
     | 
    
         
             
            		PQclear(this->pgresult);
         
     | 
| 
       150 
     | 
    
         
            -
            #ifdef HAVE_RB_GC_ADJUST_MEMORY_USAGE
         
     | 
| 
       151 
150 
     | 
    
         
             
            		rb_gc_adjust_memory_usage(-this->result_size);
         
     | 
| 
       152 
     | 
    
         
            -
            #endif
         
     | 
| 
       153 
151 
     | 
    
         
             
            	}
         
     | 
| 
       154 
152 
     | 
    
         
             
            	this->result_size = 0;
         
     | 
| 
       155 
153 
     | 
    
         
             
            	this->nfields = -1;
         
     | 
| 
         @@ -180,7 +178,7 @@ static const rb_data_type_t pgresult_type = { 
     | 
|
| 
       180 
178 
     | 
    
         
             
            		pgresult_gc_mark,
         
     | 
| 
       181 
179 
     | 
    
         
             
            		pgresult_gc_free,
         
     | 
| 
       182 
180 
     | 
    
         
             
            		pgresult_memsize,
         
     | 
| 
       183 
     | 
    
         
            -
            		 
     | 
| 
      
 181 
     | 
    
         
            +
            		pgresult_gc_compact,
         
     | 
| 
       184 
182 
     | 
    
         
             
            	},
         
     | 
| 
       185 
183 
     | 
    
         
             
            	0, 0,
         
     | 
| 
       186 
184 
     | 
    
         
             
            	RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
         
     | 
| 
         @@ -253,9 +251,7 @@ pg_new_result(PGresult *result, VALUE rb_pgconn) 
     | 
|
| 
       253 
251 
     | 
    
         
             
            	 */
         
     | 
| 
       254 
252 
     | 
    
         
             
            	this->result_size = pgresult_approx_size(result);
         
     | 
| 
       255 
253 
     | 
    
         | 
| 
       256 
     | 
    
         
            -
            #ifdef HAVE_RB_GC_ADJUST_MEMORY_USAGE
         
     | 
| 
       257 
254 
     | 
    
         
             
            	rb_gc_adjust_memory_usage(this->result_size);
         
     | 
| 
       258 
     | 
    
         
            -
            #endif
         
     | 
| 
       259 
255 
     | 
    
         | 
| 
       260 
256 
     | 
    
         
             
            	return self;
         
     | 
| 
       261 
257 
     | 
    
         
             
            }
         
     | 
| 
         @@ -323,6 +319,9 @@ pg_result_check( VALUE self ) 
     | 
|
| 
       323 
319 
     | 
    
         
             
            		case PGRES_COMMAND_OK:
         
     | 
| 
       324 
320 
     | 
    
         
             
            #ifdef HAVE_PQENTERPIPELINEMODE
         
     | 
| 
       325 
321 
     | 
    
         
             
            		case PGRES_PIPELINE_SYNC:
         
     | 
| 
      
 322 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 323 
     | 
    
         
            +
            #ifdef HAVE_PQSETCHUNKEDROWSMODE
         
     | 
| 
      
 324 
     | 
    
         
            +
            		case PGRES_TUPLES_CHUNK:
         
     | 
| 
       326 
325 
     | 
    
         
             
            #endif
         
     | 
| 
       327 
326 
     | 
    
         
             
            			return self;
         
     | 
| 
       328 
327 
     | 
    
         
             
            		case PGRES_BAD_RESPONSE:
         
     | 
| 
         @@ -549,6 +548,7 @@ static void pgresult_init_fnames(VALUE self) 
     | 
|
| 
       549 
548 
     | 
    
         
             
             * * +PGRES_FATAL_ERROR+
         
     | 
| 
       550 
549 
     | 
    
         
             
             * * +PGRES_COPY_BOTH+
         
     | 
| 
       551 
550 
     | 
    
         
             
             * * +PGRES_SINGLE_TUPLE+
         
     | 
| 
      
 551 
     | 
    
         
            +
             * * +PGRES_TUPLES_CHUNK+
         
     | 
| 
       552 
552 
     | 
    
         
             
             * * +PGRES_PIPELINE_SYNC+
         
     | 
| 
       553 
553 
     | 
    
         
             
             * * +PGRES_PIPELINE_ABORTED+
         
     | 
| 
       554 
554 
     | 
    
         
             
             *
         
     | 
| 
         @@ -613,14 +613,12 @@ pgresult_error_message(VALUE self) 
     | 
|
| 
       613 
613 
     | 
    
         
             
            	return ret;
         
     | 
| 
       614 
614 
     | 
    
         
             
            }
         
     | 
| 
       615 
615 
     | 
    
         | 
| 
       616 
     | 
    
         
            -
            #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
         
     | 
| 
       617 
616 
     | 
    
         
             
            /*
         
     | 
| 
       618 
617 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       619 
618 
     | 
    
         
             
             *    res.verbose_error_message( verbosity, show_context ) -> String
         
     | 
| 
       620 
619 
     | 
    
         
             
             *
         
     | 
| 
       621 
620 
     | 
    
         
             
             * Returns a reformatted version of the error message associated with a PGresult object.
         
     | 
| 
       622 
621 
     | 
    
         
             
             *
         
     | 
| 
       623 
     | 
    
         
            -
             * Available since PostgreSQL-9.6
         
     | 
| 
       624 
622 
     | 
    
         
             
             */
         
     | 
| 
       625 
623 
     | 
    
         
             
            static VALUE
         
     | 
| 
       626 
624 
     | 
    
         
             
            pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
         
     | 
| 
         @@ -639,7 +637,6 @@ pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context) 
     | 
|
| 
       639 
637 
     | 
    
         | 
| 
       640 
638 
     | 
    
         
             
            	return ret;
         
     | 
| 
       641 
639 
     | 
    
         
             
            }
         
     | 
| 
       642 
     | 
    
         
            -
            #endif
         
     | 
| 
       643 
640 
     | 
    
         | 
| 
       644 
641 
     | 
    
         
             
            /*
         
     | 
| 
       645 
642 
     | 
    
         
             
             * call-seq:
         
     | 
| 
         @@ -1528,6 +1525,9 @@ pgresult_stream_any(VALUE self, int (*yielder)(VALUE, int, int, void*), void* da 
     | 
|
| 
       1528 
1525 
     | 
    
         
             
            					return self;
         
     | 
| 
       1529 
1526 
     | 
    
         
             
            				rb_raise( rb_eInvalidResultStatus, "PG::Result is not in single row mode");
         
     | 
| 
       1530 
1527 
     | 
    
         
             
            			case PGRES_SINGLE_TUPLE:
         
     | 
| 
      
 1528 
     | 
    
         
            +
            #ifdef HAVE_PQSETCHUNKEDROWSMODE
         
     | 
| 
      
 1529 
     | 
    
         
            +
            			case PGRES_TUPLES_CHUNK:
         
     | 
| 
      
 1530 
     | 
    
         
            +
            #endif
         
     | 
| 
       1531 
1531 
     | 
    
         
             
            				break;
         
     | 
| 
       1532 
1532 
     | 
    
         
             
            			default:
         
     | 
| 
       1533 
1533 
     | 
    
         
             
            				pg_result_check( self );
         
     | 
| 
         @@ -1572,7 +1572,7 @@ pgresult_stream_any(VALUE self, int (*yielder)(VALUE, int, int, void*), void* da 
     | 
|
| 
       1572 
1572 
     | 
    
         
             
             * wrapping each row into a dedicated result object, it delivers data in nearly
         
     | 
| 
       1573 
1573 
     | 
    
         
             
             * the same speed as with ordinary results.
         
     | 
| 
       1574 
1574 
     | 
    
         
             
             *
         
     | 
| 
       1575 
     | 
    
         
            -
             * The base result must be in status PGRES_SINGLE_TUPLE.
         
     | 
| 
      
 1575 
     | 
    
         
            +
             * The base result must be in status PGRES_SINGLE_TUPLE or PGRES_TUPLES_CHUNK.
         
     | 
| 
       1576 
1576 
     | 
    
         
             
             * It iterates over all tuples until the status changes to PGRES_TUPLES_OK.
         
     | 
| 
       1577 
1577 
     | 
    
         
             
             * A PG::Error is raised for any errors from the server.
         
     | 
| 
       1578 
1578 
     | 
    
         
             
             *
         
     | 
| 
         @@ -1707,10 +1707,8 @@ init_pg_result(void) 
     | 
|
| 
       1707 
1707 
     | 
    
         
             
            	rb_define_singleton_method(rb_cPGresult, "res_status", pgresult_s_res_status, 1);
         
     | 
| 
       1708 
1708 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "error_message", pgresult_error_message, 0);
         
     | 
| 
       1709 
1709 
     | 
    
         
             
            	rb_define_alias( rb_cPGresult, "result_error_message", "error_message");
         
     | 
| 
       1710 
     | 
    
         
            -
            #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
         
     | 
| 
       1711 
1710 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "verbose_error_message", pgresult_verbose_error_message, 2);
         
     | 
| 
       1712 
1711 
     | 
    
         
             
            	rb_define_alias( rb_cPGresult, "result_verbose_error_message", "verbose_error_message");
         
     | 
| 
       1713 
     | 
    
         
            -
            #endif
         
     | 
| 
       1714 
1712 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "error_field", pgresult_error_field, 1);
         
     | 
| 
       1715 
1713 
     | 
    
         
             
            	rb_define_alias( rb_cPGresult, "result_error_field", "error_field" );
         
     | 
| 
       1716 
1714 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "clear", pg_result_clear, 0);
         
     | 
    
        data/ext/pg_text_encoder.c
    CHANGED
    
    | 
         @@ -231,7 +231,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat 
     | 
|
| 
       231 
231 
     | 
    
         
             
             *
         
     | 
| 
       232 
232 
     | 
    
         
             
             */
         
     | 
| 
       233 
233 
     | 
    
         
             
            static int
         
     | 
| 
       234 
     | 
    
         
            -
            pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE * 
     | 
| 
      
 234 
     | 
    
         
            +
            pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate1, int enc_idx)
         
     | 
| 
       235 
235 
     | 
    
         
             
            {
         
     | 
| 
       236 
236 
     | 
    
         
             
            	if(out){
         
     | 
| 
       237 
237 
     | 
    
         
             
            		double dvalue = NUM2DBL(value);
         
     | 
| 
         @@ -239,7 +239,6 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, 
     | 
|
| 
       239 
239 
     | 
    
         
             
            		int neg = 0;
         
     | 
| 
       240 
240 
     | 
    
         
             
            		int exp2i, exp10i, i;
         
     | 
| 
       241 
241 
     | 
    
         
             
            		unsigned long long ll, remainder, oldval;
         
     | 
| 
       242 
     | 
    
         
            -
            		VALUE intermediate;
         
     | 
| 
       243 
242 
     | 
    
         | 
| 
       244 
243 
     | 
    
         
             
            		/* Cast to the same strings as value.to_s . */
         
     | 
| 
       245 
244 
     | 
    
         
             
            		if( isinf(dvalue) ){
         
     | 
| 
         @@ -283,6 +282,7 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, 
     | 
|
| 
       283 
282 
     | 
    
         | 
| 
       284 
283 
     | 
    
         
             
            		if( exp10i <= -5 || exp10i >= 15 ) {
         
     | 
| 
       285 
284 
     | 
    
         
             
            			/* Write the float in exponent format (1.23e45) */
         
     | 
| 
      
 285 
     | 
    
         
            +
            			VALUE intermediate;
         
     | 
| 
       286 
286 
     | 
    
         | 
| 
       287 
287 
     | 
    
         
             
            			/* write fraction digits from right to left */
         
     | 
| 
       288 
288 
     | 
    
         
             
            			for( i = MAX_DOUBLE_DIGITS; i > 1; i--){
         
     | 
    
        data/ext/pg_tuple.c
    CHANGED
    
    | 
         @@ -125,7 +125,7 @@ static const rb_data_type_t pg_tuple_type = { 
     | 
|
| 
       125 
125 
     | 
    
         
             
            		pg_tuple_gc_mark,
         
     | 
| 
       126 
126 
     | 
    
         
             
            		pg_tuple_gc_free,
         
     | 
| 
       127 
127 
     | 
    
         
             
            		pg_tuple_memsize,
         
     | 
| 
       128 
     | 
    
         
            -
            		 
     | 
| 
      
 128 
     | 
    
         
            +
            		pg_tuple_gc_compact,
         
     | 
| 
       129 
129 
     | 
    
         
             
            	},
         
     | 
| 
       130 
130 
     | 
    
         
             
            	0, 0,
         
     | 
| 
       131 
131 
     | 
    
         
             
            	RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
         
     | 
| 
         @@ -135,7 +135,7 @@ static const rb_data_type_t pg_tuple_type = { 
     | 
|
| 
       135 
135 
     | 
    
         
             
             * Document-method: allocate
         
     | 
| 
       136 
136 
     | 
    
         
             
             *
         
     | 
| 
       137 
137 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       138 
     | 
    
         
            -
             *   PG:: 
     | 
| 
      
 138 
     | 
    
         
            +
             *   PG::Tuple.allocate -> obj
         
     | 
| 
       139 
139 
     | 
    
         
             
             */
         
     | 
| 
       140 
140 
     | 
    
         
             
            static VALUE
         
     | 
| 
       141 
141 
     | 
    
         
             
            pg_tuple_s_allocate( VALUE klass )
         
     | 
    
        data/ext/pg_type_map.c
    CHANGED
    
    
    
        data/ext/pg_type_map_by_class.c
    CHANGED
    
    
    
        data/ext/pg_type_map_by_column.c
    CHANGED
    
    
    
        data/ext/pg_type_map_by_oid.c
    CHANGED
    
    
    
        data/ext/pg_type_map_in_ruby.c
    CHANGED
    
    
| 
         @@ -127,8 +127,8 @@ class PG::BasicTypeRegistry 
     | 
|
| 
       127 
127 
     | 
    
         
             
            			@maps = [
         
     | 
| 
       128 
128 
     | 
    
         
             
            				[0, :encoder, PG::TextEncoder::Array],
         
     | 
| 
       129 
129 
     | 
    
         
             
            				[0, :decoder, PG::TextDecoder::Array],
         
     | 
| 
       130 
     | 
    
         
            -
            				[1, :encoder,  
     | 
| 
       131 
     | 
    
         
            -
            				[1, :decoder,  
     | 
| 
      
 130 
     | 
    
         
            +
            				[1, :encoder, PG::BinaryEncoder::Array],
         
     | 
| 
      
 131 
     | 
    
         
            +
            				[1, :decoder, PG::BinaryDecoder::Array],
         
     | 
| 
       132 
132 
     | 
    
         
             
            			].inject([]) do |h, (format, direction, arraycoder)|
         
     | 
| 
       133 
133 
     | 
    
         
             
            				coders = registry.coders_for(format, direction) || {}
         
     | 
| 
       134 
134 
     | 
    
         
             
            				h[format] ||= {}
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- ruby -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'pg' unless defined?( PG )
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            if defined?(PG::CancelConnection)
         
     | 
| 
      
 7 
     | 
    
         
            +
            	class PG::CancelConnection
         
     | 
| 
      
 8 
     | 
    
         
            +
            		include PG::Connection::Pollable
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            		# The timeout used by #cancel and async_cancel to establish the cancel connection.
         
     | 
| 
      
 11 
     | 
    
         
            +
            		attr_accessor :async_connect_timeout
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            		# call-seq:
         
     | 
| 
      
 14 
     | 
    
         
            +
            		#    conn.cancel
         
     | 
| 
      
 15 
     | 
    
         
            +
            		#
         
     | 
| 
      
 16 
     | 
    
         
            +
            		# Requests that the server abandons processing of the current command in a blocking manner.
         
     | 
| 
      
 17 
     | 
    
         
            +
            		#
         
     | 
| 
      
 18 
     | 
    
         
            +
            		# If the cancel request wasn't successfully dispatched an error message is raised.
         
     | 
| 
      
 19 
     | 
    
         
            +
            		#
         
     | 
| 
      
 20 
     | 
    
         
            +
            		# Successful dispatch of the cancellation is no guarantee that the request will have any effect, however.
         
     | 
| 
      
 21 
     | 
    
         
            +
            		# If the cancellation is effective, the command being canceled will terminate early and raises an error.
         
     | 
| 
      
 22 
     | 
    
         
            +
            		# If the cancellation fails (say, because the server was already done processing the command), then there will be no visible result at all.
         
     | 
| 
      
 23 
     | 
    
         
            +
            		#
         
     | 
| 
      
 24 
     | 
    
         
            +
            		def cancel
         
     | 
| 
      
 25 
     | 
    
         
            +
            			start
         
     | 
| 
      
 26 
     | 
    
         
            +
            			polling_loop(:poll, async_connect_timeout)
         
     | 
| 
      
 27 
     | 
    
         
            +
            		end
         
     | 
| 
      
 28 
     | 
    
         
            +
            		alias async_cancel cancel
         
     | 
| 
      
 29 
     | 
    
         
            +
            	end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/pg/connection.rb
    CHANGED
    
    | 
         @@ -356,21 +356,18 @@ class PG::Connection 
     | 
|
| 
       356 
356 
     | 
    
         
             
            		end
         
     | 
| 
       357 
357 
     | 
    
         
             
            	end
         
     | 
| 
       358 
358 
     | 
    
         | 
| 
       359 
     | 
    
         
            -
            	#  
     | 
| 
       360 
     | 
    
         
            -
            	 
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
       363 
     | 
    
         
            -
             
     | 
| 
       364 
     | 
    
         
            -
             
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
       367 
     | 
    
         
            -
             
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
            		 
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
            			ssl_attribute_names.each.with_object({}) do |n,h|
         
     | 
| 
       372 
     | 
    
         
            -
            				h[n] = ssl_attribute(n)
         
     | 
| 
       373 
     | 
    
         
            -
            			end
         
     | 
| 
      
 359 
     | 
    
         
            +
            	# call-seq:
         
     | 
| 
      
 360 
     | 
    
         
            +
            	#   conn.ssl_attributes -> Hash<String,String>
         
     | 
| 
      
 361 
     | 
    
         
            +
            	#
         
     | 
| 
      
 362 
     | 
    
         
            +
            	# Returns SSL-related information about the connection as key/value pairs
         
     | 
| 
      
 363 
     | 
    
         
            +
            	#
         
     | 
| 
      
 364 
     | 
    
         
            +
            	# The available attributes varies depending on the SSL library being used,
         
     | 
| 
      
 365 
     | 
    
         
            +
            	# and the type of connection.
         
     | 
| 
      
 366 
     | 
    
         
            +
            	#
         
     | 
| 
      
 367 
     | 
    
         
            +
            	# See also #ssl_attribute
         
     | 
| 
      
 368 
     | 
    
         
            +
            	def ssl_attributes
         
     | 
| 
      
 369 
     | 
    
         
            +
            		ssl_attribute_names.each.with_object({}) do |n,h|
         
     | 
| 
      
 370 
     | 
    
         
            +
            			h[n] = ssl_attribute(n)
         
     | 
| 
       374 
371 
     | 
    
         
             
            		end
         
     | 
| 
       375 
372 
     | 
    
         
             
            	end
         
     | 
| 
       376 
373 
     | 
    
         | 
| 
         @@ -539,6 +536,25 @@ class PG::Connection 
     | 
|
| 
       539 
536 
     | 
    
         
             
            	end
         
     | 
| 
       540 
537 
     | 
    
         
             
            	alias async_put_copy_end put_copy_end
         
     | 
| 
       541 
538 
     | 
    
         | 
| 
      
 539 
     | 
    
         
            +
            	if method_defined? :send_pipeline_sync
         
     | 
| 
      
 540 
     | 
    
         
            +
            		# call-seq:
         
     | 
| 
      
 541 
     | 
    
         
            +
            		#    conn.pipeline_sync
         
     | 
| 
      
 542 
     | 
    
         
            +
            		#
         
     | 
| 
      
 543 
     | 
    
         
            +
            		# Marks a synchronization point in a pipeline by sending a sync message and flushing the send buffer.
         
     | 
| 
      
 544 
     | 
    
         
            +
            		# This serves as the delimiter of an implicit transaction and an error recovery point.
         
     | 
| 
      
 545 
     | 
    
         
            +
            		#
         
     | 
| 
      
 546 
     | 
    
         
            +
            		# See enter_pipeline_mode
         
     | 
| 
      
 547 
     | 
    
         
            +
            		#
         
     | 
| 
      
 548 
     | 
    
         
            +
            		# Raises PG::Error if the connection is not in pipeline mode or sending a sync message failed.
         
     | 
| 
      
 549 
     | 
    
         
            +
            		#
         
     | 
| 
      
 550 
     | 
    
         
            +
            		# Available since PostgreSQL-14
         
     | 
| 
      
 551 
     | 
    
         
            +
            		def pipeline_sync(*args)
         
     | 
| 
      
 552 
     | 
    
         
            +
            			send_pipeline_sync(*args)
         
     | 
| 
      
 553 
     | 
    
         
            +
            			flush
         
     | 
| 
      
 554 
     | 
    
         
            +
            		end
         
     | 
| 
      
 555 
     | 
    
         
            +
            		alias async_pipeline_sync pipeline_sync
         
     | 
| 
      
 556 
     | 
    
         
            +
            	end
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
       542 
558 
     | 
    
         
             
            	if method_defined? :sync_encrypt_password
         
     | 
| 
       543 
559 
     | 
    
         
             
            		# call-seq:
         
     | 
| 
       544 
560 
     | 
    
         
             
            		#    conn.encrypt_password( password, username, algorithm=nil ) -> String
         
     | 
| 
         @@ -586,128 +602,144 @@ class PG::Connection 
     | 
|
| 
       586 
602 
     | 
    
         
             
            	end
         
     | 
| 
       587 
603 
     | 
    
         
             
            	alias async_reset reset
         
     | 
| 
       588 
604 
     | 
    
         | 
| 
       589 
     | 
    
         
            -
            	 
     | 
| 
       590 
     | 
    
         
            -
             
     | 
| 
       591 
     | 
    
         
            -
             
     | 
| 
       592 
     | 
    
         
            -
             
     | 
| 
       593 
     | 
    
         
            -
             
     | 
| 
       594 
     | 
    
         
            -
             
     | 
| 
       595 
     | 
    
         
            -
             
     | 
| 
       596 
     | 
    
         
            -
             
     | 
| 
       597 
     | 
    
         
            -
             
     | 
| 
       598 
     | 
    
         
            -
             
     | 
| 
       599 
     | 
    
         
            -
            		 
     | 
| 
       600 
     | 
    
         
            -
            		 
     | 
| 
       601 
     | 
    
         
            -
             
     | 
| 
       602 
     | 
    
         
            -
            		 
     | 
| 
       603 
     | 
    
         
            -
             
     | 
| 
       604 
     | 
    
         
            -
             
     | 
| 
       605 
     | 
    
         
            -
             
     | 
| 
       606 
     | 
    
         
            -
             
     | 
| 
       607 
     | 
    
         
            -
             
     | 
| 
       608 
     | 
    
         
            -
             
     | 
| 
       609 
     | 
    
         
            -
             
     | 
| 
       610 
     | 
    
         
            -
             
     | 
| 
       611 
     | 
    
         
            -
            			 
     | 
| 
       612 
     | 
    
         
            -
            			 
     | 
| 
       613 
     | 
    
         
            -
             
     | 
| 
       614 
     | 
    
         
            -
             
     | 
| 
       615 
     | 
    
         
            -
             
     | 
| 
       616 
     | 
    
         
            -
             
     | 
| 
       617 
     | 
    
         
            -
             
     | 
| 
       618 
     | 
    
         
            -
             
     | 
| 
       619 
     | 
    
         
            -
             
     | 
| 
       620 
     | 
    
         
            -
             
     | 
| 
       621 
     | 
    
         
            -
             
     | 
| 
       622 
     | 
    
         
            -
             
     | 
| 
       623 
     | 
    
         
            -
             
     | 
| 
       624 
     | 
    
         
            -
             
     | 
| 
       625 
     | 
    
         
            -
             
     | 
| 
       626 
     | 
    
         
            -
             
     | 
| 
       627 
     | 
    
         
            -
             
     | 
| 
       628 
     | 
    
         
            -
             
     | 
| 
       629 
     | 
    
         
            -
             
     | 
| 
       630 
     | 
    
         
            -
            				 
     | 
| 
       631 
     | 
    
         
            -
             
     | 
| 
       632 
     | 
    
         
            -
            					cl. 
     | 
| 
      
 605 
     | 
    
         
            +
            	if defined?(PG::CancelConnection)
         
     | 
| 
      
 606 
     | 
    
         
            +
            		# PostgreSQL-17+
         
     | 
| 
      
 607 
     | 
    
         
            +
             
     | 
| 
      
 608 
     | 
    
         
            +
            		def sync_cancel
         
     | 
| 
      
 609 
     | 
    
         
            +
            			cancon = PG::CancelConnection.new(self)
         
     | 
| 
      
 610 
     | 
    
         
            +
            			cancon.sync_cancel
         
     | 
| 
      
 611 
     | 
    
         
            +
            		rescue PG::Error => err
         
     | 
| 
      
 612 
     | 
    
         
            +
            			err.to_s
         
     | 
| 
      
 613 
     | 
    
         
            +
            		end
         
     | 
| 
      
 614 
     | 
    
         
            +
             
     | 
| 
      
 615 
     | 
    
         
            +
            		# call-seq:
         
     | 
| 
      
 616 
     | 
    
         
            +
            		#    conn.cancel() -> String
         
     | 
| 
      
 617 
     | 
    
         
            +
            		#
         
     | 
| 
      
 618 
     | 
    
         
            +
            		# Requests cancellation of the command currently being
         
     | 
| 
      
 619 
     | 
    
         
            +
            		# processed.
         
     | 
| 
      
 620 
     | 
    
         
            +
            		#
         
     | 
| 
      
 621 
     | 
    
         
            +
            		# Returns +nil+ on success, or a string containing the
         
     | 
| 
      
 622 
     | 
    
         
            +
            		# error message if a failure occurs.
         
     | 
| 
      
 623 
     | 
    
         
            +
            		#
         
     | 
| 
      
 624 
     | 
    
         
            +
            		# On PostgreSQL-17+ client libaray the class PG::CancelConnection is used.
         
     | 
| 
      
 625 
     | 
    
         
            +
            		# On older client library a pure ruby implementation is used.
         
     | 
| 
      
 626 
     | 
    
         
            +
            		def cancel
         
     | 
| 
      
 627 
     | 
    
         
            +
            			cancon = PG::CancelConnection.new(self)
         
     | 
| 
      
 628 
     | 
    
         
            +
            			cancon.async_connect_timeout = conninfo_hash[:connect_timeout]
         
     | 
| 
      
 629 
     | 
    
         
            +
            			cancon.async_cancel
         
     | 
| 
      
 630 
     | 
    
         
            +
            		rescue PG::Error => err
         
     | 
| 
      
 631 
     | 
    
         
            +
            			err.to_s
         
     | 
| 
      
 632 
     | 
    
         
            +
            		end
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
      
 634 
     | 
    
         
            +
            	else
         
     | 
| 
      
 635 
     | 
    
         
            +
             
     | 
| 
      
 636 
     | 
    
         
            +
            		# PostgreSQL < 17
         
     | 
| 
      
 637 
     | 
    
         
            +
             
     | 
| 
      
 638 
     | 
    
         
            +
            		def cancel
         
     | 
| 
      
 639 
     | 
    
         
            +
            			be_pid = backend_pid
         
     | 
| 
      
 640 
     | 
    
         
            +
            			be_key = backend_key
         
     | 
| 
      
 641 
     | 
    
         
            +
            			cancel_request = [0x10, 1234, 5678, be_pid, be_key].pack("NnnNN")
         
     | 
| 
      
 642 
     | 
    
         
            +
             
     | 
| 
      
 643 
     | 
    
         
            +
            			if Fiber.respond_to?(:scheduler) && Fiber.scheduler && RUBY_PLATFORM =~ /mingw|mswin/
         
     | 
| 
      
 644 
     | 
    
         
            +
            				# Ruby's nonblocking IO is not really supported on Windows.
         
     | 
| 
      
 645 
     | 
    
         
            +
            				# We work around by using threads and explicit calls to wait_readable/wait_writable.
         
     | 
| 
      
 646 
     | 
    
         
            +
            				cl = Thread.new(socket_io.remote_address) { |ra| ra.connect }.value
         
     | 
| 
      
 647 
     | 
    
         
            +
            				begin
         
     | 
| 
      
 648 
     | 
    
         
            +
            					cl.write_nonblock(cancel_request)
         
     | 
| 
      
 649 
     | 
    
         
            +
            				rescue IO::WaitReadable, Errno::EINTR
         
     | 
| 
      
 650 
     | 
    
         
            +
            					cl.wait_writable
         
     | 
| 
      
 651 
     | 
    
         
            +
            					retry
         
     | 
| 
       633 
652 
     | 
    
         
             
            				end
         
     | 
| 
      
 653 
     | 
    
         
            +
            				begin
         
     | 
| 
      
 654 
     | 
    
         
            +
            					cl.read_nonblock(1)
         
     | 
| 
      
 655 
     | 
    
         
            +
            				rescue IO::WaitReadable, Errno::EINTR
         
     | 
| 
      
 656 
     | 
    
         
            +
            					cl.wait_readable
         
     | 
| 
      
 657 
     | 
    
         
            +
            					retry
         
     | 
| 
      
 658 
     | 
    
         
            +
            				rescue EOFError
         
     | 
| 
      
 659 
     | 
    
         
            +
            				end
         
     | 
| 
      
 660 
     | 
    
         
            +
            			else
         
     | 
| 
      
 661 
     | 
    
         
            +
            				cl = socket_io.remote_address.connect
         
     | 
| 
      
 662 
     | 
    
         
            +
            				# Send CANCEL_REQUEST_CODE and parameters
         
     | 
| 
      
 663 
     | 
    
         
            +
            				cl.write(cancel_request)
         
     | 
| 
      
 664 
     | 
    
         
            +
            				# Wait for the postmaster to close the connection, which indicates that it's processed the request.
         
     | 
| 
      
 665 
     | 
    
         
            +
            				cl.read(1)
         
     | 
| 
       634 
666 
     | 
    
         
             
            			end
         
     | 
| 
       635 
     | 
    
         
            -
            			cl.write(cancel_request)
         
     | 
| 
       636 
     | 
    
         
            -
            			cl.read(1)
         
     | 
| 
       637 
     | 
    
         
            -
            		else
         
     | 
| 
       638 
     | 
    
         
            -
            			cl = socket_io.remote_address.connect
         
     | 
| 
       639 
     | 
    
         
            -
            			# Send CANCEL_REQUEST_CODE and parameters
         
     | 
| 
       640 
     | 
    
         
            -
            			cl.write(cancel_request)
         
     | 
| 
       641 
     | 
    
         
            -
            			# Wait for the postmaster to close the connection, which indicates that it's processed the request.
         
     | 
| 
       642 
     | 
    
         
            -
            			cl.read(1)
         
     | 
| 
       643 
     | 
    
         
            -
            		end
         
     | 
| 
       644 
667 
     | 
    
         | 
| 
       645 
     | 
    
         
            -
             
     | 
| 
       646 
     | 
    
         
            -
             
     | 
| 
       647 
     | 
    
         
            -
             
     | 
| 
       648 
     | 
    
         
            -
             
     | 
| 
      
 668 
     | 
    
         
            +
            			cl.close
         
     | 
| 
      
 669 
     | 
    
         
            +
            			nil
         
     | 
| 
      
 670 
     | 
    
         
            +
            		rescue SystemCallError => err
         
     | 
| 
      
 671 
     | 
    
         
            +
            			err.to_s
         
     | 
| 
      
 672 
     | 
    
         
            +
            		end
         
     | 
| 
       649 
673 
     | 
    
         
             
            	end
         
     | 
| 
       650 
674 
     | 
    
         
             
            	alias async_cancel cancel
         
     | 
| 
       651 
675 
     | 
    
         | 
| 
       652 
     | 
    
         
            -
            	 
     | 
| 
      
 676 
     | 
    
         
            +
            	module Pollable
         
     | 
| 
       653 
677 
     | 
    
         
             
            		# Track the progress of the connection, waiting for the socket to become readable/writable before polling it
         
     | 
| 
      
 678 
     | 
    
         
            +
            		private def polling_loop(poll_meth, connect_timeout)
         
     | 
| 
      
 679 
     | 
    
         
            +
            			if (timeo = connect_timeout.to_i) && timeo > 0
         
     | 
| 
      
 680 
     | 
    
         
            +
            				host_count = conninfo_hash[:host].to_s.count(",") + 1
         
     | 
| 
      
 681 
     | 
    
         
            +
            				stop_time = timeo * host_count + Process.clock_gettime(Process::CLOCK_MONOTONIC)
         
     | 
| 
      
 682 
     | 
    
         
            +
            			end
         
     | 
| 
       654 
683 
     | 
    
         | 
| 
       655 
     | 
    
         
            -
             
     | 
| 
       656 
     | 
    
         
            -
            			 
     | 
| 
       657 
     | 
    
         
            -
             
     | 
| 
       658 
     | 
    
         
            -
             
     | 
| 
       659 
     | 
    
         
            -
             
     | 
| 
       660 
     | 
    
         
            -
             
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
            				 
     | 
| 
       663 
     | 
    
         
            -
             
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
       665 
     | 
    
         
            -
             
     | 
| 
       666 
     | 
    
         
            -
             
     | 
| 
       667 
     | 
    
         
            -
             
     | 
| 
       668 
     | 
    
         
            -
             
     | 
| 
       669 
     | 
    
         
            -
             
     | 
| 
       670 
     | 
    
         
            -
             
     | 
| 
       671 
     | 
    
         
            -
             
     | 
| 
       672 
     | 
    
         
            -
             
     | 
| 
       673 
     | 
    
         
            -
            					 
     | 
| 
       674 
     | 
    
         
            -
            						IO 
     | 
| 
      
 684 
     | 
    
         
            +
            			poll_status = PG::PGRES_POLLING_WRITING
         
     | 
| 
      
 685 
     | 
    
         
            +
            			until poll_status == PG::PGRES_POLLING_OK ||
         
     | 
| 
      
 686 
     | 
    
         
            +
            					poll_status == PG::PGRES_POLLING_FAILED
         
     | 
| 
      
 687 
     | 
    
         
            +
             
     | 
| 
      
 688 
     | 
    
         
            +
            				# Set single timeout to parameter "connect_timeout" but
         
     | 
| 
      
 689 
     | 
    
         
            +
            				# don't exceed total connection time of number-of-hosts * connect_timeout.
         
     | 
| 
      
 690 
     | 
    
         
            +
            				timeout = [timeo, stop_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)].min if stop_time
         
     | 
| 
      
 691 
     | 
    
         
            +
            				event = if !timeout || timeout >= 0
         
     | 
| 
      
 692 
     | 
    
         
            +
            					# If the socket needs to read, wait 'til it becomes readable to poll again
         
     | 
| 
      
 693 
     | 
    
         
            +
            					case poll_status
         
     | 
| 
      
 694 
     | 
    
         
            +
            					when PG::PGRES_POLLING_READING
         
     | 
| 
      
 695 
     | 
    
         
            +
            						if defined?(IO::READABLE) # ruby-3.0+
         
     | 
| 
      
 696 
     | 
    
         
            +
            							socket_io.wait(IO::READABLE | IO::PRIORITY, timeout)
         
     | 
| 
      
 697 
     | 
    
         
            +
            						else
         
     | 
| 
      
 698 
     | 
    
         
            +
            							IO.select([socket_io], nil, [socket_io], timeout)
         
     | 
| 
      
 699 
     | 
    
         
            +
            						end
         
     | 
| 
      
 700 
     | 
    
         
            +
             
     | 
| 
      
 701 
     | 
    
         
            +
            					# ...and the same for when the socket needs to write
         
     | 
| 
      
 702 
     | 
    
         
            +
            					when PG::PGRES_POLLING_WRITING
         
     | 
| 
      
 703 
     | 
    
         
            +
            						if defined?(IO::WRITABLE) # ruby-3.0+
         
     | 
| 
      
 704 
     | 
    
         
            +
            							# Use wait instead of wait_readable, since connection errors are delivered as
         
     | 
| 
      
 705 
     | 
    
         
            +
            							# exceptional/priority events on Windows.
         
     | 
| 
      
 706 
     | 
    
         
            +
            							socket_io.wait(IO::WRITABLE | IO::PRIORITY, timeout)
         
     | 
| 
      
 707 
     | 
    
         
            +
            						else
         
     | 
| 
      
 708 
     | 
    
         
            +
            							# io#wait on ruby-2.x doesn't wait for priority, so fallback to IO.select
         
     | 
| 
      
 709 
     | 
    
         
            +
            							IO.select(nil, [socket_io], [socket_io], timeout)
         
     | 
| 
      
 710 
     | 
    
         
            +
            						end
         
     | 
| 
       675 
711 
     | 
    
         
             
            					end
         
     | 
| 
       676 
     | 
    
         
            -
             
     | 
| 
       677 
     | 
    
         
            -
            				#  
     | 
| 
       678 
     | 
    
         
            -
            				 
     | 
| 
       679 
     | 
    
         
            -
             
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
            						 
     | 
| 
       682 
     | 
    
         
            -
             
     | 
| 
      
 712 
     | 
    
         
            +
            				end
         
     | 
| 
      
 713 
     | 
    
         
            +
            				# connection to server at "localhost" (127.0.0.1), port 5433 failed: timeout expired (PG::ConnectionBad)
         
     | 
| 
      
 714 
     | 
    
         
            +
            				# connection to server on socket "/var/run/postgresql/.s.PGSQL.5433" failed: No such file or directory
         
     | 
| 
      
 715 
     | 
    
         
            +
            				unless event
         
     | 
| 
      
 716 
     | 
    
         
            +
            					if self.class.send(:host_is_named_pipe?, host)
         
     | 
| 
      
 717 
     | 
    
         
            +
            						connhost = "on socket \"#{host}\""
         
     | 
| 
      
 718 
     | 
    
         
            +
            					elsif respond_to?(:hostaddr)
         
     | 
| 
      
 719 
     | 
    
         
            +
            						connhost = "at \"#{host}\" (#{hostaddr}), port #{port}"
         
     | 
| 
       683 
720 
     | 
    
         
             
            					else
         
     | 
| 
       684 
     | 
    
         
            -
            						 
     | 
| 
       685 
     | 
    
         
            -
            						IO.select(nil, [socket_io], [socket_io], timeout)
         
     | 
| 
      
 721 
     | 
    
         
            +
            						connhost = "at \"#{host}\", port #{port}"
         
     | 
| 
       686 
722 
     | 
    
         
             
            					end
         
     | 
| 
      
 723 
     | 
    
         
            +
            					raise PG::ConnectionBad.new("connection to server #{connhost} failed: timeout expired", connection: self)
         
     | 
| 
       687 
724 
     | 
    
         
             
            				end
         
     | 
| 
       688 
     | 
    
         
            -
             
     | 
| 
       689 
     | 
    
         
            -
             
     | 
| 
       690 
     | 
    
         
            -
             
     | 
| 
       691 
     | 
    
         
            -
            			unless event
         
     | 
| 
       692 
     | 
    
         
            -
            				if self.class.send(:host_is_named_pipe?, host)
         
     | 
| 
       693 
     | 
    
         
            -
            					connhost = "on socket \"#{host}\""
         
     | 
| 
       694 
     | 
    
         
            -
            				elsif respond_to?(:hostaddr)
         
     | 
| 
       695 
     | 
    
         
            -
            					connhost = "at \"#{host}\" (#{hostaddr}), port #{port}"
         
     | 
| 
       696 
     | 
    
         
            -
            				else
         
     | 
| 
       697 
     | 
    
         
            -
            					connhost = "at \"#{host}\", port #{port}"
         
     | 
| 
       698 
     | 
    
         
            -
            				end
         
     | 
| 
       699 
     | 
    
         
            -
            				raise PG::ConnectionBad.new("connection to server #{connhost} failed: timeout expired", connection: self)
         
     | 
| 
      
 725 
     | 
    
         
            +
             
     | 
| 
      
 726 
     | 
    
         
            +
            				# Check to see if it's finished or failed yet
         
     | 
| 
      
 727 
     | 
    
         
            +
            				poll_status = send( poll_meth )
         
     | 
| 
       700 
728 
     | 
    
         
             
            			end
         
     | 
| 
       701 
729 
     | 
    
         | 
| 
       702 
     | 
    
         
            -
            			 
     | 
| 
       703 
     | 
    
         
            -
             
     | 
| 
      
 730 
     | 
    
         
            +
            			unless status == PG::CONNECTION_OK
         
     | 
| 
      
 731 
     | 
    
         
            +
            				msg = error_message
         
     | 
| 
      
 732 
     | 
    
         
            +
            				finish
         
     | 
| 
      
 733 
     | 
    
         
            +
            				raise PG::ConnectionBad.new(msg, connection: self)
         
     | 
| 
      
 734 
     | 
    
         
            +
            			end
         
     | 
| 
       704 
735 
     | 
    
         
             
            		end
         
     | 
| 
      
 736 
     | 
    
         
            +
            	end
         
     | 
| 
       705 
737 
     | 
    
         | 
| 
       706 
     | 
    
         
            -
             
     | 
| 
       707 
     | 
    
         
            -
             
     | 
| 
       708 
     | 
    
         
            -
             
     | 
| 
       709 
     | 
    
         
            -
             
     | 
| 
       710 
     | 
    
         
            -
            		 
     | 
| 
      
 738 
     | 
    
         
            +
            	include Pollable
         
     | 
| 
      
 739 
     | 
    
         
            +
             
     | 
| 
      
 740 
     | 
    
         
            +
            	private def async_connect_or_reset(poll_meth)
         
     | 
| 
      
 741 
     | 
    
         
            +
            		# Track the progress of the connection, waiting for the socket to become readable/writable before polling it
         
     | 
| 
      
 742 
     | 
    
         
            +
            		polling_loop(poll_meth, conninfo_hash[:connect_timeout])
         
     | 
| 
       711 
743 
     | 
    
         | 
| 
       712 
744 
     | 
    
         
             
            		# Set connection to nonblocking to handle all blocking states in ruby.
         
     | 
| 
       713 
745 
     | 
    
         
             
            		# That way a fiber scheduler is able to handle IO requests.
         
     | 
| 
         @@ -825,6 +857,14 @@ class PG::Connection 
     | 
|
| 
       825 
857 
     | 
    
         
             
            			iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
         
     | 
| 
       826 
858 
     | 
    
         
             
            			iopts = PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
         
     | 
| 
       827 
859 
     | 
    
         | 
| 
      
 860 
     | 
    
         
            +
            			if PG::BUNDLED_LIBPQ_WITH_UNIXSOCKET && iopts[:host].to_s.empty?
         
     | 
| 
      
 861 
     | 
    
         
            +
            				# Many distors patch the hardcoded default UnixSocket path in libpq to /var/run/postgresql instead of /tmp .
         
     | 
| 
      
 862 
     | 
    
         
            +
            				# We simply try them all.
         
     | 
| 
      
 863 
     | 
    
         
            +
            				iopts[:host] = "/var/run/postgresql" + # Ubuntu, Debian, Fedora, Opensuse
         
     | 
| 
      
 864 
     | 
    
         
            +
            					",/run/postgresql" + # Alpine, Archlinux, Gentoo
         
     | 
| 
      
 865 
     | 
    
         
            +
            					",/tmp" # Stock PostgreSQL
         
     | 
| 
      
 866 
     | 
    
         
            +
            			end
         
     | 
| 
      
 867 
     | 
    
         
            +
             
     | 
| 
       828 
868 
     | 
    
         
             
            			iopts_for_reset = iopts
         
     | 
| 
       829 
869 
     | 
    
         
             
            			if iopts[:hostaddr]
         
     | 
| 
       830 
870 
     | 
    
         
             
            				# hostaddr is provided -> no need to resolve hostnames
         
     | 
| 
         @@ -897,14 +937,29 @@ class PG::Connection 
     | 
|
| 
       897 
937 
     | 
    
         
             
            		private_constant :REDIRECT_CLASS_METHODS
         
     | 
| 
       898 
938 
     | 
    
         | 
| 
       899 
939 
     | 
    
         
             
            		# These methods are affected by PQsetnonblocking
         
     | 
| 
       900 
     | 
    
         
            -
            		REDIRECT_SEND_METHODS =  
     | 
| 
      
 940 
     | 
    
         
            +
            		REDIRECT_SEND_METHODS = {
         
     | 
| 
       901 
941 
     | 
    
         
             
            			:isnonblocking => [:async_isnonblocking, :sync_isnonblocking],
         
     | 
| 
       902 
942 
     | 
    
         
             
            			:nonblocking? => [:async_isnonblocking, :sync_isnonblocking],
         
     | 
| 
       903 
943 
     | 
    
         
             
            			:put_copy_data => [:async_put_copy_data, :sync_put_copy_data],
         
     | 
| 
       904 
944 
     | 
    
         
             
            			:put_copy_end => [:async_put_copy_end, :sync_put_copy_end],
         
     | 
| 
       905 
945 
     | 
    
         
             
            			:flush => [:async_flush, :sync_flush],
         
     | 
| 
       906 
     | 
    
         
            -
            		} 
     | 
| 
      
 946 
     | 
    
         
            +
            		}
         
     | 
| 
       907 
947 
     | 
    
         
             
            		private_constant :REDIRECT_SEND_METHODS
         
     | 
| 
      
 948 
     | 
    
         
            +
            		if PG::Connection.instance_methods.include? :sync_pipeline_sync
         
     | 
| 
      
 949 
     | 
    
         
            +
            			if PG::Connection.instance_methods.include? :send_pipeline_sync
         
     | 
| 
      
 950 
     | 
    
         
            +
            				# PostgreSQL-17+
         
     | 
| 
      
 951 
     | 
    
         
            +
            				REDIRECT_SEND_METHODS.merge!({
         
     | 
| 
      
 952 
     | 
    
         
            +
            					:pipeline_sync => [:async_pipeline_sync, :sync_pipeline_sync],
         
     | 
| 
      
 953 
     | 
    
         
            +
            				})
         
     | 
| 
      
 954 
     | 
    
         
            +
            			else
         
     | 
| 
      
 955 
     | 
    
         
            +
            				# PostgreSQL-14+
         
     | 
| 
      
 956 
     | 
    
         
            +
            				REDIRECT_SEND_METHODS.merge!({
         
     | 
| 
      
 957 
     | 
    
         
            +
            					:pipeline_sync => [:sync_pipeline_sync, :sync_pipeline_sync],
         
     | 
| 
      
 958 
     | 
    
         
            +
            				})
         
     | 
| 
      
 959 
     | 
    
         
            +
            			end
         
     | 
| 
      
 960 
     | 
    
         
            +
            		end
         
     | 
| 
      
 961 
     | 
    
         
            +
            		PG.make_shareable(REDIRECT_SEND_METHODS)
         
     | 
| 
      
 962 
     | 
    
         
            +
             
     | 
| 
       908 
963 
     | 
    
         
             
            		REDIRECT_METHODS = {
         
     | 
| 
       909 
964 
     | 
    
         
             
            			:exec => [:async_exec, :sync_exec],
         
     | 
| 
       910 
965 
     | 
    
         
             
            			:query => [:async_exec, :sync_exec],
         
     | 
| 
         @@ -921,12 +976,13 @@ class PG::Connection 
     | 
|
| 
       921 
976 
     | 
    
         
             
            			:set_client_encoding => [:async_set_client_encoding, :sync_set_client_encoding],
         
     | 
| 
       922 
977 
     | 
    
         
             
            			:client_encoding= => [:async_set_client_encoding, :sync_set_client_encoding],
         
     | 
| 
       923 
978 
     | 
    
         
             
            			:cancel => [:async_cancel, :sync_cancel],
         
     | 
| 
      
 979 
     | 
    
         
            +
            			:encrypt_password => [:async_encrypt_password, :sync_encrypt_password],
         
     | 
| 
       924 
980 
     | 
    
         
             
            		}
         
     | 
| 
       925 
981 
     | 
    
         
             
            		private_constant :REDIRECT_METHODS
         
     | 
| 
       926 
     | 
    
         
            -
             
     | 
| 
       927 
     | 
    
         
            -
            		if PG::Connection.instance_methods.include? :async_encrypt_password
         
     | 
| 
      
 982 
     | 
    
         
            +
            		if PG::Connection.instance_methods.include? :async_close_prepared
         
     | 
| 
       928 
983 
     | 
    
         
             
            			REDIRECT_METHODS.merge!({
         
     | 
| 
       929 
     | 
    
         
            -
            				: 
     | 
| 
      
 984 
     | 
    
         
            +
            				:close_prepared => [:async_close_prepared, :sync_close_prepared],
         
     | 
| 
      
 985 
     | 
    
         
            +
            				:close_portal => [:async_close_portal, :sync_close_portal],
         
     | 
| 
       930 
986 
     | 
    
         
             
            			})
         
     | 
| 
       931 
987 
     | 
    
         
             
            		end
         
     | 
| 
       932 
988 
     | 
    
         
             
            		PG.make_shareable(REDIRECT_METHODS)
         
     |