pg 1.5.9-x64-mingw-ucrt → 1.6.0-x64-mingw-ucrt
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/{History.md → CHANGELOG.md} +46 -0
- data/Gemfile +7 -4
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +4 -4
- data/README.md +6 -5
- data/Rakefile +80 -13
- data/ext/extconf.rb +158 -14
- data/ext/gvl_wrappers.c +13 -2
- data/ext/gvl_wrappers.h +33 -0
- data/ext/pg.c +16 -5
- data/ext/pg.h +9 -9
- data/ext/pg_binary_decoder.c +150 -0
- data/ext/pg_binary_encoder.c +210 -7
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +52 -5
- data/ext/pg_connection.c +368 -158
- data/ext/pg_copy_coder.c +2 -2
- data/ext/pg_record_coder.c +1 -1
- data/ext/pg_result.c +9 -11
- data/ext/pg_text_encoder.c +20 -7
- data/ext/pg_tuple.c +2 -2
- data/ext/pg_type_map.c +1 -1
- data/ext/pg_type_map_all_strings.c +1 -1
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +2 -1
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +3 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/lib/3.1/pg_ext.so +0 -0
- data/lib/3.2/pg_ext.so +0 -0
- data/lib/3.3/pg_ext.so +0 -0
- data/lib/3.4/pg_ext.so +0 -0
- data/lib/pg/basic_type_map_for_queries.rb +7 -3
- data/lib/pg/basic_type_registry.rb +2 -2
- data/lib/pg/cancel_connection.rb +53 -0
- data/lib/pg/coder.rb +2 -1
- data/lib/pg/connection.rb +254 -131
- data/lib/pg/version.rb +1 -1
- data/lib/pg.rb +13 -8
- data/misc/yugabyte/Dockerfile +9 -0
- data/misc/yugabyte/docker-compose.yml +28 -0
- data/misc/yugabyte/pg-test.rb +45 -0
- data/pg.gemspec +5 -3
- data/ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch +21 -0
- data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
- data/{lib/x64-mingw-ucrt → ports/x64-mingw-ucrt/lib}/libpq.dll +0 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data.tar.gz.sig +0 -0
- metadata +34 -25
- metadata.gz.sig +0 -0
- data/Manifest.txt +0 -72
- 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
|
-
|
34
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
*
|
851
|
-
*
|
852
|
-
*
|
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
|
-
|
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
|
-
*
|
865
|
-
*
|
866
|
-
*
|
867
|
-
*
|
868
|
-
*
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
*
|
1817
|
-
*
|
1818
|
-
*
|
1819
|
-
* application
|
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( ¶msData );
|
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( ¶msData );
|
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
|
-
|
2089
|
-
|
2090
|
-
|
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
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2204
|
+
return pgconn_send_describe_close_prepared_portal(
|
2205
|
+
self, portal, gvl_PQsendDescribePortal,
|
2206
|
+
"PQsendDescribePortal");
|
2207
|
+
}
|
2112
2208
|
|
2113
|
-
|
2114
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
3505
|
-
|
3506
|
-
|
3507
|
-
|
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.
|
3829
|
+
* conn.sync_pipeline_sync -> nil
|
3662
3830
|
*
|
3663
|
-
*
|
3664
|
-
*
|
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-
|
3860
|
+
* Available since PostgreSQL-17
|
3669
3861
|
*/
|
3670
3862
|
static VALUE
|
3671
|
-
|
3863
|
+
pgconn_send_pipeline_sync(VALUE self)
|
3672
3864
|
{
|
3673
3865
|
PGconn *conn = pg_get_pgconn(self);
|
3674
|
-
int res =
|
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.
|
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, "
|
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 ******/
|