pg 1.5.9 → 1.6.0.rc2

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 (51) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/{History.md → CHANGELOG.md} +54 -0
  4. data/Gemfile +7 -4
  5. data/README-Windows.rdoc +1 -1
  6. data/README.ja.md +4 -4
  7. data/README.md +6 -5
  8. data/Rakefile +80 -13
  9. data/ext/extconf.rb +158 -14
  10. data/ext/gvl_wrappers.c +13 -2
  11. data/ext/gvl_wrappers.h +33 -0
  12. data/ext/pg.c +16 -5
  13. data/ext/pg.h +9 -9
  14. data/ext/pg_binary_decoder.c +150 -0
  15. data/ext/pg_binary_encoder.c +210 -7
  16. data/ext/pg_cancel_connection.c +360 -0
  17. data/ext/pg_coder.c +52 -5
  18. data/ext/pg_connection.c +368 -158
  19. data/ext/pg_copy_coder.c +2 -2
  20. data/ext/pg_record_coder.c +1 -1
  21. data/ext/pg_result.c +9 -11
  22. data/ext/pg_text_encoder.c +20 -7
  23. data/ext/pg_tuple.c +2 -2
  24. data/ext/pg_type_map.c +1 -1
  25. data/ext/pg_type_map_all_strings.c +1 -1
  26. data/ext/pg_type_map_by_class.c +1 -1
  27. data/ext/pg_type_map_by_column.c +2 -1
  28. data/ext/pg_type_map_by_mri_type.c +1 -1
  29. data/ext/pg_type_map_by_oid.c +3 -1
  30. data/ext/pg_type_map_in_ruby.c +1 -1
  31. data/lib/pg/basic_type_map_for_queries.rb +7 -3
  32. data/lib/pg/basic_type_registry.rb +2 -2
  33. data/lib/pg/cancel_connection.rb +53 -0
  34. data/lib/pg/coder.rb +2 -1
  35. data/lib/pg/connection.rb +252 -131
  36. data/lib/pg/version.rb +1 -1
  37. data/lib/pg.rb +13 -8
  38. data/misc/yugabyte/Dockerfile +9 -0
  39. data/misc/yugabyte/docker-compose.yml +28 -0
  40. data/misc/yugabyte/pg-test.rb +45 -0
  41. data/pg.gemspec +5 -3
  42. data/ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch +30 -0
  43. data/ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch +21 -0
  44. data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
  45. data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
  46. data/rakelib/pg_gem_helper.rb +64 -0
  47. data.tar.gz.sig +0 -0
  48. metadata +32 -21
  49. metadata.gz.sig +0 -0
  50. data/Manifest.txt +0 -72
  51. 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;
@@ -96,6 +93,20 @@ pg_get_pgconn( VALUE self )
96
93
  }
97
94
 
98
95
 
96
+ void
97
+ pg_unwrap_socket_io( VALUE self, VALUE *p_socket_io, int ruby_sd )
98
+ {
99
+ if ( RTEST(*p_socket_io) ) {
100
+ #if defined(_WIN32)
101
+ if( rb_w32_unwrap_io_handle(ruby_sd) )
102
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not unwrap win32 socket handle");
103
+ #endif
104
+ rb_funcall( *p_socket_io, rb_intern("close"), 0 );
105
+ }
106
+
107
+ RB_OBJ_WRITE(self, p_socket_io, Qnil);
108
+ }
109
+
99
110
 
100
111
  /*
101
112
  * Close the associated socket IO object if there is one.
@@ -104,17 +115,7 @@ static void
104
115
  pgconn_close_socket_io( VALUE self )
105
116
  {
106
117
  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);
118
+ pg_unwrap_socket_io( self, &this->socket_io, this->ruby_sd);
118
119
  }
119
120
 
120
121
 
@@ -230,7 +231,7 @@ static const rb_data_type_t pg_connection_type = {
230
231
  pgconn_gc_mark,
231
232
  pgconn_gc_free,
232
233
  pgconn_memsize,
233
- pg_compact_callback(pgconn_gc_compact),
234
+ pgconn_gc_compact,
234
235
  },
235
236
  0,
236
237
  0,
@@ -419,7 +420,6 @@ pgconn_s_conninfo_parse(VALUE self, VALUE conninfo)
419
420
  }
420
421
 
421
422
 
422
- #ifdef HAVE_PQENCRYPTPASSWORDCONN
423
423
  static VALUE
424
424
  pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
425
425
  {
@@ -443,7 +443,6 @@ pgconn_sync_encrypt_password(int argc, VALUE *argv, VALUE self)
443
443
 
444
444
  return rval;
445
445
  }
446
- #endif
447
446
 
448
447
 
449
448
  /*
@@ -609,7 +608,7 @@ pgconn_reset_start(VALUE self)
609
608
  * conn.reset_poll -> Integer
610
609
  *
611
610
  * Checks the status of a connection reset operation.
612
- * See #connect_start and #connect_poll for
611
+ * See Connection.connect_start and #connect_poll for
613
612
  * usage information and return values.
614
613
  */
615
614
  static VALUE
@@ -760,7 +759,6 @@ pgconn_options(VALUE self)
760
759
  *
761
760
  * Returns the connection options used by a live connection.
