pg 1.2.3 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +36 -0
  4. data/.gems +6 -0
  5. data/.github/workflows/binary-gems.yml +86 -0
  6. data/.github/workflows/source-gem.yml +129 -0
  7. data/.gitignore +13 -0
  8. data/.hgsigs +34 -0
  9. data/.hgtags +41 -0
  10. data/.irbrc +23 -0
  11. data/.pryrc +23 -0
  12. data/.tm_properties +21 -0
  13. data/.travis.yml +49 -0
  14. data/Gemfile +14 -0
  15. data/History.rdoc +153 -7
  16. data/Manifest.txt +0 -1
  17. data/README.rdoc +7 -6
  18. data/Rakefile +27 -138
  19. data/Rakefile.cross +8 -5
  20. data/certs/ged.pem +24 -0
  21. data/certs/larskanis-2022.pem +26 -0
  22. data/ext/errorcodes.def +8 -0
  23. data/ext/errorcodes.rb +0 -0
  24. data/ext/errorcodes.txt +3 -1
  25. data/ext/extconf.rb +131 -25
  26. data/ext/gvl_wrappers.c +4 -0
  27. data/ext/gvl_wrappers.h +23 -0
  28. data/ext/pg.c +59 -4
  29. data/ext/pg.h +19 -1
  30. data/ext/pg_coder.c +82 -28
  31. data/ext/pg_connection.c +680 -508
  32. data/ext/pg_copy_coder.c +45 -16
  33. data/ext/pg_record_coder.c +45 -15
  34. data/ext/pg_result.c +77 -40
  35. data/ext/pg_text_decoder.c +1 -1
  36. data/ext/pg_text_encoder.c +6 -6
  37. data/ext/pg_tuple.c +49 -29
  38. data/ext/pg_type_map.c +41 -8
  39. data/ext/pg_type_map_all_strings.c +15 -1
  40. data/ext/pg_type_map_by_class.c +49 -24
  41. data/ext/pg_type_map_by_column.c +66 -28
  42. data/ext/pg_type_map_by_mri_type.c +47 -18
  43. data/ext/pg_type_map_by_oid.c +52 -23
  44. data/ext/pg_type_map_in_ruby.c +50 -19
  45. data/ext/pg_util.c +2 -2
  46. data/lib/pg/basic_type_map_based_on_result.rb +47 -0
  47. data/lib/pg/basic_type_map_for_queries.rb +193 -0
  48. data/lib/pg/basic_type_map_for_results.rb +81 -0
  49. data/lib/pg/basic_type_registry.rb +301 -0
  50. data/lib/pg/coder.rb +1 -1
  51. data/lib/pg/connection.rb +589 -58
  52. data/lib/pg/version.rb +4 -0
  53. data/lib/pg.rb +47 -32
  54. data/misc/openssl-pg-segfault.rb +31 -0
  55. data/misc/postgres/History.txt +9 -0
  56. data/misc/postgres/Manifest.txt +5 -0
  57. data/misc/postgres/README.txt +21 -0
  58. data/misc/postgres/Rakefile +21 -0
  59. data/misc/postgres/lib/postgres.rb +16 -0
  60. data/misc/ruby-pg/History.txt +9 -0
  61. data/misc/ruby-pg/Manifest.txt +5 -0
  62. data/misc/ruby-pg/README.txt +21 -0
  63. data/misc/ruby-pg/Rakefile +21 -0
  64. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  65. data/pg.gemspec +32 -0
  66. data/rakelib/task_extension.rb +46 -0
  67. data/sample/array_insert.rb +20 -0
  68. data/sample/async_api.rb +102 -0
  69. data/sample/async_copyto.rb +39 -0
  70. data/sample/async_mixed.rb +56 -0
  71. data/sample/check_conn.rb +21 -0
  72. data/sample/copydata.rb +71 -0
  73. data/sample/copyfrom.rb +81 -0
  74. data/sample/copyto.rb +19 -0
  75. data/sample/cursor.rb +21 -0
  76. data/sample/disk_usage_report.rb +177 -0
  77. data/sample/issue-119.rb +94 -0
  78. data/sample/losample.rb +69 -0
  79. data/sample/minimal-testcase.rb +17 -0
  80. data/sample/notify_wait.rb +72 -0
  81. data/sample/pg_statistics.rb +285 -0
  82. data/sample/replication_monitor.rb +222 -0
  83. data/sample/test_binary_values.rb +33 -0
  84. data/sample/wal_shipper.rb +434 -0
  85. data/sample/warehouse_partitions.rb +311 -0
  86. data.tar.gz.sig +0 -0
  87. metadata +87 -224
  88. metadata.gz.sig +0 -0
  89. data/ChangeLog +0 -0
  90. data/lib/pg/basic_type_mapping.rb +0 -522
  91. data/spec/data/expected_trace.out +0 -26
  92. data/spec/data/random_binary_data +0 -0
  93. data/spec/helpers.rb +0 -380
  94. data/spec/pg/basic_type_mapping_spec.rb +0 -630
  95. data/spec/pg/connection_spec.rb +0 -1949
  96. data/spec/pg/connection_sync_spec.rb +0 -41
  97. data/spec/pg/result_spec.rb +0 -681
  98. data/spec/pg/tuple_spec.rb +0 -333
  99. data/spec/pg/type_map_by_class_spec.rb +0 -138
  100. data/spec/pg/type_map_by_column_spec.rb +0 -226
  101. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  102. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  103. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  104. data/spec/pg/type_map_spec.rb +0 -22
  105. data/spec/pg/type_spec.rb +0 -1123
  106. data/spec/pg_spec.rb +0 -50
