pg 1.4.4 → 1.5.9

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 (77) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Gemfile +6 -0
  4. data/{History.rdoc → History.md} +303 -151
  5. data/README.ja.md +300 -0
  6. data/README.md +286 -0
  7. data/Rakefile +16 -4
  8. data/Rakefile.cross +15 -14
  9. data/certs/kanis@comcard.de.pem +20 -0
  10. data/certs/larskanis-2023.pem +24 -0
  11. data/certs/larskanis-2024.pem +24 -0
  12. data/ext/errorcodes.def +8 -5
  13. data/ext/errorcodes.txt +3 -5
  14. data/ext/extconf.rb +7 -0
  15. data/ext/pg.c +15 -30
  16. data/ext/pg.h +10 -6
  17. data/ext/pg_binary_decoder.c +81 -0
  18. data/ext/pg_binary_encoder.c +224 -0
  19. data/ext/pg_coder.c +16 -7
  20. data/ext/pg_connection.c +220 -82
  21. data/ext/pg_copy_coder.c +315 -22
  22. data/ext/pg_record_coder.c +11 -10
  23. data/ext/pg_result.c +93 -19
  24. data/ext/pg_text_decoder.c +31 -10
  25. data/ext/pg_text_encoder.c +38 -19
  26. data/ext/pg_tuple.c +34 -31
  27. data/ext/pg_type_map.c +3 -2
  28. data/ext/pg_type_map_all_strings.c +2 -2
  29. data/ext/pg_type_map_by_class.c +5 -3
  30. data/ext/pg_type_map_by_column.c +7 -3
  31. data/ext/pg_type_map_by_oid.c +7 -4
  32. data/ext/pg_type_map_in_ruby.c +5 -2
  33. data/lib/pg/basic_type_map_based_on_result.rb +21 -1
  34. data/lib/pg/basic_type_map_for_queries.rb +19 -10
  35. data/lib/pg/basic_type_map_for_results.rb +26 -3
  36. data/lib/pg/basic_type_registry.rb +44 -34
  37. data/lib/pg/binary_decoder/date.rb +9 -0
  38. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  39. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  40. data/lib/pg/coder.rb +15 -13
  41. data/lib/pg/connection.rb +158 -64
  42. data/lib/pg/exceptions.rb +13 -0
  43. data/lib/pg/text_decoder/date.rb +21 -0
  44. data/lib/pg/text_decoder/inet.rb +9 -0
  45. data/lib/pg/text_decoder/json.rb +17 -0
  46. data/lib/pg/text_decoder/numeric.rb +9 -0
  47. data/lib/pg/text_decoder/timestamp.rb +30 -0
  48. data/lib/pg/text_encoder/date.rb +13 -0
  49. data/lib/pg/text_encoder/inet.rb +31 -0
  50. data/lib/pg/text_encoder/json.rb +17 -0
  51. data/lib/pg/text_encoder/numeric.rb +9 -0
  52. data/lib/pg/text_encoder/timestamp.rb +24 -0
  53. data/lib/pg/version.rb +1 -1
  54. data/lib/pg.rb +65 -15
  55. data/pg.gemspec +7 -3
  56. data/rakelib/task_extension.rb +1 -1
  57. data.tar.gz.sig +2 -4
  58. metadata +104 -46
  59. metadata.gz.sig +0 -0
  60. data/.appveyor.yml +0 -36
  61. data/.gems +0 -6
  62. data/.gemtest +0 -0
  63. data/.github/workflows/binary-gems.yml +0 -86
  64. data/.github/workflows/source-gem.yml +0 -131
  65. data/.gitignore +0 -13
  66. data/.hgsigs +0 -34
  67. data/.hgtags +0 -41
  68. data/.irbrc +0 -23
  69. data/.pryrc +0 -23
  70. data/.tm_properties +0 -21
  71. data/.travis.yml +0 -49
  72. data/README.ja.rdoc +0 -13
  73. data/README.rdoc +0 -233
  74. data/lib/pg/binary_decoder.rb +0 -23
  75. data/lib/pg/constants.rb +0 -12
  76. data/lib/pg/text_decoder.rb +0 -46
  77. data/lib/pg/text_encoder.rb +0 -59
data/Rakefile.cross CHANGED
@@ -31,8 +31,8 @@ class CrossLibrary < OpenStruct
31
31
  self.host_platform = toolchain