762
761
  *
763
- * Available since PostgreSQL-9.3
764
762
  */
765
763
  static VALUE
766
764
  pgconn_conninfo( VALUE self )
@@ -847,31 +845,52 @@ pgconn_parameter_status(VALUE self, VALUE param_name)
847
845
  * call-seq:
848
846
  * conn.protocol_version -> Integer
849
847
  *
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.)
848
+ * Interrogates the frontend/backend protocol being used.
849
+ *
850
+ * Applications might wish to use this function to determine whether certain features are supported.
851
+ * Currently, the only value is 3 (3.0 protocol).
852
+ * The protocol version will not change after connection startup is complete, but it could theoretically change during a connection reset.
853
+ * The 3.0 protocol is supported by PostgreSQL server versions 7.4 and above.
854
+ *
855
+ * PG::ConnectionBad is raised if the connection is bad.
853
856
  */
854
857
  static VALUE
855
858
  pgconn_protocol_version(VALUE self)
856
859
  {
857
- return INT2NUM(PQprotocolVersion(pg_get_pgconn(self)));
860
+ int protocol_version = PQprotocolVersion(pg_get_pgconn(self));
861
+ if (protocol_version == 0) {
862
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQprotocolVersion() can't get protocol version");
863
+ }
864
+ return INT2NUM(protocol_version);
858
865
  }
859
866
 
860
867
  /*
861
868
  * call-seq:
862
869
  * conn.server_version -> Integer
863
870
  *
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.
871
+ * Returns an integer representing the server version.
872
+ *
873
+ * Applications might use this function to determine the version of the database server they are connected to.
874
+ * The result is formed by multiplying the server's major version number by 10000 and adding the minor version number.
875
+ * For example, version 10.1 will be returned as 100001, and version 11.0 will be returned as 110000.
876
+ *
877
+ * PG::ConnectionBad is raised if the connection is bad.
878
+ *
879
+ * Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version.
880
+ * 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.
881
+ *
882
+ * 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.
883
+ * In all release series, only the last two digits differ between minor releases (bug-fix releases).
869
884
  *
870
885
  */
871
886
  static VALUE
872
887
  pgconn_server_version(VALUE self)
873
888
  {
874
- return INT2NUM(PQserverVersion(pg_get_pgconn(self)));
889
+ int server_version = PQserverVersion(pg_get_pgconn(self));
890
+ if (server_version == 0) {
891
+ pg_raise_conn_error( rb_eConnectionBad, self, "PQserverVersion() can't get server version");
892
+ }
893
+ return INT2NUM(server_version);
875
894
  }
876
895
 
877
896
  /*
@@ -920,13 +939,42 @@ pgconn_socket(VALUE self)
920
939
  return INT2NUM(sd);
921
940
  }
922
941
 
942
+
943
+ VALUE
944
+ pg_wrap_socket_io(int sd, VALUE self, VALUE *p_socket_io, int *p_ruby_sd)
945
+ {
946
+ int ruby_sd;
947
+ VALUE cSocket;
948
+ VALUE socket_io = *p_socket_io;
949
+
950
+ #ifdef _WIN32
951
+ ruby_sd = rb_w32_wrap_io_handle((HANDLE)(intptr_t)sd, O_RDWR|O_BINARY|O_NOINHERIT);
952
+ if( ruby_sd == -1 )
953
+ pg_raise_conn_error( rb_eConnectionBad, self, "Could not wrap win32 socket handle");
954
+
955
+ *p_ruby_sd = ruby_sd;
956
+ #else
957
+ *p_ruby_sd = ruby_sd = sd;
958
+ #endif
959
+
960
+ cSocket = rb_const_get(rb_cObject, rb_intern("BasicSocket"));
961
+ socket_io = rb_funcall( cSocket, rb_intern("for_fd"), 1, INT2NUM(ruby_sd));
962
+
963
+ /* Disable autoclose feature */
964
+ rb_funcall( socket_io, s_id_autoclose_set, 1, Qfalse );
965
+
966
+ RB_OBJ_WRITE(self, p_socket_io, socket_io);
967
+
968
+ return socket_io;
969
+ }
970
+
923
971
  /*
924
972
  * call-seq:
925
973
  * conn.socket_io() -> IO
926
974
  *
927
975
  * Fetch an IO object created from the Connection's underlying socket.
928
976
  * 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>.
977
+ * <tt>IO#wait_*able</tt> is <tt>Fiber.scheduler</tt> compatible in contrast to <tt>IO.select</tt>.
930
978
  *
931
979
  * The IO object can change while the connection is established, but is memorized afterwards.
932
980
  * So be sure not to cache the IO object, but repeat calling <tt>conn.socket_io</tt> instead.
@@ -937,37 +985,17 @@ pgconn_socket(VALUE self)
937
985
  static VALUE
938
986
  pgconn_socket_io(VALUE self)
939
987
  {
940
- int sd;
941
- int ruby_sd;
942
988
  t_pg_connection *this = pg_get_connection_safe( self );
943
- VALUE cSocket;
944
- VALUE socket_io = this->socket_io;
945
989
 
946
- if ( !RTEST(socket_io) ) {
990
+ if ( !RTEST(this->socket_io) ) {
991
+ int sd;
947
992
  if( (sd = PQsocket(this->pgconn)) < 0){
948
993
  pg_raise_conn_error( rb_eConnectionBad, self, "PQsocket() can't get socket descriptor");
949
994
  }
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);
995
+ return pg_wrap_socket_io( sd, self, &this->socket_io, &this->ruby_sd);
968
996
  }
969
997
 
970
- return socket_io;
998
+ return this->socket_io;
971
999
  }
972
1000
 
973
1001
  /*
@@ -984,6 +1012,7 @@ pgconn_backend_pid(VALUE self)
984
1012
  return INT2NUM(PQbackendPID(pg_get_pgconn(self)));
985
1013
  }
986
1014
 
1015
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
987
1016
  typedef struct
988
1017
  {
989
1018
  struct sockaddr_storage addr;
@@ -1028,6 +1057,7 @@ pgconn_backend_key(VALUE self)
1028
1057
 
1029
1058
  return INT2NUM(be_key);
1030
1059
  }
1060
+ #endif
1031
1061
 
1032
1062
  /*
1033
1063
  * call-seq:
@@ -1300,7 +1330,7 @@ alloc_query_params(struct query_params_data *paramsData)
1300
1330
  paramsData->lengths[i] = 0;
1301
1331
  } else {
1302
1332
  t_pg_coder_enc_func enc_func = pg_coder_enc_func( conv );
1303
- VALUE intermediate;
1333
+ VALUE intermediate = Qnil;
1304
1334
 
1305
1335
  /* 1st pass for retiving the required memory space */
