pg 1.4.4-x64-mingw32 → 1.4.6-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2021, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2022, PostgreSQL Global Development Group
6
6
  #
7
7
  # This list serves as the basis for generating source files containing error
8
8
  # codes. It is kept in a common format to make sure all these source files have
@@ -222,6 +222,7 @@ Section: Class 22 - Data Exception
222
222
  2203D E ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS too_many_json_array_elements
223
223
  2203E E ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS too_many_json_object_members
224
224
  2203F E ERRCODE_SQL_JSON_SCALAR_REQUIRED sql_json_scalar_required
225
+ 2203G E ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE sql_json_item_cannot_be_cast_to_target_type
225
226
 
226
227
  Section: Class 23 - Integrity Constraint Violation
227
228
 
data/ext/pg.c CHANGED
@@ -679,6 +679,9 @@ Init_pg_ext(void)
679
679
  rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
680
680
  rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid));
681
681
 
682
+ /* PostgreSQL compiled in default port */
683
+ rb_define_const(rb_mPGconstants, "DEF_PGPORT", INT2FIX(DEF_PGPORT));
684
+
682
685
  /* Add the constants to the toplevel namespace */
683
686
  rb_include_module( rb_mPG, rb_mPGconstants );
684
687
 
data/ext/pg_connection.c CHANGED
@@ -702,7 +702,10 @@ static VALUE
702
702
  pgconn_port(VALUE self)
703
703
  {
704
704
  char* port = PQport(pg_get_pgconn(self));
705
- return INT2NUM(atoi(port));
705
+ if (!port || port[0] == '\0')
706
+ return INT2NUM(DEF_PGPORT);
707
+ else
708
+ return INT2NUM(atoi(port));
706
709
  }
707
710
 
708
711
  /*
@@ -2443,8 +2446,9 @@ pgconn_async_flush(VALUE self)
2443
2446
  VALUE socket_io = pgconn_socket_io(self);
2444
2447
  events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE | PG_RUBY_IO_WRITABLE), Qnil));
2445
2448
 
2446
- if (events & PG_RUBY_IO_READABLE)
2449
+ if (events & PG_RUBY_IO_READABLE){
2447
2450
  pgconn_consume_input(self);
2451
+ }
2448
2452
  }
2449
2453
  return Qtrue;
2450
2454
  }
@@ -3123,8 +3127,14 @@ pgconn_async_get_last_result(VALUE self)
3123
3127
  * conn.discard_results()
3124
3128
  *
3125
3129
  * Silently discard any prior query result that application didn't eat.
3126
- * This is done prior of Connection#exec and sibling methods and can
3127
- * be called explicitly when using the async API.
3130
+ * This is internally used prior to Connection#exec and sibling methods.
3131
+ * It doesn't raise an exception on connection errors, but returns +false+ instead.
3132
+ *
3133
+ * Returns:
3134
+ * * +nil+ when the connection is already idle
3135
+ * * +true+ when some results have been discarded
3136
+ * * +false+ when a failure occured and the connection was closed
3137
+ *
3128
3138
  */
3129
3139
  static VALUE
3130
3140
  pgconn_discard_results(VALUE self)
@@ -3132,8 +3142,12 @@ pgconn_discard_results(VALUE self)
3132
3142
  PGconn *conn = pg_get_pgconn(self);
3133
3143
  VALUE socket_io;
3134
3144
 
