pg 1.5.9 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/{History.md → CHANGELOG.md} +80 -0
  4. data/Gemfile +10 -7
  5. data/README-Windows.rdoc +1 -1
  6. data/README.ja.md +4 -4
  7. data/README.md +66 -23
  8. data/Rakefile +78 -14
  9. data/ext/errorcodes.def +9 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +8 -1
  12. data/ext/extconf.rb +189 -15
  13. data/ext/gvl_wrappers.c +13 -2
  14. data/ext/gvl_wrappers.h +33 -0
  15. data/ext/pg.c +16 -5
  16. data/ext/pg.h +15 -13
  17. data/ext/pg_binary_decoder.c +151 -1
  18. data/ext/pg_binary_encoder.c +212 -9
  19. data/ext/pg_cancel_connection.c +360 -0
  20. data/ext/pg_coder.c +54 -5
  21. data/ext/pg_connection.c +390 -160
  22. data/ext/pg_copy_coder.c +2 -2
  23. data/ext/pg_record_coder.c +1 -1
  24. data/ext/pg_result.c +104 -52
  25. data/ext/pg_text_decoder.c +1 -1
  26. data/ext/pg_text_encoder.c +22 -9
  27. data/ext/pg_tuple.c +8 -8
  28. data/ext/pg_type_map.c +4 -2
  29. data/ext/pg_type_map_all_strings.c +1 -1
  30. data/ext/pg_type_map_by_class.c +1 -1
  31. data/ext/pg_type_map_by_column.c +2 -1
  32. data/ext/pg_type_map_by_mri_type.c +1 -1
  33. data/ext/pg_type_map_by_oid.c +3 -1
  34. data/ext/pg_type_map_in_ruby.c +1 -1
  35. data/ext/pg_util.c +2 -2
  36. data/ext/pg_util.h +2 -2
  37. data/lib/pg/basic_type_map_for_queries.rb +7 -3
  38. data/lib/pg/basic_type_registry.rb +2 -2
  39. data/lib/pg/cancel_connection.rb +53 -0
  40. data/lib/pg/coder.rb +4 -2
  41. data/lib/pg/connection.rb +254 -131
  42. data/lib/pg/version.rb +2 -1
  43. data/lib/pg.rb +156 -130
  44. data/misc/glibc/Dockerfile +20 -0
  45. data/misc/glibc/docker-compose.yml +9 -0
  46. data/misc/glibc/glibc_spec.rb +5 -0
  47. data/misc/yugabyte/Dockerfile +9 -0
  48. data/misc/yugabyte/docker-compose.yml +28 -0
  49. data/misc/yugabyte/pg-test.rb +45 -0
  50. data/pg.gemspec +5 -3
  51. data/ports/patches/krb5/1.22.1/0001-Allow-static-linking-krb5-library.patch +30 -0
  52. data/ports/patches/krb5/1.22.1/0002-unknown-command-line-option-on-clang.patch +12 -0
  53. data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +21 -0
  54. data/ports/patches/postgresql/18.1/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
  55. data/ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
  56. data/rakelib/pg_gem_helper.rb +64 -0
  57. data.tar.gz.sig +0 -0
  58. metadata +37 -22
  59. metadata.gz.sig +0 -0
  60. data/Manifest.txt +0 -72
  61. data/Rakefile.cross +0 -303
data/ext/pg_connection.c CHANGED
@@ -30,11 +30,8 @@ static VALUE pgconn_async_flush(VALUE self);
30
30
  /*
31
31
  * Convenience function to raise connection errors
32
32
  */
33
- #ifdef __GNUC__
34
- __attribute__((format(printf, 3, 4)))
35
- #endif
36
- NORETURN( static void
37
- pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...))
33
+ void
34
+ pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...)
38
35
  {
39
36
  VALUE msg, error;
40
37
  va_list ap;
@@ -69,6 +66,7 @@ pg_get_connection_safe( VALUE self )
69
66
  t_pg_connection *this;
70
67
  TypedData_Get_Struct( self, t_pg_connection, &pg_connection_type, this);
71
68
 
69
+ rb_check_frozen(self);
72
70
  if ( !this->pgconn )
73
71
  pg_raise_conn_error( rb_eConnectionBad, self, "connection is closed");
74
72
 
@@ -96,6 +94,20 @@ pg_get_pgconn( VALUE self )
96
94
  }
97
95
 
98
96
 
97
+ void
98
+ pg_unwrap_socket_io( VALUE self, VALUE *p_socket_io, int ruby_sd )
99
+ {
100
+ if ( RTEST(*p_socket_io) ) {
101
+ #if defined(_WIN32)
102
+ if( rb_w32_unwrap_io_handle(ruby_sd) )
103
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
104
+ #endif
105
+ rb_funcall( *p_socket_io, rb_intern("close"), 0 );
106
+ }
107
+
108
+ RB_OBJ_WRITE(self, p_socket_io, Qnil);
109
+ }
110
+
99
111
 
100
112
  /*
101
113
  * Close the associated socket IO object if there is one.
@@ -104,17 +116,7 @@ static void
104
116
  pgconn_close_socket_io( VALUE self )
105
117
  {
106
118
  t_pg_connection *this = pg_get_connection( self );
107
- VALUE socket_io = this->socket_io;
108
-
109
- if ( RTEST(socket_io) ) {
110
- #if defined(_WIN32)
111
- if( rb_w32_unwrap_io_handle(this->ruby_sd) )
112
- pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
113
- #endif
114
- rb_funcall( socket_io, rb_intern("close"), 0 );
115
- }
116
-
117
- RB_OBJ_WRITE(self, &this->socket_io, Qnil);
119
+ pg_unwrap_socket_io( self, &this->socket_io, this->ruby_sd);
118
120
  }
119
121
 
120
122
 
@@ -230,7 +232,7 @@ static const rb_data_type_t pg_connection_type = {
230
232
  pgconn_gc_mark,
231
233
  pgconn_gc_free,
232
234
  pgconn_memsize,
233
- pg_compact_callback(pgconn_gc_compact),
235
+ pgconn_gc_compact,
234
236
  },
235
237
  0,
236
238
  0,
@@ -419,7 +421,6 @@ pgconn_s_conninfo_parse(VALUE self, VALUE conninfo)
419
421
  }
420
422
 
421
423
 
422
- #ifdef HAVE_PQENCRYPTPASSWORDCONN
423
424
  static VALUE
424
425
  pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
425
426
  {
@@ -443,7 +444,6 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
443
444
 
444
445
  return rval;
445
446
  }
446
- #endif
447
447
 
448
448
 
449
449
  /*
@@ -609,7 +609,7 @@ pgconn_reset_start(VALUE self)
609
609
  * conn.reset_poll -> Integer
610
610
  *
611
611
  * Checks the status of a connection reset operation.
612
- * See #connect_start and #connect_poll for
612
+ * See Connection.connect_start and #connect_poll for
613
613
  * usage information and return values.
614
614
  */