32
32
 
33
33
  # Cross-compilation constants
34
- self.openssl_version = ENV['OPENSSL_VERSION'] || '1.1.1q'
35
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '14.5'
34
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '3.4.0'
35
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '17.0'
36
36
 
37
37
  # Check if symlinks work in the current working directory.
38
38
  # This fails, if rake-compiler-dock is running on a Windows box.
@@ -52,9 +52,8 @@ class CrossLibrary < OpenStruct
52
52
 
53
53
  # Static OpenSSL build vars
54
54
  self.static_openssl_builddir = static_builddir + "openssl-#{openssl_version}"
55
-
56
55
  self.openssl_source_uri =
57
- URI( "http://www.openssl.org/source/openssl-#{openssl_version}.tar.gz" )
56
+ URI( "https://github.com/openssl/openssl/releases/download/openssl-#{openssl_version}/openssl-#{openssl_version}.tar.gz" )
58
57
  self.openssl_tarball = static_sourcesdir + File.basename( openssl_source_uri.path )
59
58
  self.openssl_makefile = static_openssl_builddir + 'Makefile'
60
59
 
@@ -119,7 +118,7 @@ class CrossLibrary < OpenStruct
119
118
  self.cmd_prelude = [
120
119
  "env",
121
120
  "CROSS_COMPILE=#{host_platform}-",
122
- "CFLAGS=-DDSO_WIN32",
121
+ "CFLAGS=-DDSO_WIN32 -DOPENSSL_THREADS",
123
122
  ]
124
123
 
125
124
 
@@ -127,7 +126,7 @@ class CrossLibrary < OpenStruct
127
126
  file openssl_makefile => static_openssl_builddir do |t|
128
127
  chdir( static_openssl_builddir ) do
129
128
  cmd = cmd_prelude.dup
130
- cmd << "./Configure" << openssl_config
129
+ cmd << "./Configure" << "threads" << "-static" << openssl_config
131
130
 
132
131
  run( *cmd )
133
132
  end
@@ -146,14 +145,10 @@ class CrossLibrary < OpenStruct
146
145
  end
147
146
 
148
147
  desc "compile static #{libssl}"
149
- file libssl => "compile_static_openssl:#{for_platform}" do |t|
150
- rm t.name.gsub(/\.a$/, ".dll.a")
151
- end
148
+ file libssl => "compile_static_openssl:#{for_platform}"
152
149
 
153
150
  desc "compile static #{libcrypto}"
154
- file libcrypto => "compile_static_openssl:#{for_platform}" do |t|
155
- rm t.name.gsub(/\.a$/, ".dll.a")
156
- end
151
+ file libcrypto => "compile_static_openssl:#{for_platform}"
157
152
 
158
153
 
159
154
 
@@ -188,6 +183,7 @@ class CrossLibrary < OpenStruct
188
183
  "--host=#{host_platform}",
189
184
  '--with-openssl',
190
185
  '--without-zlib',
186
+ '--without-icu',
191
187
  ]
192
188
 
193
189
  chdir( static_postgresql_builddir ) do
@@ -196,7 +192,7 @@ class CrossLibrary < OpenStruct
196
192
  cmd << "CFLAGS=-L#{static_openssl_builddir}"
197
193
  cmd << "LDFLAGS=-L#{static_openssl_builddir}"
198
194
  cmd << "LDFLAGS_SL=-L#{static_openssl_builddir}"
199
- cmd << "LIBS=-lwsock32 -lgdi32 -lws2_32"
195
+ cmd << "LIBS=-lssl -lwsock32 -lgdi32 -lws2_32 -lcrypt32"
200
196
  cmd << "CPPFLAGS=-I#{static_openssl_builddir}/include"
201
197
 
202
198
  run( *cmd )
@@ -210,6 +206,10 @@ class CrossLibrary < OpenStruct
210
206
  chdir( static_postgresql_srcdir + "common" ) do
211
207
  sh 'make', "-j#{NUM_CPUS}"
212
208
  end
209
+ # Work around missing dependency to errorcodes.h in PostgreSQL-17.0
210
+ chdir( static_postgresql_srcdir + "backend" + "utils" ) do
211
+ sh 'make', "-j#{NUM_CPUS}"
212
+ end
213
213
  chdir( static_postgresql_srcdir + "port" ) do