1306
1336
  int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
@@ -1340,8 +1370,6 @@ alloc_query_params(struct query_params_data *paramsData)
1340
1370
  required_pool_size += len;
1341
1371
  }
1342
1372
  }
1343
-
1344
- RB_GC_GUARD(intermediate);
1345
1373
  }
1346
1374
  }
1347
1375
  }
@@ -1516,6 +1544,19 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
1516
1544
  return rb_pgresult;
1517
1545
  }
1518
1546
 
1547
+ static VALUE
1548
+ pgconn_sync_describe_close_prepared_portal(VALUE self, VALUE name, PGresult *(*func)(PGconn *, const char *))
1549
+ {
1550
+ PGresult *result;
1551
+ VALUE rb_pgresult;
1552
+ t_pg_connection *this = pg_get_connection_safe( self );
1553
+ const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
1554
+ result = func(this->pgconn, stmt);
1555
+ rb_pgresult = pg_new_result(result, self);
1556
+ pg_result_check(rb_pgresult);
1557
+ return rb_pgresult;
1558
+ }
1559
+
1519
1560
  /*
1520
1561
  * call-seq:
1521
1562
  * conn.sync_describe_prepared( statement_name ) -> PG::Result
@@ -1527,20 +1568,7 @@ pgconn_sync_exec_prepared(int argc, VALUE *argv, VALUE self)
1527
1568
  static VALUE
1528
1569
  pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1529
1570
  {
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;
1571
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePrepared);
1544
1572
  }
1545
1573
 
1546
1574
 
@@ -1555,23 +1583,44 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1555
1583
  static VALUE
1556
1584
  pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1557
1585
  {
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;
1586
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQdescribePortal);
1572
1587
  }
1573
1588
 
1574
1589
 
1590
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
1591
+ /*
1592
+ * call-seq:
1593
+ * conn.sync_close_prepared( stmt_name ) -> PG::Result
1594
+ *
1595
+ * This function has the same behavior as #async_close_prepared, but is implemented using the synchronous command processing API of libpq.
1596
+ * See #async_exec for the differences between the two API variants.
1597
+ * It's not recommended to use explicit sync or async variants but #close_prepared instead, unless you have a good reason to do so.
1598
+ *
1599
+ * Available since PostgreSQL-17.
1600
+ */
1601
+ static VALUE
1602
+ pgconn_sync_close_prepared(VALUE self, VALUE stmt_name)
1603
+ {
1604
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePrepared);
1605
+ }
1606
+
1607
+ /*
1608
+ * call-seq:
1609
+ * conn.sync_close_portal( portal_name ) -> PG::Result
1610
+ *
1611
+ * This function has the same behavior as #async_close_portal, but is implemented using the synchronous command processing API of libpq.
1612
+ * See #async_exec for the differences between the two API variants.
1613
+ * It's not recommended to use explicit sync or async variants but #close_portal instead, unless you have a good reason to do so.
1614
+ *
1615
+ * Available since PostgreSQL-17.
1616
+ */
1617
+ static VALUE
1618
+ pgconn_sync_close_portal(VALUE self, VALUE stmt_name)
1619
+ {
1620
+ return pgconn_sync_describe_close_prepared_portal(self, stmt_name, gvl_PQclosePortal);
1621
+ }
1622
+ #endif
1623
+
1575
1624
  /*
1576
1625
  * call-seq:
1577
1626
  * conn.make_empty_pgresult( status ) -> PG::Result
@@ -1588,6 +1637,7 @@ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1588
1637
  * * +PGRES_FATAL_ERROR+
1589
1638
  * * +PGRES_COPY_BOTH+
1590
1639
  * * +PGRES_SINGLE_TUPLE+
1640
+ * * +PGRES_TUPLES_CHUNK+
1591
1641
  * * +PGRES_PIPELINE_SYNC+
1592
1642
  * * +PGRES_PIPELINE_ABORTED+
1593
1643
  */