615
615
  static VALUE
@@ -760,7 +760,6 @@ pgconn_options(VALUE self)
760
760
  *
761
761
  * Returns the connection options used by a live connection.
762
762
  *
763
- * Available since PostgreSQL-9.3
764
763
  */
765
764
  static VALUE
766
765
  pgconn_conninfo( VALUE self )
@@ -847,31 +846,52 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
847
846
  * call-seq:
848
847
  * conn.protocol_version -> Integer
849
848
  *
850
- * The 3.0 protocol will normally be used when communicating with PostgreSQL 7.4
851
- * or later servers; pre-7.4 servers support only protocol 2.0. (Protocol 1.0 is
852
- * obsolete and not supported by libpq.)
849
+ * Interrogates the frontend/backend protocol being used.
850
+ *
851
+ * Applications might wish to use this function to determine whether certain features are supported.
852
+ * Currently, the only value is 3 (3.0 protocol).
853
+ * The protocol version will not change after connection startup is complete, but it could theoretically change during a connection reset.
854
+ * The 3.0 protocol is supported by PostgreSQL server versions 7.4 and above.
855
+ *
856
+ * PG::ConnectionBad is raised if the connection is bad.
853
857
  */
854
858
  static VALUE
855
859
  pgconn_protocol_version(VALUE self)
856
860
  {
857
- return INT2NUM(PQprotocolVersion(pg_get_pgconn(self)));
861
+ int protocol_version = PQprotocolVersion(pg_get_pgconn(self));
862
+ if (protocol_version == 0) {
863
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQprotocolVersion() can't get protocol version");
864
+ }
865
+ return INT2NUM(protocol_version);
858
866
  }
859
867
 
860
868
  /*
861
869
  * call-seq:
862
870
  * conn.server_version -> Integer
863
871
  *
864
- * The number is formed by converting the major, minor, and revision
865
- * numbers into two-decimal-digit numbers and appending them together.
866
- * For example, version 7.4.2 will be returned as 70402, and version
867
- * 8.1 will be returned as 80100 (leading zeroes are not shown). Zero
868
- * is returned if the connection is bad.
872
+ * Returns an integer representing the server version.
873
+ *
874
+ * Applications might use this function to determine the version of the database server they are connected to.
875
+ * The result is formed by multiplying the server's major version number by 10000 and adding the minor version number.
876
+ * For example, version 10.1 will be returned as 100001, and version 11.0 will be returned as 110000.
877
+ *
878
+ * PG::ConnectionBad is raised if the connection is bad.
879
+ *
880
+ * Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version.
881
+ * For those versions, PQserverVersion uses two digits for each part; for example version 9.1.5 will be returned as 90105, and version 9.2.0 will be returned as 90200.
882
+ *
883
+ * Therefore, for purposes of determining feature compatibility, applications should divide the result of PQserverVersion by 100 not 10000 to determine a logical major version number.
884
+ * In all release series, only the last two digits differ between minor releases (bug-fix releases).
869
885
  *
870
886
  */
871
887
  static VALUE
872
888
  pgconn_server_version(VALUE self)
873
889
  {
874
- return INT2NUM(PQserverVersion(pg_get_pgconn(self)));
890
+ int server_version = PQserverVersion(pg_get_pgconn(self));
891
+ if (server_version == 0) {
892
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQserverVersion() can't get server version");
893
+ }
894
+ return INT2NUM(server_version);
875
895
  }
876
896
 
877
897
  /*
@@ -920,13 +940,42 @@ pgconn_socket(VALUE self)
920
940
  return INT2NUM(sd);
921
941
  }
922
942
 
943
+
944
+ VALUE
945
+ pg_wrap_socket_io(int sd, VALUE self, VALUE *p_socket_io, int *p_ruby_sd)
946
+ {
947
+ int ruby_sd;
948
+ VALUE cSocket;
949
+ VALUE socket_io = *p_socket_io;
950
+
951
+ #ifdef _WIN32
952
+ ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
953
+ if( ruby_sd == -1 )
954
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
955
+
956
+ *p_ruby_sd = ruby_sd;
957
+ #else
958
+ *p_ruby_sd = ruby_sd = sd;
959
+ #endif
960
+
961
+ cSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
962
+ socket_io = rb_funcall( cSocket, rb_intern("for_fd"), 1, INT2NUM(ruby_sd));
963
+
964
+ /* Disable autoclose feature */
965
+ rb_funcall( socket_io, s_id_autoclose_set, 1, Qfalse );
966
+
967
+ RB_OBJ_WRITE(self, p_socket_io, socket_io);
968
+
969
+ return socket_io;
970
+ }
971
+
923
972
  /*
924
973
  * call-seq:
925
974
  * conn.socket_io() -> IO
926
975
  *
927
976
  * Fetch an IO object created from the Connection's underlying socket.
928
977
  * This object can be used per <tt>socket_io.wait_readable</tt>, <tt>socket_io.wait_writable</tt> or for <tt>IO.select</tt> to wait for events while running asynchronous API calls.
929
- * <tt>IO#wait_*able</tt> is is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
978
+ * <tt>IO#wait_*able</tt> is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
930
979
  *
931
980
  * The IO object can change while the connection is established, but is memorized afterwards.
932
981
  * So be sure not to cache the IO object, but repeat calling <tt>conn.socket_io</tt> instead.
@@ -937,37 +986,17 @@ pgconn_socket(VALUE self)
937
986
  static VALUE
938
987
  pgconn_socket_io(VALUE self)
939
988
  {
940
- int sd;
941
- int ruby_sd;
942
989
  t_pg_connection *this = pg_get_connection_safe( self );
943
- VALUE cSocket;
944
- VALUE socket_io = this->socket_io;
945
990
 
946
- if ( !RTEST(socket_io) ) {
991
+ if ( !RTEST(this->socket_io) ) {
992
+ int sd;
947
993
  if( (sd = PQsocket(this->pgconn)) < 0){
948
994
  pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
949
995
  }
950
-
951
- #ifdef _WIN32
952
- ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
953
- if( ruby_sd == -1 )
954
- pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
955
-
956
- this->ruby_sd = ruby_sd;
957
- #else
958
- ruby_sd = sd;
959
- #endif
960
-
961
- cSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
962
- socket_io = rb_funcall( cSocket, rb_intern("for_fd"), 1, INT2NUM(ruby_sd));
963
-
964
- /* Disable autoclose feature */
965
- rb_funcall( socket_io, s_id_autoclose_set, 1, Qfalse );
966
-
967
- RB_OBJ_WRITE(self, &this->socket_io, socket_io);
996
+ return pg_wrap_socket_io( sd, self, &this->socket_io, &this->ruby_sd);
968
997
  }
