pg 1.6.3 → 1.7.0
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/CHANGELOG.md +52 -6
- data/Gemfile +1 -0
- data/README.ja.md +81 -30
- data/README.md +14 -7
- data/Rakefile +8 -7
- data/certs/larskanis-2026.pem +24 -0
- data/ext/extconf.rb +18 -28
- data/ext/gvl_wrappers.c +2 -2
- data/ext/gvl_wrappers.h +40 -160
- data/ext/pg.c +8 -12
- data/ext/pg.h +8 -11
- data/ext/pg_binary_decoder.c +6 -2
- data/ext/pg_binary_encoder.c +7 -0
- data/ext/pg_cancel_connection.c +6 -6
- data/ext/pg_coder.c +4 -4
- data/ext/pg_connection.c +196 -159
- data/ext/pg_copy_coder.c +34 -21
- data/ext/pg_record_coder.c +10 -6
- data/ext/pg_result.c +42 -26
- data/ext/pg_text_decoder.c +6 -6
- data/ext/pg_text_encoder.c +7 -2
- data/ext/pg_tuple.c +1 -1
- data/ext/pg_type_map.c +41 -1
- data/ext/pg_type_map_all_strings.c +2 -2
- data/ext/pg_type_map_by_class.c +1 -1
- data/ext/pg_type_map_by_column.c +2 -2
- data/ext/pg_type_map_by_oid.c +1 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/lib/pg/basic_type_map_based_on_result.rb +5 -0
- data/lib/pg/basic_type_map_for_queries.rb +9 -2
- data/lib/pg/basic_type_map_for_results.rb +5 -0
- data/lib/pg/connection.rb +166 -76
- data/lib/pg/text_decoder/date.rb +1 -1
- data/lib/pg/text_decoder/json.rb +1 -1
- data/lib/pg/text_encoder/date.rb +7 -1
- data/lib/pg/text_encoder/json.rb +1 -1
- data/lib/pg/version.rb +1 -1
- data/misc/yugabyte/docker-compose.yml +1 -1
- data/pg.gemspec +1 -1
- data/sample/async_mixed.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +18 -19
- metadata.gz.sig +0 -0
- data/ports/patches/openssl/3.5.2/0001-aarch64-mingw.patch +0 -21
- data/ports/patches/postgresql/18.1/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +0 -52
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0001-Allow-static-linking-krb5-library.patch +0 -0
- /data/ports/patches/krb5/{1.22.1 → 1.22.2}/0002-unknown-command-line-option-on-clang.patch +0 -0
- /data/ports/patches/postgresql/{18.1 → 18.6}/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +0 -0
data/ext/gvl_wrappers.h
CHANGED
|
@@ -15,13 +15,18 @@
|
|
|
15
15
|
#ifndef __gvl_wrappers_h
|
|
16
16
|
#define __gvl_wrappers_h
|
|
17
17
|
|
|
18
|
+
#include <ruby/version.h>
|
|
18
19
|
#include <ruby/thread.h>
|
|
19
20
|
|
|
20
21
|
#ifdef RUBY_EXTCONF_H
|
|
21
22
|
# include RUBY_EXTCONF_H
|
|
22
23
|
#endif
|
|
23
24
|
|
|
24
|
-
#
|
|
25
|
+
#if RUBY_API_VERSION_MAJOR < 4
|
|
26
|
+
extern int ruby_thread_has_gvl_p(void);
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
25
30
|
typedef struct pg_cancel_conn PGcancelConn;
|
|
26
31
|
#endif
|
|
27
32
|
|
|
@@ -83,20 +88,35 @@ typedef struct pg_cancel_conn PGcancelConn;
|
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
#ifdef ENABLE_GVL_UNLOCK
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
#if RUBY_API_VERSION_MAJOR >= 4 || defined(TRUFFLERUBY)
|
|
92
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
|
93
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
|
94
|
+
struct gvl_wrapper_##name##_params params = { \
|
|
95
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
|
96
|
+
}; \
|
|
97
|
+
rb_thread_call_with_gvl(gvl_##name##_skeleton, ¶ms); \
|
|
98
|
+
when_non_void( return params.retval; ) \
|
|
99
|
+
}
|
|
100
|
+
#else
|
|
101
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
|
102
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
|
103
|
+
struct gvl_wrapper_##name##_params params = { \
|
|
104
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
|
105
|
+
}; \
|
|
106
|
+
if (ruby_thread_has_gvl_p()) { \
|
|
107
|
+
gvl_##name##_skeleton(¶ms); \
|
|
108
|
+
} else { \
|
|
109
|
+
rb_thread_call_with_gvl(gvl_##name##_skeleton, ¶ms); \
|
|
110
|
+
} \
|
|
111
|
+
when_non_void( return params.retval; ) \
|
|
112
|
+
}
|
|
113
|
+
#endif
|
|
94
114
|
#else
|
|
95
|
-
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
115
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
|
116
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
|
117
|
+
when_non_void( return ) \
|
|
118
|
+
name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
|
119
|
+
}
|
|
100
120
|
#endif
|
|
101
121
|
|
|
102
122
|
#define GVL_TYPE_VOID(string)
|
|
@@ -105,174 +125,34 @@ typedef struct pg_cancel_conn PGcancelConn;
|
|
|
105
125
|
|
|
106
126
|
/*
|
|
107
127
|
* Definitions of blocking functions and their parameters
|
|
128
|
+
*
|
|
129
|
+
* ATTENTION:
|
|
130
|
+
* Do not GVL-release functions that take pointers to ruby objects.
|
|
131
|
+
* If the ruby object is relocated by `GC.compact` from a second thread, before the pointer is used, it is no longer valid.
|
|
132
|
+
* That can lead to a crash or to wrong data.
|
|
133
|
+
* This issue has been raised in https://github.com/ged/ruby-pg/issues/738 and https://github.com/ged/ruby-pg/issues/721 .
|
|
108
134
|
*/
|
|
109
135
|
|
|
110
|
-
#define FOR_EACH_PARAM_OF_PQconnectdb(param)
|
|
111
|
-
|
|
112
136
|
#define FOR_EACH_PARAM_OF_PQconnectStart(param)
|
|
113
|
-
|
|
114
137
|
#define FOR_EACH_PARAM_OF_PQconnectPoll(param)
|
|
115
138
|
|
|
116
|
-
#define FOR_EACH_PARAM_OF_PQreset(param)
|
|
117
|
-
|
|
118
139
|
#define FOR_EACH_PARAM_OF_PQresetStart(param)
|
|
119
|
-
|
|
120
140
|
#define FOR_EACH_PARAM_OF_PQresetPoll(param)
|
|
121
141
|
|
|
122
142
|
#define FOR_EACH_PARAM_OF_PQping(param)
|
|
123
143
|
|
|
124
|
-
#define FOR_EACH_PARAM_OF_PQexec(param) \
|
|
125
|
-
param(PGconn *, conn)
|
|
126
|
-
|
|
127
|
-
#define FOR_EACH_PARAM_OF_PQexecParams(param) \
|
|
128
|
-
param(PGconn *, conn) \
|
|
129
|
-
param(const char *, command) \
|
|
130
|
-
param(int, nParams) \
|
|
131
|
-
param(const Oid *, paramTypes) \
|
|
132
|
-
param(const char * const *, paramValues) \
|
|
133
|
-
param(const int *, paramLengths) \
|
|
134
|
-
param(const int *, paramFormats)
|
|
135
|
-
|
|
136
|
-
#define FOR_EACH_PARAM_OF_PQexecPrepared(param) \
|
|
137
|
-
param(PGconn *, conn) \
|
|
138
|
-
param(const char *, stmtName) \
|
|
139
|
-
param(int, nParams) \
|
|
140
|
-
param(const char * const *, paramValues) \
|
|
141
|
-
param(const int *, paramLengths) \
|
|
142
|
-
param(const int *, paramFormats)
|
|
143
|
-
|
|
144
|
-
#define FOR_EACH_PARAM_OF_PQprepare(param) \
|
|
145
|
-
param(PGconn *, conn) \
|
|
146
|
-
param(const char *, stmtName) \
|
|
147
|
-
param(const char *, query) \
|
|
148
|
-
param(int, nParams)
|
|
149
|
-
|
|
150
|
-
#define FOR_EACH_PARAM_OF_PQdescribePrepared(param) \
|
|
151
|
-
param(PGconn *, conn)
|
|
152
|
-
|
|
153
|
-
#define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
|
|
154
|
-
param(PGconn *, conn)
|
|
155
|
-
|
|
156
|
-
#define FOR_EACH_PARAM_OF_PQclosePrepared(param) \
|
|
157
|
-
param(PGconn *, conn)
|
|
158
|
-
|
|
159
|
-
#define FOR_EACH_PARAM_OF_PQclosePortal(param) \
|
|
160
|
-
param(PGconn *, conn)
|
|
161
|
-
|
|
162
|
-
#define FOR_EACH_PARAM_OF_PQgetResult(param)
|
|
163
|
-
|
|
164
|
-
#define FOR_EACH_PARAM_OF_PQputCopyData(param) \
|
|
165
|
-
param(PGconn *, conn) \
|
|
166
|
-
param(const char *, buffer)
|
|
167
|
-
|
|
168
|
-
#define FOR_EACH_PARAM_OF_PQputCopyEnd(param) \
|
|
169
|
-
param(PGconn *, conn)
|
|
170
|
-
|
|
171
|
-
#define FOR_EACH_PARAM_OF_PQgetCopyData(param) \
|
|
172
|
-
param(PGconn *, conn) \
|
|
173
|
-
param(char **, buffer)
|
|
174
|
-
|
|
175
|
-
#define FOR_EACH_PARAM_OF_PQnotifies(param)
|
|
176
|
-
|
|
177
|
-
#define FOR_EACH_PARAM_OF_PQsendQuery(param) \
|
|
178
|
-
param(PGconn *, conn)
|
|
179
|
-
|
|
180
|
-
#define FOR_EACH_PARAM_OF_PQsendQueryParams(param) \
|
|
181
|
-
param(PGconn *, conn) \
|
|
182
|
-
param(const char *, command) \
|
|
183
|
-
param(int, nParams) \
|
|
184
|
-
param(const Oid *, paramTypes) \
|
|
185
|
-
param(const char *const *, paramValues) \
|
|
186
|
-
param(const int *, paramLengths) \
|
|
187
|
-
param(const int *, paramFormats)
|
|
188
|
-
|
|
189
|
-
#define FOR_EACH_PARAM_OF_PQsendPrepare(param) \
|
|
190
|
-
param(PGconn *, conn) \
|
|
191
|
-
param(const char *, stmtName) \
|
|
192
|
-
param(const char *, query) \
|
|
193
|
-
param(int, nParams)
|
|
194
|
-
|
|
195
|
-
#define FOR_EACH_PARAM_OF_PQsendQueryPrepared(param) \
|
|
196
|
-
param(PGconn *, conn) \
|
|
197
|
-
param(const char *, stmtName) \
|
|
198
|
-
param(int, nParams) \
|
|
199
|
-
param(const char *const *, paramValues) \
|
|
200
|
-
param(const int *, paramLengths) \
|
|
201
|
-
param(const int *, paramFormats)
|
|
202
|
-
|
|
203
|
-
#define FOR_EACH_PARAM_OF_PQsendDescribePrepared(param) \
|
|
204
|
-
param(PGconn *, conn)
|
|
205
|
-
|
|
206
|
-
#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
|
|
207
|
-
param(PGconn *, conn)
|
|
208
|
-
|
|
209
|
-
#define FOR_EACH_PARAM_OF_PQsendClosePrepared(param) \
|
|
210
|
-
param(PGconn *, conn)
|
|
211
|
-
|
|
212
|
-
#define FOR_EACH_PARAM_OF_PQsendClosePortal(param) \
|
|
213
|
-
param(PGconn *, conn)
|
|
214
|
-
|
|
215
|
-
#define FOR_EACH_PARAM_OF_PQpipelineSync(param)
|
|
216
|
-
|
|
217
|
-
#define FOR_EACH_PARAM_OF_PQsendPipelineSync(param)
|
|
218
|
-
|
|
219
|
-
#define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
|
|
220
|
-
param(PGconn *, conn)
|
|
221
|
-
|
|
222
|
-
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
|
223
|
-
|
|
224
|
-
#define FOR_EACH_PARAM_OF_PQcancelBlocking(param)
|
|
225
144
|
#define FOR_EACH_PARAM_OF_PQcancelStart(param)
|
|
226
145
|
#define FOR_EACH_PARAM_OF_PQcancelPoll(param)
|
|
227
146
|
|
|
228
|
-
#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
|
|
229
|
-
param(PGconn *, conn) \
|
|
230
|
-
param(const char *, passwd) \
|
|
231
|
-
param(const char *, user)
|
|
232
|
-
|
|
233
|
-
#define FOR_EACH_PARAM_OF_PQcancel(param) \
|
|
234
|
-
param(PGcancel *, cancel) \
|
|
235
|
-
param(char *, errbuf)
|
|
236
|
-
|
|
237
147
|
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
|
238
148
|
#define FOR_EACH_BLOCKING_FUNCTION(function) \
|
|
239
|
-
function(PQconnectdb, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
|
240
149
|
function(PQconnectStart, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
|
241
150
|
function(PQconnectPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
|
242
|
-
function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
|
|
243
151
|
function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
|
244
152
|
function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
|
245
153
|
function(PQping, GVL_TYPE_NONVOID, PGPing, const char *, conninfo) \
|
|
246
|
-
function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
|
|
247
|
-
function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
|
248
|
-
function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
|
249
|
-
function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
|
|
250
|
-
function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
|
251
|
-
function(PQdescribePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
|
|
252
|
-
function(PQclosePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
|
253
|
-
function(PQclosePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
|
|
254
|
-
function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
|
|
255
|
-
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
|
|
256
|
-
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
|
257
|
-
function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
|
|
258
|
-
function(PQnotifies, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
|
|
259
|
-
function(PQsendQuery, GVL_TYPE_NONVOID, int, const char *, query) \
|
|
260
|
-
function(PQsendQueryParams, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
|
261
|
-
function(PQsendPrepare, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
|
|
262
|
-
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
|
263
|
-
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
|
264
|
-
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
|
265
|
-
function(PQsendClosePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
|
266
|
-
function(PQsendClosePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
|
267
|
-
function(PQpipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
|
268
|
-
function(PQsendPipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
|
269
|
-
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
|
|
270
|
-
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
|
271
|
-
function(PQcancelBlocking, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
|
|
272
154
|
function(PQcancelStart, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
|
|
273
155
|
function(PQcancelPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGcancelConn *, conn) \
|
|
274
|
-
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
|
|
275
|
-
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
|
276
156
|
|
|
277
157
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
|
278
158
|
|
data/ext/pg.c
CHANGED
|
@@ -212,10 +212,10 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
|
|
|
212
212
|
*
|
|
213
213
|
*/
|
|
214
214
|
char *
|
|
215
|
-
pg_rb_str_ensure_capa( VALUE str,
|
|
215
|
+
pg_rb_str_ensure_capa( VALUE str, size_t expand_len, char *curr_ptr, char **end_ptr )
|
|
216
216
|
{
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
size_t curr_len = curr_ptr - RSTRING_PTR(str);
|
|
218
|
+
size_t curr_capa = rb_str_capacity( str );
|
|
219
219
|
if( curr_capa < curr_len + expand_len ){
|
|
220
220
|
rb_str_set_len( str, curr_len );
|
|
221
221
|
rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
|
|
@@ -384,14 +384,10 @@ Init_pg_ext(void)
|
|
|
384
384
|
rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
|
|
385
385
|
/* Internal state - PG.connect() needed. */
|
|
386
386
|
rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
|
|
387
|
-
|
|
388
|
-
/* Checking if session is read-write. Available since PostgreSQL-10. */
|
|
387
|
+
/* Checking if session is read-write. */
|
|
389
388
|
rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_WRITABLE", INT2FIX(CONNECTION_CHECK_WRITABLE));
|
|
390
|
-
|
|
391
|
-
#if PG_MAJORVERSION_NUM >= 10
|
|
392
|
-
/* Consuming any extra messages. Available since PostgreSQL-10. */
|
|
389
|
+
/* Consuming any extra messages. */
|
|
393
390
|
rb_define_const(rb_mPGconstants, "CONNECTION_CONSUME", INT2FIX(CONNECTION_CONSUME));
|
|
394
|
-
#endif
|
|
395
391
|
#if PG_MAJORVERSION_NUM >= 12
|
|
396
392
|
/* Negotiating GSSAPI. Available since PostgreSQL-12. */
|
|
397
393
|
rb_define_const(rb_mPGconstants, "CONNECTION_GSS_STARTUP", INT2FIX(CONNECTION_GSS_STARTUP));
|
|
@@ -508,12 +504,12 @@ Init_pg_ext(void)
|
|
|
508
504
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
|
|
509
505
|
/* Result#result_status constant - Single tuple from larger resultset. */
|
|
510
506
|
rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
|
|
511
|
-
#ifdef
|
|
507
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
512
508
|
/* Result#result_status constant - tuple chunk from larger resultset. */
|
|
513
509
|
rb_define_const(rb_mPGconstants, "PGRES_TUPLES_CHUNK", INT2FIX(PGRES_TUPLES_CHUNK));
|
|
514
510
|
#endif
|
|
515
511
|
|
|
516
|
-
#ifdef
|
|
512
|
+
#ifdef LIBPQ_HAS_PIPELINING
|
|
517
513
|
/* Result#result_status constant - The PG::Result represents a synchronization point in pipeline mode, requested by Connection#pipeline_sync.
|
|
518
514
|
*
|
|
519
515
|
* This status occurs only when pipeline mode has been selected. */
|
|
@@ -643,7 +639,7 @@ Init_pg_ext(void)
|
|
|
643
639
|
rb_define_const(rb_mPGconstants, "PG_DIAG_CONSTRAINT_NAME", INT2FIX(PG_DIAG_CONSTRAINT_NAME));
|
|
644
640
|
#endif
|
|
645
641
|
|
|
646
|
-
#ifdef
|
|
642
|
+
#ifdef LIBPQ_HAS_PIPELINING
|
|
647
643
|
/* Connection#pipeline_status constant
|
|
648
644
|
*
|
|
649
645
|
* The libpq connection is in pipeline mode.
|
data/ext/pg.h
CHANGED
|
@@ -82,12 +82,8 @@ typedef long suseconds_t;
|
|
|
82
82
|
|
|
83
83
|
#define pg_gc_location(x) x = rb_gc_location(x)
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
#define PG_RUBY_TYPED_FROZEN_SHAREABLE 0
|
|
88
|
-
#else
|
|
89
|
-
#define PG_RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
|
|
90
|
-
#endif
|
|
85
|
+
extern int ruby_native_thread_p(void);
|
|
86
|
+
|
|
91
87
|
#define PG_ENC_IDX_BITS 28
|
|
92
88
|
|
|
93
89
|
/* The data behind each PG::Connection object */
|
|
@@ -103,6 +99,8 @@ typedef struct {
|
|
|
103
99
|
VALUE notice_receiver;
|
|
104
100
|
/* Proc object that receives notices as String objects */
|
|
105
101
|
VALUE notice_processor;
|
|
102
|
+
/* Corresponding PG::Connection ruby object. Only used for the notice_receiver */
|
|
103
|
+
VALUE self;
|
|
106
104
|
/* Kind of PG::TypeMap object for casting query params */
|
|
107
105
|
VALUE type_map_for_queries;
|
|
108
106
|
/* Kind of PG::TypeMap object for casting result values */
|
|
@@ -116,7 +114,7 @@ typedef struct {
|
|
|
116
114
|
/* Ruby encoding index of the client/internal encoding */
|
|
117
115
|
int enc_idx : PG_ENC_IDX_BITS;
|
|
118
116
|
/* flags controlling Symbol/String field names */
|
|
119
|
-
unsigned int flags :
|
|
117
|
+
unsigned int flags : 1;
|
|
120
118
|
/* enable automatic flushing of send data at the end of send_query calls */
|
|
121
119
|
unsigned int flush_data : 1;
|
|
122
120
|
|
|
@@ -151,7 +149,7 @@ typedef struct {
|
|
|
151
149
|
unsigned int autoclear : 1;
|
|
152
150
|
|
|
153
151
|
/* flags controlling Symbol/String field names */
|
|
154
|
-
unsigned int flags :
|
|
152
|
+
unsigned int flags : 1;
|
|
155
153
|
|
|
156
154
|
/* Number of fields in fnames[] .
|
|
157
155
|
* Set to -1 if fnames[] is not yet initialized.
|
|
@@ -181,9 +179,8 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
|
|
181
179
|
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
|
182
180
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
|
183
181
|
|
|
184
|
-
#define PG_RESULT_FIELD_NAMES_MASK
|
|
182
|
+
#define PG_RESULT_FIELD_NAMES_MASK 0x01
|
|
185
183
|
#define PG_RESULT_FIELD_NAMES_SYMBOL 0x01
|
|
186
|
-
#define PG_RESULT_FIELD_NAMES_STATIC_SYMBOL 0x02
|
|
187
184
|
|
|
188
185
|
#define PG_CODER_TIMESTAMP_DB_UTC 0x0
|
|
189
186
|
#define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
|
|
@@ -320,7 +317,7 @@ VALUE pg_tmbc_allocate _(( void ));
|
|
|
320
317
|
void pg_coder_init_encoder _(( VALUE ));
|
|
321
318
|
void pg_coder_init_decoder _(( VALUE ));
|
|
322
319
|
void pg_coder_compact _(( void * ));
|
|
323
|
-
char *pg_rb_str_ensure_capa _(( VALUE,
|
|
320
|
+
char *pg_rb_str_ensure_capa _(( VALUE, size_t, char *, char ** ));
|
|
324
321
|
|
|
325
322
|
#define PG_RB_STR_ENSURE_CAPA( str, expand_len, curr_ptr, end_ptr ) \
|
|
326
323
|
do { \
|
data/ext/pg_binary_decoder.c
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
VALUE rb_mPG_BinaryDecoder;
|
|
15
15
|
static VALUE s_Date;
|
|
16
|
+
static VALUE s_Date_GREGORIAN; /* Date::GREGORIAN */
|
|
16
17
|
static ID s_id_new;
|
|
17
18
|
|
|
18
19
|
|
|
@@ -218,6 +219,7 @@ pg_bin_dec_array(t_pg_coder *conv, const char *input_line, int len, int tuple, i
|
|
|
218
219
|
cur_ptr += 8;
|
|
219
220
|
}
|
|
220
221
|
nitems = (int)nitems32;
|
|
222
|
+
if (nitems > (line_end_ptr - cur_ptr) / 4) goto length_error;
|
|
221
223
|
|
|
222
224
|
dim = 0;
|
|
223
225
|
arrays[dim] = rb_ary_new2(ndim == 0 ? 0 : dim_sizes[dim]);
|
|
@@ -403,7 +405,7 @@ pg_bin_dec_date(t_pg_coder *conv, const char *val, int len, int tuple, int field
|
|
|
403
405
|
default:
|
|
404
406
|
j2date(date + POSTGRES_EPOCH_JDATE, &year, &month, &day);
|
|
405
407
|
|
|
406
|
-
return rb_funcall(s_Date, s_id_new,
|
|
408
|
+
return rb_funcall(s_Date, s_id_new, 4, INT2NUM(year), INT2NUM(month), INT2NUM(day), s_Date_GREGORIAN);
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
411
|
|
|
@@ -412,8 +414,10 @@ static VALUE
|
|
|
412
414
|
init_pg_bin_decoder_date(VALUE rb_mPG_BinaryDecoder)
|
|
413
415
|
{
|
|
414
416
|
rb_require("date");
|
|
417
|
+
rb_gc_register_address(&s_Date);
|
|
418
|
+
rb_gc_register_address(&s_Date_GREGORIAN);
|
|
415
419
|
s_Date = rb_const_get(rb_cObject, rb_intern("Date"));
|
|
416
|
-
|
|
420
|
+
s_Date_GREGORIAN = rb_const_get(s_Date, rb_intern("GREGORIAN"));
|
|
417
421
|
s_id_new = rb_intern("new");
|
|
418
422
|
|
|
419
423
|
/* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Date", rb_cPG_SimpleDecoder ); */
|
data/ext/pg_binary_encoder.c
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
#endif
|
|
12
12
|
|
|
13
13
|
VALUE rb_mPG_BinaryEncoder;
|
|
14
|
+
static ID s_id_gregorianP;
|
|
15
|
+
static ID s_id_gregorian;
|
|
14
16
|
static ID s_id_year;
|
|
15
17
|
static ID s_id_month;
|
|
16
18
|
static ID s_id_day;
|
|
@@ -272,6 +274,9 @@ pg_bin_enc_date(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, i
|
|
|
272
274
|
write_nbo32(PG_INT32_MIN, out);
|
|
273
275
|
return 4;
|
|
274
276
|
} {
|
|
277
|
+
/* Only create a new gregorian Date object if necessary */
|
|
278
|
+
if( rb_funcall(value, s_id_gregorianP, 0) != Qtrue )
|
|
279
|
+
value = rb_funcall(value, s_id_gregorian, 0);
|
|
275
280
|
VALUE year = rb_funcall(value, s_id_year, 0);
|
|
276
281
|
VALUE month = rb_funcall(value, s_id_month, 0);
|
|
277
282
|
VALUE day = rb_funcall(value, s_id_day, 0);
|
|
@@ -554,6 +559,8 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
|
|
|
554
559
|
void
|
|
555
560
|
init_pg_binary_encoder(void)
|
|
556
561
|
{
|
|
562
|
+
s_id_gregorianP = rb_intern("gregorian?");
|
|
563
|
+
s_id_gregorian = rb_intern("gregorian");
|
|
557
564
|
s_id_year = rb_intern("year");
|
|
558
565
|
s_id_month = rb_intern("month");
|
|
559
566
|
s_id_day = rb_intern("day");
|
data/ext/pg_cancel_connection.c
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* The class to represent a connection to cancel a query.
|
|
8
8
|
*
|
|
9
|
-
* On PostgreSQL-17+ client
|
|
9
|
+
* On PostgreSQL-17+ client library this class is used to implement PG::Connection#cancel .
|
|
10
10
|
* It works on older PostgreSQL server versions too.
|
|
11
11
|
*
|
|
12
12
|
* Available since PostgreSQL-17
|
|
13
13
|
*
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
#ifdef
|
|
16
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
17
17
|
|
|
18
18
|
static VALUE rb_cPG_Cancon;
|
|
19
19
|
static ID s_id_autoclose_set;
|
|
@@ -75,7 +75,7 @@ static const rb_data_type_t pg_cancon_type = {
|
|
|
75
75
|
pg_cancon_gc_compact,
|
|
76
76
|
},
|
|
77
77
|
0, 0,
|
|
78
|
-
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED |
|
|
78
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
/*
|
|
@@ -155,7 +155,7 @@ pg_cancon_initialize(VALUE self, VALUE rb_conn)
|
|
|
155
155
|
*
|
|
156
156
|
* Requests that the server abandons processing of the current command in a blocking manner.
|
|
157
157
|
*
|
|
158
|
-
* This method directly calls +PQcancelBlocking+ of libpq, so that it doesn't respond to ruby interrupts and doesn't trigger the +Thread.scheduler+ .
|
|
158
|
+
* This method directly calls +PQcancelBlocking+ of libpq, so that it doesn't allow parallel threads, doesn't respond to ruby interrupts and doesn't trigger the +Thread.scheduler+ .
|
|
159
159
|
* It is threrfore recommended to call #cancel instead.
|
|
160
160
|
*
|
|
161
161
|
*/
|
|
@@ -165,7 +165,7 @@ pg_cancon_sync_cancel(VALUE self)
|
|
|
165
165
|
PGcancelConn *conn = pg_cancon_get_conn(self);
|
|
166
166
|
|
|
167
167
|
pg_cancon_close_socket_io( self );
|
|
168
|
-
if(
|
|
168
|
+
if(PQcancelBlocking(conn) == 0)
|
|
169
169
|
pg_raise_conn_error( rb_eConnectionBad, self, "PQcancelBlocking %s", PQcancelErrorMessage(conn));
|
|
170
170
|
return Qnil;
|
|
171
171
|
}
|
|
@@ -340,7 +340,7 @@ pg_cancon_finish(VALUE self)
|
|
|
340
340
|
void
|
|
341
341
|
init_pg_cancon(void)
|
|
342
342
|
{
|
|
343
|
-
#ifdef
|
|
343
|
+
#ifdef LIBPQ_HAS_CHUNK_MODE
|
|
344
344
|
s_id_autoclose_set = rb_intern("autoclose=");
|
|
345
345
|
|
|
346
346
|
rb_cPG_Cancon = rb_define_class_under( rb_mPG, "CancelConnection", rb_cObject );
|
data/ext/pg_coder.c
CHANGED
|
@@ -101,7 +101,7 @@ const rb_data_type_t pg_coder_type = {
|
|
|
101
101
|
0,
|
|
102
102
|
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
|
103
103
|
// macro to update VALUE references, as to trigger write barriers.
|
|
104
|
-
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED |
|
|
104
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
static VALUE
|
|
@@ -123,7 +123,7 @@ static const rb_data_type_t pg_composite_coder_type = {
|
|
|
123
123
|
},
|
|
124
124
|
&pg_coder_type,
|
|
125
125
|
0,
|
|
126
|
-
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED |
|
|
126
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
127
127
|
};
|
|
128
128
|
|
|
129
129
|
static VALUE
|
|
@@ -505,7 +505,7 @@ static const rb_data_type_t pg_coder_cfunc_type = {
|
|
|
505
505
|
},
|
|
506
506
|
0,
|
|
507
507
|
0,
|
|
508
|
-
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED |
|
|
508
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
509
509
|
};
|
|
510
510
|
|
|
511
511
|
VALUE
|
|
@@ -631,7 +631,7 @@ init_pg_coder(void)
|
|
|
631
631
|
/*
|
|
632
632
|
* Name of the coder or the corresponding data type.
|
|
633
633
|
*
|
|
634
|
-
* This accessor is
|
|
634
|
+
* This accessor is used by PG::Coder#inspect and PG::Connection#embed_params .
|
|
635
635
|
*/
|
|
636
636
|
rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
|
|
637
637
|
|