pg 1.2.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 ));