pg 1.6.2-aarch64-linux-musl → 1.6.3-aarch64-linux-musl

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e73f0f55598cec5939aab959f72f289d4d191c0b34eff5e141f8a3313fba0dd6
4
- data.tar.gz: eef1203dbc8311e98917284b2d564e15d111527e70817be9b25a8b7f6c248c4f
3
+ metadata.gz: a74a45f9f5ba0b37683f6430d86016656f03d69c53a748d6d62bfc8cfb97e299
4
+ data.tar.gz: c1becc32b822870f61cf07e4e4eb4e81512a042947071b00c8c8cc44016f7070
5
5
  SHA512:
6
- metadata.gz: ecf4c445f007550242aedd95356ce33d805a7ae553184d9de172fbec59e491fc3f78b56ed7efcd42557024275a4b7d3e51b8c649572a1cb8edcc6595e659a67d
7
- data.tar.gz: 8395c9802229813f5902976b30513e573043ecacaa3cf12b92d534afcfd55cad41d6d7fde93d762bcd7790eb9eb018e0c1b3d6579446f97032d0a8af08fcc75f
6
+ metadata.gz: 7fdf2fdd9eecf76d8d8130d140655759defd05edebdeaaf596b2cf3b76a89f03f75b81a200a3f70bdea894ea87779e39d0659e6db8718d0153a3299dcd251e6e
7
+ data.tar.gz: 954f449b6f987a6951eb5e834b5795dbca2b7e62cb35ca676750d9a181f5ec28fda99e3641e37e65d2c5d76db2161a40427ccfc8b34c4649f8e801b05cc4f67e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## v1.6.3 [2025-12-29] Lars Kanis <lars@greiz-reinsdorf.de>
2
+
3
+ Added:
4
+ - Add binary gems for ruby-4.0, now providing ruby-3.0 to 4.0. #682
5
+ - Improve documentation of PG::Result and README. #676
6
+ - Update errorcodes to PostgreSQL-18.
7
+ - Use `rb_hash_new_capa` on Ruby-3.2+ . #674
8
+ - Deny any server communication on a frozen PG::Connection . #677
9
+ - Fix possible race condition in PG::Result in Ractor context. #674
10
+
11
+ Removed:
12
+ - Drop binary gem support for platform `x86-mingw32`. #682
13
+ - Drop binary gems for ruby-2.7.
14
+
15
+
1
16
  ## v1.6.2 [2025-09-02] Lars Kanis <lars@greiz-reinsdorf.de>
2
17
 
