pg 1.5.6 → 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dabf91eb5c0f0871f693465f33fdd345e7b5fca07ffe35a0dad65f3b851d5292
4
- data.tar.gz: ecfb93d8f10e6835b5c7b134d2861161faa9c13ecbd0fe7e5c2cc0d5257faf2b
3
+ metadata.gz: c0abb6cbfa5134825baaaa3cab5bbb2d88a5092559331239ccb977c24579d27d
4
+ data.tar.gz: 53d6fd115d923b9654b2928791309d290a87f01275a13f3489025d673ba967ab
5
5
  SHA512:
6
- metadata.gz: cbba19b5af6b7eeae29313fe028579c1f1c3005a4ae0244bafa7e2562279986cbbc851a089286bd40302bc8eb46b865e0b0baa7d80ee7b8797e50f12dd4f9633
7
- data.tar.gz: 7e4a0c5fba7fb69a25297300c92f2a96599798390b77fb26c46056bb1557682c58f905006aacdf754a83880f2e01218b04ff32473be76eeb178161098a04ab39
6
+ metadata.gz: c7b1c92f223b4250fd56d37bbfa94dadf19d9e03518e7a3426bb19800745f031ab133a3d8921ec2f63045762e46bbfe7ac5a01f0144c4eb3d5b3ad8cf2f1197d
7
+ data.tar.gz: 3fd53f91bfc2880da42fddcc5ae6a9334c419025636e0d1626b533da7fa62a6f87942629ed6c24c1183002295dcbdf56a33c96af2323e3a9fb0396bcb68e673e
checksums.yaml.gz.sig CHANGED
Binary file
data/Gemfile CHANGED
@@ -11,7 +11,10 @@ group :development, :test do
11
11
  gem "rake-compiler-dock", "~> 1.0"
12
12
  gem "rdoc", "~> 6.4"
13
13
  gem "rspec", "~> 3.5"
14
+ gem "ostruct", "~> 0.5" # for Rakefile.cross
14
15
  # "bigdecimal" is a gem on ruby-3.4+ and it's optional for ruby-pg.
15
16
  # Specs should succeed without it, but 4 examples are then excluded.
17
+ # With bigdecimal commented out here, corresponding tests are omitted on ruby-3.4+ but are executed on ruby < 3.4.
18
+ # That way we can check both situations in CI.
16
19
  # gem "bigdecimal", "~> 3.0"
17
20
  end
