pg 1.6.2 → 1.7.0

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +61 -0
  4. data/Gemfile +5 -4
  5. data/README.ja.md +81 -30
  6. data/README.md +20 -10
  7. data/Rakefile +13 -26
  8. data/certs/larskanis-2026.pem +24 -0
  9. data/ext/errorcodes.def +9 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +8 -1
  12. data/ext/extconf.rb +19 -28
  13. data/ext/gvl_wrappers.c +2 -2
  14. data/ext/gvl_wrappers.h +40 -160
  15. data/ext/pg.c +8 -12
  16. data/ext/pg.h +14 -15
  17. data/ext/pg_binary_decoder.c +6 -2
  18. data/ext/pg_binary_encoder.c +7 -0
  19. data/ext/pg_cancel_connection.c +6 -6
  20. data/ext/pg_coder.c +4 -4
  21. data/ext/pg_connection.c +218 -161
  22. data/ext/pg_copy_coder.c +34 -21
  23. data/ext/pg_record_coder.c +10 -6
  24. data/ext/pg_result.c +131 -61
  25. data/ext/pg_text_decoder.c +6 -6
  26. data/ext/pg_text_encoder.c +7 -2
  27. data/ext/pg_tuple.c +2 -2
  28. data/ext/pg_type_map.c +41 -1
  29. data/ext/pg_type_map_all_strings.c +2 -2
  30. data/ext/pg_type_map_by_class.c +1 -1
  31. data/ext/pg_type_map_by_column.c +2 -2
  32. data/ext/pg_type_map_by_oid.c +1 -1
  33. data/ext/pg_type_map_in_ruby.c +1 -1
  34. data/lib/pg/basic_type_map_based_on_result.rb +5 -0
  35. data/lib/pg/basic_type_map_for_queries.rb +9 -2
  36. data/lib/pg/basic_type_map_for_results.rb +5 -0
  37. data/lib/pg/connection.rb +166 -76
  38. data/lib/pg/text_decoder/date.rb +1 -1
  39. data/lib/pg/text_decoder/json.rb +1 -1
  40. data/lib/pg/text_encoder/date.rb +7 -1
  41. data/lib/pg/text_encoder/json.rb +1 -1
  42. data/lib/pg/version.rb +1 -1
  43. data/misc/yugabyte/docker-compose.yml +1 -1
  44. data/pg.gemspec +1 -1
  45. data/sample/async_mixed.rb +1 -1
  46. data.tar.gz.sig +0 -0
  47. metadata +19 -20
  48. metadata.gz.sig +0 -0
  49. data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +0 -21
  50. data/ports/patches/postgresql/17.6/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +0 -52
  51. /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0001-Allow-static-linking-krb5-library.patch +0 -0
  52. /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0002-unknown-command-line-option-on-clang.patch +0 -0
  53. /data/ports/patches/postgresql/{17.6 → 18.6}/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +0 -0
data/ext/pg_copy_coder.c CHANGED
@@ -55,7 +55,7 @@ static const rb_data_type_t pg_copycoder_type = {
55
55
  },
56
56
  &pg_coder_type,
57
57
  0,
58
- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
58
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
59
59
  };
60
60
 
61
61
  static VALUE
