pg 1.2.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
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" );