data/ext/extconf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  require 'pp'
2
4
  require 'mkmf'
3
5
 
@@ -15,6 +17,13 @@ if pgdir = with_config( 'pg' )
15
17
  ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
16
18
  end
17
19
 
20
+ if enable_config("gvl-unlock", true)
21
+ $defs.push( "-DENABLE_GVL_UNLOCK" )
22
+ $stderr.puts "Calling libpq with GVL unlocked"
23
+ else
24
+ $stderr.puts "Calling libpq with GVL locked"
25
+ end
26
+
18
27
  if enable_config("windows-cross")
19
28
  # Avoid dependency to external libgcc.dll on x86-mingw32
20
29
  $LDFLAGS << " -static-libgcc"
@@ -30,35 +39,97 @@ else
30
39
 
31
40
  if pgconfig && pgconfig != 'ignore'
32
41
  $stderr.puts "Using config values from %s" % [ pgconfig ]
33
- incdir = `"#{pgconfig}" --includedir`.chomp
34
- libdir = `"#{pgconfig}" --libdir`.chomp
42
+ incdir = IO.popen([pgconfig, "--includedir"], &:read).chomp
43
+ libdir = IO.popen([pgconfig, "--libdir"], &:read).chomp
35
44
  dir_config 'pg', incdir, libdir
36
45
 
37
- # Try to use runtime path linker option, even if RbConfig doesn't know about it.
38
- # The rpath option is usually set implicit by dir_config(), but so far not
39
- # on MacOS-X.
40
- if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', " -Wl,-rpath,#{libdir}")
41
- $LDFLAGS << " -Wl,-rpath,#{libdir}"
46
+ # Windows traditionally stores DLLs beside executables, not in libdir
47
+ dlldir = RUBY_PLATFORM=~/mingw|mswin/ ? IO.popen([pgconfig, "--bindir"], &:read).chomp : libdir
48
+
49
+ elsif checking_for "libpq per pkg-config" do
50
+ _cflags, ldflags, _libs = pkg_config("libpq")
51
+ dlldir = ldflags && ldflags[/-L([^ ]+)/] && $1
42
52
  end
53
+
43
54
  else
44
- $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
45
- " --with-pg-config=/path/to/pg_config"
46
- dir_config 'pg'
55
+ incdir, libdir = dir_config 'pg'
56
+ dlldir = libdir
57
+ end
58
+
59
+ # Try to use runtime path linker option, even if RbConfig doesn't know about it.
60
+ # The rpath option is usually set implicit by dir_config(), but so far not
61
+ # on MacOS-X.
62
+ if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
63
+ append_ldflags "-Wl,-rpath,#{dlldir.quote}"
47
64
  end
48
65
  end
49
66
 