969
998
 
970
- return socket_io;
999
+ return this->socket_io;
971
1000
  }
972
1001
 
973
1002
  /*
@@ -984,6 +1013,7 @@ pgconn_backend_pid(VALUE self)
984
1013
  return INT2NUM(PQbackendPID(pg_get_pgconn(self)));
985
1014
  }
986
1015
 
1016
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
987
1017
  typedef struct
988
1018
  {
989
1019
  struct sockaddr_storage addr;
@@ -1028,6 +1058,7 @@ pgconn_backend_key(VALUE self)
1028
1058
 
1029
1059
  return INT2NUM(be_key);
1030
1060
  }
1061
+ #endif
1031
1062
 
1032
1063
  /*
1033
1064
  * call-seq:
@@ -1300,7 +1331,7 @@ alloc_query_params(struct query_params_data *paramsData)
1300
1331
  paramsData->lengths[i] = 0;
1301
1332
  } else {
1302
1333
  t_pg_coder_enc_func enc_func = pg_coder_enc_func( conv );
1303
- VALUE intermediate;
1334
+ VALUE intermediate = Qnil;
1304
1335
 
1305
1336
  /* 1st pass for retiving the required memory space */
1306
1337
  int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
@@ -1340,8 +1371,6 @@ alloc_query_params(struct query_params_data *paramsData)
1340
1371
  required_pool_size += len;
1341
1372
  }
1342
1373
  }
1343
-
1344
- RB_GC_GUARD(intermediate);
1345
1374
  }
1346
1375
  }
1347
1376
  }
@@ -1516,6 +1545,19 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
1516
1545
  return rb_pgresult;
1517
1546
  }
1518
1547
 
1548
+ static VALUE
1549
+ pgconn_sync_describe_close_prepared_portal(VALUE self, VALUE name, PGresult *(*func)(PGconn *, const char *))
1550
+ {
1551
+ PGresult *result;
1552
+ VALUE rb_pgresult;
1553
+ t_pg_connection *this = pg_get_connection_safe( self );
1554
+ const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
1555
+ result = func(this->pgconn, stmt);
1556
+ rb_pgresult = pg_new_result(result, self);
1557
+ pg_result_check(rb_pgresult);
1558
+ return rb_pgresult;
1559
+ }
1560
+
1519
1561
  /*
1520
1562
  * call-seq:
1521
1563
  * conn.sync_describe_prepared( statement_name ) -> PG::Result
@@ -1527,20 +1569,7 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
1527
1569
  static VALUE
1528
1570
  pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1529
1571
  {
1530
- PGresult *result;
1531
- VALUE rb_pgresult;
1532
- t_pg_connection *this = pg_get_connection_safe( self );
1533
- const char *stmt;
1534
- if(NIL_P(stmt_name)) {
1535
- stmt = NULL;
1536
- }
1537
- else {
1538
- stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1539
- }
1540
- result = gvl_PQdescribePrepared(this->pgconn, stmt);
1541
- rb_pgresult = pg_new_result(result, self);
1542
- pg_result_check(rb_pgresult);
1543
- return rb_pgresult;
1572
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePrepared);
1544
1573
  }
1545
1574
 
1546
1575
 
@@ -1555,23 +1584,44 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1555
1584
  static VALUE
1556
1585
  pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1557
1586
  {
1558
- PGresult *result;
1559
- VALUE rb_pgresult;
1560
- t_pg_connection *this = pg_get_connection_safe( self );
1561
- const char *stmt;
1562
- if(NIL_P(stmt_name)) {
1563
- stmt = NULL;
1564
- }
1565
- else {
1566
- stmt = pg_cstr_enc(stmt_name, this->enc_idx);
1567
- }
1568
- result = gvl_PQdescribePortal(this->pgconn, stmt);
1569
- rb_pgresult = pg_new_result(result, self);
1570
- pg_result_check(rb_pgresult);
1571
- return rb_pgresult;
1587
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePortal);
1572
1588
  }
1573
1589
 
1574
1590
 
1591
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
1592
+ /*
1593
+ * call-seq:
1594
+ * conn.sync_close_prepared( stmt_name ) -> PG::Result
1595
+ *
1596
+ * This function has the same behavior as #async_close_prepared, but is implemented using the synchronous command processing API of libpq.
1597
+ * See #async_exec for the differences between the two API variants.
1598
+ * It's not recommended to use explicit sync or async variants but #close_prepared instead, unless you have a good reason to do so.
1599
+ *
1600
+ * Available since PostgreSQL-17.
1601
+ */
1602
+ static VALUE
1603
+ pgconn_sync_close_prepared(VALUE self, VALUE stmt_name)
1604
+ {
1605
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePrepared);
1606
+ }
1607
+
1608
+ /*
1609
+ * call-seq:
1610
+ * conn.sync_close_portal( portal_name ) -> PG::Result
1611
+ *
1612
+ * This function has the same behavior as #async_close_portal, but is implemented using the synchronous command processing API of libpq.
1613
+ * See #async_exec for the differences between the two API variants.
1614
+ * It's not recommended to use explicit sync or async variants but #close_portal instead, unless you have a good reason to do so.
1615
+ *
1616
+ * Available since PostgreSQL-17.
1617
+ */
1618
+ static VALUE
1619
+ pgconn_sync_close_portal(VALUE self, VALUE stmt_name)
1620
+ {
1621
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePortal);
1622
+ }
1623
+ #endif
1624
+
1575
1625
  /*
1576
1626
  * call-seq:
1577
1627
  * conn.make_empty_pgresult( status ) -> PG::Result
@@ -1588,6 +1638,7 @@ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1588
1638
  * * +PGRES_FATAL_ERROR+
1589
1639
  * * +PGRES_COPY_BOTH+
1590
1640
  * * +PGRES_SINGLE_TUPLE+
1641
+ * * +PGRES_TUPLES_CHUNK+
1591
1642
  * * +PGRES_PIPELINE_SYNC+
1592
1643
  * * +PGRES_PIPELINE_ABORTED+
1593
1644
  */
