pg 1.1.0.pre20180730171000 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +6595 -0
- data/History.rdoc +3 -8
- data/Manifest.txt +70 -2
- data/Rakefile +0 -1
- data/ext/pg.c +4 -1
- data/ext/pg.h +7 -0
- data/ext/pg_binary_decoder.c +1 -1
- data/ext/pg_binary_encoder.c +1 -1
- data/ext/pg_connection.c +8 -8
- data/ext/pg_result.c +1 -1
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +6 -7
- data/ext/pg_tuple.c +4 -3
- 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 +1 -1
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +1 -1
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/util.c +1 -1
- data/lib/pg.rb +2 -2
- data/spec/pg/basic_type_mapping_spec.rb +4 -4
- data/spec/pg/connection_spec.rb +58 -13
- data/spec/pg/tuple_spec.rb +16 -2
- data/spec/pg/type_spec.rb +6 -0
- metadata +35 -69
- metadata.gz.sig +0 -0
- data/.gems +0 -6
- data/.hgignore +0 -21
- data/.hgsigs +0 -29
- data/.hgtags +0 -36
- data/.hoerc +0 -2
- data/.irbrc +0 -23
- data/.pryrc +0 -23
- data/.tm_properties +0 -21
- data/.travis.yml +0 -41
- data/Gemfile +0 -2
- data/appveyor.yml +0 -50
- data/certs/ged.pem +0 -26
- data/misc/openssl-pg-segfault.rb +0 -31
- data/misc/postgres/History.txt +0 -9
- data/misc/postgres/Manifest.txt +0 -5
- data/misc/postgres/README.txt +0 -21
- data/misc/postgres/Rakefile +0 -21
- data/misc/postgres/lib/postgres.rb +0 -16
- data/misc/ruby-pg/History.txt +0 -9
- data/misc/ruby-pg/Manifest.txt +0 -5
- data/misc/ruby-pg/README.txt +0 -21
- data/misc/ruby-pg/Rakefile +0 -21
- data/misc/ruby-pg/lib/ruby/pg.rb +0 -16
- data/pg.gemspec +0 -61
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copydata.rb +0 -71
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -177
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -285
- data/sample/replication_monitor.rb +0 -222
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -311
data/History.rdoc
CHANGED
@@ -1,12 +1,6 @@
|
|
1
|
-
==
|
1
|
+
== v1.1.0 [2018-08-24] Michael Granger <ged@FaerieMUD.org>
|
2
2
|
|
3
|
-
|
4
|
-
- Removed query method variants deprecated in pg-1.1.0.
|
5
|
-
|
6
|
-
|
7
|
-
== v1.1.0 [YYYY-MM-DD] Michael Granger <ged@FaerieMUD.org>
|
8
|
-
|
9
|
-
Deprecated:
|
3
|
+
Deprecated (disable warnings per PG_SKIP_DEPRECATION_WARNING=1):
|
10
4
|
- Forwarding conn.exec to conn.exec_params is deprecated.
|
11
5
|
- Forwarding conn.exec_params to conn.exec is deprecated.
|
12
6
|
- Forwarding conn.async_exec to conn.async_exec_params.
|
@@ -20,6 +14,7 @@ PG::Connection enhancements:
|
|
20
14
|
They are identical to their syncronous counterpart, but make use of PostgreSQL's async API.
|
21
15
|
- Replace `rb_thread_fd_select()` by faster `rb_wait_for_single_fd()` in `conn.block` and `conn.async_exec` .
|
22
16
|
- Add PG::Connection#discard_results .
|
17
|
+
- Raise an ArgumentError for strings containing zero bytes by #escape, #escape_literal, #escape_identifier, #quote_ident and PG::TextEncoder::Identifier. These methods previously truncated strings.
|
23
18
|
|
24
19
|
Result retrieval enhancements:
|
25
20
|
- Add PG::Result#tuple_values to retrieve all field values of a row as array.
|
data/Manifest.txt
CHANGED
@@ -1,4 +1,72 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
.gemtest
|
2
|
+
BSDL
|
3
|
+
ChangeLog
|
4
|
+
Contributors.rdoc
|
5
|
+
History.rdoc
|
6
|
+
LICENSE
|
7
|
+
Manifest.txt
|
8
|
+
POSTGRES
|
9
|
+
README-OS_X.rdoc
|
10
|
+
README-Windows.rdoc
|
11
|
+
README.ja.rdoc
|
3
12
|
README.rdoc
|
13
|
+
Rakefile
|
14
|
+
Rakefile.cross
|
15
|
+
ext/errorcodes.def
|
16
|
+
ext/errorcodes.rb
|
17
|
+
ext/errorcodes.txt
|
18
|
+
ext/extconf.rb
|
19
|
+
ext/gvl_wrappers.c
|
20
|
+
ext/gvl_wrappers.h
|
21
|
+
ext/pg.c
|
22
|
+
ext/pg.h
|
23
|
+
ext/pg_binary_decoder.c
|
24
|
+
ext/pg_binary_encoder.c
|
25
|
+
ext/pg_coder.c
|
26
|
+
ext/pg_connection.c
|
27
|
+
ext/pg_copy_coder.c
|
28
|
+
ext/pg_errors.c
|
29
|
+
ext/pg_result.c
|
30
|
+
ext/pg_text_decoder.c
|
31
|
+
ext/pg_text_encoder.c
|
32
|
+
ext/pg_tuple.c
|
33
|
+
ext/pg_type_map.c
|
34
|
+
ext/pg_type_map_all_strings.c
|
35
|
+
ext/pg_type_map_by_class.c
|
36
|
+
ext/pg_type_map_by_column.c
|
37
|
+
ext/pg_type_map_by_mri_type.c
|
38
|
+
ext/pg_type_map_by_oid.c
|
39
|
+
ext/pg_type_map_in_ruby.c
|
40
|
+
ext/util.c
|
41
|
+
ext/util.h
|
42
|
+
ext/vc/pg.sln
|
43
|
+
ext/vc/pg_18/pg.vcproj
|
44
|
+
ext/vc/pg_19/pg_19.vcproj
|
4
45
|
lib/pg.rb
|
46
|
+
lib/pg/basic_type_mapping.rb
|
47
|
+
lib/pg/binary_decoder.rb
|
48
|
+
lib/pg/coder.rb
|
49
|
+
lib/pg/connection.rb
|
50
|
+
lib/pg/constants.rb
|
51
|
+
lib/pg/exceptions.rb
|
52
|
+
lib/pg/result.rb
|
53
|
+
lib/pg/text_decoder.rb
|
54
|
+
lib/pg/text_encoder.rb
|
55
|
+
lib/pg/tuple.rb
|
56
|
+
lib/pg/type_map_by_column.rb
|
57
|
+
spec/data/expected_trace.out
|
58
|
+
spec/data/random_binary_data
|
59
|
+
spec/helpers.rb
|
60
|
+
spec/pg/basic_type_mapping_spec.rb
|
61
|
+
spec/pg/connection_spec.rb
|
62
|
+
spec/pg/connection_sync_spec.rb
|
63
|
+
spec/pg/result_spec.rb
|
64
|
+
spec/pg/tuple_spec.rb
|
65
|
+
spec/pg/type_map_by_class_spec.rb
|
66
|
+
spec/pg/type_map_by_column_spec.rb
|
67
|
+
spec/pg/type_map_by_mri_type_spec.rb
|
68
|
+
spec/pg/type_map_by_oid_spec.rb
|
69
|
+
spec/pg/type_map_in_ruby_spec.rb
|
70
|
+
spec/pg/type_map_spec.rb
|
71
|
+
spec/pg/type_spec.rb
|
72
|
+
spec/pg_spec.rb
|
data/Rakefile
CHANGED
@@ -55,7 +55,6 @@ $hoespec = Hoe.spec 'pg' do
|
|
55
55
|
self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
|
56
56
|
self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' )
|
57
57
|
self.extra_rdoc_files.include( 'ext/*.c' )
|
58
|
-
self.spec_extras[:files] = `hg manifest || git ls-files`.split
|
59
58
|
self.license 'BSD-3-Clause'
|
60
59
|
|
61
60
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
data/ext/pg.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg.c - Toplevel extension
|
3
|
-
* $Id$
|
3
|
+
* $Id: pg.c,v 0d4acc8a0bc5 2018/08/05 09:07:58 lars $
|
4
4
|
*
|
5
5
|
* Author/s:
|
6
6
|
*
|
@@ -48,6 +48,7 @@
|
|
48
48
|
|
49
49
|
#include "pg.h"
|
50
50
|
|
51
|
+
int pg_skip_deprecation_warning;
|
51
52
|
VALUE rb_mPG;
|
52
53
|
VALUE rb_mPGconstants;
|
53
54
|
|
@@ -381,6 +382,8 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
|
|
381
382
|
void
|
382
383
|
Init_pg_ext()
|
383
384
|
{
|
385
|
+
pg_skip_deprecation_warning = RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']"));
|
386
|
+
|
384
387
|
rb_mPG = rb_define_module( "PG" );
|
385
388
|
rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
|
386
389
|
|
data/ext/pg.h
CHANGED
@@ -217,6 +217,7 @@ typedef struct {
|
|
217
217
|
* Globals
|
218
218
|
**************************************************************************/
|
219
219
|
|
220
|
+
extern int pg_skip_deprecation_warning;
|
220
221
|
extern VALUE rb_mPG;
|
221
222
|
extern VALUE rb_ePGerror;
|
222
223
|
extern VALUE rb_eServerError;
|
@@ -350,4 +351,10 @@ rb_encoding *pg_conn_enc_get _(( PGconn * ));
|
|
350
351
|
void notice_receiver_proxy(void *arg, const PGresult *result);
|
351
352
|
void notice_processor_proxy(void *arg, const char *message);
|
352
353
|
|
354
|
+
/* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set */
|
355
|
+
#define pg_deprecated(x) \
|
356
|
+
do { \
|
357
|
+
if( !pg_skip_deprecation_warning ) rb_warning x; \
|
358
|
+
} while(0);
|
359
|
+
|
353
360
|
#endif /* end __pg_h */
|
data/ext/pg_binary_decoder.c
CHANGED
data/ext/pg_binary_encoder.c
CHANGED
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id$
|
3
|
+
* $Id: pg_connection.c,v e57f6b452eb3 2018/08/18 10:58:52 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -1006,7 +1006,7 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
1006
1006
|
}
|
1007
1007
|
return rb_pgresult;
|
1008
1008
|
}
|
1009
|
-
|
1009
|
+
pg_deprecated(("forwarding exec to exec_params is deprecated"));
|
1010
1010
|
|
1011
1011
|
/* Otherwise, just call #exec_params instead for backward-compatibility */
|
1012
1012
|
return pgconn_exec_params( argc, argv, self );
|
@@ -1321,7 +1321,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
|
|
1321
1321
|
* is passed to #exec
|
1322
1322
|
*/
|
1323
1323
|
if ( NIL_P(paramsData.params) ) {
|
1324
|
-
|
1324
|
+
pg_deprecated(("forwarding exec_params to exec is deprecated"));
|
1325
1325
|
return pgconn_exec( 1, argv, self );
|
1326
1326
|
}
|
1327
1327
|
pgconn_query_assign_typemap( self, ¶msData );
|
@@ -1587,7 +1587,7 @@ pgconn_s_escape(VALUE self, VALUE string)
|
|
1587
1587
|
int enc_idx;
|
1588
1588
|
int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
|
1589
1589
|
|
1590
|
-
|
1590
|
+
StringValueCStr(string);
|
1591
1591
|
enc_idx = ENCODING_GET( singleton ? string : self );
|
1592
1592
|
if( ENCODING_GET(string) != enc_idx ){
|
1593
1593
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
@@ -1703,7 +1703,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
|
|
1703
1703
|
VALUE result = Qnil;
|
1704
1704
|
int enc_idx = ENCODING_GET(self);
|
1705
1705
|
|
1706
|
-
|
1706
|
+
StringValueCStr(string);
|
1707
1707
|
if( ENCODING_GET(string) != enc_idx ){
|
1708
1708
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1709
1709
|
}
|
@@ -1745,7 +1745,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1745
1745
|
VALUE result = Qnil;
|
1746
1746
|
int enc_idx = ENCODING_GET(self);
|
1747
1747
|
|
1748
|
-
|
1748
|
+
StringValueCStr(string);
|
1749
1749
|
if( ENCODING_GET(string) != enc_idx ){
|
1750
1750
|
string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
|
1751
1751
|
}
|
@@ -1851,7 +1851,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1851
1851
|
return Qnil;
|
1852
1852
|
}
|
1853
1853
|
|
1854
|
-
|
1854
|
+
pg_deprecated(("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated"));
|
1855
1855
|
|
1856
1856
|
/* If called with parameters, and optionally result_format,
|
1857
1857
|
* use PQsendQueryParams
|
@@ -3223,7 +3223,7 @@ pgconn_async_exec_params(int argc, VALUE *argv, VALUE self)
|
|
3223
3223
|
pgconn_discard_results( self );
|
3224
3224
|
/* If called with no or nil parameters, use PQsendQuery for compatibility */
|
3225
3225
|
if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
|
3226
|
-
|
3226
|
+
pg_deprecated(("forwarding async_exec_params to async_exec is deprecated"));
|
3227
3227
|
pgconn_send_query( argc, argv, self );
|
3228
3228
|
} else {
|
3229
3229
|
pgconn_send_query_params( argc, argv, self );
|
data/ext/pg_result.c
CHANGED
data/ext/pg_text_decoder.c
CHANGED
data/ext/pg_text_encoder.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_text_encoder.c - PG::TextEncoder module
|
3
|
-
* $Id$
|
3
|
+
* $Id: pg_text_encoder.c,v e57f6b452eb3 2018/08/18 10:58:52 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -468,20 +468,19 @@ pg_text_enc_array(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
|
|
468
468
|
static char *
|
469
469
|
quote_identifier( VALUE value, VALUE out_string, char *current_out ){
|
470
470
|
char *p_in = RSTRING_PTR(value);
|
471
|
-
char *ptr1;
|
472
471
|
size_t strlen = RSTRING_LEN(value);
|
472
|
+
char *p_inend = p_in + strlen;
|
473
473
|
char *end_capa = current_out;
|
474
474
|
|
475
475
|
PG_RB_STR_ENSURE_CAPA( out_string, strlen + 2, current_out, end_capa );
|
476
476
|
*current_out++ = '"';
|
477
|
-
for(
|
478
|
-
char c = *
|
477
|
+
for(; p_in != p_inend; p_in++) {
|
478
|
+
char c = *p_in;
|
479
479
|
if (c == '"'){
|
480
|
-
|
481
|
-
PG_RB_STR_ENSURE_CAPA( out_string, p_in - ptr1 + strlen + 1, current_out, end_capa );
|
480
|
+
PG_RB_STR_ENSURE_CAPA( out_string, p_inend - p_in + 2, current_out, end_capa );
|
482
481
|
*current_out++ = '"';
|
483
482
|
} else if (c == 0){
|
484
|
-
|
483
|
+
rb_raise(rb_eArgError, "string contains null byte");
|
485
484
|
}
|
486
485
|
*current_out++ = c;
|
487
486
|
}
|
data/ext/pg_tuple.c
CHANGED
@@ -311,9 +311,9 @@ pg_tuple_yield_key_value(VALUE key, VALUE index, VALUE _this)
|
|
311
311
|
|
312
312
|
/*
|
313
313
|
* call-seq:
|
314
|
-
* tup.each{ |value| ... }
|
314
|
+
* tup.each{ |key, value| ... }
|
315
315
|
*
|
316
|
-
* Invokes block for each field value in the tuple.
|
316
|
+
* Invokes block for each field name and value in the tuple.
|
317
317
|
*/
|
318
318
|
static VALUE
|
319
319
|
pg_tuple_each(VALUE self)
|
@@ -354,7 +354,8 @@ pg_tuple_each_value(VALUE self)
|
|
354
354
|
RETURN_SIZED_ENUMERATOR(self, 0, NULL, pg_tuple_num_fields_for_enum);
|
355
355
|
|
356
356
|
for(field_num = 0; field_num < this->num_fields; field_num++) {
|
357
|
-
|
357
|
+
VALUE value = pg_tuple_materialize_field(this, field_num);
|
358
|
+
rb_yield(value);
|
358
359
|
}
|
359
360
|
|
360
361
|
pg_tuple_detach(this);
|
data/ext/pg_type_map.c
CHANGED
data/ext/pg_type_map_by_class.c
CHANGED
data/ext/pg_type_map_by_column.c
CHANGED
data/ext/pg_type_map_by_oid.c
CHANGED
data/ext/pg_type_map_in_ruby.c
CHANGED
data/ext/util.c
CHANGED
data/lib/pg.rb
CHANGED
@@ -256,10 +256,10 @@ describe 'Basic type mapping' do
|
|
256
256
|
CAST('294276-12-31 23:58:59.1231+03' AS TIMESTAMP WITH TIME ZONE),
|
257
257
|
CAST('infinity' AS TIMESTAMP WITH TIME ZONE),
|
258
258
|
CAST('-infinity' AS TIMESTAMP WITH TIME ZONE)", [], format )
|
259
|
-
expect( res.getvalue(0,0)
|
260
|
-
expect( res.getvalue(0,1)
|
261
|
-
expect( res.getvalue(0,2)
|
262
|
-
expect( res.getvalue(0,3)
|
259
|
+
expect( res.getvalue(0,0) ).to be_within(1e-3).of( Time.new(2013, 12, 31, 23, 58, 59, "+02:00").getlocal )
|
260
|
+
expect( res.getvalue(0,1) ).to be_within(1e-3).of( Time.new(1913, 12, 31, 23, 58, 59.1231, "-03:00").getlocal )
|
261
|
+
expect( res.getvalue(0,2) ).to be_within(1e-3).of( Time.new(-4713, 11, 24, 23, 58, 59.1231, "-03:00").getlocal )
|
262
|
+
expect( res.getvalue(0,3) ).to be_within(1e-3).of( Time.new(294276, 12, 31, 23, 58, 59.1231, "+03:00").getlocal )
|
263
263
|
expect( res.getvalue(0,4) ).to eq( 'infinity' )
|
264
264
|
expect( res.getvalue(0,5) ).to eq( '-infinity' )
|
265
265
|
end
|
data/spec/pg/connection_spec.rb
CHANGED
@@ -1237,51 +1237,51 @@ describe PG::Connection do
|
|
1237
1237
|
end
|
1238
1238
|
|
1239
1239
|
it "uses the client encoding for escaped string" do
|
1240
|
-
original = "Möhre to
|
1240
|
+
original = "Möhre to 'scape".encode( "utf-16be" )
|
1241
1241
|
@conn.set_client_encoding( "euc_jp" )
|
1242
1242
|
escaped = @conn.escape( original )
|
1243
1243
|
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1244
|
-
expect( escaped ).to eq( "Möhre to".encode(Encoding::EUC_JP) )
|
1244
|
+
expect( escaped ).to eq( "Möhre to ''scape".encode(Encoding::EUC_JP) )
|
1245
1245
|
end
|
1246
1246
|
|
1247
1247
|
it "uses the client encoding for escaped literal" do
|
1248
|
-
original = "Möhre to
|
1248
|
+
original = "Möhre to 'scape".encode( "utf-16be" )
|
1249
1249
|
@conn.set_client_encoding( "euc_jp" )
|
1250
1250
|
escaped = @conn.escape_literal( original )
|
1251
1251
|
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1252
|
-
expect( escaped ).to eq( "'Möhre to'".encode(Encoding::EUC_JP) )
|
1252
|
+
expect( escaped ).to eq( "'Möhre to ''scape'".encode(Encoding::EUC_JP) )
|
1253
1253
|
end
|
1254
1254
|
|
1255
1255
|
it "uses the client encoding for escaped identifier" do
|
1256
|
-
original = "Möhre to
|
1256
|
+
original = "Möhre to 'scape".encode( "utf-16le" )
|
1257
1257
|
@conn.set_client_encoding( "euc_jp" )
|
1258
1258
|
escaped = @conn.escape_identifier( original )
|
1259
1259
|
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1260
|
-
expect( escaped ).to eq( "\"Möhre to\"".encode(Encoding::EUC_JP) )
|
1260
|
+
expect( escaped ).to eq( "\"Möhre to 'scape\"".encode(Encoding::EUC_JP) )
|
1261
1261
|
end
|
1262
1262
|
|
1263
1263
|
it "uses the client encoding for quote_ident" do
|
1264
|
-
original = "Möhre to
|
1264
|
+
original = "Möhre to 'scape".encode( "utf-16le" )
|
1265
1265
|
@conn.set_client_encoding( "euc_jp" )
|
1266
1266
|
escaped = @conn.quote_ident( original )
|
1267
1267
|
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1268
|
-
expect( escaped ).to eq( "\"Möhre to\"".encode(Encoding::EUC_JP) )
|
1268
|
+
expect( escaped ).to eq( "\"Möhre to 'scape\"".encode(Encoding::EUC_JP) )
|
1269
1269
|
end
|
1270
1270
|
|
1271
1271
|
it "uses the previous string encoding for escaped string" do
|
1272
|
-
original = "Möhre to
|
1272
|
+
original = "Möhre to 'scape".encode( "iso-8859-1" )
|
1273
1273
|
@conn.set_client_encoding( "euc_jp" )
|
1274
1274
|
escaped = described_class.escape( original )
|
1275
1275
|
expect( escaped.encoding ).to eq( Encoding::ISO8859_1 )
|
1276
|
-
expect( escaped ).to eq( "Möhre to".encode(Encoding::ISO8859_1) )
|
1276
|
+
expect( escaped ).to eq( "Möhre to ''scape".encode(Encoding::ISO8859_1) )
|
1277
1277
|
end
|
1278
1278
|
|
1279
1279
|
it "uses the previous string encoding for quote_ident" do
|
1280
|
-
original = "Möhre to
|
1280
|
+
original = "Möhre to 'scape".encode( "iso-8859-1" )
|
1281
1281
|
@conn.set_client_encoding( "euc_jp" )
|
1282
1282
|
escaped = described_class.quote_ident( original )
|
1283
1283
|
expect( escaped.encoding ).to eq( Encoding::ISO8859_1 )
|
1284
|
-
expect( escaped.encode ).to eq( "\"Möhre to\"".encode(Encoding::ISO8859_1) )
|
1284
|
+
expect( escaped.encode ).to eq( "\"Möhre to 'scape\"".encode(Encoding::ISO8859_1) )
|
1285
1285
|
end
|
1286
1286
|
|
1287
1287
|
it "raises appropriate error if set_client_encoding is called with invalid arguments" do
|
@@ -1366,9 +1366,54 @@ describe PG::Connection do
|
|
1366
1366
|
end
|
1367
1367
|
end
|
1368
1368
|
|
1369
|
+
it "rejects command strings with zero bytes" do
|
1370
|
+
expect{ @conn.exec( "SELECT 1;\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1371
|
+
expect{ @conn.exec_params( "SELECT 1;\x00", [] ) }.to raise_error(ArgumentError, /null byte/)
|
1372
|
+
expect{ @conn.prepare( "abc\x00", "SELECT 1;" ) }.to raise_error(ArgumentError, /null byte/)
|
1373
|
+
expect{ @conn.prepare( "abc", "SELECT 1;\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1374
|
+
expect{ @conn.exec_prepared( "abc\x00", [] ) }.to raise_error(ArgumentError, /null byte/)
|
1375
|
+
expect{ @conn.describe_prepared( "abc\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1376
|
+
expect{ @conn.describe_portal( "abc\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1377
|
+
expect{ @conn.send_query( "SELECT 1;\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1378
|
+
expect{ @conn.send_query_params( "SELECT 1;\x00", [] ) }.to raise_error(ArgumentError, /null byte/)
|
1379
|
+
expect{ @conn.send_prepare( "abc\x00", "SELECT 1;" ) }.to raise_error(ArgumentError, /null byte/)
|
1380
|
+
expect{ @conn.send_prepare( "abc", "SELECT 1;\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1381
|
+
expect{ @conn.send_query_prepared( "abc\x00", [] ) }.to raise_error(ArgumentError, /null byte/)
|
1382
|
+
expect{ @conn.send_describe_prepared( "abc\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1383
|
+
expect{ @conn.send_describe_portal( "abc\x00" ) }.to raise_error(ArgumentError, /null byte/)
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
it "rejects query params with zero bytes" do
|
1387
|
+
expect{ @conn.exec_params( "SELECT 1;\x00", ["ab\x00"] ) }.to raise_error(ArgumentError, /null byte/)
|
1388
|
+
expect{ @conn.exec_prepared( "abc\x00", ["ab\x00"] ) }.to raise_error(ArgumentError, /null byte/)
|
1389
|
+
expect{ @conn.send_query_params( "SELECT 1;\x00", ["ab\x00"] ) }.to raise_error(ArgumentError, /null byte/)
|
1390
|
+
expect{ @conn.send_query_prepared( "abc\x00", ["ab\x00"] ) }.to raise_error(ArgumentError, /null byte/)
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
it "rejects string with zero bytes in escape" do
|
1394
|
+
expect{ @conn.escape( "ab\x00cd" ) }.to raise_error(ArgumentError, /null byte/)
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
it "rejects string with zero bytes in escape_literal" do
|
1398
|
+
expect{ @conn.escape_literal( "ab\x00cd" ) }.to raise_error(ArgumentError, /null byte/)
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
it "rejects string with zero bytes in escape_identifier" do
|
1402
|
+
expect{ @conn.escape_identifier( "ab\x00cd" ) }.to raise_error(ArgumentError, /null byte/)
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
it "rejects string with zero bytes in quote_ident" do
|
1406
|
+
expect{ described_class.quote_ident( "ab\x00cd" ) }.to raise_error(ArgumentError, /null byte/)
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
it "rejects Array with string with zero bytes" do
|
1410
|
+
original = ["xyz", "2\x00"]
|
1411
|
+
expect{ described_class.quote_ident( original ) }.to raise_error(ArgumentError, /null byte/)
|
1412
|
+
end
|
1413
|
+
|
1369
1414
|
it "can quote bigger strings with quote_ident" do
|
1370
1415
|
original = "'01234567\"" * 100
|
1371
|
-
escaped = described_class.quote_ident( original
|
1416
|
+
escaped = described_class.quote_ident( original )
|
1372
1417
|
expect( escaped ).to eq( "\"" + original.gsub("\"", "\"\"") + "\"" )
|
1373
1418
|
end
|
1374
1419
|
|