214
214
  sh 'make', "-j#{NUM_CPUS}"
215
215
  end
@@ -293,8 +293,9 @@ CrossLibraries.each do |xlib|
293
293
  task "gem:windows:#{platform}" => ['gem:windows:prepare', xlib.openssl_tarball, xlib.postgresql_tarball] do
294
294
  RakeCompilerDock.sh <<-EOT, platform: platform
295
295
  (cp build/gem/gem-*.pem ~/.gem/ || true) &&
296
+ sudo apt-get update && sudo apt-get install -y bison flex &&
296
297
  bundle install --local &&
297
- rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKE="make -j`nproc`" RUBY_CC_VERSION=3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
298
+ rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEOPTS=-j`nproc` RUBY_CC_VERSION=3.3.0:3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
298
299
  EOT
299
300
  end
300
301
  desc "Build the windows binary gems"
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDLjCCAhagAwIBAgIBCzANBgkqhkiG9w0BAQsFADA9MQ4wDAYDVQQDDAVrYW5p
3
+ czEXMBUGCgmSJomT8ixkARkWB2NvbWNhcmQxEjAQBgoJkiaJk/IsZAEZFgJkZTAe
4
+ Fw0yMzA0MjgwOTI0NDhaFw0yNDA0MjcwOTI0NDhaMD0xDjAMBgNVBAMMBWthbmlz
5
+ MRcwFQYKCZImiZPyLGQBGRYHY29tY2FyZDESMBAGCgmSJomT8ixkARkWAmRlMIIB
6
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApop+rNmg35bzRugZ21VMGqI6
7
+ HGzPLO4VHYncWn/xmgPU/ZMcZdfj6MzIaZJ/czXyt4eHpBk1r8QOV3gBXnRXEjVW
8
+ 9xi+EdVOkTV2/AVFKThcbTAQGiF/bT1n2M+B1GTybRzMg6hyhOJeGPqIhLfJEpxn
9
+ lJi4+ENAVT4MpqHEAGB8yFoPC0GqiOHQsdHxQV3P3c2OZqG+yJey74QtwA2tLcLn
10
+ Q53c63+VLGsOjODl1yPn/2ejyq8qWu6ahfTxiIlSar2UbwtaQGBDFdb2CXgEufXT
11
+ L7oaPxlmj+Q2oLOfOnInd2Oxop59HoJCQPsg8f921J43NCQGA8VHK6paxIRDLQID
12
+ AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUvgTdT7fe
13
+ x17ugO3IOsjEJwW7KP4wDQYJKoZIhvcNAQELBQADggEBACAxNXwfMGG7paZjnG/c
14
+ smdi/ocW2GmCNtILaSzDZqlD5LoA68MiO7u5vwWyBaDJ6giUB330VJoGRbWMxvxN
15
+ JU6Bnwa4yYp9YtF91wYIi7FXwIrCPKd9bk3bf4M5wECdsv+zvVceq2zRXqD7fci8
16
+ 1LRG8ort/f4TgaT7B4aNwOaabA2UT6u0FGeglqxLkhir86MY3QQyBfJZUoTKWGkz
17
+ S9a7GXsYpe+8HMOaE4+SZp8SORKPgATND5m/4VdzuO59VXjE5UP7QpXigbxAt7H7
18
+ ciK5Du2ZDhowmWzZwNzR7VvVmfAK6RQJlRB03VkkQRWGld5yApOrYDne6WbD8kE0
19
+ uM8=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEBDCCAmygAwIBAgIBAjANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yMzAyMTUxNzQxMTVaFw0yNDAy
4
+ MTUxNzQxMTVaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
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
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
14
+ A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
15
+ 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAQAcuTARfiiVUVx5KURICfdTM2Kd7LhOn
16
+ qt3Vs4ANGvT226LEp3RnQ+kWGQYMRb3cw3LY2TNQRPlnZxE994mgjBscN4fbjXqO
17
+ T0JbVpeszRZa5k1goggbnWT7CO7yU7WcHh13DaSubY7HUpAJn2xz9w2stxQfN/EE
18
+ VMlnDJ1P7mUHAvpK8X9j9h7Xlc1niViT18MYwux8mboVTryrLr+clATUkkM3yBF0
19
+ RV+c34ReW5eXO9Tr6aKTxh/pFC9ggDT6jOxuJgSvG8HWJzVf4NDvMavIas4KYjiI
20
+ BU6CpWaG5NxicqL3BERi52U43HV08br+LNVpb7Rekgve/PJuSFnAR015bhSRXe5U
21
+ vBioD1qW2ZW9tXg8Ww2IfDaO5a1So5Xby51rhNlyo6ATj2NkuLWZUKPKHhAz0TKm
22
+ Dzx/gFSOrRoCt2mXNgrmcAfr386AfaMvCh7cXqdxZwmVo7ILZCYXck0pajvubsDd
23
+ NUIIFkVXvd1odFyK9LF1RFAtxn/iAmpx
24
+ -----END CERTIFICATE-----
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDAyMjgxOTMxNDdaFw0yNTAy
4
+ MjcxOTMxNDdaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
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
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
14
+ A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
15
+ 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEArBmHSfnUyNWf3R1Fx0mMHloWGdcKn2D2
16
+ BsqTApXU2nADiyppIqRq4b9e7hw342uzadSLkoQcEFOxThLRhAcijoWfQVBcsbV/
17
+ ZsCY1qlUTIJuSWxaSyS4efUX+N4eMNyPM9oW/sphlWFo0DgI34Y9WB6HDzH+O71y
18
+ R7PARke3f4kYnRJf5yRQLPDrH9UYt9KlBQm6l7XMtr5EMnQt0EfcmZEi9H4t/vS2
19
+ haxvpFMdAKo4H46GBYNO96r6b74t++vgQSBTg/AFVwvRZwNSrPPcBfb4xxeEAhRR
20
+ x+LU7feIH7lZ//3buiyD03gLAEtHXai0Y+/VfuWIpwYJAl2BO/tU7FS/dtbJq9oc
21
+ dI36Yyzy+BrCM0WT4oCsagePNb97FaNhl4F6sM5JEPT0ZPxRx0i3G4TNNIYziVos
22
+ 5wFER6XhvvLDFAMh/jMg+s7Wd5SbSHgHNSUaUGVtdWkVPOer6oF0aLdZUR3CETkn
23
+ 5nWXZma/BUd3YgYA/Xumc6QQqIS4p7mr
24
+ -----END CERTIFICATE-----
data/ext/errorcodes.def CHANGED
@@ -366,6 +366,10 @@
366
366
  VALUE klass = define_error_class( "SqlJsonScalarRequired", "22" );