@@ -1812,14 +1863,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1812
1863
  * (column names, types, etc) that an ordinary Result object for the query
1813
1864
  * would have.
1814
1865
  *
1815
- * *Caution:* While processing a query, the server may return some rows and
1816
- * then encounter an error, causing the query to be aborted. Ordinarily, pg
1817
- * discards any such rows and reports only the error. But in single-row mode,
1818
- * those rows will have already been returned to the application. Hence, the
1819
- * application will see some Result objects followed by an Error raised in get_result.
1820
- * For proper transactional behavior, the application must be designed to discard
1821
- * or undo whatever has been done with the previously-processed rows, if the query
1822
- * ultimately fails.
1866
+ * *Caution:* While processing a query, the server may return some rows and then encounter an error, causing the query to be aborted.
1867
+ * Ordinarily, pg discards any such rows and reports only the error.
1868
+ * But in single-row or chunked mode, some rows may have already been returned to the application.
1869
+ * Hence, the application will see some PGRES_SINGLE_TUPLE or PGRES_TUPLES_CHUNK PG::Result objects followed by a PG::Error raised in get_result.
1870
+ * For proper transactional behavior, the application must be designed to discard or undo whatever has been done with the previously-processed rows, if the query ultimately fails.
1823
1871
  *
1824
1872
  * Example:
1825
1873
  * conn.send_query( "your SQL command" )
@@ -1839,10 +1887,49 @@ pgconn_set_single_row_mode(VALUE self)
1839
1887
 
1840
1888
  rb_check_frozen(self);
1841
1889
  if( PQsetSingleRowMode(conn) == 0 )
1842
- pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1890
+ pg_raise_conn_error( rb_ePGerror, self, "PQsetSingleRowMode %s", PQerrorMessage(conn));
1891
+
1892
+ return self;
1893
+ }
1894
+
1895
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
1896
+ /*
1897
+ * call-seq:
1898
+ * conn.set_chunked_rows_mode -> self
1899
+ *
1900
+ * Select chunked mode for the currently-executing query.
1901
+ *
1902
+ * This function is similar to set_single_row_mode, except that it specifies retrieval of up to +chunk_size+ rows per PGresult, not necessarily just one row.
1903
+ * This function can only be called immediately after send_query or one of its sibling functions, before any other operation on the connection such as consume_input or get_result.
1904
+ * If called at the correct time, the function activates chunked mode for the current query.
1905
+ * Otherwise the mode stays unchanged and the function raises an error.
1906
+ * In any case, the mode reverts to normal after completion of the current query.
1907
+ *
1908
+ * Example:
1909
+ * conn.send_query( "your SQL command" )
1910
+ * conn.set_chunked_rows_mode(10)
1911
+ * loop do
1912
+ * res = conn.get_result or break
1913
+ * res.check
1914
+ * res.each do |row|
1915
+ * # do something with the received max. 10 rows
1916
+ * end
1917
+ * end
1918
+ *
1919
+ * Available since PostgreSQL-17
1920
+ */
1921
+ static VALUE
1922
+ pgconn_set_chunked_rows_mode(VALUE self, VALUE chunk_size)
1923
+ {
1924
+ PGconn *conn = pg_get_pgconn(self);
1925
+
1926
+ rb_check_frozen(self);
1927
+ if( PQsetChunkedRowsMode(conn, NUM2INT(chunk_size)) == 0 )
1928
+ pg_raise_conn_error( rb_ePGerror, self, "PQsetChunkedRowsMode %s", PQerrorMessage(conn));
1843
1929
 
1844
1930
  return self;
1845
1931
  }
1932
+ #endif
1846
1933
 
1847
1934
  static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1848
1935
 
@@ -1867,7 +1954,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1867
1954
  /* If called with no or nil parameters, use PQexec for compatibility */
1868
1955
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1869
1956
  if(gvl_PQsendQuery(this->pgconn, pg_cstr_enc(argv[0], this->enc_idx)) == 0)
1870
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
1957
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQuery %s", PQerrorMessage(this->pgconn));
1871
1958
 
1872
1959
  pgconn_wait_for_flush( self );
1873
1960
  return Qnil;
@@ -1942,7 +2029,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1942
2029
  free_query_params( &paramsData );
1943
2030
 
1944
2031
  if(result == 0)
1945
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2032
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryParams %s", PQerrorMessage(this->pgconn));
1946
2033
 
1947
2034
  pgconn_wait_for_flush( self );
1948
2035
  return Qnil;
@@ -2003,7 +2090,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
2003
2090
  xfree(paramTypes);
2004
2091
 
2005
2092
  if(result == 0) {
2006
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2093
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendPrepare %s", PQerrorMessage(this->pgconn));
2007
2094
  }
2008
2095
  pgconn_wait_for_flush( self );
2009
2096
  return Qnil;
@@ -2069,7 +2156,21 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2069
2156
  free_query_params( &paramsData );
2070
2157
 
2071
2158
  if(result == 0)
