pg 1.2.3 → 1.4.3

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 (107) 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 +199 -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 +100 -25
  26. data/ext/gvl_wrappers.c +4 -0
  27. data/ext/gvl_wrappers.h +23 -0
  28. data/ext/pg.c +59 -28
  29. data/ext/pg.h +19 -1
  30. data/ext/pg_coder.c +82 -28
  31. data/ext/pg_connection.c +855 -654
  32. data/ext/pg_copy_coder.c +45 -16
  33. data/ext/pg_record_coder.c +45 -15
  34. data/ext/pg_result.c +79 -42
  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 +668 -70
  52. data/lib/pg/exceptions.rb +7 -1
  53. data/lib/pg/version.rb +4 -0
  54. data/lib/pg.rb +47 -32
  55. data/misc/openssl-pg-segfault.rb +31 -0
  56. data/misc/postgres/History.txt +9 -0
  57. data/misc/postgres/Manifest.txt +5 -0
  58. data/misc/postgres/README.txt +21 -0
  59. data/misc/postgres/Rakefile +21 -0
  60. data/misc/postgres/lib/postgres.rb +16 -0
  61. data/misc/ruby-pg/History.txt +9 -0
  62. data/misc/ruby-pg/Manifest.txt +5 -0
  63. data/misc/ruby-pg/README.txt +21 -0
  64. data/misc/ruby-pg/Rakefile +21 -0
  65. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  66. data/pg.gemspec +32 -0
  67. data/rakelib/task_extension.rb +46 -0
  68. data/sample/array_insert.rb +20 -0
  69. data/sample/async_api.rb +102 -0
  70. data/sample/async_copyto.rb +39 -0
  71. data/sample/async_mixed.rb +56 -0
  72. data/sample/check_conn.rb +21 -0
  73. data/sample/copydata.rb +71 -0
  74. data/sample/copyfrom.rb +81 -0
  75. data/sample/copyto.rb +19 -0
  76. data/sample/cursor.rb +21 -0
  77. data/sample/disk_usage_report.rb +177 -0
  78. data/sample/issue-119.rb +94 -0
  79. data/sample/losample.rb +69 -0
  80. data/sample/minimal-testcase.rb +17 -0
  81. data/sample/notify_wait.rb +72 -0
  82. data/sample/pg_statistics.rb +285 -0
  83. data/sample/replication_monitor.rb +222 -0
  84. data/sample/test_binary_values.rb +33 -0
  85. data/sample/wal_shipper.rb +434 -0
  86. data/sample/warehouse_partitions.rb +311 -0
  87. data.tar.gz.sig +0 -0
  88. metadata +87 -224
  89. metadata.gz.sig +0 -0
  90. data/ChangeLog +0 -0
  91. data/lib/pg/basic_type_mapping.rb +0 -522
  92. data/spec/data/expected_trace.out +0 -26
  93. data/spec/data/random_binary_data +0 -0
  94. data/spec/helpers.rb +0 -380
  95. data/spec/pg/basic_type_mapping_spec.rb +0 -630
  96. data/spec/pg/connection_spec.rb +0 -1949
  97. data/spec/pg/connection_sync_spec.rb +0 -41
  98. data/spec/pg/result_spec.rb +0 -681
  99. data/spec/pg/tuple_spec.rb +0 -333
  100. data/spec/pg/type_map_by_class_spec.rb +0 -138
  101. data/spec/pg/type_map_by_column_spec.rb +0 -226
  102. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  103. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  104. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  105. data/spec/pg/type_map_spec.rb +0 -22
  106. data/spec/pg/type_spec.rb +0 -1123
  107. data/spec/pg_spec.rb +0 -50
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2019, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2021, 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
@@ -207,6 +207,7 @@ Section: Class 22 - Data Exception
207
207
  2200S E ERRCODE_INVALID_XML_COMMENT invalid_xml_comment
208
208
  2200T E ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION invalid_xml_processing_instruction
209
209
  22030 E ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE duplicate_json_object_key_value
210
+ 22031 E ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION invalid_argument_for_sql_json_datetime_function
210
211
  22032 E ERRCODE_INVALID_JSON_TEXT invalid_json_text