367
367
  register_error_class( "2203F", klass );
368
368
  }
369
+ {
370
+ VALUE klass = define_error_class( "SqlJsonItemCannotBeCastToTargetType", "22" );
371
+ register_error_class( "2203G", klass );
372
+ }
369
373
  {
370
374
  VALUE klass = define_error_class( "IntegrityConstraintViolation", NULL );
371
375
  register_error_class( "23000", klass );
@@ -449,6 +453,10 @@
449
453
  VALUE klass = define_error_class( "IdleInTransactionSessionTimeout", "25" );
450
454
  register_error_class( "25P03", klass );
451
455
  }
456
+ {
457
+ VALUE klass = define_error_class( "TransactionTimeout", "25" );
458
+ register_error_class( "25P04", klass );
459
+ }
452
460
  {
453
461
  VALUE klass = define_error_class( "InvalidSqlStatementName", NULL );
454
462
  register_error_class( "26000", klass );
@@ -881,11 +889,6 @@
881
889
  VALUE klass = define_error_class( "DuplicateFile", "58" );
882
890
  register_error_class( "58P02", klass );
883
891
  }
884
- {
885
- VALUE klass = define_error_class( "SnapshotTooOld", NULL );
886
- register_error_class( "72000", klass );
887
- register_error_class( "72", klass );
888
- }
889
892
  {
890
893
  VALUE klass = define_error_class( "ConfigFileError", NULL );
891
894
  register_error_class( "F0000", klass );
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2021, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2024, 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
@@ -222,6 +222,7 @@ Section: Class 22 - Data Exception
222
222
  2203D E ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS too_many_json_array_elements
223
223
  2203E E ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS too_many_json_object_members
224
224
  2203F E ERRCODE_SQL_JSON_SCALAR_REQUIRED sql_json_scalar_required
225
+ 2203G E ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE sql_json_item_cannot_be_cast_to_target_type
225
226
 
226
227
  Section: Class 23 - Integrity Constraint Violation
227
228
 
@@ -251,6 +252,7 @@ Section: Class 25 - Invalid Transaction State
251
252
  25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction
252
253
  25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction
253
254
  25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout
255
+ 25P04 E ERRCODE_TRANSACTION_TIMEOUT transaction_timeout
254
256
 
255
257
  Section: Class 26 - Invalid SQL Statement Name
256
258
 
@@ -438,10 +440,6 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
438
440
  58P01 E ERRCODE_UNDEFINED_FILE undefined_file
439
441
  58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
440
442
 
441
- Section: Class 72 - Snapshot Failure
442
- # (class borrowed from Oracle)
443
- 72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old
444
-
445
443
  Section: Class F0 - Configuration File Error
446
444
 
447
445
  # (PostgreSQL-specific error class)
data/ext/extconf.rb CHANGED
@@ -9,6 +9,8 @@ if ENV['MAINTAINER_MODE']
9
9
  ' -ggdb' <<
10
10
  ' -DDEBUG' <<
11
11
  ' -pedantic'
12
+ $LDFLAGS <<
13
+ ' -ggdb'
12
14
  end
13
15
 
14
16
  if pgdir = with_config( 'pg' )
@@ -60,6 +62,10 @@ else
60
62
  if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
61
63
  append_ldflags "-Wl,-rpath,#{dlldir.quote}"
62
64
  end
65
+
66
+ if /mswin/ =~ RUBY_PLATFORM
67
+ $libs = append_library($libs, 'ws2_32')
68
+ end
63
69
  end
64
70
 
65
71
  $stderr.puts "Using libpq from #{dlldir}"
@@ -154,6 +160,7 @@ have_func 'timegm'
154
160
  have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
155
161
  have_func 'rb_gc_mark_movable' # since ruby-2.7
156
162
  have_func 'rb_io_wait' # since ruby-3.0
163
+ have_func 'rb_io_descriptor' # since ruby-3.1
157
164
 
158
165
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
159
166
  have_header 'unistd.h'
data/ext/pg.c CHANGED
@@ -33,7 +33,6 @@
33
33
  *
34
34
  * - PQfreemem -- unnecessary: copied to ruby object, then freed. Ruby object's
35
35
  * memory is freed when it is garbage collected.
36
- * - PQbinaryTuples -- better to use PQfformat
37
36
  * - PQprint -- not very useful
38
37
  * - PQsetdb -- not very useful
39
38
  * - PQoidStatus -- deprecated, use PQoidValue
@@ -74,6 +73,7 @@ VALUE rb_mPGconstants;
74
73
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
75
74
  */
76
75
  const char * const (pg_enc_pg2ruby_mapping[][2]) = {
76
+ {"UTF8", "UTF-8" },
77
77
  {"BIG5", "Big5" },
78
78
  {"EUC_CN", "GB2312" },
79
79
  {"EUC_JP", "EUC-JP" },
@@ -105,7 +105,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
105
105
  {"SHIFT_JIS_2004","Windows-31J" },
106
106
  /* {"SQL_ASCII", NULL }, special case*/
107
107
  {"UHC", "CP949" },
108
- {"UTF8", "UTF-8" },
109
108
  {"WIN866", "IBM866" },
110
109
  {"WIN874", "Windows-874" },
111
110
  {"WIN1250", "Windows-1250"},
@@ -120,36 +119,17 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
120
119
  };
121
120
 
122
121
 
123
- /*
124
- * A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s.
125
- */
126
- static struct st_table *enc_pg2ruby;
127
-
128
-
129
122
  /*
130
123
  * Return the given PostgreSQL encoding ID as an rb_encoding.
131
124
  *
132
125
  * - returns NULL if the client encoding is 'SQL_ASCII'.
133
126
  * - returns ASCII-8BIT if the client encoding is unknown.
134
127
  */
135
- rb_encoding *
128
+ static rb_encoding *
136
129
  pg_get_pg_encoding_as_rb_encoding( int enc_id )
137
130
  {
138
- rb_encoding *enc;
139
-
140
- /* Use the cached value if it exists */
141
- if ( st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc) ) {
142
- return enc;
143
- }
144
- else {
145
- const char *name = pg_encoding_to_char( enc_id );
146
-
147
- enc = pg_get_pg_encname_as_rb_encoding( name );
148
- st_insert( enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc );
149
-
150
- return enc;
151
- }
152
-
131
+ const char *name = pg_encoding_to_char( enc_id );
132
+ return pg_get_pg_encname_as_rb_encoding( name );
153
133
  }
