pg 1.2.3 → 1.4.4

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 (110) 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 +131 -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 +209 -7
  16. data/Manifest.txt +0 -1
  17. data/README.rdoc +31 -11
  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 -29
  29. data/ext/pg.h +20 -1
  30. data/ext/pg_binary_decoder.c +1 -1
  31. data/ext/pg_binary_encoder.c +1 -1
  32. data/ext/pg_coder.c +83 -29
  33. data/ext/pg_connection.c +856 -656
  34. data/ext/pg_copy_coder.c +46 -17
  35. data/ext/pg_errors.c +1 -1
  36. data/ext/pg_record_coder.c +46 -16
  37. data/ext/pg_result.c +88 -49
  38. data/ext/pg_text_decoder.c +2 -2
  39. data/ext/pg_text_encoder.c +7 -7
  40. data/ext/pg_tuple.c +50 -30
  41. data/ext/pg_type_map.c +42 -9
  42. data/ext/pg_type_map_all_strings.c +16 -2
  43. data/ext/pg_type_map_by_class.c +50 -25
  44. data/ext/pg_type_map_by_column.c +68 -30
  45. data/ext/pg_type_map_by_mri_type.c +48 -19
  46. data/ext/pg_type_map_by_oid.c +53 -24
  47. data/ext/pg_type_map_in_ruby.c +51 -20
  48. data/ext/pg_util.c +2 -2
  49. data/lib/pg/basic_type_map_based_on_result.rb +47 -0
  50. data/lib/pg/basic_type_map_for_queries.rb +193 -0
  51. data/lib/pg/basic_type_map_for_results.rb +81 -0
  52. data/lib/pg/basic_type_registry.rb +301 -0
  53. data/lib/pg/coder.rb +1 -1
  54. data/lib/pg/connection.rb +655 -69
  55. data/lib/pg/exceptions.rb +7 -1
  56. data/lib/pg/version.rb +4 -0
  57. data/lib/pg.rb +47 -32
  58. data/misc/openssl-pg-segfault.rb +31 -0
  59. data/misc/postgres/History.txt +9 -0
  60. data/misc/postgres/Manifest.txt +5 -0
  61. data/misc/postgres/README.txt +21 -0
  62. data/misc/postgres/Rakefile +21 -0
  63. data/misc/postgres/lib/postgres.rb +16 -0
  64. data/misc/ruby-pg/History.txt +9 -0
  65. data/misc/ruby-pg/Manifest.txt +5 -0
  66. data/misc/ruby-pg/README.txt +21 -0
  67. data/misc/ruby-pg/Rakefile +21 -0
  68. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  69. data/pg.gemspec +32 -0
  70. data/rakelib/task_extension.rb +46 -0
  71. data/sample/array_insert.rb +20 -0
  72. data/sample/async_api.rb +102 -0
  73. data/sample/async_copyto.rb +39 -0
  74. data/sample/async_mixed.rb +56 -0
  75. data/sample/check_conn.rb +21 -0
  76. data/sample/copydata.rb +71 -0
  77. data/sample/copyfrom.rb +81 -0
  78. data/sample/copyto.rb +19 -0
  79. data/sample/cursor.rb +21 -0
  80. data/sample/disk_usage_report.rb +177 -0
  81. data/sample/issue-119.rb +94 -0
  82. data/sample/losample.rb +69 -0
  83. data/sample/minimal-testcase.rb +17 -0
  84. data/sample/notify_wait.rb +72 -0
  85. data/sample/pg_statistics.rb +285 -0
  86. data/sample/replication_monitor.rb +222 -0
  87. data/sample/test_binary_values.rb +33 -0
  88. data/sample/wal_shipper.rb +434 -0
  89. data/sample/warehouse_partitions.rb +311 -0
  90. data.tar.gz.sig +0 -0
  91. metadata +81 -224
  92. metadata.gz.sig +0 -0
  93. data/ChangeLog +0 -0
  94. data/lib/pg/basic_type_mapping.rb +0 -522
  95. data/spec/data/expected_trace.out +0 -26
  96. data/spec/data/random_binary_data +0 -0
  97. data/spec/helpers.rb +0 -380
  98. data/spec/pg/basic_type_mapping_spec.rb +0 -630
  99. data/spec/pg/connection_spec.rb +0 -1949
  100. data/spec/pg/connection_sync_spec.rb +0 -41
  101. data/spec/pg/result_spec.rb +0 -681
  102. data/spec/pg/tuple_spec.rb +0 -333
  103. data/spec/pg/type_map_by_class_spec.rb +0 -138
  104. data/spec/pg/type_map_by_column_spec.rb +0 -226
  105. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  106. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  107. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  108. data/spec/pg/type_map_spec.rb +0 -22
  109. data/spec/pg/type_spec.rb +0 -1123
  110. data/spec/pg_spec.rb +0 -50