@@ -1812,14 +1862,11 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1812
1862
  * (column names, types, etc) that an ordinary Result object for the query
1813
1863
  * would have.
1814
1864
  *
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.
1865
+ * *Caution:* While processing a query, the server may return some rows and then encounter an error, causing the query to be aborted.
1866
+ * Ordinarily, pg discards any such rows and reports only the error.
1867
+ * But in single-row or chunked mode, some rows may have already been returned to the application.
1868
+ * 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.
1869
+ * 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
1870
  *
1824
1871
  * Example:
1825
1872
  * conn.send_query( "your SQL command" )
@@ -1839,11 +1886,50 @@ pgconn_set_single_row_mode(VALUE self)
1839
1886
 
1840
1887
  rb_check_frozen(self);
1841
1888
  if( PQsetSingleRowMode(conn) == 0 )
1842
- pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
1889
+ pg_raise_conn_error( rb_ePGerror, self, "PQsetSingleRowMode %s", PQerrorMessage(conn));
1843
1890
 
1844
1891
  return self;
1845
1892
  }
1846
1893
 
1894
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
1895
+ /*
1896
+ * call-seq:
1897
+ * conn.set_chunked_rows_mode -> self
1898
+ *
1899
+ * Select chunked mode for the currently-executing query.
1900
+ *
1901
+ * 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.
1902
+ * 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.
1903
+ * If called at the correct time, the function activates chunked mode for the current query.
1904
+ * Otherwise the mode stays unchanged and the function raises an error.
1905
+ * In any case, the mode reverts to normal after completion of the current query.
1906
+ *
1907
+ * Example:
1908
+ * conn.send_query( "your SQL command" )
1909
+ * conn.set_chunked_rows_mode(10)
1910
+ * loop do
1911
+ * res = conn.get_result or break
1912
+ * res.check
1913
+ * res.each do |row|
1914
+ * # do something with the received max. 10 rows
1915
+ * end
1916
+ * end
1917
+ *
1918
+ * Available since PostgreSQL-17
1919
+ */
1920
+ static VALUE
1921
+ pgconn_set_chunked_rows_mode(VALUE self, VALUE chunk_size)
1922
+ {
1923
+ PGconn *conn = pg_get_pgconn(self);
1924
+
1925
+ rb_check_frozen(self);
1926
+ if( PQsetChunkedRowsMode(conn, NUM2INT(chunk_size)) == 0 )
1927
+ pg_raise_conn_error( rb_ePGerror, self, "PQsetChunkedRowsMode %s", PQerrorMessage(conn));
1928
+
1929
+ return self;
1930
+ }
1931
+ #endif
1932
+
1847
1933
  static VALUE pgconn_send_query_params(int argc, VALUE *argv, VALUE self);
1848
1934
 
1849
1935
  /*
@@ -1867,7 +1953,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1867
1953
  /* If called with no or nil parameters, use PQexec for compatibility */
1868
1954
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
1869
1955
  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));
1956
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQuery %s", PQerrorMessage(this->pgconn));
1871
1957
 
1872
1958
  pgconn_wait_for_flush( self );
1873
1959
  return Qnil;
@@ -1942,7 +2028,7 @@ pgconn_send_query_params(int argc, VALUE *argv, VALUE self)
1942
2028
  free_query_params( &paramsData );
1943
2029
 
1944
2030
  if(result == 0)
1945
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2031
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryParams %s", PQerrorMessage(this->pgconn));
1946
2032
 
1947
2033
  pgconn_wait_for_flush( self );
1948
2034
  return Qnil;
@@ -2003,7 +2089,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
2003
2089
  xfree(paramTypes);
2004
2090
 
2005
2091
  if(result == 0) {
2006
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2092
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendPrepare %s", PQerrorMessage(this->pgconn));
2007
2093
  }
2008
2094
  pgconn_wait_for_flush( self );
2009
2095
  return Qnil;
@@ -2069,7 +2155,21 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2069
2155
  free_query_params( &paramsData );
2070
2156
 
2071
2157
  if(result == 0)