67
+ $stderr.puts "Using libpq from #{dlldir}"
68
+
69
+ File.write("postgresql_lib_path.rb", <<-EOT)
70
+ module PG
71
+ POSTGRESQL_LIB_PATH = #{dlldir.inspect}
72
+ end
73
+ EOT
74
+ $INSTALLFILES = {
75
+ "./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
76
+ }
77
+
50
78
  if RUBY_VERSION >= '2.3.0' && /solaris/ =~ RUBY_PLATFORM
51
79
  append_cppflags( '-D__EXTENSIONS__' )
52
80
  end
53
81
 
54
- find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
55
- find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
56
- find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
82
+ begin
83
+ find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
84
+ find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
85
+ find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
86
+
87
+ abort "Can't find the PostgreSQL client library (libpq)" unless
88
+ have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
89
+ have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
90
+ have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
91
+
92
+ rescue SystemExit
93
+ install_text = case RUBY_PLATFORM
94
+ when /linux/
95
+ <<-EOT
96
+ Please install libpq or postgresql client package like so:
97
+ sudo apt install libpq-dev
98
+ sudo yum install postgresql-devel
99
+ sudo zypper in postgresql-devel
100
+ sudo pacman -S postgresql-libs
101
+ EOT
102
+ when /darwin/
103
+ <<-EOT
104
+ Please install libpq or postgresql client package like so:
105
+ brew install libpq
106
+ EOT
107
+ when /mingw/
108
+ <<-EOT
109
+ Please install libpq or postgresql client package like so:
110
+ ridk exec sh -c "pacman -S ${MINGW_PACKAGE_PREFIX}-postgresql"
111
+ EOT
112
+ else
113
+ <<-EOT
114
+ Please install libpq or postgresql client package.
115
+ EOT
116
+ end
117
+
118
+ $stderr.puts <<-EOT
119
+ *****************************************************************************
120
+
121
+ Unable to find PostgreSQL client library.
57
122
 
58
- abort "Can't find the PostgreSQL client library (libpq)" unless
59
- have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
60
- have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
61
- have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
123
+ #{install_text}
124
+ or try again with:
125
+ gem install pg -- --with-pg-config=/path/to/pg_config
126
+
127
+ or set library paths manually with:
128
+ gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/
129
+
130
+ EOT
131
+ raise
132
+ end
62
133
 
63
134
  if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
64
135
  # Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
@@ -69,21 +140,27 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
69
140
  end
70
141
  end
71
142
 
72
- # optional headers/functions
73
- have_func 'PQsetSingleRowMode' or
143
+ have_func 'PQconninfo', 'libpq-fe.h' or
74
144
  abort "Your PostgreSQL is too old. Either install an older version " +
75
- "of this gem or upgrade your database to at least PostgreSQL-9.2."
76
- have_func 'PQconninfo' # since PostgreSQL-9.3
77
- have_func 'PQsslAttribute' # since PostgreSQL-9.5
78
- have_func 'PQresultVerboseErrorMessage' # since PostgreSQL-9.6
79
- have_func 'PQencryptPasswordConn' # since PostgreSQL-10
80
- have_func 'PQresultMemorySize' # since PostgreSQL-12
145
+ "of this gem or upgrade your database to at least PostgreSQL-9.3."
146
+ # optional headers/functions
147
+ have_func 'PQsslAttribute', 'libpq-fe.h' # since PostgreSQL-9.5
148
+ have_func 'PQresultVerboseErrorMessage', 'libpq-fe.h' # since PostgreSQL-9.6
149
+ have_func 'PQencryptPasswordConn', 'libpq-fe.h' # since PostgreSQL-10
150
+ have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
151
+ have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
152
+ # Ensure header files fit as well
153
+ src + " int con(){ return PGRES_PIPELINE_SYNC; }"
154
+ end
81
155
  have_func 'timegm'
82
156
  have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
157
+ have_func 'rb_gc_mark_movable' # since ruby-2.7
158
+ have_func 'rb_io_wait' # since ruby-3.0
83
159
 
84
160
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
85
161
  have_header 'unistd.h'
86
162
  have_header 'inttypes.h'
163
+ have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
87
164
 
88
165
  checking_for "C99 variable length arrays" do
89
166
  $defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
@@ -92,3 +169,32 @@ end
92
169
  create_header()
93
170
  create_makefile( "pg_ext" )
94
171
 