3135
- if( PQtransactionStatus(conn) == PQTRANS_IDLE ) {
3136
- return Qnil;
3145
+ switch( PQtransactionStatus(conn) ) {
3146
+ case PQTRANS_IDLE:
3147
+ case PQTRANS_INTRANS:
3148
+ case PQTRANS_INERROR:
3149
+ return Qnil;
3150
+ default:;
3137
3151
  }
3138
3152
 
3139
3153
  socket_io = pgconn_socket_io(self);
@@ -3146,10 +3160,21 @@ pgconn_discard_results(VALUE self)
3146
3160
  * To avoid this call pg_rb_io_wait() and PQconsumeInput() without rb_raise().
3147
3161
  */
3148
3162
  while( gvl_PQisBusy(conn) ){
3149
- pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
3150
- if ( PQconsumeInput(conn) == 0 ) {
3151
- pgconn_close_socket_io(self);
3152
- return Qfalse;
3163
+ int events;
3164
+
3165
+ switch( PQflush(conn) ) {
3166
+ case 1:
3167
+ events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE | PG_RUBY_IO_WRITABLE), Qnil));
3168
+ if (events & PG_RUBY_IO_READABLE){
3169
+ if ( PQconsumeInput(conn) == 0 ) goto error;
3170
+ }
3171
+ break;
3172
+ case 0:
3173
+ pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
3174
+ if ( PQconsumeInput(conn) == 0 ) goto error;
3175
+ break;
3176
+ default:
3177
+ goto error;
3153
3178
  }
3154
3179
  }
3155
3180
 
@@ -3159,7 +3184,9 @@ pgconn_discard_results(VALUE self)
3159
3184
  status = PQresultStatus(cur);
3160
3185
  PQclear(cur);
3161
3186
  if (status == PGRES_COPY_IN){
3162
- gvl_PQputCopyEnd(conn, "COPY terminated by new PQexec");
3187
+ while( gvl_PQputCopyEnd(conn, "COPY terminated by new query or discard_results") == 0 ){
3188
+ pgconn_async_flush(self);
3189
+ }
3163
3190
  }