211
212
  22033 E ERRCODE_INVALID_SQL_JSON_SUBSCRIPT invalid_sql_json_subscript
212
213
  22034 E ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM more_than_one_sql_json_item
@@ -427,6 +428,7 @@ Section: Class 57 - Operator Intervention
427
428
  57P02 E ERRCODE_CRASH_SHUTDOWN crash_shutdown
428
429
  57P03 E ERRCODE_CANNOT_CONNECT_NOW cannot_connect_now
429
430
  57P04 E ERRCODE_DATABASE_DROPPED database_dropped
431
+ 57P05 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout
430
432
 
431
433
  Section: Class 58 - System Error (errors external to PostgreSQL itself)
432
434
 
data/ext/extconf.rb CHANGED
@@ -15,6 +15,13 @@ if pgdir = with_config( 'pg' )
15
15
  ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
16
16
  end
17
17
 
18
+ if enable_config("gvl-unlock", true)
19
+ $defs.push( "-DENABLE_GVL_UNLOCK" )
20
+ $stderr.puts "Calling libpq with GVL unlocked"
21
+ else
22
+ $stderr.puts "Calling libpq with GVL locked"
23
+ end
24
+
18
25
  if enable_config("windows-cross")
19
26
  # Avoid dependency to external libgcc.dll on x86-mingw32
20
27
  $LDFLAGS << " -static-libgcc"
@@ -30,35 +37,97 @@ else
30
37
 
31
38
  if pgconfig && pgconfig != 'ignore'
32
39
  $stderr.puts "Using config values from %s" % [ pgconfig ]
33
- incdir = `"#{pgconfig}" --includedir`.chomp
34
- libdir = `"#{pgconfig}" --libdir`.chomp
40
+ incdir = IO.popen([pgconfig, "--includedir"], &:read).chomp
41
+ libdir = IO.popen([pgconfig, "--libdir"], &:read).chomp
35
42
  dir_config 'pg', incdir, libdir
36
43
 
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}"
44
+ # Windows traditionally stores DLLs beside executables, not in libdir
45
+ dlldir = RUBY_PLATFORM=~/mingw|mswin/ ? IO.popen([pgconfig, "--bindir"], &:read).chomp : libdir
46
+
47
+ elsif checking_for "libpq per pkg-config" do
48
+ _cflags, ldflags, _libs = pkg_config("libpq")
49
+ dlldir = ldflags && ldflags[/-L([^ ]+)/] && $1
42
50
  end
51
+
43
52
  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'
53
+ incdir, libdir = dir_config 'pg'
54
+ dlldir = libdir
47
55
  end
56
+
57
+ # Try to use runtime path linker option, even if RbConfig doesn't know about it.
58
+ # The rpath option is usually set implicit by dir_config(), but so far not
59
+ # on MacOS-X.
60
+ if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
61
+ append_ldflags "-Wl,-rpath,#{dlldir.quote}"
62
+ end
63
+ end
64
+
65
+ $stderr.puts "Using libpq from #{dlldir}"
66
+
67
+ File.write("postgresql_lib_path.rb", <<-EOT)
68
+ module PG
69
+ POSTGRESQL_LIB_PATH = #{dlldir.inspect}
48
70
  end
71
+ EOT
72
+ $INSTALLFILES = {
73
+ "./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
74
+ }
49
75
 
50
76
  if RUBY_VERSION >= '2.3.0' && /solaris/ =~ RUBY_PLATFORM
51
77
  append_cppflags( '-D__EXTENSIONS__' )
52
78
  end