2072
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2159
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryPrepared %s", PQerrorMessage(this->pgconn));
2160
+
2161
+ pgconn_wait_for_flush( self );
2162
+ return Qnil;
2163
+ }
2164
+
2165
+
2166
+ static VALUE
2167
+ pgconn_send_describe_close_prepared_portal(VALUE self, VALUE name, int (*func)(PGconn *, const char *), const char *funame)
2168
+ {
2169
+ t_pg_connection *this = pg_get_connection_safe( self );
2170
+ const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
2171
+ /* returns 0 on failure */
2172
+ if(func(this->pgconn, stmt) == 0)
2173
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s %s", funame, PQerrorMessage(this->pgconn));
2073
2174
 
2074
2175
  pgconn_wait_for_flush( self );
2075
2176
  return Qnil;
@@ -2085,13 +2186,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2085
2186
  static VALUE
2086
2187
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2087
2188
  {
2088
- t_pg_connection *this = pg_get_connection_safe( self );
2089
- /* returns 0 on failure */
2090
- if(gvl_PQsendDescribePrepared(this->pgconn, pg_cstr_enc(stmt_name, this->enc_idx)) == 0)
2091
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2092
-
2093
- pgconn_wait_for_flush( self );
2094
- return Qnil;
2189
+ return pgconn_send_describe_close_prepared_portal(
2190
+ self, stmt_name, gvl_PQsendDescribePrepared,
2191
+ "PQsendDescribePrepared");
2095
2192
  }
2096
2193
 
2097
2194
 
@@ -2105,16 +2202,48 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2105
2202
  static VALUE
2106
2203
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2107
2204
  {
2108
- t_pg_connection *this = pg_get_connection_safe( self );
2109
- /* returns 0 on failure */
2110
- if(gvl_PQsendDescribePortal(this->pgconn, pg_cstr_enc(portal, this->enc_idx)) == 0)
2111
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2205
+ return pgconn_send_describe_close_prepared_portal(
2206
+ self, portal, gvl_PQsendDescribePortal,
2207
+ "PQsendDescribePortal");
2208
+ }
2112
2209
 
2113
- pgconn_wait_for_flush( self );
2114
- return Qnil;
2210
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
2211
+ /*
2212
+ * call-seq:
2213
+ * conn.send_close_prepared( statement_name ) -> nil
2214
+ *
2215
+ * Asynchronously send _command_ to the server. Does not block.
2216
+ * Use in combination with +conn.get_result+.
2217
+ *
2218
+ * Available since PostgreSQL-17.
2219
+ */
2220
+ static VALUE
2221
+ pgconn_send_close_prepared(VALUE self, VALUE stmt_name)
2222
+ {
2223
+ return pgconn_send_describe_close_prepared_portal(
2224
+ self, stmt_name, gvl_PQsendClosePrepared,
2225
+ "PQsendClosePrepared");
2115
2226
  }
2116
2227
 
2117
2228
 
2229
+ /*
2230
+ * call-seq:
2231
+ * conn.send_close_portal( portal_name ) -> nil
2232
+ *
2233
+ * Asynchronously send _command_ to the server. Does not block.
2234
+ * Use in combination with +conn.get_result+.
2235
+ *
2236
+ * Available since PostgreSQL-17.
2237
+ */
2238
+ static VALUE
2239
+ pgconn_send_close_portal(VALUE self, VALUE portal)
2240
+ {
2241
+ return pgconn_send_describe_close_prepared_portal(
2242
+ self, portal, gvl_PQsendClosePortal,
2243
+ "PQsendClosePortal");
2244
+ }
2245
+ #endif
2246
+
2118
2247
  static VALUE
2119
2248
  pgconn_sync_get_result(VALUE self)
2120
2249
  {
@@ -2204,6 +2333,7 @@ pgconn_sync_flush(VALUE self)
2204
2333
  return (ret) ? Qfalse : Qtrue;
2205
2334
  }
2206
2335
 
2336
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
2207
2337
  static VALUE
2208
2338
  pgconn_sync_cancel(VALUE self)
2209
2339
  {
@@ -2225,6 +2355,7 @@ pgconn_sync_cancel(VALUE self)
2225
2355
  PQfreeCancel(cancel);
2226
2356
  return retval;
2227
2357
  }
2358
+ #endif
2228
2359
 
2229
2360
 
2230
2361
  /*
@@ -2252,7 +2383,7 @@ pgconn_notifies(VALUE self)
2252
2383
  return Qnil;
2253
2384
  }
2254
2385
 
2255
- hash = rb_hash_new();
2386
+ hash = rb_hash_new_capa(3);
2256
2387
  relname = rb_str_new2(notification->relname);
2257
2388
  be_pid = INT2NUM(notification->be_pid);
2258
2389
  extra = rb_str_new2(notification->extra);
@@ -2271,8 +2402,9 @@ pgconn_notifies(VALUE self)
2271
2402
  static int
2272
2403
  rb_io_descriptor(VALUE io)
2273
2404
  {
2405
+ rb_io_t *fptr;
2274
2406
  Check_Type(io, T_FILE);
2275
- rb_io_t *fptr = RFILE(io)->fptr;
2407
+ fptr = RFILE(io)->fptr;
2276
2408
  rb_io_check_closed(fptr);
2277
2409
  return fptr->fd;
2278
2410
  }
@@ -2568,7 +2700,7 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2568
2700
  VALUE value;
2569
2701
  VALUE buffer = Qnil;
2570
2702
  VALUE encoder;
2571
- VALUE intermediate;
2703
+ VALUE intermediate = Qnil;
2572
2704
  t_pg_coder *p_coder = NULL;
2573
2705
 
2574
2706
  rb_scan_args( argc, argv, "11", &value, &encoder );
@@ -2607,7 +2739,6 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2607
2739
  if(ret == -1)
2608
2740
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2609
2741
 
2610
- RB_GC_GUARD(intermediate);
2611
2742
  RB_GC_GUARD(buffer);
2612
2743
 
2613
2744
  return (ret) ? Qtrue : Qfalse;
@@ -2702,7 +2833,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2702
2833
  return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
2703
2834
  }
2704
2835
 
2705
- #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
2706
2836
  /*
2707
2837
  * call-seq:
2708
2838
  * conn.set_error_context_visibility( context_visibility ) -> Integer
@@ -2722,7 +2852,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2722
2852
  *
2723
2853
  * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY].
2724
2854
  *
2725
- * Available since PostgreSQL-9.6
2726
2855
  */
2727
2856
  static VALUE
2728
2857
  pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
@@ -2731,7 +2860,6 @@ pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
2731
2860
  PGContextVisibility context_visibility = NUM2INT(in_context_visibility);
2732
2861
  return INT2FIX(PQsetErrorContextVisibility(conn, context_visibility));
2733
2862
  }
2734
- #endif
2735
2863
 
