pg 1.0.0 → 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 (126) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Gemfile +20 -0
  4. data/History.md +932 -0
  5. data/Manifest.txt +8 -3
  6. data/README-Windows.rdoc +4 -4
  7. data/README.ja.md +300 -0
  8. data/README.md +286 -0
  9. data/Rakefile +41 -138
  10. data/Rakefile.cross +71 -66
  11. data/certs/ged.pem +24 -0
  12. data/certs/kanis@comcard.de.pem +20 -0
  13. data/certs/larskanis-2022.pem +26 -0
  14. data/certs/larskanis-2023.pem +24 -0
  15. data/certs/larskanis-2024.pem +24 -0
  16. data/ext/errorcodes.def +84 -5
  17. data/ext/errorcodes.rb +1 -1
  18. data/ext/errorcodes.txt +23 -6
  19. data/ext/extconf.rb +109 -25
  20. data/ext/gvl_wrappers.c +4 -0
  21. data/ext/gvl_wrappers.h +23 -0
  22. data/ext/pg.c +213 -155
  23. data/ext/pg.h +89 -23
  24. data/ext/pg_binary_decoder.c +164 -16
  25. data/ext/pg_binary_encoder.c +238 -13
  26. data/ext/pg_coder.c +159 -35
  27. data/ext/pg_connection.c +1584 -967
  28. data/ext/pg_copy_coder.c +373 -43
  29. data/ext/pg_errors.c +1 -1
  30. data/ext/pg_record_coder.c +522 -0
  31. data/ext/pg_result.c +710 -217
  32. data/ext/pg_text_decoder.c +630 -43
  33. data/ext/pg_text_encoder.c +222 -72
  34. data/ext/pg_tuple.c +572 -0
  35. data/ext/pg_type_map.c +45 -11
  36. data/ext/pg_type_map_all_strings.c +21 -7
  37. data/ext/pg_type_map_by_class.c +59 -27
  38. data/ext/pg_type_map_by_column.c +80 -37
  39. data/ext/pg_type_map_by_mri_type.c +49 -20
  40. data/ext/pg_type_map_by_oid.c +62 -29
  41. data/ext/pg_type_map_in_ruby.c +56 -22
  42. data/ext/{util.c → pg_util.c} +12 -12
  43. data/ext/{util.h → pg_util.h} +2 -2
  44. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  45. data/lib/pg/basic_type_map_for_queries.rb +202 -0
  46. data/lib/pg/basic_type_map_for_results.rb +104 -0
  47. data/lib/pg/basic_type_registry.rb +311 -0
  48. data/lib/pg/binary_decoder/date.rb +9 -0
  49. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  50. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  51. data/lib/pg/coder.rb +36 -13
  52. data/lib/pg/connection.rb +769 -70
  53. data/lib/pg/exceptions.rb +22 -2
  54. data/lib/pg/result.rb +14 -2
  55. data/lib/pg/text_decoder/date.rb +21 -0
  56. data/lib/pg/text_decoder/inet.rb +9 -0
  57. data/lib/pg/text_decoder/json.rb +17 -0
  58. data/lib/pg/text_decoder/numeric.rb +9 -0
  59. data/lib/pg/text_decoder/timestamp.rb +30 -0
  60. data/lib/pg/text_encoder/date.rb +13 -0
  61. data/lib/pg/text_encoder/inet.rb +31 -0
  62. data/lib/pg/text_encoder/json.rb +17 -0
  63. data/lib/pg/text_encoder/numeric.rb +9 -0
  64. data/lib/pg/text_encoder/timestamp.rb +24 -0
  65. data/lib/pg/tuple.rb +30 -0
  66. data/lib/pg/type_map_by_column.rb +3 -2
  67. data/lib/pg/version.rb +4 -0
  68. data/lib/pg.rb +106 -39
  69. data/misc/openssl-pg-segfault.rb +31 -0
  70. data/misc/postgres/History.txt +9 -0
  71. data/misc/postgres/Manifest.txt +5 -0
  72. data/misc/postgres/README.txt +21 -0
  73. data/misc/postgres/Rakefile +21 -0
  74. data/misc/postgres/lib/postgres.rb +16 -0
  75. data/misc/ruby-pg/History.txt +9 -0
  76. data/misc/ruby-pg/Manifest.txt +5 -0
  77. data/misc/ruby-pg/README.txt +21 -0
  78. data/misc/ruby-pg/Rakefile +21 -0
  79. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  80. data/pg.gemspec +36 -0
  81. data/rakelib/task_extension.rb +46 -0
  82. data/sample/array_insert.rb +20 -0
  83. data/sample/async_api.rb +102 -0
  84. data/sample/async_copyto.rb +39 -0
  85. data/sample/async_mixed.rb +56 -0
  86. data/sample/check_conn.rb +21 -0
  87. data/sample/copydata.rb +71 -0
  88. data/sample/copyfrom.rb +81 -0
  89. data/sample/copyto.rb +19 -0
  90. data/sample/cursor.rb +21 -0
  91. data/sample/disk_usage_report.rb +177 -0
  92. data/sample/issue-119.rb +94 -0
  93. data/sample/losample.rb +69 -0
  94. data/sample/minimal-testcase.rb +17 -0
  95. data/sample/notify_wait.rb +72 -0
  96. data/sample/pg_statistics.rb +285 -0
  97. data/sample/replication_monitor.rb +222 -0
  98. data/sample/test_binary_values.rb +33 -0
  99. data/sample/wal_shipper.rb +434 -0
  100. data/sample/warehouse_partitions.rb +311 -0
  101. data.tar.gz.sig +0 -0
  102. metadata +138 -223
  103. metadata.gz.sig +0 -0
  104. data/.gemtest +0 -0
  105. data/ChangeLog +0 -6595
  106. data/History.rdoc +0 -422
  107. data/README.ja.rdoc +0 -14
  108. data/README.rdoc +0 -167
  109. data/lib/pg/basic_type_mapping.rb +0 -426
  110. data/lib/pg/constants.rb +0 -11
  111. data/lib/pg/text_decoder.rb +0 -51
  112. data/lib/pg/text_encoder.rb +0 -35
  113. data/spec/data/expected_trace.out +0 -26
  114. data/spec/data/random_binary_data +0 -0
  115. data/spec/helpers.rb +0 -348
  116. data/spec/pg/basic_type_mapping_spec.rb +0 -305
  117. data/spec/pg/connection_spec.rb +0 -1719
  118. data/spec/pg/result_spec.rb +0 -456
  119. data/spec/pg/type_map_by_class_spec.rb +0 -138
  120. data/spec/pg/type_map_by_column_spec.rb +0 -222
  121. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  122. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  123. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  124. data/spec/pg/type_map_spec.rb +0 -22
  125. data/spec/pg/type_spec.rb +0 -777
  126. data/spec/pg_spec.rb +0 -50