53
79
 
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"
80
+ begin
81
+ find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
82
+ find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
83
+ find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
84
+
85
+ abort "Can't find the PostgreSQL client library (libpq)" unless
86
+ have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
87
+ have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
88
+ have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
89
+
90
+ rescue SystemExit
91
+ install_text = case RUBY_PLATFORM
92
+ when /linux/
93
+ <<-EOT
94
+ Please install libpq or postgresql client package like so:
95
+ sudo apt install libpq-dev
96
+ sudo yum install postgresql-devel
97
+ sudo zypper in postgresql-devel
98
+ sudo pacman -S postgresql-libs
99
+ EOT
100
+ when /darwin/
101
+ <<-EOT
102
+ Please install libpq or postgresql client package like so:
103
+ brew install libpq
104
+ EOT
105
+ when /mingw/
106
+ <<-EOT
107
+ Please install libpq or postgresql client package like so:
108
+ ridk exec sh -c "pacman -S ${MINGW_PACKAGE_PREFIX}-postgresql"
109
+ EOT
110
+ else
111
+ <<-EOT
112
+ Please install libpq or postgresql client package.
113
+ EOT
114
+ end
115
+
116
+ $stderr.puts <<-EOT
117
+ *****************************************************************************
118
+
119
+ Unable to find PostgreSQL client library.
120
+
121
+ #{install_text}
122
+ or try again with:
123
+ gem install pg -- --with-pg-config=/path/to/pg_config
57
124
 
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'] )
125
+ or set library paths manually with:
126
+ gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/
127
+
128
+ EOT
129
+ raise
130
+ end
62
131
 
63
132
  if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
64
133
  # Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
@@ -69,21 +138,27 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
69
138
  end
70
139
  end
71
140
 
72
- # optional headers/functions
73
- have_func 'PQsetSingleRowMode' or
141
+ have_func 'PQconninfo', 'libpq-fe.h' or
74
142
  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
143
+ "of this gem or upgrade your database to at least PostgreSQL-9.3."
144
+ # optional headers/functions
145
+ have_func 'PQsslAttribute', 'libpq-fe.h' # since PostgreSQL-9.5
146
+ have_func 'PQresultVerboseErrorMessage', 'libpq-fe.h' # since PostgreSQL-9.6
147
+ have_func 'PQencryptPasswordConn', 'libpq-fe.h' # since PostgreSQL-10
148
+ have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
149
+ have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
150
+ # Ensure header files fit as well
151
+ src + " int con(){ return PGRES_PIPELINE_SYNC; }"
152
+ end
81
153
  have_func 'timegm'
82
154
  have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
155
+ have_func 'rb_gc_mark_movable' # since ruby-2.7
156
+ have_func 'rb_io_wait' # since ruby-3.0
83
157
 
84
158
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
85
159
  have_header 'unistd.h'
86
160
  have_header 'inttypes.h'
161
+ have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
87
162
 
88
163
  checking_for "C99 variable length arrays" do
89
164
  $defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
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;
@@ -126,26 +127,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
126
127
  static struct st_table *enc_pg2ruby;
127
128
 
128
129
 
129
- /*
130
- * Look up the JOHAB encoding, creating it as a dummy encoding if it's not
131
- * already defined.
132
- */
133
- static rb_encoding *
134
- pg_find_or_create_johab(void)
135
- {
136
- static const char * const aliases[] = { "JOHAB", "Windows-1361", "CP1361" };
137
- int enc_index;
138
- size_t i;
139
-
140
- for (i = 0; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
141
- enc_index = rb_enc_find_index(aliases[i]);
142
- if (enc_index > 0) return rb_enc_from_index(enc_index);
143
- }
144
-
145
- enc_index = rb_define_dummy_encoding(aliases[0]);
146
- return rb_enc_from_index(enc_index);
147
- }
148
-
149
130
  /*
150
131
  * Return the given PostgreSQL encoding ID as an rb_encoding.
151
132
  *
@@ -186,10 +167,6 @@ pg_get_pg_encname_as_rb_encoding( const char *pg_encname )
186
167
  return rb_enc_find( pg_enc_pg2ruby_mapping[i][1] );
187
168
  }
188
169
 
189
- /* JOHAB isn't a builtin encoding, so make up a dummy encoding if it's seen */
190
- if ( strncmp(pg_encname, "JOHAB", 5) == 0 )
191
- return pg_find_or_create_johab();
192
-
193
170
  /* Fallthrough to ASCII-8BIT */
194
171
  return rb_ascii8bit_encoding();
195
172
  }
@@ -415,14 +392,34 @@ Init_pg_ext()
415
392
  rb_define_const(rb_mPGconstants, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE));
416
393
  /* Waiting for a response from the server. */
417
394
  rb_define_const(rb_mPGconstants, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE));
418
- /* Received authentication; waiting for backend start-up to finish. */
395
+ /* Received authentication; waiting for backend startup. */
419
396
  rb_define_const(rb_mPGconstants, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK));