2736
2864
  /*
2737
2865
  * call-seq:
@@ -3459,6 +3587,21 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3459
3587
  return rb_pgresult;
3460
3588
  }
3461
3589
 
3590
+ static VALUE
3591
+ pgconn_async_describe_close_prepared_potral(VALUE self, VALUE name, VALUE
3592
+ (*func)(VALUE, VALUE))
3593
+ {
3594
+ VALUE rb_pgresult = Qnil;
3595
+
3596
+ pgconn_discard_results( self );
3597
+ func( self, name );
3598
+ rb_pgresult = pgconn_async_get_last_result( self );
3599
+
3600
+ if ( rb_block_given_p() ) {
3601
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3602
+ }
3603
+ return rb_pgresult;
3604
+ }
3462
3605
 
3463
3606
  /*
3464
3607
  * call-seq:
@@ -3471,16 +3614,7 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3471
3614
  static VALUE
3472
3615
  pgconn_async_describe_portal(VALUE self, VALUE portal)
3473
3616
  {
3474
- VALUE rb_pgresult = Qnil;
3475
-
3476
- pgconn_discard_results( self );
3477
- pgconn_send_describe_portal( self, portal );
3478
- rb_pgresult = pgconn_async_get_last_result( self );
3479
-
3480
- if ( rb_block_given_p() ) {
3481
- return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3482
- }
3483
- return rb_pgresult;
3617
+ return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_describe_portal);
3484
3618
  }
3485
3619
 
3486
3620
 
@@ -3495,27 +3629,64 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
3495
3629
  static VALUE
3496
3630
  pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3497
3631
  {
3498
- VALUE rb_pgresult = Qnil;
3499
-
3500
- pgconn_discard_results( self );
3501
- pgconn_send_describe_prepared( self, stmt_name );
3502
- rb_pgresult = pgconn_async_get_last_result( self );
3632
+ return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_describe_prepared);
3633
+ }
3503
3634
 
3504
- if ( rb_block_given_p() ) {
3505
- return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3506
- }
3507
- return rb_pgresult;
3635
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
3636
+ /*
3637
+ * call-seq:
3638
+ * conn.close_prepared( statement_name ) -> PG::Result
3639
+ *
3640
+ * Submits a request to close the specified prepared statement, and waits for completion.
3641
+ * close_prepared allows an application to close a previously prepared statement.
3642
+ * Closing a statement releases all of its associated resources on the server and allows its name to be reused.
3643
+ * It's the same as using the +DEALLOCATE+ SQL statement, but on a lower protocol level.
3644
+ *
3645
+ * +statement_name+ can be "" or +nil+ to reference the unnamed statement.
3646
+ * It is fine if no statement exists with this name, in that case the operation is a no-op.
3647
+ * On success, a PG::Result with status PGRES_COMMAND_OK is returned.
3648
+ *
3649
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPREPARED].
3650
+ *
3651
+ * Available since PostgreSQL-17.
3652
+ */
3653
+ static VALUE
3654
+ pgconn_async_close_prepared(VALUE self, VALUE stmt_name)
3655
+ {
3656
+ return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_close_prepared);
3508
3657
  }
3509
3658
 
3659
+ /*
3660
+ * call-seq:
3661
+ * conn.close_portal( portal_name ) -> PG::Result
3662
+ *
3663
+ * Submits a request to close the specified portal, and waits for completion.
3664
+ *
3665
+ * close_portal allows an application to trigger a close of a previously created portal.
3666
+ * Closing a portal releases all of its associated resources on the server and allows its name to be reused.
3667
+ * (pg does not provide any direct access to portals, but you can use this function to close a cursor created with a DECLARE CURSOR SQL command.)
3668
+ *
3669
+ * +portal_name+ can be "" or +nil+ to reference the unnamed portal.
3670
+ * It is fine if no portal exists with this name, in that case the operation is a no-op.
3671
+ * On success, a PG::Result with status PGRES_COMMAND_OK is returned.
3672
+ *
3673
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPORTAL].
3674
+ *
3675
+ * Available since PostgreSQL-17.
3676
+ */
3677
+ static VALUE
3678
+ pgconn_async_close_portal(VALUE self, VALUE portal)
3679
+ {
3680
+ return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_close_portal);
3681
+ }
3682
+ #endif
3510
3683
 
3511
- #ifdef HAVE_PQSSLATTRIBUTE
3512
3684
  /*
3513
3685
  * call-seq:
3514
3686
  * conn.ssl_in_use? -> Boolean
3515
3687
  *
3516
3688
  * Returns +true+ if the connection uses SSL/TLS, +false+ if not.
3517
3689
  *
3518
- * Available since PostgreSQL-9.5
3519
3690
  */
3520
3691
  static VALUE
3521
3692
  pgconn_ssl_in_use(VALUE self)
@@ -3549,7 +3720,6 @@ pgconn_ssl_in_use(VALUE self)
3549
3720
  *
3550
3721
  * See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
3551
3722
  *
3552
- * Available since PostgreSQL-9.5
3553
3723
  */
3554
3724
  static VALUE
3555
3725
  pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
@@ -3568,7 +3738,6 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3568
3738
  *
3569
3739
  * See also #ssl_attribute
3570
3740
  *
3571
- * Available since PostgreSQL-9.5
3572
3741
  */
3573
3742
  static VALUE
3574
3743
  pgconn_ssl_attribute_names(VALUE self)
@@ -3584,8 +3753,6 @@ pgconn_ssl_attribute_names(VALUE self)
3584
3753
  }
3585
3754
 
3586
3755
 
3587
- #endif
3588
-
3589
3756
 
3590
3757
  #ifdef HAVE_PQENTERPIPELINEMODE
3591
3758
  /*
@@ -3620,6 +3787,8 @@ pgconn_pipeline_status(VALUE self)
3620
3787
  * Raises PG::Error and has no effect if the connection is not currently idle, i.e., it has a result ready, or it is waiting for more input from the server, etc.
3621
3788
  * This function does not actually send anything to the server, it just changes the libpq connection state.
3622
3789
  *
3790
+ * See the {PostgreSQL documentation}[https://www.postgresql.org/docs/17/libpq-pipeline-mode.html#LIBPQ-PIPELINE-MODE].
3791
+ *
3623
3792
  * Available since PostgreSQL-14
3624
3793
  */
3625
3794
  static VALUE
@@ -3658,29 +3827,55 @@ pgconn_exit_pipeline_mode(VALUE self)
3658
3827
 
