pg 1.1.0.pre20180730171000-x86-mingw32 → 1.1.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -3
  4. data/ChangeLog +6595 -0
  5. data/History.rdoc +3 -8
  6. data/Manifest.txt +70 -2
  7. data/Rakefile +0 -1
  8. data/ext/extconf.rb +0 -0
  9. data/ext/pg.c +4 -1
  10. data/ext/pg.h +7 -0
  11. data/ext/pg_binary_decoder.c +1 -1
  12. data/ext/pg_binary_encoder.c +1 -1
  13. data/ext/pg_connection.c +8 -8
  14. data/ext/pg_result.c +1 -1
  15. data/ext/pg_text_decoder.c +1 -1
  16. data/ext/pg_text_encoder.c +6 -7
  17. data/ext/pg_tuple.c +4 -3
  18. data/ext/pg_type_map.c +1 -1
  19. data/ext/pg_type_map_all_strings.c +1 -1
  20. data/ext/pg_type_map_by_class.c +1 -1
  21. data/ext/pg_type_map_by_column.c +1 -1
  22. data/ext/pg_type_map_by_mri_type.c +1 -1
  23. data/ext/pg_type_map_by_oid.c +1 -1
  24. data/ext/pg_type_map_in_ruby.c +1 -1
  25. data/ext/util.c +1 -1
  26. data/lib/2.0/pg_ext.so +0 -0
  27. data/lib/2.1/pg_ext.so +0 -0
  28. data/lib/2.2/pg_ext.so +0 -0
  29. data/lib/2.3/pg_ext.so +0 -0
  30. data/lib/2.4/pg_ext.so +0 -0
  31. data/lib/2.5/pg_ext.so +0 -0
  32. data/lib/libpq.dll +0 -0
  33. data/lib/pg.rb +2 -2
  34. data/lib/pg/connection.rb +0 -0
  35. data/spec/helpers.rb +0 -0
  36. data/spec/pg/basic_type_mapping_spec.rb +4 -4
  37. data/spec/pg/connection_spec.rb +58 -13
  38. data/spec/pg/tuple_spec.rb +16 -2
  39. data/spec/pg/type_spec.rb +6 -0
  40. metadata +35 -69
  41. metadata.gz.sig +0 -0
  42. data/.gems +0 -6
  43. data/.hgignore +0 -21
  44. data/.hgsigs +0 -29
  45. data/.hgtags +0 -36
  46. data/.hoerc +0 -2
  47. data/.irbrc +0 -23
  48. data/.pryrc +0 -23
  49. data/.tm_properties +0 -21
  50. data/.travis.yml +0 -41
  51. data/Gemfile +0 -2
  52. data/appveyor.yml +0 -50
  53. data/certs/ged.pem +0 -26
  54. data/misc/openssl-pg-segfault.rb +0 -31
  55. data/misc/postgres/History.txt +0 -9
  56. data/misc/postgres/Manifest.txt +0 -5
  57. data/misc/postgres/README.txt +0 -21
  58. data/misc/postgres/Rakefile +0 -21
  59. data/misc/postgres/lib/postgres.rb +0 -16
  60. data/misc/ruby-pg/History.txt +0 -9
  61. data/misc/ruby-pg/Manifest.txt +0 -5
  62. data/misc/ruby-pg/README.txt +0 -21
  63. data/misc/ruby-pg/Rakefile +0 -21
  64. data/misc/ruby-pg/lib/ruby/pg.rb +0 -16
  65. data/pg.gemspec +0 -61
  66. data/sample/array_insert.rb +0 -20
  67. data/sample/async_api.rb +0 -106
  68. data/sample/async_copyto.rb +0 -39
  69. data/sample/async_mixed.rb +0 -56
  70. data/sample/check_conn.rb +0 -21
  71. data/sample/copydata.rb +0 -71
  72. data/sample/copyfrom.rb +0 -81
  73. data/sample/copyto.rb +0 -19
  74. data/sample/cursor.rb +0 -21
  75. data/sample/disk_usage_report.rb +0 -177
  76. data/sample/issue-119.rb +0 -94
  77. data/sample/losample.rb +0 -69
  78. data/sample/minimal-testcase.rb +0 -17
  79. data/sample/notify_wait.rb +0 -72
  80. data/sample/pg_statistics.rb +0 -285
  81. data/sample/replication_monitor.rb +0 -222
  82. data/sample/test_binary_values.rb +0 -33
  83. data/sample/wal_shipper.rb +0 -434
  84. data/sample/warehouse_partitions.rb +0 -311
@@ -1,12 +1,6 @@
1
- == v2.0.0 - far from release -
1
+ == v1.1.0 [2018-08-24] Michael Granger <ged@FaerieMUD.org>
2
2
 
3
- Removed:
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.
@@ -1,4 +1,72 @@
1
- # Manifest is built per Rakefile as part of `rake gem`.
2
- # These files are required to satisfy Hoe:
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'
File without changes
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 */
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_binary_decoder.c,v 5d166a4d0441 2018/07/29 12:03:00 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_binary_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
4
4
  *