data/ext/errorcodes.def CHANGED
@@ -186,6 +186,10 @@
186
186
  VALUE klass = define_error_class( "InvalidParameterValue", "22" );
187
187
  register_error_class( "22023", klass );
188
188
  }
189
+ {
190
+ VALUE klass = define_error_class( "InvalidPrecedingOrFollowingSize", "22" );
191
+ register_error_class( "22013", klass );
192
+ }
189
193
  {
190
194
  VALUE klass = define_error_class( "InvalidRegularExpression", "22" );
191
195
  register_error_class( "2201B", klass );
@@ -298,6 +302,74 @@
298
302
  VALUE klass = define_error_class( "InvalidXmlProcessingInstruction", "22" );
299
303
  register_error_class( "2200T", klass );
300
304
  }
305
+ {
306
+ VALUE klass = define_error_class( "DuplicateJsonObjectKeyValue", "22" );
307
+ register_error_class( "22030", klass );
308
+ }
309
+ {
310
+ VALUE klass = define_error_class( "InvalidArgumentForSqlJsonDatetimeFunction", "22" );
311
+ register_error_class( "22031", klass );
312
+ }
313
+ {
314
+ VALUE klass = define_error_class( "InvalidJsonText", "22" );
315
+ register_error_class( "22032", klass );
316
+ }
317
+ {
318
+ VALUE klass = define_error_class( "InvalidSqlJsonSubscript", "22" );
319
+ register_error_class( "22033", klass );
320
+ }
321
+ {
322
+ VALUE klass = define_error_class( "MoreThanOneSqlJsonItem", "22" );
323
+ register_error_class( "22034", klass );
324
+ }
325
+ {
326
+ VALUE klass = define_error_class( "NoSqlJsonItem", "22" );
327
+ register_error_class( "22035", klass );
328
+ }
329
+ {
330
+ VALUE klass = define_error_class( "NonNumericSqlJsonItem", "22" );
331
+ register_error_class( "22036", klass );
332
+ }
333
+ {
334
+ VALUE klass = define_error_class( "NonUniqueKeysInAJsonObject", "22" );
335
+ register_error_class( "22037", klass );
336
+ }
337
+ {
338
+ VALUE klass = define_error_class( "SingletonSqlJsonItemRequired", "22" );
339
+ register_error_class( "22038", klass );
340
+ }
341
+ {
342
+ VALUE klass = define_error_class( "SqlJsonArrayNotFound", "22" );
343
+ register_error_class( "22039", klass );
344
+ }
345
+ {
346
+ VALUE klass = define_error_class( "SqlJsonMemberNotFound", "22" );
347
+ register_error_class( "2203A", klass );
348
+ }
349
+ {
350
+ VALUE klass = define_error_class( "SqlJsonNumberNotFound", "22" );
351
+ register_error_class( "2203B", klass );
352
+ }
353
+ {
354
+ VALUE klass = define_error_class( "SqlJsonObjectNotFound", "22" );
355
+ register_error_class( "2203C", klass );
356
+ }
357
+ {
358
+ VALUE klass = define_error_class( "TooManyJsonArrayElements", "22" );
359
+ register_error_class( "2203D", klass );
360
+ }
361
+ {
362
+ VALUE klass = define_error_class( "TooManyJsonObjectMembers", "22" );
363
+ register_error_class( "2203E", klass );
364
+ }
365
+ {
366
+ VALUE klass = define_error_class( "SqlJsonScalarRequired", "22" );
367
+ register_error_class( "2203F", klass );
368
+ }
369
+ {
370
+ VALUE klass = define_error_class( "SqlJsonItemCannotBeCastToTargetType", "22" );
371
+ register_error_class( "2203G", klass );
372
+ }
301
373
  {
302
374
  VALUE klass = define_error_class( "IntegrityConstraintViolation", NULL );
303
375
  register_error_class( "23000", klass );
@@ -381,6 +453,10 @@
381
453
  VALUE klass = define_error_class( "IdleInTransactionSessionTimeout", "25" );
382
454
  register_error_class( "25P03", klass );
383
455
  }