@@ -0,0 +1,26 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIETTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yMjAyMTQxMzMwNTZaFw0yMzAy
4
+ MTQxMzMwNTZaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
5
+ PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
6
+ mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
7
+ eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
8
+ 8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
9
+ SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
10
+ JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
11
+ eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
12
+ chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
13
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjgYEwfzAJ
14
+ BgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUOIdbSMr3VFrTCO9/cTM0
15
+ 0exHzBcwIgYDVR0RBBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwIgYDVR0S
16
+ BBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwDQYJKoZIhvcNAQELBQADggGB
17
+ AFWP7F/y3Oq3NgrqUOnjKOeDaBa7AqNhHS+PZg+C90lnJzMgOs4KKgZYxqSQVSab
18
+ SCEmzIO/StkXY4NpJ4fYLrHemf/fJy1wPyu+fNdp5SEEUwEo+2toRFlzTe4u4LdS
19
+ QC636nPPTMt8H3xz2wf/lUIUeo2Qc95Qt2BQM465ibbG9kmA3c7Sopx6yOabYOAl
20
+ KPRbOSEPiWYcF9Suuz8Gdf8jxEtPlnZiwRvnYJ+IHMq3XQCJWPpMzdDMbtlgHbXE
21
+ vq1zOTLMSYAS0UB3uionR4yo1hLz60odwkCm7qf0o2Ci/5OjtB0a89VuyqRU2vUJ
22
+ QH95WBjDJ6lCCW7J0mrMPnJQSUFTmufsU6jOChvPaCeAzW1YwrsP/YKnvwueG7ip
23
+ VOdW6RitjtFxhS7evRL0201+KUvLz12zZWWjOcujlQs64QprxOtiv/MiisKb1Ng+
24
+ oL1mUdzB8KrZL4/WbG5YNX6UTtJbIOu9qEFbBAy4/jtIkJX+dlNoFwd4GXQW1YNO
25
+ nA==
26
+ -----END CERTIFICATE-----
data/ext/errorcodes.def CHANGED
@@ -306,6 +306,10 @@
306
306
  VALUE klass = define_error_class( "DuplicateJsonObjectKeyValue", "22" );
307
307
  register_error_class( "22030", klass );
308
308
  }
309
+ {
310
+ VALUE klass = define_error_class( "InvalidArgumentForSqlJsonDatetimeFunction", "22" );
311
+ register_error_class( "22031", klass );
312
+ }
309
313
  {
310
314
  VALUE klass = define_error_class( "InvalidJsonText", "22" );
311
315
  register_error_class( "22032", klass );
@@ -856,6 +860,10 @@
856
860
  VALUE klass = define_error_class( "DatabaseDropped", "57" );
857
861
  register_error_class( "57P04", klass );
858
862
  }
863
+ {
864
+ VALUE klass = define_error_class( "IdleSessionTimeout", "57" );
865
+ register_error_class( "57P05", klass );
866
+ }
859
867
  {
860
868
  VALUE klass = define_error_class( "SystemError", NULL );
861
869
  register_error_class( "58000", klass );
data/ext/errorcodes.rb CHANGED
File without changes
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
@@ -126,26 +126,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
126
126
  static struct st_table *enc_pg2ruby;
127
127
 
128
128
 
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
129
  /*
150
130
  * Return the given PostgreSQL encoding ID as an rb_encoding.
151
131
  *
@@ -186,10 +166,6 @@ pg_get_pg_encname_as_rb_encoding( const char *pg_encname )
186
166
  return rb_enc_find( pg_enc_pg2ruby_mapping[i][1] );
187
167
  }
188
168
 
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
169
  /* Fallthrough to ASCII-8BIT */
194
170
  return rb_ascii8bit_encoding();
195
171
  }
@@ -376,7 +352,7 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
376
352
  **************************************************************************/
377
353
 
378
354
  void
379
- Init_pg_ext()
355
+ Init_pg_ext(void)
380
356
  {
381
357
  if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
382
358
  /* Set all bits to disable all deprecation warnings. */
@@ -415,14 +391,34 @@ Init_pg_ext()
415
391
  rb_define_const(rb_mPGconstants, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE));