data/History.md CHANGED
@@ -1,3 +1,34 @@
1
+ ## v1.5.9 [2024-10-24] Lars Kanis <lars@greiz-reinsdorf.de>
2
+
3
+ - Enable thread safety in static OpenSSL build for Windows. [#595](https://github.com/ged/ruby-pg/pull/595)
4
+ - Remove raising `conect_timeout` from 1 to 2 seconds. [#590](https://github.com/ged/ruby-pg/pull/590)
5
+ - Fix binary copy_data in Ractor context. [#594](https://github.com/ged/ruby-pg/pull/594)
6
+ - Exclude CI files and hidden files from built gem. [#591](https://github.com/ged/ruby-pg/pull/591)
7
+ This is to simplify security inspection.
8
+ - Update error classes to PostgreSQL-17.
9
+ - Update Windows fat binary gem to OpenSSL-3.4.0 and PostgreSQL-17.0.
10
+
11
+
12
+ ## v1.5.8 [2024-09-06] Lars Kanis <lars@greiz-reinsdorf.de>
13
+
14
+ - Fix host list duplication every time conn.reset is used. [#586](https://github.com/ged/ruby-pg/pull/586)
15
+ - Add default decoder for anonymous record types to BasicTypeRegistry [#579](https://github.com/ged/ruby-pg/pull/579)
16
+ - Update Windows fat binary gem to OpenSSL-3.3.2 and PostgreSQL-16.4.
17
+
18
+
19
+ ## v1.5.7 [2024-07-28] Lars Kanis <lars@greiz-reinsdorf.de>
20
+
21
+ - Remove deprecated use of fptr->fd.[#562](https://github.com/ged/ruby-pg/pull/562)
22
+ Direct access is disallowed since ruby-3.4.
23
+ - Make `pgconn_connect_poll` close the socket prior to calling `PQconnectPoll`. [#564](https://github.com/ged/ruby-pg/pull/564)
24
+ This could result in an exception while connecting when used multi threaded.
25
+ - Fix several typos and improve spelling in documentation and code. [#566](https://github.com/ged/ruby-pg/pull/566)
26
+ - Add missing PG::RollbackTransaction as an option to exit conn.transaction. [#560](https://github.com/ged/ruby-pg/pull/560)
27
+ Usage like in rails: https://api.rubyonrails.org/classes/ActiveRecord/Rollback.html
28
+ - Don't print a warning when bigdecimal is required on ruby-3.4+ [#574](https://github.com/ged/ruby-pg/pull/574)
29
+ - Update Windows fat binary gem to OpenSSL-3.3.1 and PostgreSQL-16.3.
30
+
31
+
1
32
  ## v1.5.6 [2024-03-01] Lars Kanis <lars@greiz-reinsdorf.de>
2
33
 
3
34
  - Renew address resolution (DNS) in conn.reset. [#558](https://github.com/ged/ruby-pg/pull/558)
@@ -92,7 +123,7 @@ Removed:
92
123
  Repository:
93
124
 
94
125
  - `rake test` tries to find PostgreSQL server commands by pg_config [#503](https://github.com/ged/ruby-pg/pull/503)
95
- So there's no need to set the PATH manuelly any longer.
126
+ So there's no need to set the PATH manually any longer.
96
127
 
97
128
 
98
129
  ## v1.4.6 [2023-02-26] Lars Kanis <lars@greiz-reinsdorf.de>
@@ -161,7 +192,7 @@ Added:
161
192
  Bugfixes:
162
193
 
163
194
  - Try IPv6 and IPv4 addresses, if DNS resolves to both. [#452](https://github.com/ged/ruby-pg/pull/452)
164
- - Re-add block-call semantics to PG::Connection.new accidently removed in pg-1.3.0. [#454](https://github.com/ged/ruby-pg/pull/454)
195
+ - Re-add block-call semantics to PG::Connection.new accidentally removed in pg-1.3.0. [#454](https://github.com/ged/ruby-pg/pull/454)
165
196
  - Handle client error after all data consumed in #copy_data for output. [#455](https://github.com/ged/ruby-pg/pull/455)
166
197
  - Avoid spurious keyword argument warning on Ruby 2.7. [#456](https://github.com/ged/ruby-pg/pull/456)
167
198
  - Change connection setup to respect connect_timeout parameter. [#459](https://github.com/ged/ruby-pg/pull/459)
@@ -200,7 +231,7 @@ Bugfixes:
200
231
 
201
232
  - Don't leak IO in case of connection errors. [#439](https://github.com/ged/ruby-pg/pull/439)
202
233
  Previously it was kept open until the PG::Connection was garbage collected.
203
- - Fix a performance regession in conn.get_result noticed in single row mode. [#442](https://github.com/ged/ruby-pg/pull/442)
234
+ - Fix a performance regression in conn.get_result noticed in single row mode. [#442](https://github.com/ged/ruby-pg/pull/442)
204
235
  - Fix occasional error Errno::EBADF (Bad file descriptor) while connecting. [#444](https://github.com/ged/ruby-pg/pull/444)
205
236
  - Fix compatibility of res.stream_each* methods with Fiber.scheduler. [#446](https://github.com/ged/ruby-pg/pull/446)
206
237
  - Remove FL_TEST and FL_SET, which are MRI-internal. [#437](https://github.com/ged/ruby-pg/pull/437)
@@ -286,7 +317,7 @@ Type cast enhancements:
286
317
  - Add PG::BasicTypeMapForQueries::BinaryData for encoding of bytea columns. [#348](https://github.com/ged/ruby-pg/pull/348)
287
318
  - Reduce time to build coder maps and permit to reuse them for several type maps per PG::BasicTypeRegistry::CoderMapsBundle.new(conn) . [#376](https://github.com/ged/ruby-pg/pull/376)
288
319
  - Make BasicTypeRegistry a class and use a global default instance of it.
289
- Now a local type registry can be instanciated and given to the type map, to avoid changing shared global states.
320
+ Now a local type registry can be instantiated and given to the type map, to avoid changing shared global states.
290
321
  - Allow PG::BasicTypeMapForQueries to take a Proc as callback for undefined types.
291
322
 
292
323
  Other Enhancements:
data/Rakefile CHANGED
@@ -94,7 +94,7 @@ end
94
94
 
95
95
  desc "Update list of server error codes"
96
96
  task :update_error_codes do
97
- URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_16_0"
97
+ 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"
98
98
 
99
99
  ERRORCODES_TXT = "ext/errorcodes.txt"
100
100
  sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
data/Rakefile.cross CHANGED
@@ -31,8 +31,8 @@ class CrossLibrary < OpenStruct
31
31
  self.host_platform = toolchain
32
32
 
33
33
  # Cross-compilation constants
34
- self.openssl_version = ENV['OPENSSL_VERSION'] || '3.2.1'
35
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '16.2'
34
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '3.4.0'
35
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '17.0'
36
36
 
37
37
  # Check if symlinks work in the current working directory.
38
38
  # This fails, if rake-compiler-dock is running on a Windows box.
@@ -52,9 +52,8 @@ class CrossLibrary < OpenStruct
52
52
 
53
53
  # Static OpenSSL build vars
54
54
  self.static_openssl_builddir = static_builddir + "openssl-#{openssl_version}"
55
-
56
55
  self.openssl_source_uri =
57
- URI( "http://www.openssl.org/source/openssl-#{openssl_version}.tar.gz" )
56
+ URI( "https://github.com/openssl/openssl/releases/download/openssl-#{openssl_version}/openssl-#{openssl_version}.tar.gz" )
58
57
  self.openssl_tarball = static_sourcesdir + File.basename( openssl_source_uri.path )
59
58
  self.openssl_makefile = static_openssl_builddir + 'Makefile'
60
59
 
@@ -119,7 +118,7 @@ class CrossLibrary < OpenStruct
119
118
  self.cmd_prelude = [
120
119
  "env",
121
120
  "CROSS_COMPILE=#{host_platform}-",
122
- "CFLAGS=-DDSO_WIN32",
121
+ "CFLAGS=-DDSO_WIN32 -DOPENSSL_THREADS",
123
122
  ]
124
123
 
125
124
 
@@ -127,7 +126,7 @@ class CrossLibrary < OpenStruct
127
126
  file openssl_makefile => static_openssl_builddir do |t|
128
127
  chdir( static_openssl_builddir ) do
129
128
  cmd = cmd_prelude.dup
130
- cmd << "./Configure" << "-static" << openssl_config
129
+ cmd << "./Configure" << "threads" << "-static" << openssl_config
131
130
 
132
131
  run( *cmd )
133
132
  end
@@ -193,7 +192,7 @@ class CrossLibrary < OpenStruct
193
192
  cmd << "CFLAGS=-L#{static_openssl_builddir}"
194
193
  cmd << "LDFLAGS=-L#{static_openssl_builddir}"
195
194
  cmd << "LDFLAGS_SL=-L#{static_openssl_builddir}"
196
- cmd << "LIBS=-lwsock32 -lgdi32 -lws2_32 -lcrypt32"
195
+ cmd << "LIBS=-lssl -lwsock32 -lgdi32 -lws2_32 -lcrypt32"
197
196
  cmd << "CPPFLAGS=-I#{static_openssl_builddir}/include"
198
197
 
199
198
  run( *cmd )
@@ -207,6 +206,10 @@ class CrossLibrary < OpenStruct
207
206
  chdir( static_postgresql_srcdir + "common" ) do
208
207
  sh 'make', "-j#{NUM_CPUS}"
209
208
  end
209
+ # Work around missing dependency to errorcodes.h in PostgreSQL-17.0
210
+ chdir( static_postgresql_srcdir + "backend" + "utils" ) do
211
+ sh 'make', "-j#{NUM_CPUS}"
212
+ end
210
213
  chdir( static_postgresql_srcdir + "port" ) do
211
214
  sh 'make', "-j#{NUM_CPUS}"
212
215
  end
@@ -290,8 +293,9 @@ CrossLibraries.each do |xlib|
290
293
  task "gem:windows:#{platform}" => ['gem:windows:prepare', xlib.openssl_tarball, xlib.postgresql_tarball] do
291
294
  RakeCompilerDock.sh <<-EOT, platform: platform
292
295
  (cp build/gem/gem-*.pem ~/.gem/ || true) &&
296
+ sudo apt-get update && sudo apt-get install -y bison flex &&
293
297
  bundle install --local &&
294
- rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKE="make -j`nproc`" RUBY_CC_VERSION=3.3.0:3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
298
+ rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEOPTS=-j`nproc` RUBY_CC_VERSION=3.3.0:3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
295
299
  EOT
296
300
  end
297
301
  desc "Build the windows binary gems"
data/ext/errorcodes.def CHANGED
@@ -453,6 +453,10 @@
453
453
  VALUE klass = define_error_class( "IdleInTransactionSessionTimeout", "25" );
454
454
  register_error_class( "25P03", klass );
455
455
  }
456
+ {
457
+ VALUE klass = define_error_class( "TransactionTimeout", "25" );
458
+ register_error_class( "25P04", klass );
459
+ }
456
460
  {
457
461
  VALUE klass = define_error_class( "InvalidSqlStatementName", NULL );
458
462
  register_error_class( "26000", klass );
@@ -885,11 +889,6 @@
885
889
  VALUE klass = define_error_class( "DuplicateFile", "58" );
886
890
  register_error_class( "58P02", klass );
887
891
  }
888
- {
889
- VALUE klass = define_error_class( "SnapshotTooOld", NULL );
890
- register_error_class( "72000", klass );
891
- register_error_class( "72", klass );
892
- }
893
892
  {
894
893
  VALUE klass = define_error_class( "ConfigFileError", NULL );
895
894
  register_error_class( "F0000", klass );
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2023, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2024, 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
@@ -252,6 +252,7 @@ Section: Class 25 - Invalid Transaction State
252
252
  25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction
253
253
  25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction
254
254
  25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout
255
+ 25P04 E ERRCODE_TRANSACTION_TIMEOUT transaction_timeout
255
256
 
256
257
  Section: Class 26 - Invalid SQL Statement Name
257
258
 
@@ -439,10 +440,6 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
439
440
  58P01 E ERRCODE_UNDEFINED_FILE undefined_file
440
441
  58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
441
442
 
442
- Section: Class 72 - Snapshot Failure
443
- # (class borrowed from Oracle)
444
- 72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old
445
-
446
443
  Section: Class F0 - Configuration File Error
447
444
 
448
445
  # (PostgreSQL-specific error class)
data/ext/extconf.rb CHANGED
@@ -9,6 +9,8 @@ if ENV['MAINTAINER_MODE']
9
9
  ' -ggdb' <<
10
10
  ' -DDEBUG' <<
11
11
  ' -pedantic'
12
+ $LDFLAGS <<
13
+ ' -ggdb'
12
14
  end
13
15
 
14
16
  if pgdir = with_config( 'pg' )
@@ -158,6 +160,7 @@ have_func 'timegm'
158
160
  have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
159
161
  have_func 'rb_gc_mark_movable' # since ruby-2.7
160
162
  have_func 'rb_io_wait' # since ruby-3.0
163
+ have_func 'rb_io_descriptor' # since ruby-3.1
161
164
 
162
165
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
163
166
  have_header 'unistd.h'
data/ext/pg.c CHANGED
@@ -543,7 +543,7 @@ Init_pg_ext(void)
543
543
  /* Result#result_error_field argument constant
544
544
  *
545
545
  * The SQLSTATE code for the error.
546
- * The SQLSTATE code identies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error.
546
+ * The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error.
547
547
  * For a list of the possible SQLSTATE codes, see Appendix A.
548
548
  * This field is not localizable, and is always present.
549
549
  */
@@ -233,6 +233,8 @@ j2date(int jd, int *year, int *month, int *day)
233
233
  *
234
234
  * This is a decoder class for conversion of PostgreSQL binary date
235
235
  * to Ruby Date objects.
236
+ *
237
+ * As soon as this class is used, it requires the ruby standard library 'date'.
236
238
  */
237
239
  static VALUE
238
240
  pg_bin_dec_date(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
data/ext/pg_connection.c CHANGED
@@ -33,8 +33,8 @@ static VALUE pgconn_async_flush(VALUE self);
33
33
  #ifdef __GNUC__
34
34
  __attribute__((format(printf, 3, 4)))
35
35
  #endif
36
- static void
37
- pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...)
36
+ NORETURN( static void
37
+ pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...))
38
38
  {
39
39
  VALUE msg, error;
40
40
  va_list ap;
@@ -264,6 +264,7 @@ pgconn_s_allocate( VALUE klass )
264
264
  RB_OBJ_WRITE(self, &this->decoder_for_get_copy_data, Qnil);
265
265
  RB_OBJ_WRITE(self, &this->trace_stream, Qnil);
266
266
  rb_ivar_set(self, rb_intern("@calls_to_put_copy_data"), INT2FIX(0));
267
+ rb_ivar_set(self, rb_intern("@iopts_for_reset"), Qnil);
267
268
 
268
269
  return self;
269
270
  }
@@ -515,9 +516,9 @@ static VALUE
515
516
  pgconn_connect_poll(VALUE self)
516
517
  {
517
518
  PostgresPollingStatusType status;
518
- status = gvl_PQconnectPoll(pg_get_pgconn(self));
519
519
 
520
520
  pgconn_close_socket_io(self);
521
+ status = gvl_PQconnectPoll(pg_get_pgconn(self));
521
522
 
522
523
  return INT2FIX((int)status);
523
524
  }
@@ -615,9 +616,9 @@ static VALUE
615
616
  pgconn_reset_poll(VALUE self)
616
617
  {
617
618
  PostgresPollingStatusType status;
618
- status = gvl_PQresetPoll(pg_get_pgconn(self));
619
619
 
620
620
  pgconn_close_socket_io(self);
621
+ status = gvl_PQresetPoll(pg_get_pgconn(self));
621
622
 
622
623
  return INT2FIX((int)status);
623
624
  }
@@ -2266,6 +2267,17 @@ pgconn_notifies(VALUE self)
2266
2267
  return hash;
2267
2268
  }
2268
2269
 
2270
+ #ifndef HAVE_RB_IO_DESCRIPTOR
2271
+ static int
2272
+ rb_io_descriptor(VALUE io)
2273
+ {
2274
+ Check_Type(io, T_FILE);
2275
+ rb_io_t *fptr = RFILE(io)->fptr;
2276
+ rb_io_check_closed(fptr);
2277
+ return fptr->fd;
2278
+ }
2279
+ #endif
2280
+
2269
2281
  #if defined(_WIN32)
2270
2282
 
2271
2283
  /* We use a specialized implementation of rb_io_wait() on Windows.
@@ -2286,7 +2298,6 @@ int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2286
2298
 
2287
2299
  static VALUE
2288
2300
  pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
2289
- rb_io_t *fptr;
2290
2301
  struct timeval ptimeout;
2291
2302
 
2292
2303
  struct timeval aborttime={0,0}, currtime, waittime;
@@ -2297,7 +2308,6 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
2297
2308
  long w32_events = 0;
2298
2309
  DWORD wait_ret;
2299
2310
 
2300
- GetOpenFile((io), fptr);
2301
2311
  if( !NIL_P(timeout) ){
2302
2312
  ptimeout.tv_sec = (time_t)(NUM2DBL(timeout));
2303
2313
  ptimeout.tv_usec = (time_t)((NUM2DBL(timeout) - (double)ptimeout.tv_sec) * 1e6);
@@ -2311,7 +2321,7 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
2311
2321
  if(rb_events & PG_RUBY_IO_PRIORITY) w32_events |= FD_OOB;
2312
2322
 
2313
2323
  for(;;) {
2314
- if ( WSAEventSelect(_get_osfhandle(fptr->fd), hEvent, w32_events) == SOCKET_ERROR ) {
2324
+ if ( WSAEventSelect(_get_osfhandle(rb_io_descriptor(io)), hEvent, w32_events) == SOCKET_ERROR ) {
2315
2325
  WSACloseEvent( hEvent );
2316
2326
  rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
2317
2327
  }
@@ -2354,7 +2364,7 @@ static VALUE
2354
2364
  pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2355
2365
  #if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
2356
2366
  /* We don't support Fiber.scheduler on Windows ruby-3.0 because there is no fast way to check whether a scheduler is active.
2357
- * Fortunatelly ruby-3.1 offers a C-API for it.
2367
+ * Fortunately ruby-3.1 offers a C-API for it.
2358
2368
  */
2359
2369
  VALUE scheduler = rb_fiber_scheduler_current();
2360
2370
 
@@ -2384,16 +2394,14 @@ typedef enum {
2384
2394
 
2385
2395
  static VALUE
2386
2396
  pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
2387
- rb_io_t *fptr;
2388
2397
  struct timeval waittime;
2389
2398
  int res;
2390
2399
 
2391
- GetOpenFile((io), fptr);
2392
2400
  if( !NIL_P(timeout) ){
2393
2401
  waittime.tv_sec = (time_t)(NUM2DBL(timeout));
2394
2402
  waittime.tv_usec = (time_t)((NUM2DBL(timeout) - (double)waittime.tv_sec) * 1e6);
2395
2403
  }
2396
- res = rb_wait_for_single_fd(fptr->fd, NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
2404
+ res = rb_wait_for_single_fd(rb_io_descriptor(io), NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
2397
2405
 
2398
2406
  return UINT2NUM(res);
2399
2407
  }
@@ -3128,7 +3136,9 @@ pgconn_async_get_last_result(VALUE self)
3128
3136
  for(;;) {
3129
3137
  int status;
3130
3138
 
3131
- /* wait for input (without blocking) before reading each result */
3139
+ /* Wait for input before reading each result.
3140
+ * That way we support the ruby-3.x IO scheduler and don't block other ruby threads.
3141
+ */
3132
3142
  wait_socket_readable(self, NULL, get_result_readable);
3133
3143
 
3134
3144
  cur = gvl_PQgetResult(conn);
@@ -3162,7 +3172,7 @@ pgconn_async_get_last_result(VALUE self)
3162
3172
  * Returns:
3163
3173
  * * +nil+ when the connection is already idle
3164
3174
  * * +true+ when some results have been discarded
3165
- * * +false+ when a failure occured and the connection was closed
3175
+ * * +false+ when a failure occurred and the connection was closed
3166
3176
  *
3167
3177
  */
3168
3178
  static VALUE
data/ext/pg_copy_coder.c CHANGED
@@ -212,6 +212,7 @@ pg_copycoder_type_map_get(VALUE self)
212
212
  *
213
213
  * See also PG::TextDecoder::CopyRow for the decoding direction with
214
214
  * PG::Connection#get_copy_data .
215
+ * And see PG::BinaryEncoder::CopyRow for an encoder of the COPY binary format.
215
216
  */
216
217
  static int
217
218
  pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
@@ -235,7 +236,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
235
236
  char *ptr1;
236
237
  char *ptr2;
237
238
  int strlen;
238
- int backslashs;
239
+ int backslashes;
239
240
  VALUE subint;
240
241
  VALUE entry;
241
242
 
@@ -286,19 +287,19 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
286
287
  ptr2 = current_out + strlen;
287
288
 
288
289
  /* count required backlashs */
289
- for(backslashs = 0; ptr1 != ptr2; ptr1++) {
290
+ for(backslashes = 0; ptr1 != ptr2; ptr1++) {
290
291
  /* Escape backslash itself, newline, carriage return, and the current delimiter character. */
291
292
  if(*ptr1 == '\\' || *ptr1 == '\n' || *ptr1 == '\r' || *ptr1 == this->delimiter){
292
- backslashs++;
293
+ backslashes++;
293
294
  }
294
295
  }
295
296
 
296
297
  ptr1 = current_out + strlen;
297
- ptr2 = current_out + strlen + backslashs;
298
+ ptr2 = current_out + strlen + backslashes;
298
299
  current_out = ptr2;
299
300
 
300
301
  /* Then store the escaped string on the final position, walking
301
- * right to left, until all backslashs are placed. */
302
+ * right to left, until all backslashes are placed. */
302
303
  while( ptr1 != ptr2 ) {
303
304
  *--ptr2 = *--ptr1;
304
305
  if(*ptr1 == '\\' || *ptr1 == '\n' || *ptr1 == '\r' || *ptr1 == this->delimiter){
@@ -358,6 +359,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
358
359
  *
359
360
  * See also PG::BinaryDecoder::CopyRow for the decoding direction with
360
361
  * PG::Connection#get_copy_data .
362
+ * And see PG::TextEncoder::CopyRow for an encoder of the COPY text format.
361
363
  */
362
364
  static int
363
365
  pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
@@ -391,7 +393,7 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
391
393
 
392
394
  switch(TYPE(entry)){
393
395
  case T_NIL:
394
- /* 4 bytes for -1 indicationg a NULL value */
396
+ /* 4 bytes for -1 indicating a NULL value */
395
397
  PG_RB_STR_ENSURE_CAPA( *intermediate, 4, current_out, end_capa_ptr );
396
398
  write_nbo32(-1, current_out);
397
399
  current_out += 4;
@@ -496,6 +498,7 @@ GetDecimalFromHex(char hex)
496
498
  *
497
499
  * See also PG::TextEncoder::CopyRow for the encoding direction with
498
500
  * PG::Connection#put_copy_data .
501
+ * And see PG::BinaryDecoder::CopyRow for a decoder of the COPY binary format.
499
502
  */
500
503
  /*
501
504
  * Parse the current line into separate attributes (fields),
@@ -763,6 +766,7 @@ static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
763
766
  *
764
767
  * See also PG::BinaryEncoder::CopyRow for the encoding direction with
765
768
  * PG::Connection#put_copy_data .
769
+ * And see PG::TextDecoder::CopyRow for a decoder of the COPY text format.
766
770
  */
767
771
  static VALUE
768
772
  pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tuple, int _field, int enc_idx)
@@ -198,7 +198,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
198
198
  char *ptr1;
199
199
  char *ptr2;
200
200
  long strlen;
201
- int backslashs;
201
+ int backslashes;
202
202
  VALUE subint;
203
203
  VALUE entry;
204
204
 
@@ -249,19 +249,19 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
249
249
  ptr2 = current_out + strlen;
250
250
 
251
251
  /* count required backlashs */
252
- for(backslashs = 0; ptr1 != ptr2; ptr1++) {
252
+ for(backslashes = 0; ptr1 != ptr2; ptr1++) {
253
253
  /* Escape backslash itself, newline, carriage return, and the current delimiter character. */
254
254
  if(*ptr1 == '"' || *ptr1 == '\\'){
255
- backslashs++;
255
+ backslashes++;
256
256
  }
257
257
  }
258
258
 
259
259
  ptr1 = current_out + strlen;
260
- ptr2 = current_out + strlen + backslashs;
260
+ ptr2 = current_out + strlen + backslashes;
261
261
  current_out = ptr2;
262
262
 
263
263
  /* Then store the escaped string on the final position, walking
264
- * right to left, until all backslashs are placed. */
264
+ * right to left, until all backslashes are placed. */
265
265
  while( ptr1 != ptr2 ) {
266
266
  *--ptr2 = *--ptr1;
267
267
  if(*ptr1 == '"' || *ptr1 == '\\'){
@@ -340,7 +340,7 @@ record_isspace(char ch)
340
340
  * conn.exec("SELECT * FROM my_table").map_types!(PG::TypeMapByColumn.new([deco]*2)).to_a
341
341
  * # => [{"v1"=>[2.0, 3.0], "v2"=>[4.0, 5.0]}, {"v1"=>[6.0, 7.0], "v2"=>[8.0, 9.0]}]
342
342
  *
343
- * It's more very convenient to use the PG::BasicTypeRegistry, which is based on database OIDs.
343
+ * It's more convenient to use the PG::BasicTypeRegistry, which is based on database OIDs.
344
344
  * # Fetch a NULL record of our type to retrieve the OIDs of the two fields "r" and "i"
345
345
  * oids = conn.exec( "SELECT (NULL::complex).*" )
346
346
  * # Build a type map (PG::TypeMapByColumn) for decoding the "complex" type
data/ext/pg_result.c CHANGED
@@ -664,7 +664,7 @@ pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
664
664
  * An example:
665
665
  *
666
666
  * begin
667
- * conn.exec( "SELECT * FROM nonexistant_table" )
667
+ * conn.exec( "SELECT * FROM nonexistent_table" )
668
668
  * rescue PG::Error => err
669
669
  * p [
670
670
  * err.result.error_field( PG::Result::PG_DIAG_SEVERITY ),
@@ -684,7 +684,7 @@ pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
684
684
  *
685
685
  * Outputs:
686
686
  *
687
- * ["ERROR", "42P01", "relation \"nonexistant_table\" does not exist", nil, nil,
687
+ * ["ERROR", "42P01", "relation \"nonexistent_table\" does not exist", nil, nil,
688
688
  * "15", nil, nil, nil, "path/to/parse_relation.c", "857", "parserOpenTable"]
689
689
  */
690
690
  static VALUE
@@ -163,6 +163,8 @@ pg_text_dec_integer(t_pg_coder *conv, const char *val, int len, int tuple, int f
163
163
  * This is a decoder class for conversion of PostgreSQL numeric types
164
164
  * to Ruby BigDecimal objects.
165
165
  *
166
+ * As soon as this class is used, it requires the 'bigdecimal' gem.
167
+ *
166
168
  */
167
169
  static VALUE
168
170
  pg_text_dec_numeric(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
@@ -174,7 +176,7 @@ pg_text_dec_numeric(t_pg_coder *conv, const char *val, int len, int tuple, int f
174
176
  static VALUE
175
177
  init_pg_text_decoder_numeric(VALUE rb_mPG_TextDecoder)
176
178
  {
177
- rb_require("bigdecimal");
179
+ rb_funcall(rb_mPG, rb_intern("require_bigdecimal_without_warning"), 0);
178
180
  s_id_BigDecimal = rb_intern("BigDecimal");
179
181
 
180
182
  /* dummy = rb_define_class_under( rb_mPG_TextDecoder, "Numeric", rb_cPG_SimpleDecoder ); */
@@ -811,6 +813,7 @@ static VALUE pg_text_dec_timestamp(t_pg_coder *conv, const char *val, int len, i
811
813
  * This is a decoder class for conversion of PostgreSQL inet type
812
814
  * to Ruby IPAddr values.
813
815
  *
816
+ * As soon as this class is used, it requires the ruby standard library 'ipaddr'.
814
817
  */
815
818
  static VALUE
816
819
  pg_text_dec_inet(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
@@ -119,6 +119,10 @@ pg_text_enc_boolean(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
119
119
  int
120
120
  pg_coder_enc_to_s(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
121
121
  {
122
+ /* Attention:
123
+ * In contrast to all other encoders, the "this" pointer of this encoder can be NULL.
124
+ * This is because it is used as a fall-back if no encoder is defined.
125
+ */
122
126
  VALUE str = rb_obj_as_string(value);
123
127
  if( ENCODING_GET(str) == enc_idx ){
124
128
  *intermediate = str;
@@ -345,6 +349,8 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
345
349
  *
346
350
  * It converts Integer, Float and BigDecimal objects.
347
351
  * All other objects are expected to respond to +to_s+.
352
+ *
353
+ * As soon as this class is used, it requires the 'bigdecimal' gem.
348
354
  */
349
355
  static int
350
356
  pg_text_enc_numeric(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
@@ -377,7 +383,7 @@ init_pg_text_encoder_numeric(VALUE rb_mPG_TextDecoder)
377
383
  {
378
384
  s_str_F = rb_str_freeze(rb_str_new_cstr("F"));
379
385
  rb_global_variable(&s_str_F);
380
- rb_require("bigdecimal");
386
+ rb_funcall(rb_mPG, rb_intern("require_bigdecimal_without_warning"), 0);
381
387
  s_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
382
388
 
383
389
  /* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Numeric", rb_cPG_SimpleEncoder ); */
@@ -437,7 +443,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
437
443
  t_pg_composite_coder *this = _this;
438
444
  char *ptr1;
439
445
  char *ptr2;
440
- int backslashs = 0;
446
+ int backslashes = 0;
441
447
  int needquote;
442
448
 
443
449
  /* count data plus backslashes; detect chars needing quotes */
@@ -454,7 +460,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
454
460
 
455
461
  if (ch == '"' || ch == '\\'){
456
462
  needquote = 1;
457
- backslashs++;
463
+ backslashes++;
458
464
  } else if (ch == '{' || ch == '}' || ch == this->delimiter ||
459
465
  ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f'){
460
466
  needquote = 1;
@@ -463,12 +469,12 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
463
469
 
464
470
  if( needquote ){
465
471
  ptr1 = p_in + strlen;
466
- ptr2 = p_out + strlen + backslashs + 2;
472
+ ptr2 = p_out + strlen + backslashes + 2;
467
473
  /* Write end quote */
468
474
  *--ptr2 = '"';
469
475
 
470
476
  /* Then store the escaped string on the final position, walking
471
- * right to left, until all backslashs are placed. */
477
+ * right to left, until all backslashes are placed. */
472
478
  while( ptr1 != p_in ) {
473
479
  *--ptr2 = *--ptr1;
474
480
  if(*ptr2 == '"' || *ptr2 == '\\'){
@@ -477,7 +483,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
477
483
  }
478
484
  /* Write start quote */
479
485
  *p_out = '"';
480
- return strlen + backslashs + 2;
486
+ return strlen + backslashes + 2;
481
487
  } else {
482
488
  if( p_in != p_out )
483
489
  memcpy( p_out, p_in, strlen );
@@ -692,22 +698,22 @@ static int
692
698
  quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
693
699
  char *ptr1;
694
700
  char *ptr2;
695
- int backslashs = 0;
701
+ int backslashes = 0;
696
702
 
697
703
  /* count required backlashs */
698
704
  for(ptr1 = p_in; ptr1 != p_in + strlen; ptr1++) {
699
705
  if (*ptr1 == '\''){
700
- backslashs++;
706
+ backslashes++;
701
707
  }
702
708
  }
703
709
 
704
710
  ptr1 = p_in + strlen;
705
- ptr2 = p_out + strlen + backslashs + 2;
711
+ ptr2 = p_out + strlen + backslashes + 2;
706
712
  /* Write end quote */
707
713
  *--ptr2 = '\'';
708
714
 
709
715
  /* Then store the escaped string on the final position, walking
710
- * right to left, until all backslashs are placed. */
716
+ * right to left, until all backslashes are placed. */
711
717
  while( ptr1 != p_in ) {
712
718
  *--ptr2 = *--ptr1;
713
719
  if(*ptr2 == '\''){
@@ -716,7 +722,7 @@ quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
716
722
  }
717
723
  /* Write start quote */
718
724
  *p_out = '\'';
719
- return strlen + backslashs + 2;
725
+ return strlen + backslashes + 2;
720
726
  }
721
727
 
722
728