456
+ {
457
+ VALUE klass = define_error_class( "TransactionTimeout", "25" );
458
+ register_error_class( "25P04", klass );
459
+ }
384
460
  {
385
461
  VALUE klass = define_error_class( "InvalidSqlStatementName", NULL );
386
462
  register_error_class( "26000", klass );
@@ -763,6 +839,10 @@
763
839
  VALUE klass = define_error_class( "LockNotAvailable", "55" );
764
840
  register_error_class( "55P03", klass );
765
841
  }
842
+ {
843
+ VALUE klass = define_error_class( "UnsafeNewEnumValueUsage", "55" );
844
+ register_error_class( "55P04", klass );
845
+ }
766
846
  {
767
847
  VALUE klass = define_error_class( "OperatorIntervention", NULL );
768
848
  register_error_class( "57000", klass );
@@ -788,6 +868,10 @@
788
868
  VALUE klass = define_error_class( "DatabaseDropped", "57" );
789
869
  register_error_class( "57P04", klass );
790
870
  }
871
+ {
872
+ VALUE klass = define_error_class( "IdleSessionTimeout", "57" );
873
+ register_error_class( "57P05", klass );
874
+ }
791
875
  {
792
876
  VALUE klass = define_error_class( "SystemError", NULL );
793
877
  register_error_class( "58000", klass );
@@ -805,11 +889,6 @@
805
889
  VALUE klass = define_error_class( "DuplicateFile", "58" );
806
890
  register_error_class( "58P02", klass );
807
891
  }