172
+
173
+ def message!(important_message)
174
+ message important_message
175
+ if !$stdout.tty? && File.chardev?('/dev/tty')
176
+ File.open('/dev/tty', 'w') do |tty|
177
+ tty.print important_message
178
+ end
179
+ end
180
+ rescue
181
+ end
182
+
183
+ if "2022-04-01" == Time.now.strftime("%Y-%m-%d")
184
+ message! <<-EOM
185
+ ===================================================================
186
+ HEADS UP! Prepare for pg-1.4.2022 ! 🎉🎉🎉
187
+
188
+ Now that psycopg3 has most of the features of ruby-pg, we plan to
189
+ switch to using it as our foundation for the next pg release.
190
+ It will run through pycall and requires a working python setup.
191
+ This will minimize our development and maintenance efforts, since
192
+ it allows us to use one and the same code base for both programming
193
+ languages - ruby and python. 👏😃
194
+
195
+ And we follow the recent merge of the Django and Rails teams! ❤️
196
+
197
+ Stay up-to-date at https://github.com/ged/ruby-pg/issues/449
198
+ ===================================================================
199
+ EOM
200
+ end
data/ext/gvl_wrappers.c CHANGED
@@ -9,9 +9,13 @@
9
9
  char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm){return NULL;}
10
10
  #endif
11
11
 
12
+ #ifdef ENABLE_GVL_UNLOCK
12
13
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
13
14
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
15
+ #endif
14
16
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
17
+ #ifdef ENABLE_GVL_UNLOCK
15
18
  FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
16
19
  FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON );
20
+ #endif
17
21
  FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB );
data/ext/gvl_wrappers.h CHANGED
@@ -17,6 +17,10 @@
17
17
 
18
18
  #include <ruby/thread.h>
19
19
 
20
+ #ifdef RUBY_EXTCONF_H
21
+ # include RUBY_EXTCONF_H
22
+ #endif
23
+
20
24
  #define DEFINE_PARAM_LIST1(type, name) \
21
25
  name,
22
26
 
@@ -46,6 +50,7 @@
46
50
  return NULL; \
47
51
  }
48
52
 
53
+ #ifdef ENABLE_GVL_UNLOCK
49
54
  #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
50
55
  rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
51
56
  struct gvl_wrapper_##name##_params params = { \
@@ -54,6 +59,13 @@
54
59
  rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
55
60
  when_non_void( return params.retval; ) \
56
61
  }
62
+ #else
63
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
64
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
65
+ when_non_void( return ) \
66
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
67
+ }
68
+ #endif
57
69
 
58
70
  #define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
59
71
  rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
@@ -66,6 +78,7 @@
66
78
  return NULL; \
67
79
  }
68
80
 
81
+ #ifdef ENABLE_GVL_UNLOCK
69
82
  #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
70
83
  rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
71
84
  struct gvl_wrapper_##name##_params params = { \
@@ -74,6 +87,13 @@
74
87
  rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
75
88
  when_non_void( return params.retval; ) \
76
89
  }
90
+ #else
91
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
92
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
93
+ when_non_void( return ) \
94
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
95
+ }
96
+ #endif
77
97
 
78
98
  #define GVL_TYPE_VOID(string)
79
99
  #define GVL_TYPE_NONVOID(string) string
@@ -95,6 +115,8 @@
95
115
 
96
116
  #define FOR_EACH_PARAM_OF_PQresetPoll(param)
97
117
 
118
+ #define FOR_EACH_PARAM_OF_PQping(param)
119
+
98
120
  #define FOR_EACH_PARAM_OF_PQexec(param) \
99
121
  param(PGconn *, conn)
100
122
 
@@ -196,6 +218,7 @@
196
218
  function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
197
219
  function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
198
220
  function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
221
+ function(PQping, GVL_TYPE_NONVOID, PGPing, const char *, conninfo) \
199
222
  function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
200
223
  function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
201
224
  function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
data/ext/pg.c CHANGED
@@ -47,6 +47,7 @@
47
47
  */
48
48
 
49
49
  #include "pg.h"
50
+ #include "pg_config.h"
50
51
 
51
52
  int pg_skip_deprecation_warning;
52
53
  VALUE rb_mPG;
@@ -415,14 +416,34 @@ Init_pg_ext()
415
416
  rb_define_const(rb_mPGconstants, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE));