@@ -219,20 +219,21 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
219
219
  {
220
220
  t_pg_copycoder *this = (t_pg_copycoder *)conv;
221
221
  t_pg_coder_enc_func enc_func;
222
- static t_pg_coder *p_elem_coder;
222
+ t_pg_coder *p_elem_coder;
223
223
  int i;
224
+ VALUE rb_typemap = this->typemap;
224
225
  t_typemap *p_typemap;
225
226
  char *current_out;
226
227
  char *end_capa_ptr;
227
228
 
228
- p_typemap = RTYPEDDATA_DATA( this->typemap );
229
- p_typemap->funcs.fit_to_query( this->typemap, value );
229
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
230
+ p_typemap->funcs.fit_to_query( rb_typemap, value );
230
231
 
231
232
  /* Allocate a new string with embedded capacity and realloc exponential when needed. */
232
233
  PG_RB_STR_NEW( *intermediate, current_out, end_capa_ptr );
233
234
  PG_ENCODING_SET_NOCHECK(*intermediate, enc_idx);
234
235
 
235
- for( i=0; i<RARRAY_LEN(value); i++){
236
+ for( i=0; i<RARRAY_LENINT(value); i++){
236
237
  char *ptr1;
237
238
  char *ptr2;
238
239
  int strlen;
@@ -265,7 +266,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
265
266
  strlen = RSTRING_LENINT(subint);
266
267
 
267
268
  /* size of string assuming the worst case, that every character must be escaped. */
268
- PG_RB_STR_ENSURE_CAPA( *intermediate, strlen * 2, current_out, end_capa_ptr );
269
+ PG_RB_STR_ENSURE_CAPA( *intermediate, (size_t)strlen * 2, current_out, end_capa_ptr );
269
270
 
270
271
  /* Copy string from subint with backslash escaping */
271
272
  for(ptr1 = RSTRING_PTR(subint); ptr1 < RSTRING_PTR(subint) + strlen; ptr1++) {
@@ -278,7 +279,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
278
279
  } else {
279
280
  /* 2nd pass for writing the data to prepared buffer */
280
281
  /* size of string assuming the worst case, that every character must be escaped. */
281
- PG_RB_STR_ENSURE_CAPA( *intermediate, strlen * 2, current_out, end_capa_ptr );
282
+ PG_RB_STR_ENSURE_CAPA( *intermediate, (size_t)strlen * 2, current_out, end_capa_ptr );
282
283
 
283
284
  /* Place the unescaped string at current output position. */
284
285
  strlen = enc_func(p_elem_coder, entry, current_out, &subint, enc_idx);
@@ -314,6 +315,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
314
315
 
315
316
  rb_str_set_len( *intermediate, current_out - RSTRING_PTR(*intermediate) );
316
317
 
318
+ RB_GC_GUARD(rb_typemap);
317
319
  return -1;
318
320
  }
319
321
 
@@ -366,12 +368,17 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
366
368
  {
367
369
  t_pg_copycoder *this = (t_pg_copycoder *)conv;
368
370
  int i;
371
+ VALUE rb_typemap = this->typemap;
369
372
  t_typemap *p_typemap;
370
373
  char *current_out;
371
374
  char *end_capa_ptr;
372
375
 
373
- p_typemap = RTYPEDDATA_DATA( this->typemap );
374
- p_typemap->funcs.fit_to_query( this->typemap, value );
376
+ if( RARRAY_LEN(value) >= 32768 ){
377
+ rb_raise( rb_eArgError, "too many columns in array for PG::BinaryEncoder::CopyRow: %ld", RARRAY_LEN(value) );
378
+ }
379
+
380
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
381
+ p_typemap->funcs.fit_to_query( rb_typemap, value );
375
382
 
376
383
  /* Allocate a new string with embedded capacity and realloc exponential when needed. */
377
384
  PG_RB_STR_NEW( *intermediate, current_out, end_capa_ptr );
@@ -382,12 +389,12 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
382
389
  write_nbo16(RARRAY_LEN(value), current_out);
383
390
  current_out += 2;
384
391
 
385
- for( i=0; i<RARRAY_LEN(value); i++){
392
+ for( i=0; i<RARRAY_LENINT(value); i++){
386
393
  int strlen;
387
394
  VALUE subint;
388
395
  VALUE entry;
389
396
  t_pg_coder_enc_func enc_func;
390
- static t_pg_coder *p_elem_coder;
397
+ t_pg_coder *p_elem_coder;
391
398
 
392
399
  entry = rb_ary_entry(value, i);
393
400
 
@@ -409,7 +416,7 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
409
416
  /* we can directly use String value in subint */
410
417
  strlen = RSTRING_LENINT(subint);
411
418
 
412
- PG_RB_STR_ENSURE_CAPA( *intermediate, 4 + strlen, current_out, end_capa_ptr );
419
+ PG_RB_STR_ENSURE_CAPA( *intermediate, (size_t)4 + strlen, current_out, end_capa_ptr );
413
420
  /* 4 bytes length */
414
421
  write_nbo32(strlen, current_out);
415
422
  current_out += 4;
@@ -418,7 +425,7 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
418
425
  current_out += strlen;
419
426
  } else {
420
427
  /* 2nd pass for writing the data to prepared buffer */
421
- PG_RB_STR_ENSURE_CAPA( *intermediate, 4 + strlen, current_out, end_capa_ptr );
428
+ PG_RB_STR_ENSURE_CAPA( *intermediate, (size_t)4 + strlen, current_out, end_capa_ptr );
422
429
  /* 4 bytes length */
423
430
  write_nbo32(strlen, current_out);
424
431
  current_out += 4;
@@ -432,6 +439,7 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
432
439
 
433
440
  rb_str_set_len( *intermediate, current_out - RSTRING_PTR(*intermediate) );
434
441
 
442
+ RB_GC_GUARD(rb_typemap);
435
443
  return -1;
436
444
  }
437
445
 
@@ -530,10 +538,11 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
530
538
  const char *cur_ptr;
531
539
  const char *line_end_ptr;
532
540
  char *end_capa_ptr;
541
+ VALUE rb_typemap = this->typemap;
533
542
  t_typemap *p_typemap;
534
543
 
535
- p_typemap = RTYPEDDATA_DATA( this->typemap );
536
- expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
544
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
545
+ expected_fields = p_typemap->funcs.fit_to_copy_get( rb_typemap );
537
546
 
538
547
  /* The received input string will probably have this->nfields fields. */
539
548
  array = rb_ary_new2(expected_fields);
@@ -553,7 +562,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
553
562
  int found_delim = 0;
554
563
  const char *start_ptr;
555
564
  const char *end_ptr;
556
- long input_len;
565
+ size_t input_len;
557
566
 
558
567
  /* Remember start of field on input side */
559
568
  start_ptr = cur_ptr;
@@ -688,7 +697,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
688
697
 
689
698
  /* Check whether raw input matched null marker */
690
699
  input_len = end_ptr - start_ptr;
691
- if (input_len == RSTRING_LEN(this->null_string) &&
700
+ if (input_len == (size_t)RSTRING_LEN(this->null_string) &&
692
701
  strncmp(start_ptr, RSTRING_PTR(this->null_string), input_len) == 0) {
693
702
  rb_ary_push(array, Qnil);
694
703
  } else {
@@ -714,11 +723,13 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
714
723
  break;
715
724
  }
716
725
 
726
+ RB_GC_GUARD(rb_typemap);
727
+
717
728
  return array;
718
729
  }
719
730
 
720
731
 
721
- static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
732
+ static const char BinarySignature[11] = {'P','G','C','O','P','Y','\n','\377','\r','\n','\0'};
722
733
 
723
734
  /*
724
735
  * Document-class: PG::BinaryDecoder::CopyRow < PG::CopyDecoder
@@ -786,10 +797,11 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
786
797
  const char *cur_ptr;
787
798
  const char *line_end_ptr;
788
799
  char *end_capa_ptr;
800
+ VALUE rb_typemap = this->typemap;
789
801
  t_typemap *p_typemap;
790
802
 
791
- p_typemap = RTYPEDDATA_DATA( this->typemap );
792
- expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
803
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
804
+ expected_fields = p_typemap->funcs.fit_to_copy_get( rb_typemap );
793
805
 
794
806
  /* Allocate a new string with embedded capacity and realloc later with
795
807
  * exponential growing size when needed. */
@@ -830,7 +842,7 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
830
842
  array = rb_ary_new2(expected_fields);
831
843
 
832
844
  for( fieldno = 0; fieldno < nfields; fieldno++){
833
- long input_len;
845
+ int input_len;
834
846
 
835
847
  /* read field size */
836
848
  if (line_end_ptr - cur_ptr < 4 ) goto length_error;
@@ -871,6 +883,7 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
871
883
  if (cur_ptr < line_end_ptr)
872
884
  rb_raise( rb_eArgError, "trailing data after row data at position: %ld", (long)(cur_ptr - input_line) + 1 );
873
885
 
886
+ RB_GC_GUARD(rb_typemap);
874
887
  return array;
875
888
 
876
889
  length_error:
@@ -47,7 +47,7 @@ static const rb_data_type_t pg_recordcoder_type = {
47
47
  },
48
48
  &pg_coder_type,
49
49
  0,
50
- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
50
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
51
51
  };
52
52
 
53
53
  static VALUE
@@ -179,14 +179,15 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
179
179
  {
180
180
  t_pg_recordcoder *this = (t_pg_recordcoder *)conv;
181
181
  t_pg_coder_enc_func enc_func;
182
- static t_pg_coder *p_elem_coder;
182
+ t_pg_coder *p_elem_coder;
183
183
  int i;
184
+ VALUE rb_typemap = this->typemap;
184
185
  t_typemap *p_typemap;
185
186
  char *current_out;
186
187
  char *end_capa_ptr;
187
188
 
188
- p_typemap = RTYPEDDATA_DATA( this->typemap );
189
- p_typemap->funcs.fit_to_query( this->typemap, value );
189
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
190
+ p_typemap->funcs.fit_to_query( rb_typemap, value );
190
191
 
191
192
  /* Allocate a new string with embedded capacity and realloc exponential when needed. */
192
193
  PG_RB_STR_NEW( *intermediate, current_out, end_capa_ptr );
@@ -277,6 +278,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
277
278
 
278
279
  rb_str_set_len( *intermediate, current_out - RSTRING_PTR(*intermediate) );
279
280
 
281
+ RB_GC_GUARD(rb_typemap);
280
282
  return -1;
281
283
  }
282
284
 
@@ -387,10 +389,11 @@ pg_text_dec_record(t_pg_coder *conv, char *input_line, int len, int _tuple, int
387
389
  char *output_ptr;
388
390
  char *cur_ptr;
389
391
  char *end_capa_ptr;
392
+ VALUE rb_typemap = this->typemap;
390
393
  t_typemap *p_typemap;
391
394
 
392
- p_typemap = RTYPEDDATA_DATA( this->typemap );
393
- expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
395
+ p_typemap = RTYPEDDATA_DATA( rb_typemap );
396
+ expected_fields = p_typemap->funcs.fit_to_copy_get( rb_typemap );
394
397
 
395
398
  /* The received input string will probably have this->nfields fields. */
396
399
  array = rb_ary_new2(expected_fields);
@@ -490,6 +493,7 @@ pg_text_dec_record(t_pg_coder *conv, char *input_line, int len, int _tuple, int
490
493
  if (*cur_ptr)
491
494
  rb_raise( rb_eArgError, "malformed record literal: \"%s\" - Junk after right parenthesis.", input_line );
492
495
 
496
+ RB_GC_GUARD(rb_typemap);
493
497
  return array;
494
498
  }
495
499