3659
3828
  /*
3660
3829
  * call-seq:
3661
- * conn.pipeline_sync -> nil
3830
+ * conn.sync_pipeline_sync -> nil
3831
+ *
3832
+ * This function has the same behavior as #async_pipeline_sync, but is implemented using the synchronous command processing API of libpq.
3833
+ * See #async_exec for the differences between the two API variants.
3834
+ * It's not recommended to use explicit sync or async variants but #pipeline_sync instead, unless you have a good reason to do so.
3835
+ *
3836
+ * Available since PostgreSQL-14
3837
+ */
3838
+ static VALUE
3839
+ pgconn_sync_pipeline_sync(VALUE self)
3840
+ {
3841
+ PGconn *conn = pg_get_pgconn(self);
3842
+ int res = gvl_PQpipelineSync(conn);
3843
+ if( res != 1 )
3844
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3845
+
3846
+ return Qnil;
3847
+ }
3848
+
3849
+
3850
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
3851
+ /*
3852
+ * call-seq:
3853
+ * conn.send_pipeline_sync -> nil
3662
3854
  *
3663
- * Marks a synchronization point in a pipeline by sending a sync message and flushing the send buffer.
3664
- * This serves as the delimiter of an implicit transaction and an error recovery point; see Section 34.5.1.3 of the PostgreSQL documentation.
3855
+ * Marks a synchronization point in a pipeline by sending a sync message without flushing the send buffer.
3665
3856
  *
3857
+ * This serves as the delimiter of an implicit transaction and an error recovery point.
3666
3858
  * Raises PG::Error if the connection is not in pipeline mode or sending a sync message failed.
3859
+ * Note that the message is not itself flushed to the server automatically; use flush if necessary.
3667
3860
  *
3668
- * Available since PostgreSQL-14
3861
+ * Available since PostgreSQL-17
3669
3862
  */
3670
3863
  static VALUE
3671
- pgconn_pipeline_sync(VALUE self)
3864
+ pgconn_send_pipeline_sync(VALUE self)
3672
3865
  {
3673
3866
  PGconn *conn = pg_get_pgconn(self);
3674
- int res = PQpipelineSync(conn);
3867
+ int res = gvl_PQsendPipelineSync(conn);
3675
3868
  if( res != 1 )
3676
3869
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3677
3870
 
3678
3871
  return Qnil;
3679
3872
  }
3873
+ #endif
3874
+
3680
3875
 
3681
3876
  /*
3682
3877
  * call-seq:
3683
- * conn.pipeline_sync -> nil
3878
+ * conn.send_flush_request -> nil
3684
3879
  *
3685
3880
  * Sends a request for the server to flush its output buffer.
3686
3881
  *
@@ -4231,9 +4426,11 @@ pgconn_set_default_encoding( VALUE self )
4231
4426
  * res.type_map_for_queries = typemap
4232
4427
  *
4233
4428
  * Set the default TypeMap that is used for type casts of query bind parameters.
4429
+ * It can be overwritten per +type_map+ parameter of #exec_params and siblings.
4234
4430
  *
4235
4431
  * +typemap+ must be a kind of PG::TypeMap .
4236
4432
  *
4433
+ * See also #type_map_for_queries
4237
4434
  */
4238
4435
  static VALUE
4239
4436
  pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
@@ -4258,6 +4455,9 @@ pgconn_type_map_for_queries_set(VALUE self, VALUE typemap)
4258
4455
  * Returns the default TypeMap that is currently set for type casts of query
4259
4456
  * bind parameters.
4260
4457
  *
4458
+ * Default is PG::TypeMapAllStrings .
4459
+ *
4460
+ * See also #type_map_for_queries=
4261
4461
  */
4262
4462
  static VALUE
4263
4463
  pgconn_type_map_for_queries_get(VALUE self)
@@ -4272,9 +4472,11 @@ pgconn_type_map_for_queries_get(VALUE self)
4272
4472
  * res.type_map_for_results = typemap
4273
4473
  *
4274
4474
  * Set the default TypeMap that is used for type casts of result values.
4475
+ * It can be overwritten per PG::Result#type_map= .
4275
4476
  *
4276
4477
  * +typemap+ must be a kind of PG::TypeMap .
4277
4478
  *
4479
+ * See also #type_map_for_results
4278
4480
  */
4279
4481
  static VALUE
4280
4482
  pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
@@ -4296,6 +4498,9 @@ pgconn_type_map_for_results_set(VALUE self, VALUE typemap)
4296
4498
  *
4297
4499
  * Returns the default TypeMap that is currently set for type casts of result values.
4298
4500
  *
4501
+ * Default is PG::TypeMapAllStrings .
4502
+ *
4503
+ * See also #type_map_for_results=
4299
4504
  */
4300
4505
  static VALUE
4301
4506
  pgconn_type_map_for_results_get(VALUE self)
@@ -4312,11 +4517,13 @@ pgconn_type_map_for_results_get(VALUE self)
4312
4517
  *
4313
4518
  * Set the default coder that is used for type casting of parameters
4314
4519
  * to #put_copy_data .
4520
+ * It can be overwritten per +encoder+ parameter of #put_copy_data and +coder+ parameter of #copy_data.
4315
4521
  *
4316
4522
  * +encoder+ can be:
4317
4523
  * * a kind of PG::Coder
4318
4524
  * * +nil+ - disable type encoding, data must be a String.
4319
4525
  *
4526
+ * See also #encoder_for_put_copy_data
4320
4527
  */
4321
4528
  static VALUE
4322
4529
  pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
@@ -4346,6 +4553,8 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE encoder)
4346
4553
  * * a kind of PG::Coder
4347
4554
  * * +nil+ - type encoding is disabled, data must be a String.
4348
4555
  *
4556
+ * Default is +nil+ .
4557
+ * See also #encoder_for_put_copy_data=
4349
4558
  */
4350
4559
  static VALUE
4351
4560
  pgconn_encoder_for_put_copy_data_get(VALUE self)
@@ -4361,11 +4570,13 @@ pgconn_encoder_for_put_copy_data_get(VALUE self)
4361
4570
  *
4362
4571
  * Set the default coder that is used for type casting of received data
4363
4572
  * by #get_copy_data .
4573
+ * It can be overwritten per +decoder+ parameter of #get_copy_data and +coder+ parameter of #copy_data.
4364
4574
  *