808
- {
809
- VALUE klass = define_error_class( "SnapshotTooOld", NULL );
810
- register_error_class( "72000", klass );
811
- register_error_class( "72", klass );
812
- }
813
892
  {
814
893
  VALUE klass = define_error_class( "ConfigFileError", NULL );
815
894
  register_error_class( "F0000", klass );
data/ext/errorcodes.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
2
 
3
3
  def camelize(lower_case_and_underscored_word)
4
4
  lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2017, 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
@@ -18,7 +18,7 @@
18
18
  # src/pl/tcl/pltclerrcodes.h
19
19
  # the same, for PL/Tcl
20
20
  #
21
- # doc/src/sgml/errcodes-list.sgml
21
+ # doc/src/sgml/errcodes-table.sgml
22
22
  # a SGML table of error codes for inclusion in the documentation
23
23
  #
24
24
  # The format of this file is one error code per line, with the following
@@ -177,6 +177,7 @@ Section: Class 22 - Data Exception
177
177
  22P06 E ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER nonstandard_use_of_escape_character
178
178
  22010 E ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE invalid_indicator_parameter_value
179
179
  22023 E ERRCODE_INVALID_PARAMETER_VALUE invalid_parameter_value
180
+ 22013 E ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE invalid_preceding_or_following_size
180
181
  2201B E ERRCODE_INVALID_REGULAR_EXPRESSION invalid_regular_expression
181
182
  2201W E ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE invalid_row_count_in_limit_clause
182
183
  2201X E ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE invalid_row_count_in_result_offset_clause
@@ -205,6 +206,23 @@ Section: Class 22 - Data Exception
205
206
  2200N E ERRCODE_INVALID_XML_CONTENT invalid_xml_content
206
207
  2200S E ERRCODE_INVALID_XML_COMMENT invalid_xml_comment
207
208
  2200T E ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION invalid_xml_processing_instruction
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
211
+ 22032 E ERRCODE_INVALID_JSON_TEXT invalid_json_text
212
+ 22033 E ERRCODE_INVALID_SQL_JSON_SUBSCRIPT invalid_sql_json_subscript
213
+ 22034 E ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM more_than_one_sql_json_item
214
+ 22035 E ERRCODE_NO_SQL_JSON_ITEM no_sql_json_item
215
+ 22036 E ERRCODE_NON_NUMERIC_SQL_JSON_ITEM non_numeric_sql_json_item
216
+ 22037 E ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT non_unique_keys_in_a_json_object
217
+ 22038 E ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED singleton_sql_json_item_required
218
+ 22039 E ERRCODE_SQL_JSON_ARRAY_NOT_FOUND sql_json_array_not_found
219
+ 2203A E ERRCODE_SQL_JSON_MEMBER_NOT_FOUND sql_json_member_not_found
220
+ 2203B E ERRCODE_SQL_JSON_NUMBER_NOT_FOUND sql_json_number_not_found
221
+ 2203C E ERRCODE_SQL_JSON_OBJECT_NOT_FOUND sql_json_object_not_found
222
+ 2203D E ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS too_many_json_array_elements
223
+ 2203E E ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS too_many_json_object_members
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
208
226
 
209
227
  Section: Class 23 - Integrity Constraint Violation
210
228
 
@@ -234,6 +252,7 @@ Section: Class 25 - Invalid Transaction State
234
252
  25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction
235
253
  25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction
236
254
  25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout
255
+ 25P04 E ERRCODE_TRANSACTION_TIMEOUT transaction_timeout
237
256
 
238
257
  Section: Class 26 - Invalid SQL Statement Name
239
258
 
@@ -400,6 +419,7 @@ Section: Class 55 - Object Not In Prerequisite State
400
419
  55006 E ERRCODE_OBJECT_IN_USE object_in_use
401
420
  55P02 E ERRCODE_CANT_CHANGE_RUNTIME_PARAM cant_change_runtime_param
402
421
  55P03 E ERRCODE_LOCK_NOT_AVAILABLE lock_not_available
422
+ 55P04 E ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE unsafe_new_enum_value_usage
403
423
 
404
424
  Section: Class 57 - Operator Intervention
405
425
 
@@ -410,6 +430,7 @@ Section: Class 57 - Operator Intervention
410
430
  57P02 E ERRCODE_CRASH_SHUTDOWN crash_shutdown
411
431
  57P03 E ERRCODE_CANNOT_CONNECT_NOW cannot_connect_now
412
432
  57P04 E ERRCODE_DATABASE_DROPPED database_dropped
433
+ 57P05 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout
413
434
 
414
435
  Section: Class 58 - System Error (errors external to PostgreSQL itself)
415
436
 
@@ -419,10 +440,6 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
419
440
  58P01 E ERRCODE_UNDEFINED_FILE undefined_file
420
441
  58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
421
442
 
422
- Section: Class 72 - Snapshot Failure
423
- # (class borrowed from Oracle)
424
- 72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old
425
-
426
443
  Section: Class F0 - Configuration File Error
427
444
 
428
445
  # (PostgreSQL-specific error class)
data/ext/extconf.rb CHANGED
@@ -9,12 +9,21 @@ 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' )
15
17
  ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
16
18
  end
17
19
 
20
+ if enable_config("gvl-unlock", true)
21
+ $defs.push( "-DENABLE_GVL_UNLOCK" )
22
+ $stderr.puts "Calling libpq with GVL unlocked"
23
+ else
24
+ $stderr.puts "Calling libpq with GVL locked"
25
+ end
26
+
18
27
  if enable_config("windows-cross")
19
28
  # Avoid dependency to external libgcc.dll on x86-mingw32
20
29
  $LDFLAGS << " -static-libgcc"
@@ -30,35 +39,101 @@ else
30
39
 
31
40
  if pgconfig && pgconfig != 'ignore'
32
41
  $stderr.puts "Using config values from %s" % [ pgconfig ]
33
- incdir = `"#{pgconfig}" --includedir`.chomp
34
- libdir = `"#{pgconfig}" --libdir`.chomp
42
+ incdir = IO.popen([pgconfig, "--includedir"], &:read).chomp
43
+ libdir = IO.popen([pgconfig, "--libdir"], &:read).chomp
35
44
  dir_config 'pg', incdir, libdir
36
45
 
37
- # Try to use runtime path linker option, even if RbConfig doesn't know about it.
38
- # The rpath option is usually set implicit by dir_config(), but so far not
39
- # on MacOS-X.
40
- if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', " -Wl,-rpath,#{libdir}")
41
- $LDFLAGS << " -Wl,-rpath,#{libdir}"
46
+ # Windows traditionally stores DLLs beside executables, not in libdir
47
+ dlldir = RUBY_PLATFORM=~/mingw|mswin/ ? IO.popen([pgconfig, "--bindir"], &:read).chomp : libdir
48
+
49
+ elsif checking_for "libpq per pkg-config" do
50
+ _cflags, ldflags, _libs = pkg_config("libpq")
51
+ dlldir = ldflags && ldflags[/-L([^ ]+)/] && $1
42
52
  end
53
+
43
54
  else
44
- $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
45
- " --with-pg-config=/path/to/pg_config"
46
- dir_config 'pg'
55
+ incdir, libdir = dir_config 'pg'
56
+ dlldir = libdir
57
+ end
58
+
59
+ # Try to use runtime path linker option, even if RbConfig doesn't know about it.
60
+ # The rpath option is usually set implicit by dir_config(), but so far not
61
+ # on MacOS-X.
62
+ if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
63
+ append_ldflags "-Wl,-rpath,#{dlldir.quote}"
64
+ end
65
+
66
+ if /mswin/ =~ RUBY_PLATFORM
67
+ $libs = append_library($libs, 'ws2_32')
47
68
  end
48
69
  end
49
70
 
71
+ $stderr.puts "Using libpq from #{dlldir}"
72
+
73
+ File.write("postgresql_lib_path.rb", <<-EOT)
74
+ module PG
75
+ POSTGRESQL_LIB_PATH = #{dlldir.inspect}
76
+ end
77
+ EOT
78
+ $INSTALLFILES = {
79
+ "./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
80
+ }
81
+
50
82
  if RUBY_VERSION >= '2.3.0' && /solaris/ =~ RUBY_PLATFORM
51
83
  append_cppflags( '-D__EXTENSIONS__' )
52
84
  end
53
85
 
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"
86
+ begin
87
+ find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
88
+ find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
89
+ find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
90
+
91
+ abort "Can't find the PostgreSQL client library (libpq)" unless
92
+ have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
93
+ have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
94
+ have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
95
+
96
+ rescue SystemExit
97
+ install_text = case RUBY_PLATFORM
98
+ when /linux/
99
+ <<-EOT
100
+ Please install libpq or postgresql client package like so:
101
+ sudo apt install libpq-dev
102
+ sudo yum install postgresql-devel
103
+ sudo zypper in postgresql-devel
104
+ sudo pacman -S postgresql-libs
105
+ EOT
106
+ when /darwin/
107
+ <<-EOT
108
+ Please install libpq or postgresql client package like so:
109
+ brew install libpq
110
+ EOT
111
+ when /mingw/
112
+ <<-EOT
113
+ Please install libpq or postgresql client package like so:
114
+ ridk exec sh -c "pacman -S ${MINGW_PACKAGE_PREFIX}-postgresql"
115
+ EOT
116
+ else
117
+ <<-EOT
118
+ Please install libpq or postgresql client package.
119
+ EOT
120
+ end
121
+
122
+ $stderr.puts <<-EOT
123
+ *****************************************************************************
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
+ Unable to find PostgreSQL client library.
126
+
127
+ #{install_text}
128
+ or try again with:
129
+ gem install pg -- --with-pg-config=/path/to/pg_config
130
+
131
+ or set library paths manually with:
132
+ gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/
133
+
134
+ EOT
135
+ raise
136
+ end
62
137
 
63
138
  if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
64
139
  # Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
@@ -69,19 +144,28 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
69
144
  end
70
145
  end
71
146
 
72
- # optional headers/functions
73
- have_func 'PQsetSingleRowMode' or
147
+ have_func 'PQconninfo', 'libpq-fe.h' or
74
148
  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'
77
- have_func 'PQsslAttribute'
78
- have_func 'PQencryptPasswordConn'
79
-
80
- have_const 'PG_DIAG_TABLE_NAME', 'libpq-fe.h'
149
+ "of this gem or upgrade your database to at least PostgreSQL-9.3."
150
+ # optional headers/functions
151
+ have_func 'PQsslAttribute', 'libpq-fe.h' # since PostgreSQL-9.5
152
+ have_func 'PQresultVerboseErrorMessage', 'libpq-fe.h' # since PostgreSQL-9.6
153
+ have_func 'PQencryptPasswordConn', 'libpq-fe.h' # since PostgreSQL-10
154
+ have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
155
+ have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
156
+ # Ensure header files fit as well
157
+ src + " int con(){ return PGRES_PIPELINE_SYNC; }"
158
+ end
159
+ have_func 'timegm'
160
+ have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
161
+ have_func 'rb_gc_mark_movable' # since ruby-2.7
162
+ have_func 'rb_io_wait' # since ruby-3.0
163
+ have_func 'rb_io_descriptor' # since ruby-3.1
81
164
 
82
165
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
83
166
  have_header 'unistd.h'
84
167
  have_header 'inttypes.h'
168
+ have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
85
169
 
86
170
  checking_for "C99 variable length arrays" do
87
171
  $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) \