154
134
 
155
135
  /*
@@ -354,6 +334,11 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
354
334
  void
355
335
  Init_pg_ext(void)
356
336
  {
337
+
338
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
339
+ rb_ext_ractor_safe(PQisthreadsafe());
340
+ #endif
341
+
357
342
  if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
358
343
  /* Set all bits to disable all deprecation warnings. */
359
344
  pg_skip_deprecation_warning = 0xFFFF;
@@ -372,8 +357,8 @@ Init_pg_ext(void)
372
357
  SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
373
358
  SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
374
359
 
375
- rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
376
- rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
360
+ rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
361
+ rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
377
362
 
378
363
 
379
364
  /****** PG::Connection CLASS CONSTANTS: Connection Status ******/
@@ -558,7 +543,7 @@ Init_pg_ext(void)
558
543
  /* Result#result_error_field argument constant
559
544
  *
560
545
  * The SQLSTATE code for the 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.
546
+ * The SQLSTATE code identifies 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.
562
547
  * For a list of the possible SQLSTATE codes, see Appendix A.
563
548
  * This field is not localizable, and is always present.
564
549
  */
@@ -679,11 +664,12 @@ Init_pg_ext(void)
679
664
  rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
680
665
  rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid));
681
666
 
667
+ /* PostgreSQL compiled in default port */
668
+ rb_define_const(rb_mPGconstants, "DEF_PGPORT", INT2FIX(DEF_PGPORT));
669
+
682
670
  /* Add the constants to the toplevel namespace */