397
+ /* This state is no longer used. */
398
+ rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
420
399
  /* Negotiating SSL encryption. */
421
400
  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
401
  /* Internal state - PG.connect() needed. */
425
402
  rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
403
+ #if PG_MAJORVERSION_NUM >= 10
404
+ /* Checking if session is read-write. Available since PostgreSQL-10. */
405
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_WRITABLE", INT2FIX(CONNECTION_CHECK_WRITABLE));
406
+ #endif
407
+ #if PG_MAJORVERSION_NUM >= 10
408
+ /* Consuming any extra messages. Available since PostgreSQL-10. */
409
+ rb_define_const(rb_mPGconstants, "CONNECTION_CONSUME", INT2FIX(CONNECTION_CONSUME));
410
+ #endif
411
+ #if PG_MAJORVERSION_NUM >= 12
412
+ /* Negotiating GSSAPI. Available since PostgreSQL-12. */
413
+ rb_define_const(rb_mPGconstants, "CONNECTION_GSS_STARTUP", INT2FIX(CONNECTION_GSS_STARTUP));
414
+ #endif
415
+ #if PG_MAJORVERSION_NUM >= 13
416
+ /* Checking target server properties. Available since PostgreSQL-13. */
417
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_TARGET", INT2FIX(CONNECTION_CHECK_TARGET));
418
+ #endif
419
+ #if PG_MAJORVERSION_NUM >= 14
420
+ /* Checking if server is in standby mode. Available since PostgreSQL-14. */
421
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_STANDBY", INT2FIX(CONNECTION_CHECK_STANDBY));
422
+ #endif
426
423
 
427
424
  /****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
428
425
 
@@ -526,6 +523,19 @@ Init_pg_ext()
526
523
  /* Result#result_status constant - Single tuple from larger resultset. */
527
524
  rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
528
525
 
526
+ #ifdef HAVE_PQENTERPIPELINEMODE
527
+ /* Result#result_status constant - The PG::Result represents a synchronization point in pipeline mode, requested by Connection#pipeline_sync.
528
+ *
529
+ * This status occurs only when pipeline mode has been selected. */
530
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_SYNC", INT2FIX(PGRES_PIPELINE_SYNC));
531
+
532
+ /* Result#result_status constant - The PG::Result represents a pipeline that has received an error from the server.
533
+ *
534
+ * 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.
535
+ */
536
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_ABORTED", INT2FIX(PGRES_PIPELINE_ABORTED));
537
+ #endif
538
+
529
539
  /****** Result CONSTANTS: result error field codes ******/
530
540
 
531
541
  /* Result#result_error_field argument constant
@@ -549,7 +559,7 @@ Init_pg_ext()
549
559
  /* Result#result_error_field argument constant
550
560
  *
551
561
  * 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.
562
+ * 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
563
  * For a list of the possible SQLSTATE codes, see Appendix A.
554
564
  * This field is not localizable, and is always present.
555
565
  */
@@ -645,6 +655,27 @@ Init_pg_ext()
645
655
  rb_define_const(rb_mPGconstants, "PG_DIAG_CONSTRAINT_NAME", INT2FIX(PG_DIAG_CONSTRAINT_NAME));
646
656
  #endif
647
657
 
658
+ #ifdef HAVE_PQENTERPIPELINEMODE
659
+ /* Connection#pipeline_status constant
660
+ *
661
+ * The libpq connection is in pipeline mode.
662
+ */
663
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ON", INT2FIX(PQ_PIPELINE_ON));
664
+
665
+ /* Connection#pipeline_status constant
666
+ *
667
+ * The libpq connection is not in pipeline mode.
668
+ */
669
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_OFF", INT2FIX(PQ_PIPELINE_OFF));
670
+
671
+ /* Connection#pipeline_status constant
672
+ *
673
+ * The libpq connection is in pipeline mode and an error occurred while processing the current pipeline.
674
+ * The aborted flag is cleared when PQgetResult returns a result of type PGRES_PIPELINE_SYNC.
675
+ */
676
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ABORTED", INT2FIX(PQ_PIPELINE_ABORTED));
677
+ #endif
678
+
648
679
  /* Invalid OID constant */
649
680
  rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
650
681
  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 ));