416
392
  /* Waiting for a response from the server. */
417
393
  rb_define_const(rb_mPGconstants, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE));
418
- /* Received authentication; waiting for backend start-up to finish. */
394
+ /* Received authentication; waiting for backend startup. */
419
395
  rb_define_const(rb_mPGconstants, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK));
396
+ /* This state is no longer used. */
397
+ rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
420
398
  /* Negotiating SSL encryption. */
421
399
  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
400
  /* Internal state - PG.connect() needed. */
425
401
  rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
402
+ #if PG_MAJORVERSION_NUM >= 10
403
+ /* Checking if session is read-write. Available since PostgreSQL-10. */
404
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_WRITABLE", INT2FIX(CONNECTION_CHECK_WRITABLE));
405
+ #endif
406
+ #if PG_MAJORVERSION_NUM >= 10
407
+ /* Consuming any extra messages. Available since PostgreSQL-10. */
408
+ rb_define_const(rb_mPGconstants, "CONNECTION_CONSUME", INT2FIX(CONNECTION_CONSUME));
409
+ #endif
410
+ #if PG_MAJORVERSION_NUM >= 12
411
+ /* Negotiating GSSAPI. Available since PostgreSQL-12. */
412
+ rb_define_const(rb_mPGconstants, "CONNECTION_GSS_STARTUP", INT2FIX(CONNECTION_GSS_STARTUP));
413
+ #endif
414
+ #if PG_MAJORVERSION_NUM >= 13
415
+ /* Checking target server properties. Available since PostgreSQL-13. */
416
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_TARGET", INT2FIX(CONNECTION_CHECK_TARGET));
417
+ #endif
418
+ #if PG_MAJORVERSION_NUM >= 14
419
+ /* Checking if server is in standby mode. Available since PostgreSQL-14. */
420
+ rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_STANDBY", INT2FIX(CONNECTION_CHECK_STANDBY));
421
+ #endif
426
422
 
427
423
  /****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
428
424
 
@@ -526,6 +522,19 @@ Init_pg_ext()
526
522
  /* Result#result_status constant - Single tuple from larger resultset. */
527
523
  rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
528
524
 
525
+ #ifdef HAVE_PQENTERPIPELINEMODE
526
+ /* Result#result_status constant - The PG::Result represents a synchronization point in pipeline mode, requested by Connection#pipeline_sync.
527
+ *
528
+ * This status occurs only when pipeline mode has been selected. */
529
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_SYNC", INT2FIX(PGRES_PIPELINE_SYNC));
530
+
531
+ /* Result#result_status constant - The PG::Result represents a pipeline that has received an error from the server.
532
+ *
533
+ * 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.
534
+ */
535
+ rb_define_const(rb_mPGconstants, "PGRES_PIPELINE_ABORTED", INT2FIX(PGRES_PIPELINE_ABORTED));
536
+ #endif
537
+
529
538
  /****** Result CONSTANTS: result error field codes ******/
530
539
 
531
540
  /* Result#result_error_field argument constant
@@ -549,7 +558,7 @@ Init_pg_ext()
549
558
  /* Result#result_error_field argument constant
550
559
  *
551
560
  * 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.
561
+ * 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
562
  * For a list of the possible SQLSTATE codes, see Appendix A.
554
563
  * This field is not localizable, and is always present.
555
564
  */
@@ -645,6 +654,27 @@ Init_pg_ext()
645
654
  rb_define_const(rb_mPGconstants, "PG_DIAG_CONSTRAINT_NAME", INT2FIX(PG_DIAG_CONSTRAINT_NAME));
646
655
  #endif
647
656
 
657
+ #ifdef HAVE_PQENTERPIPELINEMODE
658
+ /* Connection#pipeline_status constant
659
+ *
660
+ * The libpq connection is in pipeline mode.
661
+ */
662
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ON", INT2FIX(PQ_PIPELINE_ON));
663
+
664
+ /* Connection#pipeline_status constant
665
+ *
666
+ * The libpq connection is not in pipeline mode.
667
+ */
668
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_OFF", INT2FIX(PQ_PIPELINE_OFF));
669
+
670
+ /* Connection#pipeline_status constant
671
+ *
672
+ * The libpq connection is in pipeline mode and an error occurred while processing the current pipeline.
673
+ * The aborted flag is cleared when PQgetResult returns a result of type PGRES_PIPELINE_SYNC.
674
+ */
675
+ rb_define_const(rb_mPGconstants, "PQ_PIPELINE_ABORTED", INT2FIX(PQ_PIPELINE_ABORTED));
676
+ #endif
677
+
648
678
  /* Invalid OID constant */