3
18
  - Remove several absolute paths from native binaries which pointed to build directories. [#668](https://github.com/ged/ruby-pg/pull/668)
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- ruby -*-
2
2
 
3
- # Specify your gem's runtime dependencies in pg.gemspec
4
- gemspec
3
+ # No pg gem, since "bundle package" fails on bundler-2.7+, if the extension isn't built
4
+ # gemspec
5
5
 
6
6
  source "https://rubygems.org/"
7
7
 
@@ -11,9 +11,9 @@ group :development do
11
11
  end
12
12
 
13
13
  group :test do
14
- gem "bundler", ">= 1.16", "< 3.0"
14
+ gem "bundler", ">= 1.16", "< 5.0"
15
15
  gem "rake-compiler", "~> 1.0"
16
- gem "rake-compiler-dock", "~> 1.9.1", git: "https://github.com/rake-compiler/rake-compiler-dock"
16
+ gem "rake-compiler-dock", "~> 1.11.0" #, git: "https://github.com/rake-compiler/rake-compiler-dock"
17
17
  gem "rspec", "~> 3.5"
18
18
  # "bigdecimal" is a gem on ruby-3.4+ and it's optional for ruby-pg.
19
19
  # Specs should succeed without it, but 4 examples are then excluded.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # pg
2
2
 
3
3
  * home :: https://github.com/ged/ruby-pg
4
- * docs :: http://deveiate.org/code/pg (English) ,
4
+ * docs :: http://deveiate.org/code/pg/README_md.html (English) ,
5
5
  https://deveiate.org/code/pg/README_ja_md.html (Japanese)
6
6
  * clog :: link:/CHANGELOG.md
7
7
 
@@ -30,6 +30,9 @@ A small example usage:
30
30
  end
31
31
  ```
32
32
 
33
+ See the PG::Connection class for query methods and the PG::Result class for information on working with the results of a query.
34
+
35
+
33
36
  ## Build Status
34
37
 
35
38
  [![Build Status Github Actions](https://github.com/ged/ruby-pg/actions/workflows/source-gem.yml/badge.svg?branch=master)](https://github.com/ged/ruby-pg/actions/workflows/source-gem.yml)
@@ -218,8 +221,8 @@ Several type maps can be chained by setting PG::TypeMap::DefaultTypeMappable#def
218
221
 
219
222
  ## Thread support
220
223
 
221
- PG is thread safe in such a way that different threads can use different PG::Connection objects concurrently.
222
- However it is not safe to access any Pg objects simultaneously from more than one thread.
224
+ PG is thread safe in such a way that different threads or fibers can use different PG::Connection objects concurrently.
225
+ However it is not safe to access any PG object simultaneously from more than one thread or fiber unless the object is frozen.
223
226
  So make sure to open a new database server connection for every new thread or use a wrapper library like ActiveRecord that manages connections in a thread safe way.
224
227
 
225
228
  If messages like the following are printed to stderr, you're probably using one connection from several threads:
data/Rakefile CHANGED
@@ -47,7 +47,6 @@ CrossLibrary = Struct.new :platform, :openssl_config, :toolchain
47
47
  CrossLibraries = [
48
48
  ['aarch64-mingw-ucrt', 'mingwarm64', 'aarch64-w64-mingw32'],
49
49
  ['x64-mingw-ucrt', 'mingw64', 'x86_64-w64-mingw32'],
50
- ['x86-mingw32', 'mingw', 'i686-w64-mingw32'],
51
50
  ['x64-mingw32', 'mingw64', 'x86_64-w64-mingw32'],
52
51
  ['x86_64-linux', 'linux-x86_64', 'x86_64-linux-gnu'],
53
52
  ['x86_64-linux-musl', 'linux-x86_64', 'x86_64-unknown-linux-musl'],
@@ -94,7 +93,7 @@ Rake::ExtensionTask.new do |ext|
94
93
  spec.files << "ports/#{spec.platform.to_s}/lib/libpq-ruby-pg.1.dylib" if spec.platform.to_s =~ /darwin/
95
94
  spec.files << "ports/#{spec.platform.to_s}/lib/libpq.dll" if spec.platform.to_s =~ /mingw|mswin/
96
95
 
97
- # Binary gems don't postgresql header+lib files
96
+ # Binary gems don't need postgresql header+lib files
98
97
  spec.metadata.delete("msys2_mingw_dependencies")
99
98
  end
100
99
  end
@@ -106,7 +105,8 @@ task 'gem:native:prepare' do
106
105
  # Copy gem signing key and certs to be accessible from the docker container
107
106
  mkdir_p 'build/gem'
108
107
  sh "cp ~/.gem/gem-*.pem build/gem/ || true"
109
- sh "bundle package --all"
108
+ sh "bundle config set cache_all false"
109
+ sh "bundle package"
110
110
  begin
111
111
  OpenSSL::PKey.read(File.read(File.expand_path("~/.gem/gem-private_key.pem")), ENV["GEM_PRIVATE_KEY_PASSPHRASE"] || "")
112
112
  rescue OpenSSL::PKey::PKeyError
@@ -115,19 +115,6 @@ task 'gem:native:prepare' do
115
115
  end
116
116
  end
117
117
 
118
- task 'install_darwin_mig', [:arch] do |t, args|
119
- sh <<~EOT
120
- rm -rf bootstrap_cmds &&
121
- git clone --branch=cross_platform https://github.com/markmentovai/bootstrap_cmds &&
122
- cd bootstrap_cmds &&
123
- autoreconf --install &&
124
- sh configure &&
125
- make &&
126
- sed -E -i 's/^cppflags=(.*)/cppflags=(\\1 "-D#{args[:arch]}" "-I\\/opt\\/osxcross\\/target\\/SDK\\/MacOSX11.1.sdk\\/usr\\/include")/' migcom.tproj/mig.sh &&
127
- sudo make install
128
- EOT
129
- end
130
-
131
118
  CrossLibraries.each do |xlib|
132
119
  platform = xlib.platform
133
120
  desc "Build fat binary gem for platform #{platform}"
@@ -139,9 +126,7 @@ CrossLibraries.each do |xlib|
139
126
  sudo apt-get update && sudo apt-get install -y bison flex &&
140
127
  (cp build/gem/gem-*.pem ~/.gem/ || true) &&
141
128
  bundle install --local &&
142
- #{ "rake install_darwin_mig[__arm64__]" if platform =~ /arm64-darwin/ }
143
- #{ "rake install_darwin_mig[__x86_64__]" if platform =~ /x86_64-darwin/ }
144
- rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEFLAGS="-j`nproc` V=1" RUBY_CC_VERSION=#{RakeCompilerDock.ruby_cc_version("~>2.7", "~>3.0")}
129
+ rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEFLAGS="-j`nproc` V=1" RUBY_CC_VERSION=#{RakeCompilerDock.ruby_cc_version("~>4.0", "~>3.0")}
145
130
  EOT
146
131
  end
147
132
  desc "Build the native binary gems"
@@ -172,7 +157,8 @@ end
172
157
 
173
158
  desc "Update list of server error codes"
174
159
  task :update_error_codes do
175
- URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_17_0"
160
+ # URL_ERRORCODES_TXT = "https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_18_0"
161
+ URL_ERRORCODES_TXT = "https://raw.githubusercontent.com/postgres/postgres/refs/tags/REL_18_0/src/backend/utils/errcodes.txt"
176
162
 
177
163
  ERRORCODES_TXT = "ext/errorcodes.txt"
178
164
  sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
data/ext/errorcodes.def CHANGED
@@ -87,6 +87,11 @@
87
87
  VALUE klass = define_error_class( "StackedDiagnosticsAccessedWithoutActiveHandler", "0Z" );
88
88
  register_error_class( "0Z002", klass );
89
89
  }
90
+ {
91
+ VALUE klass = define_error_class( "InvalidArgumentForXquery", NULL );
92
+ register_error_class( "10608", klass );
93
+ register_error_class( "10", klass );
94
+ }
90
95
  {
91
96
  VALUE klass = define_error_class( "CaseNotFound", NULL );
92
97
  register_error_class( "20000", klass );
@@ -889,6 +894,10 @@
889
894
  VALUE klass = define_error_class( "DuplicateFile", "58" );
890
895
  register_error_class( "58P02", klass );
891
896
  }
897
+ {
898
+ VALUE klass = define_error_class( "FileNameTooLong", "58" );
899
+ register_error_class( "58P03", klass );
900
+ }
892
901
  {
893
902
  VALUE klass = define_error_class( "ConfigFileError", NULL );
894
903
  register_error_class( "F0000", klass );
data/ext/errorcodes.rb CHANGED
@@ -28,7 +28,7 @@ EOCODE
28
28
  sqlstate, ews, errcode_macro_name = $1, $2, $3
29
29
  next unless ews=='E'
30
30
 
31
- is_sqlclass = sqlstate[2..-1] == '000'
31
+ is_sqlclass = sqlstate[2..-1] == '000' || sqlstate == '10608'
32
32
  class_code = sqlstate[0,2]
33
33
  baseclass_code = is_sqlclass ? 'NULL' : class_code.inspect
34
34
  class_name = camelize(errcode_macro_name.sub('ERRCODE_', '').downcase)
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2024, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2025, PostgreSQL Global Development Group
6
6
  #
7
7
  # This list serves as the basis for generating source files containing error
8
8
  # codes. It is kept in a common format to make sure all these source files have
@@ -141,6 +141,12 @@ Section: Class 0Z - Diagnostics Exception
141
141
  0Z000 E ERRCODE_DIAGNOSTICS_EXCEPTION diagnostics_exception
142
142
  0Z002 E ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER stacked_diagnostics_accessed_without_active_handler
143
143
 
144
+ Section: Class 10 - XQuery Error
145
+
146
+ # recent SQL versions define quite a few codes in this class, but for now
147
+ # we are only using this generic one
148
+ 10608 E ERRCODE_INVALID_ARGUMENT_FOR_XQUERY invalid_argument_for_xquery
149
+
144
150
  Section: Class 20 - Case Not Found
145
151
 
146
152
  20000 E ERRCODE_CASE_NOT_FOUND case_not_found
@@ -439,6 +445,7 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
439
445
  58030 E ERRCODE_IO_ERROR io_error
440
446
  58P01 E ERRCODE_UNDEFINED_FILE undefined_file
441
447
  58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
448
+ 58P03 E ERRCODE_FILE_NAME_TOO_LONG file_name_too_long
442
449
 
443
450
  Section: Class F0 - Configuration File Error
444
451
 
data/ext/extconf.rb CHANGED
@@ -27,13 +27,13 @@ if gem_platform=with_config("cross-build")
27
27
  gem 'mini_portile2', '~>2.1'
28
28
  require 'mini_portile2'
29
29
 
30
- OPENSSL_VERSION = ENV['OPENSSL_VERSION'] || '3.5.2'
30
+ OPENSSL_VERSION = ENV['OPENSSL_VERSION'] || '3.6.0'
31
31
  OPENSSL_SOURCE_URI = "http://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
32
32
 
33
33
  KRB5_VERSION = ENV['KRB5_VERSION'] || '1.22.1'
34
34
  KRB5_SOURCE_URI = "http://kerberos.org/dist/krb5/#{KRB5_VERSION[/^(\d+\.\d+)/]}/krb5-#{KRB5_VERSION}.tar.gz"
35
35
 
36
- POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '17.6'
36
+ POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '18.1'
37
37
  POSTGRESQL_SOURCE_URI = "http://ftp.postgresql.org/pub/source/v#{POSTGRESQL_VERSION}/postgresql-#{POSTGRESQL_VERSION}.tar.bz2"
38
38
 
39
39
  class BuildRecipe < MiniPortile
@@ -319,6 +319,7 @@ have_func 'PQsetChunkedRowsMode', 'libpq-fe.h' # since PostgreSQL-17
319
319
  have_func 'timegm'
320
320
  have_func 'rb_io_wait' # since ruby-3.0
321
321
  have_func 'rb_io_descriptor' # since ruby-3.1
322
+ have_func 'rb_hash_new_capa' # since ruby-3.2
322
323
 
323
324
  have_header 'inttypes.h'
324
325
  have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
data/ext/pg.h CHANGED
@@ -76,6 +76,10 @@ typedef long suseconds_t;
76
76
  #define PG_MAX_COLUMNS 4000
77
77
  #endif
78
78
 
79
+ #ifndef HAVE_RB_HASH_NEW_CAPA
80
+ #define rb_hash_new_capa(x) rb_hash_new()
81
+ #endif
82
+
79
83
  #define pg_gc_location(x) x = rb_gc_location(x)
80
84
 
81
85
  /* For compatibility with ruby < 3.0 */
@@ -157,10 +161,8 @@ typedef struct {
157
161
  /* Size of PGresult as published to ruby memory management. */
158
162
  ssize_t result_size;
159
163
 
160
- /* Prefilled tuple Hash with fnames[] as keys. */
161
- VALUE tuple_hash;
162
-
163
- /* Hash with fnames[] to field number mapping. */
164
+ /* Hash with fnames[] to field number mapping.
165
+ * Init on-demand to create PG::Tuple objects, otherwise Qnil. */
164
166
  VALUE field_map;
165
167
 
166
168
  /* List of field names as frozen String or Symbol objects.
data/ext/pg_connection.c CHANGED
@@ -66,6 +66,7 @@ pg_get_connection_safe( VALUE self )
66
66
  t_pg_connection *this;
67
67
  TypedData_Get_Struct( self, t_pg_connection, &pg_connection_type, this);
68
68
 
69
+ rb_check_frozen(self);
69
70
  if ( !this->pgconn )
70
71
  pg_raise_conn_error( rb_eConnectionBad, self, "connection is closed");
71
72
 
@@ -2382,7 +2383,7 @@ pgconn_notifies(VALUE self)
2382
2383
  return Qnil;
2383
2384
  }
2384
2385
 
2385
- hash = rb_hash_new();
2386
+ hash = rb_hash_new_capa(3);
2386
2387
  relname = rb_str_new2(notification->relname);
2387
2388
  be_pid = INT2NUM(notification->be_pid);
2388
2389
  extra = rb_str_new2(notification->extra);
@@ -4425,9 +4426,11 @@ pgconn_set_default_encoding( VALUE self )
4425
4426
  * res.type_map_for_queries = typemap
4426
4427
  *
4427
4428
  * Set the default TypeMap that is used for type casts of query bind parameters.
4429
+ * It can be overwritten per +type_map+ parameter of #exec_params and siblings.
4428
4430
  *
4429
4431
  * +typemap+ must be a kind of PG::TypeMap .
4430
4432
  *
4433
+ * See also #type_map_for_queries
4431
4434
  */
4432
4435
  static VALUE
4433
4436
  pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
@@ -4452,6 +4455,9 @@ pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
4452
4455
  * Returns the default TypeMap that is currently set for type casts of query
4453
4456
  * bind parameters.
4454
4457
  *
4458
+ * Default is PG::TypeMapAllStrings .
4459
+ *
4460
+ * See also #type_map_for_queries=
4455
4461
  */
4456
4462
  static VALUE
4457
4463
  pgconn_type_map_for_queries_get(VALUE self)
@@ -4466,9 +4472,11 @@ pgconn_type_map_for_queries_get(VALUE self)
4466
4472
  * res.type_map_for_results = typemap
4467
4473
  *
4468
4474
  * Set the default TypeMap that is used for type casts of result values.
4475
+ * It can be overwritten per PG::Result#type_map= .
4469
4476
  *
4470
4477
  * +typemap+ must be a kind of PG::TypeMap .
4471
4478
  *
4479
+ * See also #type_map_for_results
4472
4480
  */
4473
4481
  static VALUE
4474
4482
  pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
@@ -4490,6 +4498,9 @@ pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
4490
4498
  *
4491
4499
  * Returns the default TypeMap that is currently set for type casts of result values.
4492
4500
  *
4501
+ * Default is PG::TypeMapAllStrings .
4502
+ *
4503
+ * See also #type_map_for_results=
4493
4504
  */
4494
4505
  static VALUE
4495
4506
  pgconn_type_map_for_results_get(VALUE self)
@@ -4506,11 +4517,13 @@ pgconn_type_map_for_results_get(VALUE self)
4506
4517
  *
4507
4518
  * Set the default coder that is used for type casting of parameters
4508
4519
  * to #put_copy_data .
4520
+ * It can be overwritten per +encoder+ parameter of #put_copy_data and +coder+ parameter of #copy_data.
4509
4521
  *
4510
4522
  * +encoder+ can be:
4511
4523
  * * a kind of PG::Coder
4512
4524
  * * +nil+ - disable type encoding, data must be a String.
4513
4525
  *
4526
+ * See also #encoder_for_put_copy_data
4514
4527
  */
4515
4528
  static VALUE
4516
4529
  pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
@@ -4540,6 +4553,8 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
4540
4553
  * * a kind of PG::Coder
4541
4554
  * * +nil+ - type encoding is disabled, data must be a String.
4542
4555
  *
4556
+ * Default is +nil+ .
4557
+ * See also #encoder_for_put_copy_data=
4543
4558
  */
4544
4559
  static VALUE
4545
4560
  pgconn_encoder_for_put_copy_data_get(VALUE self)
@@ -4555,11 +4570,13 @@ pgconn_encoder_for_put_copy_data_get(VALUE self)
4555
4570
  *
4556
4571
  * Set the default coder that is used for type casting of received data
4557
4572
  * by #get_copy_data .
4573
+ * It can be overwritten per +decoder+ parameter of #get_copy_data and +coder+ parameter of #copy_data.
4558
4574
  *
4559
4575
  * +decoder+ can be:
4560
4576
  * * a kind of PG::Coder
4561
4577
  * * +nil+ - disable type decoding, returned data will be a String.
4562
4578
  *
4579
+ * See also #decoder_for_get_copy_data
4563
4580
  */
4564
4581
  static VALUE
4565
4582
  pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
@@ -4589,6 +4606,9 @@ pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
4589
4606
  * * a kind of PG::Coder
4590
4607
  * * +nil+ - type encoding is disabled, returned data will be a String.
4591
4608
  *
4609
+ * Default is +nil+ .
4610
+ *
4611
+ * See also #decoder_for_get_copy_data=
4592
4612
  */
4593
4613
  static VALUE
4594
4614
  pgconn_decoder_for_get_copy_data_get(VALUE self)
@@ -4611,7 +4631,7 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
4611
4631
  *
4612
4632
  * Settings the type of field names affects only future results.
4613
4633
  *
4614
- * See further description at PG::Result#field_name_type=
4634
+ * See further description at PG::Result#field_name_type= and #field_name_type .
4615
4635
  *
4616
4636
  */
4617
4637
  static VALUE
data/ext/pg_result.c CHANGED
@@ -12,6 +12,7 @@ static VALUE sym_symbol, sym_string, sym_static_symbol;
12
12
  static VALUE pgresult_type_map_set( VALUE, VALUE );
13
13
  static t_pg_result *pgresult_get_this( VALUE );
14
14
  static t_pg_result *pgresult_get_this_safe( VALUE );
15
+ static void ensure_init_for_tuple(VALUE self);
15
16
 
16
17
  #if defined(HAVE_PQRESULTMEMORYSIZE)
17
18
 
@@ -114,7 +115,6 @@ pgresult_gc_mark( void *_this )
114
115
 
115
116
  rb_gc_mark_movable( this->connection );
116
117
  rb_gc_mark_movable( this->typemap );
117
- rb_gc_mark_movable( this->tuple_hash );
118
118
  rb_gc_mark_movable( this->field_map );
119
119
 
120
120
  for( i=0; i < this->nfields; i++ ){
@@ -130,7 +130,6 @@ pgresult_gc_compact( void *_this )
130
130
 
131
131
  pg_gc_location( this->connection );
132
132
  pg_gc_location( this->typemap );
133
- pg_gc_location( this->tuple_hash );
134
133
  pg_gc_location( this->field_map );
135
134
 
136
135
  for( i=0; i < this->nfields; i++ ){
@@ -212,7 +211,6 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
212
211
  this->typemap = pg_typemap_all_strings;
213
212
  this->p_typemap = RTYPEDDATA_DATA( this->typemap );
214
213
  this->nfields = -1;
215
- this->tuple_hash = Qnil;
216
214
  this->field_map = Qnil;
217
215
  this->flags = 0;
218
216
  self = TypedData_Wrap_Struct(rb_cPGresult, &pgresult_type, this);
@@ -396,6 +394,7 @@ pg_result_freeze(VALUE self)
396
394
  {
397
395
  t_pg_result *this = pgresult_get_this(self);
398
396
 
397
+ ensure_init_for_tuple(self);
399
398
  RB_OBJ_WRITE(self, &this->connection, Qnil);
400
399
  return rb_call_super(0, NULL);
401
400
  }
@@ -513,20 +512,46 @@ static void pgresult_init_fnames(VALUE self)
513
512
  *
514
513
  * The class to represent the query result tuples (rows).
515
514
  * An instance of this class is created as the result of every query.
516
- * All result rows and columns are stored in a memory block attached to the PG::Result object.
517
- * Whenever a value is accessed it is casted to a Ruby object by the assigned #type_map .
515
+ * All result rows and columns are stored in an immutable memory block attached to the PG::Result object unless streaming is used.
518
516
  *
519
- * Since pg-1.1 the amount of memory in use by a PG::Result object is estimated and passed to ruby's garbage collector.
520
- * You can invoke the #clear method to force deallocation of memory of the instance when finished with the result for better memory performance.
521
- *
522
- * Example:
517
+ * A PG::Result has various ways to retrieve the result data:
523
518
  * require 'pg'
524
- * conn = PG.connect(:dbname => 'test')
525
- * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
526
- * res.getvalue(0,0) # '1'
527
- * res[0]['b'] # '2'
528
- * res[0]['c'] # nil
519
+ * conn = PG.connect(dbname: 'test')
520
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
521
+ * res.num_fields # 3
522
+ * res.num_tuples # 1
523
+ * res.fname(2) # "c"
524
+ * res.fields # ["a", "b", "c"]
525
+ * res.getvalue(0,0) # '1'
526
+ * res[0] # {"a" => "1", "b" => "2", "c" => "3"}
527
+ * res.tuple_values(0) # ["1", "2", nil]
528
+ * res.tuple(0) # #<PG::Tuple a: "1", b: "2", c: nil>
529
+ * res.values # [["1", "2", nil]]
530
+ * res.field_values(:a) # ["1"]
531
+ * res.column_values(1) # ["2"]
532
+ * res.each.first # {"a" => "1", "b" => "2", "c" => nil}
533
+ * res.each_row.first # ["1", "2", nil]
534
+ *
535
+ * Whenever a value is accessed it is casted to a Ruby object by the assigned #type_map which is PG::TypeMapAllStrings by default.
536
+ * Similarly field names can be retrieved either as strings (default) or as symbols which can be switched per #field_name_type= .
537
+ *
538
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
539
+ * res.type_map = PG::TypeMapByColumn.new([PG::TextDecoder::Integer.new]*3)
540
+ * res.field_name_type = :symbol
541
+ * res.fname(2) # :c
542
+ * res.fields # [:a, :b, :c]
543
+ * res.getvalue(0,0) # 1
544
+ * res[0] # {a: 1, b: 2, c: nil}
545
+ * res.tuple_values(0) # [1, 2, nil]
546
+ * res.tuple(0) # #<PG::Tuple a: 1, b: 2, c: nil>
547
+ * res.values # [[1, 2, nil]]
548
+ * res.field_values(:a) # [1]
549
+ * res.column_values(1) # [2]
550
+ * res.each.first # {a: 1, b: 2, c: nil}
551
+ * res.each_row.first # [1, 2, nil]
529
552
  *
553
+ * Since pg-1.1 the amount of memory in use by a PG::Result object is estimated and passed to ruby's garbage collector.
554
+ * You can invoke the #clear method to force deallocation of memory of the instance when finished with the result for better memory performance.
530
555
  */
531
556
 
532
557
  /**************************************************************************
@@ -705,6 +730,10 @@ pgresult_error_field(VALUE self, VALUE field)
705
730
  * res.ntuples() -> Integer
706
731
  *
707
732
  * Returns the number of tuples in the query result.
733
+ *
734
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
735
+ * res.ntuples # 1
736
+ * res.num_tuples # 1
708
737
  */
709
738
  static VALUE
710
739
  pgresult_ntuples(VALUE self)
@@ -723,6 +752,9 @@ pgresult_ntuples_for_enum(VALUE self, VALUE args, VALUE eobj)
723
752
  * res.nfields() -> Integer
724
753
  *
725
754
  * Returns the number of columns in the query result.
755
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
756
+ * res.nfields # 3
757
+ * res.num_fields # 3
726
758
  */
727
759
  static VALUE
728
760
  pgresult_nfields(VALUE self)
@@ -752,6 +784,8 @@ pgresult_binary_tuples(VALUE self)
752
784
  * Returns the name of the column corresponding to _index_.
753
785
  * Depending on #field_name_type= it's a String or Symbol.
754
786
  *
787
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
788
+ * res.fname(2) # "c"
755
789
  */
756
790
  static VALUE
757
791
  pgresult_fname(VALUE self, VALUE index)
@@ -1122,6 +1156,9 @@ pgresult_oid_value(VALUE self)
1122
1156
  * res[ n ] -> Hash
1123
1157
  *
1124
1158
  * Returns tuple _n_ as a hash.
1159
+ *
1160
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1161
+ * res[0] # {"a" => "1", "b" => "2", "c" => "3"}
1125
1162
  */
1126
1163
  static VALUE
1127
1164
  pgresult_aref(VALUE self, VALUE index)
@@ -1138,16 +1175,11 @@ pgresult_aref(VALUE self, VALUE index)
1138
1175
  if ( tuple_num < 0 || tuple_num >= num_tuples )
1139
1176
  rb_raise( rb_eIndexError, "Index %d is out of range", tuple_num );
1140
1177
 
1141
- /* We reuse the Hash of the previous output for larger row counts.
1142
- * This is somewhat faster than populating an empty Hash object. */
1143
- tuple = NIL_P(this->tuple_hash) ? rb_hash_new() : this->tuple_hash;
1178
+ tuple = rb_hash_new_capa(this->nfields);
1144
1179
  for ( field_num = 0; field_num < this->nfields; field_num++ ) {
1145
1180
  VALUE val = this->p_typemap->funcs.typecast_result_value(this->p_typemap, self, tuple_num, field_num);
1146
1181
  rb_hash_aset( tuple, this->fnames[field_num], val );
1147
1182
  }
1148
- /* Store a copy of the filled hash for use at the next row. */
1149
- if( num_tuples > 10 )
1150
- RB_OBJ_WRITE(self, &this->tuple_hash, rb_hash_dup(tuple));
1151
1183
 
1152
1184
  return tuple;
1153
1185
  }
@@ -1156,7 +1188,10 @@ pgresult_aref(VALUE self, VALUE index)
1156
1188
  * call-seq:
1157
1189
  * res.each_row { |row| ... }
1158
1190
  *
1159
- * Yields each row of the result. The row is a list of column values.
1191
+ * Yields an Array object for each row in the result.
1192
+ *
1193
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1194
+ * res.each_row.first # ["1", "2", nil]
1160
1195
  */
1161
1196
  static VALUE
1162
1197
  pgresult_each_row(VALUE self)
@@ -1191,6 +1226,9 @@ pgresult_each_row(VALUE self)
1191
1226
  * res.values -> Array
1192
1227
  *
1193
1228
  * Returns all tuples as an array of arrays.
1229
+ *
1230
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1231
+ * res.values # [["1", "2", nil]]
1194
1232
  */
1195
1233
  static VALUE
1196
1234
  pgresult_values(VALUE self)
@@ -1240,12 +1278,13 @@ make_column_result_array( VALUE self, int col )
1240
1278
 
1241
1279
 
1242
1280
  /*
1243
- * call-seq:
1244
- * res.column_values( n ) -> array
1281
+ * call-seq:
1282
+ * res.column_values( n ) -> array
1245
1283
  *
1246
- * Returns an Array of the values from the nth column of each
1247
- * tuple in the result.
1284
+ * Returns an Array of the values from the nth column of each tuple in the result.
1248
1285
  *
1286
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1287
+ * res.column_values(1) # ["2"]
1249
1288
  */
1250
1289
  static VALUE
1251
1290
  pgresult_column_values(VALUE self, VALUE index)
@@ -1256,11 +1295,13 @@ pgresult_column_values(VALUE self, VALUE index)
1256
1295
 
1257
1296
 
1258
1297
  /*
1259
- * call-seq:
1298
+ * call-seq:
1260
1299
  * res.field_values( field ) -> array
1261
1300
  *
1262
- * Returns an Array of the values from the given _field_ of each tuple in the result.
1301
+ * Returns an Array of the values from the given _field_ of each tuple in the result.
1263
1302
  *
1303
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1304
+ * res.field_values(:a) # ["1"]
1264
1305
  */
1265
1306
  static VALUE
1266
1307
  pgresult_field_values( VALUE self, VALUE field )
@@ -1281,11 +1322,13 @@ pgresult_field_values( VALUE self, VALUE field )
1281
1322
 
1282
1323
 
1283
1324
  /*
1284
- * call-seq:
1285
- * res.tuple_values( n ) -> array
1325
+ * call-seq:
1326
+ * res.tuple_values( n ) -> array
1286
1327
  *
1287
- * Returns an Array of the field values from the nth row of the result.
1328
+ * Returns an Array of the field values from the nth row of the result.
1288
1329
  *
1330
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1331
+ * res.tuple_values(0) # ["1", "2", nil]
1289
1332
  */
1290
1333
  static VALUE
1291
1334
  pgresult_tuple_values(VALUE self, VALUE index)
@@ -1320,11 +1363,12 @@ static void ensure_init_for_tuple(VALUE self)
1320
1363
 
1321
1364
  if( this->field_map == Qnil ){
1322
1365
  int i;
1323
- VALUE field_map = rb_hash_new();
1366
+ VALUE field_map;
1324
1367
 
1325
1368
  if( this->nfields == -1 )
1326
1369
  pgresult_init_fnames( self );
1327
1370
 
1371
+ field_map = rb_hash_new_capa(this->nfields);
1328
1372
  for( i = 0; i < this->nfields; i++ ){
1329
1373
  rb_hash_aset(field_map, this->fnames[i], INT2FIX(i));
1330
1374
  }
@@ -1334,11 +1378,13 @@ static void ensure_init_for_tuple(VALUE self)
1334
1378
  }
1335
1379
 
1336
1380
  /*
1337
- * call-seq:
1338
- * res.tuple( n ) -> PG::Tuple
1381
+ * call-seq:
1382
+ * res.tuple( n ) -> PG::Tuple
1339
1383
  *
1340
- * Returns a PG::Tuple from the nth row of the result.
1384
+ * Returns a PG::Tuple from the nth row of the result.
1341
1385
  *
1386
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1387
+ * res.tuple(0) # #<PG::Tuple a: "1", b: "2", c: nil>
1342
1388
  */
1343
1389
  static VALUE
1344
1390
  pgresult_tuple(VALUE self, VALUE index)
@@ -1363,7 +1409,10 @@ pgresult_tuple(VALUE self, VALUE index)
1363
1409
  * call-seq:
1364
1410
  * res.each{ |tuple| ... }
1365
1411
  *
1366
- * Invokes block for each tuple in the result set.
1412
+ * Yields a Hash object for each row in the result.
1413
+ *
1414
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1415
+ * res.each.first # {"a" => "1", "b" => "2", "c" => nil}
1367
1416
  */
1368
1417
  static VALUE
1369
1418
  pgresult_each(VALUE self)
@@ -1386,6 +1435,9 @@ pgresult_each(VALUE self)
1386
1435
  * res.fields() -> Array
1387
1436
  *
1388
1437
  * Depending on #field_name_type= returns an array of strings or symbols representing the names of the fields in the result.
1438
+ *
1439
+ * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
1440
+ * res.fields # ["a", "b", "c"]
1389
1441
  */
1390
1442
  static VALUE
1391
1443
  pgresult_fields(VALUE self)
@@ -1410,6 +1462,7 @@ pgresult_fields(VALUE self)
1410
1462
  *
1411
1463
  * +typemap+ must be a kind of PG::TypeMap .
1412
1464
  *
1465
+ * See also #map_types! and PG::BasicTypeMapForResults
1413
1466
  */
1414
1467
  static VALUE
1415
1468
  pgresult_type_map_set(VALUE self, VALUE typemap)
@@ -1433,6 +1486,7 @@ pgresult_type_map_set(VALUE self, VALUE typemap)
1433
1486
  * res.type_map -> value
1434
1487
  *
1435
1488
  * Returns the PG::TypeMap that is currently set for type casts of result values to ruby objects.
1489
+ * The default is retrieved from PG::Connection#type_map_for_results , which defaults to PG::TypeMapAllStrings .
1436
1490
  *
1437
1491
  */
1438
1492
  static VALUE
data/ext/pg_tuple.c CHANGED
@@ -510,7 +510,7 @@ pg_tuple_load(VALUE self, VALUE a)
510
510
  if (RARRAY_LENINT(field_names) != num_fields)
511
511
  rb_raise(rb_eTypeError, "different number of fields and values");
512
512
 
513
- field_map = rb_hash_new();
513
+ field_map = rb_hash_new_capa(num_fields);
514
514
  for( i = 0; i < num_fields; i++ ){
515
515
  rb_hash_aset(field_map, RARRAY_AREF(field_names, i), INT2FIX(i));
516
516
  }
data/lib/3.0/pg_ext.so CHANGED
Binary file
data/lib/3.1/pg_ext.so CHANGED
Binary file
data/lib/3.2/pg_ext.so CHANGED
Binary file
data/lib/3.3/pg_ext.so CHANGED
Binary file
data/lib/3.4/pg_ext.so CHANGED
Binary file
data/lib/4.0/pg_ext.so ADDED
Binary file
data/lib/pg/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module PG
3
3
  # Library version
4
- VERSION = '1.6.2'
4
+ VERSION = '1.6.3'
5
5
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.3
5
5
  platform: aarch64-linux-musl
6
6
  authors:
7
7
  - Michael Granger
@@ -10,9 +10,9 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
14
- L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDEyMjkxOTU2NTZaFw0yNTEy
15
- MjkxOTU2NTZaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
13
+ MIIEBDCCAmygAwIBAgIBBDANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
14
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNTEyMjkyMDMyMzFaFw0yNjEy
15
+ MjkyMDMyMzFaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
16
16
  PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
17
17
  mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
18
18
  eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
@@ -23,15 +23,15 @@ cert_chain:
23
23
  chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
24
24
  9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
25
25
  A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
26
- 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAoZZWzNV2XXaoSmvyamSSN+Wt/Ia+DNrU
27
- 2pc3kMEqykH6l1WiVPszr6HavQ//2I2UcSRSS5AGDdiSXcfyFmHtMBdtJHhTPcn7
28
- 4DLliB0szpvwG+ltGD8PI8eWkLaTQeFzs+0QCTavgKV+Zw56Q0J5zZvHHUMrLkUD
29
- qhwKjdTdkrRTn9Sqi0BrIRRZGTUDdrt8qoWm35aES5arKZzytgrRD/kXfFW2LCg0
30
- FzgTKibR4/3g8ph94kQLg/D2SMlVPkQ3ECi036mZxDC2n8V6u3rDkG5923wmrRZB
31
- J6cqz475Q8HYORQCB68OPzkWMfC7mBo3vpSsIqRoNs1FE4FJu4FGwZG8fBSrDC4H
32
- bZe+GtyS3e2SMjgT65zp35gLO9I7MquzYN9P6V2u1iBpTycchk5z9R1ghxzZSBT8
33
- DrkJ9tVlPQtJB0LqT0tvBap4upnwT1xYq721b5dwH6AF4Pi6iz/dc5vnq1/MH8bV
34
- 8VbbBzzeE7MsvgkP3sHlLmY8PtuyViJ8
26
+ 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAUVIier9xybHmXNsj801xD+Q7Jz7wpRsf
27
+ fMHpV2sAzvYcAa7pn+mbu9nf7RUhe5hiaUv88Usk9nRUYYrjBOO5RuD+wYNowpcE
28
+ kxUiTAP/fgUBdW6hYUJy57CH3xUD6tj1Cg9hxdKy7jItZXbfhX+qPq2BwGaXz7gn
29
+ nhrALITRmpuPnlsccM94dgSArCInSo2SEc12h2oB6FAnFG1Lre3dmQamI5q1EKp0
30
+ Yafb2+cPbFcVYUdE50wf+cdeGDOsCGlAmo2OGqXWxTP2hIfyhsFoamD6UGufLoPG
31
+ Dh6tAEZIuEvLjq93qoNceUQn+xxiiIszjY5mkTu9rVY+/gh5PJzu9IHvyIqBpb2o
32
+ fdWDISWK+KSLCrqkFtKoliLDTZau73GcYCVOkjca+3cxqABKZ+M8r42Sq8JPxPiv
33
+ KyLQBzqPeLN9qRDD1bEFHIcgwdY/zQTs4mWRBSmBWa7w+k8nP8aSV1dN/fvhYwY3
34
+ HCQwtPaMYOznIOcc8shL4zLJpcl8uCqE
35
35
  -----END CERTIFICATE-----
36
36
  date: 1980-01-02 00:00:00.000000000 Z
37
37
  dependencies: []
@@ -149,12 +149,12 @@ files:
149
149
  - ext/vc/pg.sln
150
150
  - ext/vc/pg_18/pg.vcproj
151
151
  - ext/vc/pg_19/pg_19.vcproj
152
- - lib/2.7/pg_ext.so
153
152
  - lib/3.0/pg_ext.so
154
153
  - lib/3.1/pg_ext.so
155
154
  - lib/3.2/pg_ext.so
156
155
  - lib/3.3/pg_ext.so
157
156
  - lib/3.4/pg_ext.so
157
+ - lib/4.0/pg_ext.so
158
158
  - lib/pg.rb
159
159
  - lib/pg/basic_type_map_based_on_result.rb
160
160
  - lib/pg/basic_type_map_for_queries.rb
@@ -203,8 +203,8 @@ files:
203
203
  - ports/patches/krb5/1.22.1/0001-Allow-static-linking-krb5-library.patch
204
204
  - ports/patches/krb5/1.22.1/0002-unknown-command-line-option-on-clang.patch
205
205
  - ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch
206
- - ports/patches/postgresql/17.6/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
207
- - ports/patches/postgresql/17.6/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch
206
+ - ports/patches/postgresql/18.1/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch
207
+ - ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch
208
208
  - rakelib/pg_gem_helper.rb
209
209
  - rakelib/task_extension.rb
210
210
  - sample/array_insert.rb
@@ -245,17 +245,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
245
245
  requirements:
246
246
  - - ">="
247
247
  - !ruby/object:Gem::Version
248
- version: '2.7'
248
+ version: '3.0'
249
249
  - - "<"
250
250
  - !ruby/object:Gem::Version
251
- version: 3.5.dev
251
+ version: 4.1.dev
252
252
  required_rubygems_version: !ruby/object:Gem::Requirement
253
253
  requirements:
254
254
  - - ">="
255
255
  - !ruby/object:Gem::Version
256
256
  version: 3.3.22
257
257
  requirements: []
258
- rubygems_version: 3.6.9
258
+ rubygems_version: 4.0.3
259
259
  specification_version: 4
260
260
  summary: Pg is the Ruby interface to the PostgreSQL RDBMS
261
261
  test_files: []
metadata.gz.sig CHANGED
Binary file
data/lib/2.7/pg_ext.so DELETED
Binary file