4365
4575
  * +decoder+ can be:
4366
4576
  * * a kind of PG::Coder
4367
4577
  * * +nil+ - disable type decoding, returned data will be a String.
4368
4578
  *
4579
+ * See also #decoder_for_get_copy_data
4369
4580
  */
4370
4581
  static VALUE
4371
4582
  pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
@@ -4395,6 +4606,9 @@ pgconn_decoder_for_get_copy_data_set(VALUE self, VALUE decoder)
4395
4606
  * * a kind of PG::Coder
4396
4607
  * * +nil+ - type encoding is disabled, returned data will be a String.
4397
4608
  *
4609
+ * Default is +nil+ .
4610
+ *
4611
+ * See also #decoder_for_get_copy_data=
4398
4612
  */
4399
4613
  static VALUE
4400
4614
  pgconn_decoder_for_get_copy_data_get(VALUE self)
@@ -4417,7 +4631,7 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
4417
4631
  *
4418
4632
  * Settings the type of field names affects only future results.
4419
4633
  *
4420
- * See further description at PG::Result#field_name_type=
4634
+ * See further description at PG::Result#field_name_type= and #field_name_type .
4421
4635
  *
4422
4636
  */
4423
4637
  static VALUE
@@ -4524,7 +4738,9 @@ init_pg_connection(void)
4524
4738
  rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
4525
4739
  rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
4526
4740
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
4741
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
4527
4742
  rb_define_method(rb_cPGconn, "backend_key", pgconn_backend_key, 0);
4743
+ #endif
4528
4744
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
4529
4745
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
4530
4746
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
@@ -4536,6 +4752,10 @@ init_pg_connection(void)
4536
4752
  rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_sync_exec_prepared, -1);
4537
4753
  rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_sync_describe_prepared, 1);
4538
4754
  rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_sync_describe_portal, 1);
4755
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4756
+ rb_define_method(rb_cPGconn, "sync_close_prepared", pgconn_sync_close_prepared, 1);
4757
+ rb_define_method(rb_cPGconn, "sync_close_portal", pgconn_sync_close_portal, 1);
4758
+ #endif
4539
4759
 
4540
4760
  rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
4541
4761
  rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
@@ -4543,6 +4763,10 @@ init_pg_connection(void)
4543
4763
  rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
4544
4764
  rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
4545
4765
  rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
4766
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4767
+ rb_define_method(rb_cPGconn, "close_prepared", pgconn_async_close_prepared, 1);
4768
+ rb_define_method(rb_cPGconn, "close_portal", pgconn_async_close_portal, 1);
4769
+ #endif
4546
4770
 
4547
4771
  rb_define_alias(rb_cPGconn, "async_exec", "exec");
4548
4772
  rb_define_alias(rb_cPGconn, "async_query", "async_exec");
@@ -4551,6 +4775,10 @@ init_pg_connection(void)
4551
4775
  rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
4552
4776
  rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
4553
4777
  rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
4778
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4779
+ rb_define_alias(rb_cPGconn, "async_close_prepared", "close_prepared");
4780
+ rb_define_alias(rb_cPGconn, "async_close_portal", "close_portal");
4781
+ #endif
4554
4782
 
4555
4783
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
4556
4784
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
@@ -4560,6 +4788,9 @@ init_pg_connection(void)
4560
4788
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4561
4789
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4562
4790
  rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
4791
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4792
+ rb_define_method(rb_cPGconn, "set_chunked_rows_mode", pgconn_set_chunked_rows_mode, 1);
4793
+ #endif
4563
4794
 
4564
4795
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
4565
4796
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
@@ -4579,7 +4810,9 @@ init_pg_connection(void)
4579
4810
  rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
4580
4811
 
4581
4812
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
4813
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
4582
4814
  rb_define_method(rb_cPGconn, "sync_cancel", pgconn_sync_cancel, 0);
4815
+ #endif
4583
4816
 
4584
4817
  /****** PG::Connection INSTANCE METHODS: NOTIFY ******/
4585
4818
  rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
@@ -4591,9 +4824,7 @@ init_pg_connection(void)
4591
4824
 
4592
4825
  /****** PG::Connection INSTANCE METHODS: Control Functions ******/
4593
4826
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
4594
- #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
4595
4827
  rb_define_method(rb_cPGconn, "set_error_context_visibility", pgconn_set_error_context_visibility, 1 );
4596
- #endif
4597
4828
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4598
4829
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4599
4830
 
@@ -4615,22 +4846,21 @@ init_pg_connection(void)
4615
4846
  rb_define_method(rb_cPGconn, "sync_get_last_result", pgconn_sync_get_last_result, 0);
4616
4847
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_async_get_last_result, 0);
4617
4848
  rb_define_alias(rb_cPGconn, "async_get_last_result", "get_last_result");
4618
- #ifdef HAVE_PQENCRYPTPASSWORDCONN
4619
4849
  rb_define_method(rb_cPGconn, "sync_encrypt_password", pgconn_sync_encrypt_password, -1);
4620
- #endif
4621
4850
 
4622
- #ifdef HAVE_PQSSLATTRIBUTE
4623
4851
  rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
4624
4852
  rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
4625
4853
  rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
4626
- #endif
4627
4854
 
4628
4855
  #ifdef HAVE_PQENTERPIPELINEMODE
4629
4856
  rb_define_method(rb_cPGconn, "pipeline_status", pgconn_pipeline_status, 0);
4630
4857
  rb_define_method(rb_cPGconn, "enter_pipeline_mode", pgconn_enter_pipeline_mode, 0);
4631
4858
  rb_define_method(rb_cPGconn, "exit_pipeline_mode", pgconn_exit_pipeline_mode, 0);
4632
- rb_define_method(rb_cPGconn, "pipeline_sync", pgconn_pipeline_sync, 0);
4859
+ rb_define_method(rb_cPGconn, "sync_pipeline_sync", pgconn_sync_pipeline_sync, 0);
4633
4860
  rb_define_method(rb_cPGconn, "send_flush_request", pgconn_send_flush_request, 0);
4861
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4862
+ rb_define_method(rb_cPGconn, "send_pipeline_sync", pgconn_send_pipeline_sync, 0);
4863
+ #endif
4634
4864
  #endif
4635
4865
 
4636
4866
  /****** PG::Connection INSTANCE METHODS: Large Object Support ******/