2072
- pg_raise_conn_error( rb_eUnableToSend, self, "%s", PQerrorMessage(this->pgconn));
2158
+ pg_raise_conn_error( rb_eUnableToSend, self, "PQsendQueryPrepared %s", PQerrorMessage(this->pgconn));
2159
+
2160
+ pgconn_wait_for_flush( self );
2161
+ return Qnil;
2162
+ }
2163
+
2164
+
2165
+ static VALUE
2166
+ pgconn_send_describe_close_prepared_portal(VALUE self, VALUE name, int (*func)(PGconn *, const char *), const char *funame)
2167
+ {
2168
+ t_pg_connection *this = pg_get_connection_safe( self );
2169
+ const char *stmt = NIL_P(name) ? NULL : pg_cstr_enc(name, this->enc_idx);
2170
+ /* returns 0 on failure */
2171
+ if(func(this->pgconn, stmt) == 0)
2172
+ pg_raise_conn_error( rb_eUnableToSend, self, "%s %s", funame, PQerrorMessage(this->pgconn));
2073
2173
 
2074
2174
  pgconn_wait_for_flush( self );
2075
2175
  return Qnil;
@@ -2085,13 +2185,9 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
2085
2185
  static VALUE
2086
2186
  pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2087
2187
  {
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;
2188
+ return pgconn_send_describe_close_prepared_portal(
2189
+ self, stmt_name, gvl_PQsendDescribePrepared,
2190
+ "PQsendDescribePrepared");
2095
2191
  }
2096
2192
 
2097
2193
 
@@ -2105,16 +2201,48 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
2105
2201
  static VALUE
2106
2202
  pgconn_send_describe_portal(VALUE self, VALUE portal)
2107
2203
  {
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));
2204
+ return pgconn_send_describe_close_prepared_portal(
2205
+ self, portal, gvl_PQsendDescribePortal,
2206
+ "PQsendDescribePortal");
2207
+ }
2112
2208
 
2113
- pgconn_wait_for_flush( self );
2114
- return Qnil;
2209
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
2210
+ /*
2211
+ * call-seq:
2212
+ * conn.send_close_prepared( statement_name ) -> nil
2213
+ *
2214
+ * Asynchronously send _command_ to the server. Does not block.
2215
+ * Use in combination with +conn.get_result+.
2216
+ *
2217
+ * Available since PostgreSQL-17.
2218
+ */
2219
+ static VALUE
2220
+ pgconn_send_close_prepared(VALUE self, VALUE stmt_name)
2221
+ {
2222
+ return pgconn_send_describe_close_prepared_portal(
2223
+ self, stmt_name, gvl_PQsendClosePrepared,
2224
+ "PQsendClosePrepared");
2115
2225
  }
2116
2226
 
2117
2227
 
2228
+ /*
2229
+ * call-seq:
2230
+ * conn.send_close_portal( portal_name ) -> nil
2231
+ *
2232
+ * Asynchronously send _command_ to the server. Does not block.
2233
+ * Use in combination with +conn.get_result+.
2234
+ *
2235
+ * Available since PostgreSQL-17.
2236
+ */
2237
+ static VALUE
2238
+ pgconn_send_close_portal(VALUE self, VALUE portal)
2239
+ {
2240
+ return pgconn_send_describe_close_prepared_portal(
2241
+ self, portal, gvl_PQsendClosePortal,
2242
+ "PQsendClosePortal");
2243
+ }
2244
+ #endif
2245
+
2118
2246
  static VALUE
2119
2247
  pgconn_sync_get_result(VALUE self)
2120
2248
  {
@@ -2204,6 +2332,7 @@ pgconn_sync_flush(VALUE self)
2204
2332
  return (ret) ? Qfalse : Qtrue;
2205
2333
  }
2206
2334
 
2335
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
2207
2336
  static VALUE
2208
2337
  pgconn_sync_cancel(VALUE self)
2209
2338
  {
@@ -2225,6 +2354,7 @@ pgconn_sync_cancel(VALUE self)
2225
2354
  PQfreeCancel(cancel);
2226
2355
  return retval;
2227
2356
  }
2357
+ #endif
2228
2358
 
2229
2359
 
2230
2360
  /*
@@ -2271,8 +2401,9 @@ pgconn_notifies(VALUE self)
2271
2401
  static int
2272
2402
  rb_io_descriptor(VALUE io)
2273
2403
  {
2404
+ rb_io_t *fptr;
2274
2405
  Check_Type(io, T_FILE);
2275
- rb_io_t *fptr = RFILE(io)->fptr;
2406
+ fptr = RFILE(io)->fptr;
2276
2407
  rb_io_check_closed(fptr);
2277
2408
  return fptr->fd;
2278
2409
  }
@@ -2568,7 +2699,7 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2568
2699
  VALUE value;
2569
2700
  VALUE buffer = Qnil;
2570
2701
  VALUE encoder;
2571
- VALUE intermediate;
2702
+ VALUE intermediate = Qnil;
2572
2703
  t_pg_coder *p_coder = NULL;
2573
2704
 
2574
2705
  rb_scan_args( argc, argv, "11", &value, &encoder );
@@ -2607,7 +2738,6 @@ pgconn_sync_put_copy_data(int argc, VALUE *argv, VALUE self)
2607
2738
  if(ret == -1)
2608
2739
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(this->pgconn));
2609
2740
 
2610
- RB_GC_GUARD(intermediate);
2611
2741
  RB_GC_GUARD(buffer);
2612
2742
 
2613
2743
  return (ret) ? Qtrue : Qfalse;
@@ -2702,7 +2832,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2702
2832
  return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
2703
2833
  }
2704
2834
 
2705
- #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
2706
2835
  /*
2707
2836
  * call-seq:
2708
2837
  * conn.set_error_context_visibility( context_visibility ) -> Integer
@@ -2722,7 +2851,6 @@ pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2722
2851
  *
2723
2852
  * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY].
2724
2853
  *
2725
- * Available since PostgreSQL-9.6
2726
2854
  */
2727
2855
  static VALUE
2728
2856
  pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