3164
3191
  if (status == PGRES_COPY_OUT){
3165
3192
  for(;;) {
@@ -3168,10 +3195,7 @@ pgconn_discard_results(VALUE self)
3168
3195
  if( st == 0 ) {
3169
3196
  /* would block -> wait for readable data */
3170
3197
  pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
3171
- if ( PQconsumeInput(conn) == 0 ) {
3172
- pgconn_close_socket_io(self);
3173
- return Qfalse;
3174
- }
3198
+ if ( PQconsumeInput(conn) == 0 ) goto error;
3175
3199
  } else if( st > 0 ) {
3176
3200
  /* some data retrieved -> discard it */
3177
3201
  PQfreemem(buffer);
@@ -3184,6 +3208,10 @@ pgconn_discard_results(VALUE self)
3184
3208
  }
3185
3209
 
3186
3210
  return Qtrue;
3211
+
3212
+ error:
3213
+ pgconn_close_socket_io(self);
3214
+ return Qfalse;
3187
3215
  }
3188
3216
 
3189
3217
  /*
@@ -3640,6 +3668,14 @@ pgconn_send_flush_request(VALUE self)
3640
3668
  * LARGE OBJECT SUPPORT
3641
3669
  **************************************************************************/
3642
3670
 
3671
+ #define BLOCKING_BEGIN(conn) do { \
3672
+ int old_nonblocking = PQisnonblocking(conn); \
3673
+ PQsetnonblocking(conn, 0);
3674
+
3675
+ #define BLOCKING_END(th) \
3676
+ PQsetnonblocking(conn, old_nonblocking); \
3677
+ } while(0);
3678
+
3643
3679
  /*
3644
3680
  * call-seq:
3645
3681
  * conn.lo_creat( [mode] ) -> Integer
@@ -3660,7 +3696,10 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
3660
3696
  else
3661
3697
  mode = NUM2INT(nmode);
3662
3698
 
3663
- lo_oid = lo_creat(conn, mode);
3699
+ BLOCKING_BEGIN(conn)
3700
+ lo_oid = lo_creat(conn, mode);
3701
+ BLOCKING_END(conn)
3702
+
3664
3703
  if (lo_oid == 0)
3665
3704
  pg_raise_conn_error( rb_ePGerror, self, "lo_creat failed");
3666
3705
 
@@ -3705,7 +3744,10 @@ pgconn_loimport(VALUE self, VALUE filename)
3705
3744
 
3706
3745
  Check_Type(filename, T_STRING);
3707
3746
 
3708
- lo_oid = lo_import(conn, StringValueCStr(filename));
3747
+ BLOCKING_BEGIN(conn)
3748
+ lo_oid = lo_import(conn, StringValueCStr(filename));
3749
+ BLOCKING_END(conn)
3750
+
3709
3751
  if (lo_oid == 0) {
3710
3752
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3711
3753
  }
@@ -3723,11 +3765,16 @@ pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
3723
3765
  {
3724
3766
  PGconn *conn = pg_get_pgconn(self);
3725
3767
  Oid oid;
3768
+ int ret;
3726
3769
  Check_Type(filename, T_STRING);
3727
3770
 
3728
3771
  oid = NUM2UINT(lo_oid);
3729
3772
 
3730
- if (lo_export(conn, oid, StringValueCStr(filename)) < 0) {
3773
+ BLOCKING_BEGIN(conn)
3774
+ ret = lo_export(conn, oid, StringValueCStr(filename));
3775
+ BLOCKING_END(conn)
3776
+
3777
+ if (ret < 0) {
3731
3778
  pg_raise_conn_error( rb_ePGerror, self, "%s", PQerrorMessage(conn));
3732
3779
  }
3733
3780
  return Qnil;
@@ -3758,7 +3805,11 @@ pgconn_loopen(int argc, VALUE *argv, VALUE self)
3758
3805
  else
3759
3806
  mode = NUM2INT(nmode);
3760
3807
 
3761
- if((fd = lo_open(conn, lo_oid, mode)) < 0) {
3808
+ BLOCKING_BEGIN(conn)
3809
+ fd = lo_open(conn, lo_oid, mode);
3810
+ BLOCKING_END(conn)
3811
+
3812
+ if(fd < 0) {
3762
3813
  pg_raise_conn_error( rb_ePGerror, self, "can't open large object: %s", PQerrorMessage(conn));
3763
3814
  }
3764
3815
  return INT2FIX(fd);
@@ -3783,8 +3834,12 @@ pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
3783
3834
  if( RSTRING_LEN(buffer) < 0) {
3784
3835
  pg_raise_conn_error( rb_ePGerror, self, "write buffer zero string");
3785
3836
  }
3786
- if((n = lo_write(conn, fd, StringValuePtr(buffer),
3787
- RSTRING_LEN(buffer))) < 0) {
3837
+ BLOCKING_BEGIN(conn)
3838
+ n = lo_write(conn, fd, StringValuePtr(buffer),
3839
+ RSTRING_LEN(buffer));
3840
+ BLOCKING_END(conn)
3841
+
3842
+ if(n < 0) {
3788
3843
  pg_raise_conn_error( rb_ePGerror, self, "lo_write failed: %s", PQerrorMessage(conn));
3789
3844
  }
3790
3845
 
@@ -3812,7 +3867,12 @@ pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
3812
3867
  pg_raise_conn_error( rb_ePGerror, self, "negative length %d given", len);
3813
3868
 
3814
3869
  buffer = ALLOC_N(char, len);
3815
- if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3870
+
3871
+ BLOCKING_BEGIN(conn)
3872
+ ret = lo_read(conn, lo_desc, buffer, len);
3873
+ BLOCKING_END(conn)
3874
+
3875
+ if(ret < 0)
3816
3876
  pg_raise_conn_error( rb_ePGerror, self, "lo_read failed");
3817
3877
 
3818
3878
  if(ret == 0) {
@@ -3842,7 +3902,11 @@ pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3842
3902
  int lo_desc = NUM2INT(in_lo_desc);
3843
3903
  int ret;
3844
3904
 
3845
- if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3905
+ BLOCKING_BEGIN(conn)
3906
+ ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence));
3907
+ BLOCKING_END(conn)
3908
+
3909
+ if(ret < 0) {
3846
3910
  pg_raise_conn_error( rb_ePGerror, self, "lo_lseek failed");
3847
3911
  }
3848
3912
 
@@ -3862,7 +3926,11 @@ pgconn_lotell(VALUE self, VALUE in_lo_desc)
3862
3926
  PGconn *conn = pg_get_pgconn(self);
3863
3927
  int lo_desc = NUM2INT(in_lo_desc);
3864
3928
 
3865
- if((position = lo_tell(conn, lo_desc)) < 0)
3929
+ BLOCKING_BEGIN(conn)
3930
+ position = lo_tell(conn, lo_desc);
3931
+ BLOCKING_END(conn)
3932
+
3933
+ if(position < 0)
3866
3934
  pg_raise_conn_error( rb_ePGerror, self, "lo_tell failed");
3867
3935
 
3868
3936
  return INT2FIX(position);
@@ -3880,8 +3948,13 @@ pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3880
3948
  PGconn *conn = pg_get_pgconn(self);
3881
3949
  int lo_desc = NUM2INT(in_lo_desc);
3882
3950
  size_t len = NUM2INT(in_len);
3951
+ int ret;
3952
+
3953
+ BLOCKING_BEGIN(conn)
3954
+ ret = lo_truncate(conn,lo_desc,len);
3955
+ BLOCKING_END(conn)
3883
3956
 
3884
- if(lo_truncate(conn,lo_desc,len) < 0)
3957
+ if(ret < 0)
3885
3958
  pg_raise_conn_error( rb_ePGerror, self, "lo_truncate failed");
3886
3959
 
3887
3960
  return Qnil;
@@ -3898,8 +3971,13 @@ pgconn_loclose(VALUE self, VALUE in_lo_desc)
3898
3971
  {
3899
3972
  PGconn *conn = pg_get_pgconn(self);
3900
3973
  int lo_desc = NUM2INT(in_lo_desc);
3974
+ int ret;
3975
+
3976
+ BLOCKING_BEGIN(conn)
3977
+ ret = lo_close(conn,lo_desc);
3978
+ BLOCKING_END(conn)
3901
3979
 
3902
- if(lo_close(conn,lo_desc) < 0)
3980
+ if(ret < 0)
3903
3981
  pg_raise_conn_error( rb_ePGerror, self, "lo_close failed");
3904
3982
 
3905
3983
  return Qnil;
@@ -3916,8 +3994,13 @@ pgconn_lounlink(VALUE self, VALUE in_oid)
3916
3994
  {
3917
3995
  PGconn *conn = pg_get_pgconn(self);
3918
3996
  Oid oid = NUM2UINT(in_oid);
3997
+ int ret;
3998
+
3999
+ BLOCKING_BEGIN(conn)
4000
+ ret = lo_unlink(conn,oid);
4001
+ BLOCKING_END(conn)
3919
4002
 
3920
- if(lo_unlink(conn,oid) < 0)
4003
+ if(ret < 0)
3921
4004
  pg_raise_conn_error( rb_ePGerror, self, "lo_unlink failed");
3922
4005
 
3923
4006
  return Qnil;
data/lib/2.5/pg_ext.so CHANGED
Binary file
data/lib/2.6/pg_ext.so CHANGED
Binary file
data/lib/2.7/pg_ext.so CHANGED
Binary file
data/lib/3.0/pg_ext.so CHANGED
Binary file
data/lib/pg/connection.rb CHANGED
@@ -196,11 +196,19 @@ class PG::Connection
196
196
  yield res
197
197
  rescue Exception => err
198
198
  errmsg = "%s while copy data: %s" % [ err.class.name, err.message ]
199
- put_copy_end( errmsg )
200
- get_result
201
- raise
199
+ begin
200
+ put_copy_end( errmsg )
201
+ rescue PG::Error
202
+ # Ignore error in cleanup to avoid losing original exception
203
+ end
204
+ discard_results
205
+ raise err
202
206
  else
203
- put_copy_end
207
+ begin
208
+ put_copy_end
209
+ rescue PG::Error => err
210
+ raise PG::LostCopyState.new("#{err} (probably by executing another SQL query while running a COPY command)", connection: self)
211
+ end
204
212
  get_last_result
205
213
  ensure
206
214
  self.encoder_for_put_copy_data = old_coder if coder
@@ -213,24 +221,17 @@ class PG::Connection
213
221
  self.decoder_for_get_copy_data = coder
214
222
  end
215
223
  yield res
216
- rescue Exception => err
224
+ rescue Exception
217
225
  cancel
218
- begin
219
- while get_copy_data
220
- end
221
- rescue PG::Error
222
- # Ignore error in cleanup to avoid losing original exception
223
- end
224
- while get_result
225
- end
226
- raise err
226
+ discard_results
227
+ raise
227
228
  else
228
229
  res = get_last_result
229
- if !res || res.result_status != PGRES_COMMAND_OK
230
- while get_copy_data
231
- end
232
- while get_result
233
- end
230
+ if !res
231
+ discard_results
232
+ raise PG::LostCopyState.new("Lost COPY state (probably by executing another SQL query while running a COPY command)", connection: self)
233
+ elsif res.result_status != PGRES_COMMAND_OK
234
+ discard_results
234
235
  raise PG::NotAllCopyDataRetrieved.new("Not all COPY data retrieved", connection: self)
235
236
  end
236
237
  res
@@ -723,6 +724,7 @@ class PG::Connection
723
724
  # This requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
724
725
  ihosts = iopts[:host].split(",", -1)
725
726
  iports = iopts[:port].split(",", -1)
727
+ iports = [nil] if iports.size == 0
726
728
  iports = iports * ihosts.size if iports.size == 1
727
729
  raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
728
730
 
data/lib/pg/exceptions.rb CHANGED
@@ -14,5 +14,12 @@ module PG
14
14
  end
15
15
  end
16
16
 
17
+ class NotAllCopyDataRetrieved < PG::Error
18
+ end
19
+ class LostCopyState < PG::Error
20
+ end
21
+ class NotInBlockingMode < PG::Error
22
+ end
23
+
17
24
  end # module PG
18
25
 
data/lib/pg/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module PG
2
2
  # Library version
3
- VERSION = '1.4.4'
3
+ VERSION = '1.4.6'
4
4
  end
data/lib/pg.rb CHANGED
@@ -50,12 +50,6 @@ module PG
50
50
  end
51
51
  end
52
52
 
53
-
54
- class NotAllCopyDataRetrieved < PG::Error
55
- end
56
- class NotInBlockingMode < PG::Error
57
- end
58
-
59
53
  # Get the PG library version.
60
54
  #
61
55
  # +include_buildnum+ is no longer used and any value passed will be ignored.
Binary file
data/pg.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.metadata["homepage_uri"] = spec.homepage
19
19
  spec.metadata["source_code_uri"] = "https://github.com/ged/ruby-pg"
20
- spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/History.rdoc"
20
+ spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/History.md"
21
21
  spec.metadata["documentation_uri"] = "http://deveiate.org/code/pg"
22
22
 
23
23
  # Specify which files should be added to the gem when it is released.
@@ -28,5 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.extensions = ["ext/extconf.rb"]
29
29
  spec.require_paths = ["lib"]
30
30
  spec.cert_chain = ["certs/ged.pem"]
31
- spec.rdoc_options = ["--main", "README.rdoc"]
31
+ spec.rdoc_options = ["--main", "README.md",
32
+ "--title", "PG: The Ruby PostgreSQL Driver"]
33
+ spec.extra_rdoc_files = `git ls-files -z *.rdoc *.md lib/*.rb lib/*/*.rb ext/*.c ext/*.h`.split("\x0")
32
34
  end
@@ -9,7 +9,7 @@ module TaskExtension
9
9
  def file(name, *args, &block)
10
10
  task_once(name, block) do
11
11
  super(name, *args) do |ta|
12
- block.call(ta).tap do
12
+ block&.call(ta).tap do
13
13
  raise "file #{ta.name} is missing after task executed" unless File.exist?(ta.name)
14
14
  end
15
15
  end
@@ -0,0 +1,7 @@
1
+ po4a version 0.69.
2
+ Written by Martin Quinson and Denis Barbier.
3
+
4
+ Copyright © 2002-2022 Software in the Public Interest, Inc.
5
+ This is free software; see source code for copying
6
+ conditions. There is NO warranty; not even for
7
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.