5
5
  */
6
6
 
@@ -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
- rb_warning("forwarding exec to exec_params is deprecated");
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
- rb_warning("forwarding exec_params to exec is deprecated");
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, &paramsData );
@@ -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
- Check_Type(string, T_STRING);
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
- Check_Type(string, T_STRING);
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
- Check_Type(string, T_STRING);
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
- rb_warning("forwarding async_exec to async_exec_params and send_query to send_query_params is deprecated");
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
- rb_warning("forwarding async_exec_params to async_exec is deprecated");
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 );
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_result.c - PG::Result class extension
3
- * $Id$
3
+ * $Id: pg_result.c,v a8b70c42b3e8 2018/07/30 14:09:38 kanis $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_text_decoder.c - PG::TextDecoder module
3
- * $Id$
3
+ * $Id: pg_text_decoder.c,v cee615e0ea2c 2018/07/30 05:27:05 lars $
4
4
  *
5
5
  */
6
6
 
@@ -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(ptr1 = p_in; ptr1 != p_in + strlen; ptr1++) {
478
- char c = *ptr1;
477
+ for(; p_in != p_inend; p_in++) {
478
+ char c = *p_in;
479
479
  if (c == '"'){
480
- strlen++;
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
- break;
483
+ rb_raise(rb_eArgError, "string contains null byte");
485
484
  }
486
485
  *current_out++ = c;
487
486
  }
@@ -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
- rb_yield(pg_tuple_aref(self, INT2NUM(field_num)));
357
+ VALUE value = pg_tuple_materialize_field(this, field_num);
358
+ rb_yield(value);
358
359
  }
359
360
 
360
361
  pg_tuple_detach(this);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_type_map.c,v 2af122820861 2017/01/14 19:56:36 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
3
- * $Id$
3
+ * $Id: pg_type_map_all_strings.c,v c53f993a4254 2014/12/12 21:57:29 lars $
4
4
  *
5
5
  * This is the default typemap.
6
6
  *
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_class.c - PG::TypeMapByClass class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_class.c,v eeb8a82c5328 2014/11/10 19:34:02 lars $
4
4
  *
5
5
  * This type map can be used to select value encoders based on the class
6
6
  * of the given value to be send.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_column.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_mri_type.c - PG::TypeMapByMriType class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_mri_type.c,v 1269b8ad77b8 2015/02/06 16:38:23 lars $
4
4
  *
5
5
  * This type map can be used to select value encoders based on the MRI-internal
6
6
  * value type code.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_oid.c - PG::TypeMapByOid class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_oid.c,v c99d26015e3c 2014/12/12 20:58:25 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_in_ruby.c - PG::TypeMapInRuby class extension
3
- * $Id$
3
+ * $Id: pg_type_map_in_ruby.c,v 3d89d3aae4fd 2015/01/05 16:19:41 kanis $
4
4
  *
5
5
  */
6
6
 
data/ext/util.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * util.c - Utils for ruby-pg
3
- * $Id$
3
+ * $Id: util.c,v fc1c4deb1398 2018/06/25 12:02:09 kanis $
4
4
  *
5
5
  */
6
6
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/pg.rb CHANGED
@@ -35,10 +35,10 @@ end
35
35
  module PG
36
36
 
37
37
  # Library version
38
- VERSION = '1.1.0.pre20180730171000'
38
+ VERSION = '1.1.0'
39
39
 
40
40
  # VCS revision
41
- REVISION = %q$Revision$
41
+ REVISION = %q$Revision: ca83074366ac $
42
42
 
43
43
  class NotAllCopyDataRetrieved < PG::Error
44
44
  end
File without changes
File without changes
@@ -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).iso8601(3) ).to eq( Time.new(2013, 12, 31, 23, 58, 59, "+02:00").getlocal.iso8601(3) )
260
- expect( res.getvalue(0,1).iso8601(3) ).to eq( Time.new(1913, 12, 31, 23, 58, 59.1231, "-03:00").getlocal.iso8601(3) )
261
- expect( res.getvalue(0,2).iso8601(3) ).to eq( Time.new(-4713, 11, 24, 23, 58, 59.1231, "-03:00").getlocal.iso8601(3) )
262
- expect( res.getvalue(0,3).iso8601(3) ).to eq( Time.new(294276, 12, 31, 23, 58, 59.1231, "+03:00").getlocal.iso8601(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
@@ -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\0 escape".encode( "utf-16be" )
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\0 escape".encode( "utf-16be" )
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\0 escape".encode( "utf-16le" )
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\0 escape".encode( "utf-16le" )
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\0 escape".encode( "iso-8859-1" )
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\0 escape".encode( "iso-8859-1" )
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 + "\0afterzero" )
1416
+ escaped = described_class.quote_ident( original )
1372
1417
  expect( escaped ).to eq( "\"" + original.gsub("\"", "\"\"") + "\"" )
1373
1418
  end
1374
1419