416
417
  /* Waiting for a response from the server. */
417
418
  rb_define_const(rb_mPGconstants, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE));
418
- /* Received authentication; waiting for backend start-up to finish. */
419
+ /* Received authentication; waiting for backend startup. */
419
420
  rb_define_const(rb_mPGconstants, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK));
421
+ /* This state is no longer used. */
422
+ rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
420
423
  /* Negotiating SSL encryption. */
421
424
  rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
422
- /* Negotiating environment-driven parameter settings. */
423
- rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
424
425
  /* Internal state - PG.connect() needed. */
425
426
  rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
427
+ #if PG_MAJORVERSION_NUM >= 10
428
+ /* Checking if session is read-write. Available since PostgreSQL-10. */
429
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_WRITABLE", INT2FIX(CONNECTION_CHECK_WRITABLE));
430
+ #endif
431
+ #if PG_MAJORVERSION_NUM >= 10
432
+ /* Consuming any extra messages. Available since PostgreSQL-10. */
433
+ rb_define_const(rb_mPGconstants, "CONNECTION_CONSUME", INT2FIX(CONNECTION_CONSUME));
434
+ #endif
435
+ #if PG_MAJORVERSION_NUM >= 12
436
+ /* Negotiating GSSAPI. Available since PostgreSQL-12. */
437
+ rb_define_const(rb_mPGconstants, "CONNECTION_GSS_STARTUP", INT2FIX(CONNECTION_GSS_STARTUP));
438
+ #endif
439
+ #if PG_MAJORVERSION_NUM >= 13
440
+ /* Checking target server properties. Available since PostgreSQL-13. */
441
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_TARGET", INT2FIX(CONNECTION_CHECK_TARGET));
442
+ #endif
443
+ #if PG_MAJORVERSION_NUM >= 14
444
+ /* Checking if server is in standby mode. Available since PostgreSQL-14. */
445
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_STANDBY", INT2FIX(CONNECTION_CHECK_STANDBY));
446
+ #endif
426
447
 
427
448
  /****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
428
449
 
@@ -526,6 +547,19 @@ Init_pg_ext()
526
547
  /* Result#result_status constant - Single tuple from larger resultset. */
527
548
  rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
528
549
 
550
+ #ifdef HAVE_PQENTERPIPELINEMODE
551
+ /* Result#result_status constant - The PG::Result represents a synchronization point in pipeline mode, requested by Connection#pipeline_sync.
552
+ *
553
+ * This status occurs only when pipeline mode has been selected. */
554
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_SYNC", INT2FIX(PGRES_PIPELINE_SYNC));
555
+
556
+ /* Result#result_status constant - The PG::Result represents a pipeline that has received an error from the server.
557
+ *
558
+ * Connection#get_result must be called repeatedly, and each time it will return this status code until the end of the current pipeline, at which point it will return PG::PGRES_PIPELINE_SYNC and normal processing can resume.
559
+ */
560
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_ABORTED", INT2FIX(PGRES_PIPELINE_ABORTED));
561
+ #endif
562
+
529
563
  /****** Result CONSTANTS: result error field codes ******/
530
564
 
531
565
  /* Result#result_error_field argument constant
@@ -549,7 +583,7 @@ Init_pg_ext()
549
583
  /* Result#result_error_field argument constant
550
584
  *
551
585
  * The SQLSTATE code for the error.
552
- * The SQLSTATE code identies the type of error that has occurred; it can be used by front-end applications to perform specic operations (such as error handling) in response to a particular database error.
586
+ * 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.
553
587
  * For a list of the possible SQLSTATE codes, see Appendix A.
554
588
  * This field is not localizable, and is always present.
555
589
  */
@@ -645,6 +679,27 @@ Init_pg_ext()
645
679
  rb_define_const(rb_mPGconstants, "PG_DIAG_CONSTRAINT_NAME", INT2FIX(PG_DIAG_CONSTRAINT_NAME));
646
680
  #endif
647
681
 