@@ -2731,7 +2859,6 @@ pgconn_set_error_context_visibility(VALUE self, VALUE in_context_visibility)
2731
2859
  PGContextVisibility context_visibility = NUM2INT(in_context_visibility);
2732
2860
  return INT2FIX(PQsetErrorContextVisibility(conn, context_visibility));
2733
2861
  }
2734
- #endif
2735
2862
 
2736
2863
  /*
2737
2864
  * call-seq:
@@ -3459,6 +3586,21 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3459
3586
  return rb_pgresult;
3460
3587
  }
3461
3588
 
3589
+ static VALUE
3590
+ pgconn_async_describe_close_prepared_potral(VALUE self, VALUE name, VALUE
3591
+ (*func)(VALUE, VALUE))
3592
+ {
3593
+ VALUE rb_pgresult = Qnil;
3594
+
3595
+ pgconn_discard_results( self );
3596
+ func( self, name );
3597
+ rb_pgresult = pgconn_async_get_last_result( self );
3598
+
3599
+ if ( rb_block_given_p() ) {
3600
+ return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3601
+ }
3602
+ return rb_pgresult;
3603
+ }
3462
3604
 
3463
3605
  /*
3464
3606
  * call-seq:
@@ -3471,16 +3613,7 @@ pgconn_async_exec_prepared(int argc, VALUE *argv, VALUE self)
3471
3613
  static VALUE
3472
3614
  pgconn_async_describe_portal(VALUE self, VALUE portal)
3473
3615
  {
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;
3616
+ return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_describe_portal);
3484
3617
  }
3485
3618
 
3486
3619
 
@@ -3495,27 +3628,64 @@ pgconn_async_describe_portal(VALUE self, VALUE portal)
3495
3628
  static VALUE
3496
3629
  pgconn_async_describe_prepared(VALUE self, VALUE stmt_name)
3497
3630
  {
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 );
3631
+ return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_describe_prepared);
3632
+ }
3503
3633
 
3504
- if ( rb_block_given_p() ) {
3505
- return rb_ensure( rb_yield, rb_pgresult, pg_result_clear, rb_pgresult );
3506
- }
3507
- return rb_pgresult;
3634
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
3635
+ /*
3636
+ * call-seq:
3637
+ * conn.close_prepared( statement_name ) -> PG::Result
3638
+ *
3639
+ * Submits a request to close the specified prepared statement, and waits for completion.
3640
+ * close_prepared allows an application to close a previously prepared statement.
3641
+ * Closing a statement releases all of its associated resources on the server and allows its name to be reused.
3642
+ * It's the same as using the +DEALLOCATE+ SQL statement, but on a lower protocol level.
3643
+ *
3644
+ * +statement_name+ can be "" or +nil+ to reference the unnamed statement.
3645
+ * It is fine if no statement exists with this name, in that case the operation is a no-op.
3646
+ * On success, a PG::Result with status PGRES_COMMAND_OK is returned.
3647
+ *
3648
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPREPARED].
3649
+ *
3650
+ * Available since PostgreSQL-17.
3651
+ */
3652
+ static VALUE
3653
+ pgconn_async_close_prepared(VALUE self, VALUE stmt_name)
3654
+ {
3655
+ return pgconn_async_describe_close_prepared_potral(self, stmt_name, pgconn_send_close_prepared);
3508
3656
  }
3509
3657
 
3658
+ /*
3659
+ * call-seq:
3660
+ * conn.close_portal( portal_name ) -> PG::Result
3661
+ *
3662
+ * Submits a request to close the specified portal, and waits for completion.
3663
+ *
3664
+ * close_portal allows an application to trigger a close of a previously created portal.
3665
+ * Closing a portal releases all of its associated resources on the server and allows its name to be reused.
3666
+ * (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.)
3667
+ *
3668
+ * +portal_name+ can be "" or +nil+ to reference the unnamed portal.
3669
+ * It is fine if no portal exists with this name, in that case the operation is a no-op.
3670
+ * On success, a PG::Result with status PGRES_COMMAND_OK is returned.
3671
+ *
3672
+ * See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-PQCLOSEPORTAL].
3673
+ *
3674
+ * Available since PostgreSQL-17.
3675
+ */
3676
+ static VALUE
3677
+ pgconn_async_close_portal(VALUE self, VALUE portal)
3678
+ {
3679
+ return pgconn_async_describe_close_prepared_potral(self, portal, pgconn_send_close_portal);
3680
+ }
3681
+ #endif
3510
3682
 
3511
- #ifdef HAVE_PQSSLATTRIBUTE
3512
3683
  /*
3513
3684
  * call-seq:
3514
3685
  * conn.ssl_in_use? -> Boolean
3515
3686
  *
3516
3687
  * Returns +true+ if the connection uses SSL/TLS, +false+ if not.
3517
3688
  *
3518
- * Available since PostgreSQL-9.5
3519
3689
  */
3520
3690
  static VALUE
3521
3691
  pgconn_ssl_in_use(VALUE self)
@@ -3549,7 +3719,6 @@ pgconn_ssl_in_use(VALUE self)
3549
3719
  *
3550
3720
  * See also #ssl_attribute_names and the {corresponding libpq function}[https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSSLATTRIBUTE].