683
671
  rb_include_module( rb_mPG, rb_mPGconstants );
684
672
 
685
- enc_pg2ruby = st_init_numtable();
686
-
687
673
  /* Initialize the main extension classes */
688
674
  init_pg_connection();
689
675
  init_pg_result();
@@ -704,4 +690,3 @@ Init_pg_ext(void)
704
690
  init_pg_recordcoder();
705
691
  init_pg_tuple();
706
692
  }
707
-
data/ext/pg.h CHANGED
@@ -76,10 +76,6 @@ typedef long suseconds_t;
76
76
  #define PG_MAX_COLUMNS 4000
77
77
  #endif
78
78
 
79
- #ifndef RARRAY_AREF
80
- #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
81
- #endif
82
-
83
79
  #ifdef HAVE_RB_GC_MARK_MOVABLE
84
80
  #define pg_compact_callback(x) (x)
85
81
  #define pg_gc_location(x) x = rb_gc_location(x)
@@ -89,6 +85,12 @@ typedef long suseconds_t;
89
85
  #define pg_gc_location(x) UNUSED(x)
90
86
  #endif
91
87
 
88
+ /* For compatibility with ruby < 3.0 */
89
+ #ifndef RUBY_TYPED_FROZEN_SHAREABLE
90
+ #define PG_RUBY_TYPED_FROZEN_SHAREABLE 0
91
+ #else
92
+ #define PG_RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
93
+ #endif
92
94
  #define PG_ENC_IDX_BITS 28
93
95
 
94
96
  /* The data behind each PG::Connection object */
@@ -97,6 +99,9 @@ typedef struct {
97
99
 
98
100
  /* Cached IO object for the socket descriptor */
99
101
  VALUE socket_io;
102
+ /* function pointers of the original libpq notice receivers */
103
+ PQnoticeReceiver default_notice_receiver;
104
+ PQnoticeProcessor default_notice_processor;
100
105
  /* Proc object that receives notices as PG::Result objects */
101
106
  VALUE notice_receiver;
102
107
  /* Proc object that receives notices as String objects */
@@ -314,7 +319,7 @@ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, c
314
319
  int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
315
320
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
316
321
  t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
317
- void pg_define_coder _(( const char *, void *, VALUE, VALUE ));
322
+ VALUE pg_define_coder _(( const char *, void *, VALUE, VALUE ));
318
323
  VALUE pg_obj_to_i _(( VALUE ));
319
324
  VALUE pg_tmbc_allocate _(( void ));
320
325
  void pg_coder_init_encoder _(( VALUE ));
@@ -364,7 +369,6 @@ pgresult_get_this( VALUE self )
364
369
  }