682
+ #ifdef HAVE_PQENTERPIPELINEMODE
683
+ /* Connection#pipeline_status constant
684
+ *
685
+ * The libpq connection is in pipeline mode.
686
+ */
687
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ON", INT2FIX(PQ_PIPELINE_ON));
688
+
689
+ /* Connection#pipeline_status constant
690
+ *
691
+ * The libpq connection is not in pipeline mode.
692
+ */
693
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_OFF", INT2FIX(PQ_PIPELINE_OFF));
694
+
695
+ /* Connection#pipeline_status constant
696
+ *
697
+ * The libpq connection is in pipeline mode and an error occurred while processing the current pipeline.
698
+ * The aborted flag is cleared when PQgetResult returns a result of type PGRES_PIPELINE_SYNC.
699
+ */
700
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ABORTED", INT2FIX(PQ_PIPELINE_ABORTED));
701
+ #endif
702
+
648
703
  /* Invalid OID constant */
649
704
  rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
650
705
  rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid));
data/ext/pg.h CHANGED
@@ -11,6 +11,7 @@
11
11
  #include <sys/types.h>
12
12
  #if !defined(_WIN32)
13
13
  # include <sys/time.h>
14
+ # include <sys/socket.h>
14
15
  #endif
15
16
  #if defined(HAVE_UNISTD_H) && !defined(_WIN32)
16
17
  # include <unistd.h>
@@ -78,6 +79,15 @@ typedef long suseconds_t;
78
79
  #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
79
80
  #endif
80
81
 
82
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
83
+ #define pg_compact_callback(x) (x)
84
+ #define pg_gc_location(x) x = rb_gc_location(x)
85
+ #else
86
+ #define rb_gc_mark_movable(x) rb_gc_mark(x)
87
+ #define pg_compact_callback(x) {(x)}
88
+ #define pg_gc_location(x) UNUSED(x)
89
+ #endif
90
+
81
91
  #define PG_ENC_IDX_BITS 28
82
92
 
83
93
  /* The data behind each PG::Connection object */
@@ -104,6 +114,8 @@ typedef struct {
104
114
  int enc_idx : PG_ENC_IDX_BITS;
105
115
  /* flags controlling Symbol/String field names */
106
116
  unsigned int flags : 2;
117
+ /* enable automatic flushing of send data at the end of send_query calls */
118
+ unsigned int flush_data : 1;
107
119
 
108
120
  #if defined(_WIN32)
109
121
  /* File descriptor to be used for rb_w32_unwrap_io_handle() */
@@ -220,6 +232,8 @@ typedef struct {
220
232
  } convs[0];
221
233
  } t_tmbc;
222
234
 
235
+ extern const rb_data_type_t pg_typemap_type;
236
+ extern const rb_data_type_t pg_coder_type;
223
237
 
224
238
  #include "gvl_wrappers.h"
225
239
 
@@ -304,7 +318,7 @@ VALUE pg_obj_to_i _(( VALUE ));
304
318
  VALUE pg_tmbc_allocate _(( void ));
305
319
  void pg_coder_init_encoder _(( VALUE ));
306
320
  void pg_coder_init_decoder _(( VALUE ));
307
- void pg_coder_mark _(( t_pg_coder * ));
321
+ void pg_coder_compact _(( void * ));
308
322
  char *pg_rb_str_ensure_capa _(( VALUE, long, char *, char ** ));
309
323
 
310
324
  #define PG_RB_STR_ENSURE_CAPA( str, expand_len, curr_ptr, end_ptr ) \
@@ -324,9 +338,13 @@ int pg_typemap_fit_to_copy_get _(( VALUE ));
324
338
  VALUE pg_typemap_result_value _(( t_typemap *, VALUE, int, int ));
325
339
  t_pg_coder *pg_typemap_typecast_query_param _(( t_typemap *, VALUE, int ));
326
340
  VALUE pg_typemap_typecast_copy_get _(( t_typemap *, VALUE, int, int, int ));
341
+ void pg_typemap_mark _(( void * ));
342
+ size_t pg_typemap_memsize _(( const void * ));
343
+ void pg_typemap_compact _(( void * ));
327
344
 
328
345
  PGconn *pg_get_pgconn _(( VALUE ));
329
346
  t_pg_connection *pg_get_connection _(( VALUE ));
347
+ VALUE pgconn_block _(( int, VALUE *, VALUE ));
330
348
 
331
349
  VALUE pg_new_result _(( PGresult *, VALUE ));
332
350
  VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));