3551
3721
  *
3552
- * Available since PostgreSQL-9.5
3553
3722
  */
3554
3723
  static VALUE
3555
3724
  pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
@@ -3568,7 +3737,6 @@ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3568
3737
  *
3569
3738
  * See also #ssl_attribute
3570
3739
  *
3571
- * Available since PostgreSQL-9.5
3572
3740
  */
3573
3741
  static VALUE
3574
3742
  pgconn_ssl_attribute_names(VALUE self)
@@ -3584,8 +3752,6 @@ pgconn_ssl_attribute_names(VALUE self)
3584
3752
  }
3585
3753
 
3586
3754
 
3587
- #endif
3588
-
3589
3755
 
3590
3756
  #ifdef HAVE_PQENTERPIPELINEMODE
3591
3757
  /*
@@ -3620,6 +3786,8 @@ pgconn_pipeline_status(VALUE self)
3620
3786
  * 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
3787
  * This function does not actually send anything to the server, it just changes the libpq connection state.
3622
3788
  *
3789
+ * See the {PostgreSQL documentation}[https://www.postgresql.org/docs/17/libpq-pipeline-mode.html#LIBPQ-PIPELINE-MODE].
3790
+ *
3623
3791
  * Available since PostgreSQL-14
3624
3792
  */
3625
3793
  static VALUE
@@ -3658,29 +3826,55 @@ pgconn_exit_pipeline_mode(VALUE self)
3658
3826
 
3659
3827
  /*
3660
3828
  * call-seq:
3661
- * conn.pipeline_sync -> nil
3829
+ * conn.sync_pipeline_sync -> nil
3662
3830
  *
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.
3831
+ * This function has the same behavior as #async_pipeline_sync, but is implemented using the synchronous command processing API of libpq.
3832
+ * See #async_exec for the differences between the two API variants.
3833
+ * It's not recommended to use explicit sync or async variants but #pipeline_sync instead, unless you have a good reason to do so.
3665
3834
  *
3835
+ * Available since PostgreSQL-14
3836
+ */
3837
+ static VALUE
3838
+ pgconn_sync_pipeline_sync(VALUE self)
3839
+ {
3840
+ PGconn *conn = pg_get_pgconn(self);
3841
+ int res = gvl_PQpipelineSync(conn);
3842
+ if( res != 1 )
3843
+ pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3844
+
3845
+ return Qnil;
3846
+ }
3847
+
3848
+
3849
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
3850
+ /*
3851
+ * call-seq:
3852
+ * conn.send_pipeline_sync -> nil
3853
+ *
3854
+ * Marks a synchronization point in a pipeline by sending a sync message without flushing the send buffer.
3855
+ *
3856
+ * This serves as the delimiter of an implicit transaction and an error recovery point.
3666
3857
  * Raises PG::Error if the connection is not in pipeline mode or sending a sync message failed.
3858
+ * Note that the message is not itself flushed to the server automatically; use flush if necessary.
3667
3859
  *
3668
- * Available since PostgreSQL-14
3860
+ * Available since PostgreSQL-17
3669
3861
  */
3670
3862
  static VALUE
3671
- pgconn_pipeline_sync(VALUE self)
3863
+ pgconn_send_pipeline_sync(VALUE self)
3672
3864
  {
3673
3865
  PGconn *conn = pg_get_pgconn(self);
3674
- int res = PQpipelineSync(conn);
3866
+ int res = gvl_PQsendPipelineSync(conn);
3675
3867
  if( res != 1 )
3676
3868
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3677
3869
 
3678
3870
  return Qnil;
3679
3871
  }
3872
+ #endif
3873
+
3680
3874
 
3681
3875
  /*
3682
3876
  * call-seq:
3683
- * conn.pipeline_sync -> nil
3877
+ * conn.send_flush_request -> nil
3684
3878
  *
3685
3879
  * Sends a request for the server to flush its output buffer.
3686
3880
  *
@@ -4524,7 +4718,9 @@ init_pg_connection(void)
4524
4718
  rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
4525
4719
  rb_define_method(rb_cPGconn, "socket_io", pgconn_socket_io, 0);
4526
4720
  rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
4721
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
4527
4722
  rb_define_method(rb_cPGconn, "backend_key", pgconn_backend_key, 0);
4723
+ #endif
4528
4724
  rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
4529
4725
  rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
4530
4726
  /* rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0); */
@@ -4536,6 +4732,10 @@ init_pg_connection(void)
4536
4732
  rb_define_method(rb_cPGconn, "sync_exec_prepared", pgconn_sync_exec_prepared, -1);
4537
4733
  rb_define_method(rb_cPGconn, "sync_describe_prepared", pgconn_sync_describe_prepared, 1);
4538
4734
  rb_define_method(rb_cPGconn, "sync_describe_portal", pgconn_sync_describe_portal, 1);
4735
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4736
+ rb_define_method(rb_cPGconn, "sync_close_prepared", pgconn_sync_close_prepared, 1);
4737
+ rb_define_method(rb_cPGconn, "sync_close_portal", pgconn_sync_close_portal, 1);
4738
+ #endif
4539
4739
 