365
370
 
366
371
 
367
- rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
368
372
  rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
369
373
  const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
370
374
  rb_encoding *pg_conn_enc_get _(( PGconn * ));
@@ -12,6 +12,8 @@
12
12
  #endif
13
13
 
14
14
  VALUE rb_mPG_BinaryDecoder;
15
+ static VALUE s_Date;
16
+ static ID s_id_new;
15
17
 
16
18
 
17
19
  /*
@@ -195,6 +197,84 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
195
197
  }
196
198
  }
197
199
 
200
+ #define PG_INT32_MIN (-0x7FFFFFFF-1)
201
+ #define PG_INT32_MAX (0x7FFFFFFF)
202
+ #define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
203
+ #define MONTHS_PER_YEAR 12
204
+
205
+ /* taken from PostgreSQL sources at src/backend/utils/adt/datetime.c */
206
+ void
207
+ j2date(int jd, int *year, int *month, int *day)
208
+ {
209
+ unsigned int julian;
210
+ unsigned int quad;
211
+ unsigned int extra;
212
+ int y;
213
+
214
+ julian = jd;
215
+ julian += 32044;
216
+ quad = julian / 146097;
217
+ extra = (julian - quad * 146097) * 4 + 3;
218
+ julian += 60 + quad * 3 + extra / 146097;
219
+ quad = julian / 1461;
220
+ julian -= quad * 1461;
221
+ y = julian * 4 / 1461;
222
+ julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
223
+ + 123;
224
+ y += quad * 4;
225
+ *year = y - 4800;
226
+ quad = julian * 2141 / 65536;
227
+ *day = julian - 7834 * quad / 256;
228
+ *month = (quad + 10) % MONTHS_PER_YEAR + 1;
229
+ } /* j2date() */
230
+
231
+ /*
232
+ * Document-class: PG::BinaryDecoder::Date < PG::SimpleDecoder
233
+ *
234
+ * This is a decoder class for conversion of PostgreSQL binary date
235
+ * to Ruby Date objects.
236
+ *
237
+ * As soon as this class is used, it requires the ruby standard library 'date'.
238
+ */
239
+ static VALUE
240
+ pg_bin_dec_date(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
241
+ {
242
+ int year, month, day;
243
+ int date;
244
+
245
+ if (len != 4) {
246
+ rb_raise(rb_eTypeError, "unexpected date format != 4 bytes");
247
+ }
248
+
249
+ date = read_nbo32(val);
250
+ switch(date){
251
+ case PG_INT32_MAX:
252
+ return rb_str_new2("infinity");
253
+ case PG_INT32_MIN:
254
+ return rb_str_new2("-infinity");
255
+ default:
256
+ j2date(date + POSTGRES_EPOCH_JDATE, &year, &month, &day);
257
+
258
+ return rb_funcall(s_Date, s_id_new, 3, INT2NUM(year), INT2NUM(month), INT2NUM(day));
259
+ }
260
+ }
261
+
262
+ /* called per autoload when BinaryDecoder::Date is used */
263
+ static VALUE
264
+ init_pg_bin_decoder_date(VALUE rb_mPG_BinaryDecoder)
265
+ {
266
+ rb_require("date");
267
+ s_Date = rb_const_get(rb_cObject, rb_intern("Date"));
268
+ rb_gc_register_mark_object(s_Date);
269
+ s_id_new = rb_intern("new");
270
+
271
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Date", rb_cPG_SimpleDecoder ); */
272
+ pg_define_coder( "Date", pg_bin_dec_date, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
273
+
274
+ return Qnil;
275
+ }
276
+
277
+
198
278
  /*
199
279
  * Document-class: PG::BinaryDecoder::String < PG::SimpleDecoder
200
280
  *
@@ -209,6 +289,7 @@ init_pg_binary_decoder(void)
209
289
  {
210
290
  /* This module encapsulates all decoder classes with binary input format */
211
291
  rb_mPG_BinaryDecoder = rb_define_module_under( rb_mPG, "BinaryDecoder" );
292
+ rb_define_private_method(rb_singleton_class(rb_mPG_BinaryDecoder), "init_date", init_pg_bin_decoder_date, 0);
212
293
 
213
294
  /* Make RDoc aware of the decoder classes... */
214
295
  /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Boolean", rb_cPG_SimpleDecoder ); */