649
679
  rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
650
680
  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>
@@ -56,6 +57,7 @@
56
57
  #endif
57
58
 
58
59
  /* PostgreSQL headers */
60
+ #include "pg_config.h"
59
61
  #include "libpq-fe.h"
60
62
  #include "libpq/libpq-fs.h" /* large-object interface */
61
63
  #include "pg_config_manual.h"
@@ -78,6 +80,15 @@ typedef long suseconds_t;
78
80
  #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
79
81
  #endif
80
82
 
83
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
84
+ #define pg_compact_callback(x) (x)
85
+ #define pg_gc_location(x) x = rb_gc_location(x)
86
+ #else
87
+ #define rb_gc_mark_movable(x) rb_gc_mark(x)
88
+ #define pg_compact_callback(x) {(x)}
89
+ #define pg_gc_location(x) UNUSED(x)
90
+ #endif
91
+
81
92
  #define PG_ENC_IDX_BITS 28
82
93
 
83
94
  /* The data behind each PG::Connection object */
@@ -104,6 +115,8 @@ typedef struct {
104
115
  int enc_idx : PG_ENC_IDX_BITS;
105
116
  /* flags controlling Symbol/String field names */
106
117
  unsigned int flags : 2;
118
+ /* enable automatic flushing of send data at the end of send_query calls */
119
+ unsigned int flush_data : 1;
107
120
 
108
121
  #if defined(_WIN32)
109
122
  /* File descriptor to be used for rb_w32_unwrap_io_handle() */
@@ -220,6 +233,8 @@ typedef struct {
220
233
  } convs[0];
221
234
  } t_tmbc;
222
235
 
236
+ extern const rb_data_type_t pg_typemap_type;
237
+ extern const rb_data_type_t pg_coder_type;
223
238
 
224
239
  #include "gvl_wrappers.h"
225
240
 
@@ -304,7 +319,7 @@ VALUE pg_obj_to_i _(( VALUE ));
304
319
  VALUE pg_tmbc_allocate _(( void ));
305
320
  void pg_coder_init_encoder _(( VALUE ));
306
321
  void pg_coder_init_decoder _(( VALUE ));
307
- void pg_coder_mark _(( t_pg_coder * ));
322
+ void pg_coder_compact _(( void * ));
308
323
  char *pg_rb_str_ensure_capa _(( VALUE, long, char *, char ** ));
309
324
 
310
325
  #define PG_RB_STR_ENSURE_CAPA( str, expand_len, curr_ptr, end_ptr ) \
@@ -324,9 +339,13 @@ int pg_typemap_fit_to_copy_get _(( VALUE ));
324
339
  VALUE pg_typemap_result_value _(( t_typemap *, VALUE, int, int ));
325
340
  t_pg_coder *pg_typemap_typecast_query_param _(( t_typemap *, VALUE, int ));
326
341
  VALUE pg_typemap_typecast_copy_get _(( t_typemap *, VALUE, int, int, int ));
342
+ void pg_typemap_mark _(( void * ));
343
+ size_t pg_typemap_memsize _(( const void * ));
344
+ void pg_typemap_compact _(( void * ));
327
345
 
328
346
  PGconn *pg_get_pgconn _(( VALUE ));
329
347
  t_pg_connection *pg_get_connection _(( VALUE ));
348
+ VALUE pgconn_block _(( int, VALUE *, VALUE ));
330
349
 
331
350
  VALUE pg_new_result _(( PGresult *, VALUE ));
332
351
  VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
@@ -205,7 +205,7 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
205
205
  */
206
206
 
207
207
  void
208
- init_pg_binary_decoder()
208
+ init_pg_binary_decoder(void)
209
209
  {
210
210
  /* This module encapsulates all decoder classes with binary input format */
211
211
  rb_mPG_BinaryDecoder = rb_define_module_under( rb_mPG, "BinaryDecoder" );
@@ -139,7 +139,7 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
139
139
  }
140
140
 
141
141
  void
142
- init_pg_binary_encoder()
142
+ init_pg_binary_encoder(void)
143
143
  {
144
144
  /* This module encapsulates all encoder classes with binary output format */
145
145
  rb_mPG_BinaryEncoder = rb_define_module_under( rb_mPG, "BinaryEncoder" );