4540
4740
  rb_define_method(rb_cPGconn, "exec", pgconn_async_exec, -1);
4541
4741
  rb_define_method(rb_cPGconn, "exec_params", pgconn_async_exec_params, -1);
@@ -4543,6 +4743,10 @@ init_pg_connection(void)
4543
4743
  rb_define_method(rb_cPGconn, "exec_prepared", pgconn_async_exec_prepared, -1);
4544
4744
  rb_define_method(rb_cPGconn, "describe_prepared", pgconn_async_describe_prepared, 1);
4545
4745
  rb_define_method(rb_cPGconn, "describe_portal", pgconn_async_describe_portal, 1);
4746
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4747
+ rb_define_method(rb_cPGconn, "close_prepared", pgconn_async_close_prepared, 1);
4748
+ rb_define_method(rb_cPGconn, "close_portal", pgconn_async_close_portal, 1);
4749
+ #endif
4546
4750
 
4547
4751
  rb_define_alias(rb_cPGconn, "async_exec", "exec");
4548
4752
  rb_define_alias(rb_cPGconn, "async_query", "async_exec");
@@ -4551,6 +4755,10 @@ init_pg_connection(void)
4551
4755
  rb_define_alias(rb_cPGconn, "async_exec_prepared", "exec_prepared");
4552
4756
  rb_define_alias(rb_cPGconn, "async_describe_prepared", "describe_prepared");
4553
4757
  rb_define_alias(rb_cPGconn, "async_describe_portal", "describe_portal");
4758
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4759
+ rb_define_alias(rb_cPGconn, "async_close_prepared", "close_prepared");
4760
+ rb_define_alias(rb_cPGconn, "async_close_portal", "close_portal");
4761
+ #endif
4554
4762
 
4555
4763
  rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
4556
4764
  rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
@@ -4560,6 +4768,9 @@ init_pg_connection(void)
4560
4768
  rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4561
4769
  rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4562
4770
  rb_define_method(rb_cPGconn, "set_single_row_mode", pgconn_set_single_row_mode, 0);
4771
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4772
+ rb_define_method(rb_cPGconn, "set_chunked_rows_mode", pgconn_set_chunked_rows_mode, 1);
4773
+ #endif
4563
4774
 
4564
4775
  /****** PG::Connection INSTANCE METHODS: Asynchronous Command Processing ******/
4565
4776
  rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
@@ -4579,7 +4790,9 @@ init_pg_connection(void)
4579
4790
  rb_define_method(rb_cPGconn, "discard_results", pgconn_discard_results, 0);
4580
4791
 
4581
4792
  /****** PG::Connection INSTANCE METHODS: Cancelling Queries in Progress ******/
4793
+ #ifndef HAVE_PQSETCHUNKEDROWSMODE
4582
4794
  rb_define_method(rb_cPGconn, "sync_cancel", pgconn_sync_cancel, 0);
4795
+ #endif
4583
4796
 
4584
4797
  /****** PG::Connection INSTANCE METHODS: NOTIFY ******/
4585
4798
  rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
@@ -4591,9 +4804,7 @@ init_pg_connection(void)
4591
4804
 
4592
4805
  /****** PG::Connection INSTANCE METHODS: Control Functions ******/
4593
4806
  rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
4594
- #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
4595
4807
  rb_define_method(rb_cPGconn, "set_error_context_visibility", pgconn_set_error_context_visibility, 1 );
4596
- #endif
4597
4808
  rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4598
4809
  rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4599
4810
 
@@ -4615,22 +4826,21 @@ init_pg_connection(void)
4615
4826
  rb_define_method(rb_cPGconn, "sync_get_last_result", pgconn_sync_get_last_result, 0);
4616
4827
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_async_get_last_result, 0);
4617
4828
  rb_define_alias(rb_cPGconn, "async_get_last_result", "get_last_result");
4618
- #ifdef HAVE_PQENCRYPTPASSWORDCONN
4619
4829
  rb_define_method(rb_cPGconn, "sync_encrypt_password", pgconn_sync_encrypt_password, -1);
4620
- #endif
4621
4830
 
4622
- #ifdef HAVE_PQSSLATTRIBUTE
4623
4831
  rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
4624
4832
  rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
4625
4833
  rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
4626
- #endif
4627
4834
 
4628
4835
  #ifdef HAVE_PQENTERPIPELINEMODE
4629
4836
  rb_define_method(rb_cPGconn, "pipeline_status", pgconn_pipeline_status, 0);
4630
4837
  rb_define_method(rb_cPGconn, "enter_pipeline_mode", pgconn_enter_pipeline_mode, 0);
4631
4838
  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);
4839
+ rb_define_method(rb_cPGconn, "sync_pipeline_sync", pgconn_sync_pipeline_sync, 0);
4633
4840
  rb_define_method(rb_cPGconn, "send_flush_request", pgconn_send_flush_request, 0);
4841
+ #ifdef HAVE_PQSETCHUNKEDROWSMODE
4842
+ rb_define_method(rb_cPGconn, "send_pipeline_sync", pgconn_send_pipeline_sync, 0);
4843
+ #endif
4634
4844
  #endif
4635
4845
 
4636
4846
  /****** PG::Connection INSTANCE METHODS: Large Object Support ******/