sequel_pg 1.12.5 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 609ef32bd9eb0fe13dad508682adc477415124359e04f1aebbf5e54cdaaf4630
4
- data.tar.gz: 31d2bebfa20c348daf4a0e03bee7df3f727b0306fa3f0987bbcfdaa050f2a234
3
+ metadata.gz: 41aa757cb6f4ca6f56ca26044517a47a68731dd7d51335451f6da2e5b5b34d6f
4
+ data.tar.gz: ec43d49fd7b4b8821ecbb813f6244aaf46f69866e84b94df96a3c52ef3a6fd41
5
5
  SHA512:
6
- metadata.gz: 9a1ba95aa91fa7e521b3b6991b716fec37722faca0d2a658a7743e4fdd5e631b789f3c6da667b1b6f84159ab0ce2091d72b753b1c1d7fb08a357ddf645e9b81d
7
- data.tar.gz: 97bacb9be53e6781fcdfb60abbd934b8aa269554495559a64c2d223a0dde3f78a8ca64a32dc04898bec69c753656ffcad1005913fe0b5fc34597e4ab01f3267c
6
+ metadata.gz: 2a2578bec8fed224dcd3c1263cb86a4729cf11318f80d6cdb03366ae7dae6e68995447db06a1105d1ecda50222d2ff6258079fb7395d3f262094e1e05502fd48
7
+ data.tar.gz: 26a470d0e7d8290cade76b07cecd972be840c838492607a5649c0fd803de2ca7ea2e34b0c77fddcaff734a2a875b1f26ce8d5b03ec0fe0ab887ae3045ffa10e0
data/CHANGELOG CHANGED
@@ -1,3 +1,23 @@
1
+ === 1.15.0 (2022-03-16)
2
+
3
+ * Avoid deprecation warning in the pg_streaming extension on pg 1.3+ when streaming a query with bound parameters (jeremyevans)
4
+
5
+ * Use pgresult_stream_any when using pg 1.3.4+ for faster streaming (jeremyevans)
6
+
7
+ * Do not use streaming by default for Dataset#paged_each in the pg_streaming extension (jeremyevans)
8
+
9
+ * Avoid verbose warning if loading sequel_pg after Sequel pg_array extension (jeremyevans)
10
+
11
+ === 1.14.0 (2020-09-22)
12
+
13
+ * Reduce stack memory usage for result sets with 64 or fewer columns (jeremyevans)
14
+
15
+ * Support result sets with more than 256 columns by default (jeremyevans) (#39)
16
+
17
+ === 1.13.0 (2020-04-13)
18
+
19
+ * Allow overriding of inet/cidr type conversion using conversion procs (beanieboi, jeremyevans) (#36, #37)
20
+
1
21
  === 1.12.5 (2020-03-23)
2
22
 
3
23
  * Fix offset calculation for timestamptz types when datetime_class is DateTime and using local application timezone (jeremyevans)
data/README.rdoc CHANGED
@@ -70,12 +70,6 @@ can do the following:
70
70
 
71
71
  gem install sequel_pg
72
72
 
73
- Note that by default sequel_pg only supports result sets with up to
74
- 256 columns. If you will have a result set with more than 256 columns,
75
- you should modify the maximum supported number of columns via:
76
-
77
- gem install sequel_pg -- --with-cflags=\"-DSPG_MAX_FIELDS=512\"
78
-
79
73
  Make sure the pg_config binary is in your PATH so the installation
80
74
  can find the PostgreSQL shared library and header files. Alternatively,
81
75
  you can use the POSTGRES_LIB and POSTGRES_INCLUDE environment
@@ -118,19 +112,6 @@ requirements:
118
112
 
119
113
  rake build
120
114
 
121
- == Platforms Supported
122
-
123
- sequel_pg has been tested on the following:
124
-
125
- * ruby 1.9.3
126
- * ruby 2.0
127
- * ruby 2.1
128
- * ruby 2.2
129
- * ruby 2.3
130
- * ruby 2.4
131
- * ruby 2.5
132
- * ruby 2.6
133
-
134
115
  == Known Issues
135
116
 
136
117
  * You must be using the ISO PostgreSQL date format (which is the
@@ -1,4 +1,4 @@
1
- #define SEQUEL_PG_VERSION_INTEGER 11205
1
+ #define SEQUEL_PG_VERSION_INTEGER 11500
2
2
 
3
3
  #include <string.h>
4
4
  #include <stdio.h>
@@ -15,9 +15,6 @@
15
15
  #include <ruby/version.h>
16
16
  #include <ruby/encoding.h>
17
17
 
18
- #ifndef SPG_MAX_FIELDS
19
- #define SPG_MAX_FIELDS 256
20
- #endif
21
18
  #define SPG_MINUTES_PER_DAY 1440.0
22
19
  #define SPG_SECONDS_PER_DAY 86400.0
23
20
 
@@ -73,9 +70,11 @@
73
70
  PGconn* pg_get_pgconn(VALUE);
74
71
  PGresult* pgresult_get(VALUE);
75
72
  int pg_get_result_enc_idx(VALUE);
73
+ VALUE pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int, void*), void* data);
76
74
 
77
75
  static int spg_use_ipaddr_alloc;
78
76
  static int spg_use_pg_get_result_enc_idx;
77
+ static int spg_use_pg_stream_any;
79
78
 
80
79
  static VALUE spg_Sequel;
81
80
  static VALUE spg_PGArray;
@@ -535,7 +534,7 @@ static VALUE spg_timestamp(const char *s, VALUE self, size_t length, int tz) {
535
534
  }
536
535
 
537
536
  if (remaining < 19) {
538
- return spg_timestamp_error(s, self, "unexpected timetamp format, too short");
537
+ return spg_timestamp_error(s, self, "unexpected timestamp format, too short");
539
538
  }
540
539
 
541
540
  year = parse_year(&p, &remaining);
@@ -931,8 +930,10 @@ static VALUE spg__array_col_value(char *v, size_t length, VALUE converter, int e
931
930
  break;
932
931
  case 869: /* inet */
933
932
  case 650: /* cidr */
934
- rv = spg_inet(v, length);
935
- break;
933
+ if (!RTEST(converter)) {
934
+ rv = spg_inet(v, length);
935
+ break;
936
+ }
936
937
  default:
937
938
  rv = rb_tainted_str_new(v, length);
938
939
  PG_ENCODING_SET_NOCHECK(rv, enc_index);
@@ -1079,10 +1080,6 @@ static VALUE spg__col_value(VALUE self, PGresult *res, long i, long j, VALUE* co
1079
1080
  rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
1080
1081
  PG_ENCODING_SET_NOCHECK(rv, enc_index);
1081
1082
  break;
1082
- case 869: /* inet */
1083
- case 650: /* cidr */
1084
- rv = spg_inet(v, PQgetlength(res, i, j));
1085
- break;
1086
1083
  /* array types */
1087
1084
  case 1009:
1088
1085
  case 1014:
@@ -1220,17 +1217,30 @@ static VALUE spg__col_value(VALUE self, PGresult *res, long i, long j, VALUE* co
1220
1217
  scalar_oid = 22;
1221
1218
  break;
1222
1219
  case 1041:
1220
+ if (RTEST(colconvert[j])) {
1221
+ goto default_cond;
1222
+ }
1223
1223
  array_type = spg_sym_inet;
1224
1224
  scalar_oid = 869;
1225
1225
  break;
1226
1226
  case 651:
1227
+ if (RTEST(colconvert[j])) {
1228
+ goto default_cond;
1229
+ }
1227
1230
  array_type = spg_sym_cidr;
1228
1231
  scalar_oid = 650;
1229
1232
  break;
1230
1233
  }
1231
1234
  rv = spg_array_value(v, PQgetlength(res, i, j), colconvert[j], enc_index, scalar_oid, self, array_type);
1232
1235
  break;
1236
+ case 869: /* inet */
1237
+ case 650: /* cidr */
1238
+ if (colconvert[j] == Qnil) {
1239
+ rv = spg_inet(v, PQgetlength(res, i, j));
1240
+ break;
1241
+ }
1233
1242
  default:
1243
+ default_cond:
1234
1244
  rv = rb_tainted_str_new(v, PQgetlength(res, i, j));
1235
1245
  PG_ENCODING_SET_NOCHECK(rv, enc_index);
1236
1246
  if (colconvert[j] != Qnil) {
@@ -1369,10 +1379,7 @@ static void spg_set_column_info(VALUE self, PGresult *res, VALUE *colsyms, VALUE
1369
1379
  rb_funcall(self, spg_id_columns_equal, 1, rb_ary_new4(nfields, colsyms));
1370
1380
  }
1371
1381
 
1372
- static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1373
- PGresult *res;
1374
- VALUE colsyms[SPG_MAX_FIELDS];
1375
- VALUE colconvert[SPG_MAX_FIELDS];
1382
+ static VALUE spg_yield_hash_rows_internal(VALUE self, PGresult *res, int enc_index, VALUE* colsyms, VALUE* colconvert) {
1376
1383
  long ntuples;
1377
1384
  long nfields;
1378
1385
  long i;
@@ -1382,21 +1389,9 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1382
1389
  VALUE pg_type;
1383
1390
  VALUE pg_value;
1384
1391
  char type = SPG_YIELD_NORMAL;
1385
- int enc_index;
1386
-
1387
- if (!RTEST(rres)) {
1388
- return self;
1389
- }
1390
- res = pgresult_get(rres);
1391
-
1392
- enc_index = spg_use_pg_get_result_enc_idx ? pg_get_result_enc_idx(rres) : enc_get_index(rres);
1393
1392
 
1394
1393
  ntuples = PQntuples(res);
1395
1394
  nfields = PQnfields(res);
1396
- if (nfields > SPG_MAX_FIELDS) {
1397
- rb_raise(rb_eRangeError, "more than %d columns in query (%ld columns detected)", SPG_MAX_FIELDS, nfields);
1398
- }
1399
-
1400
1395
  spg_set_column_info(self, res, colsyms, colconvert, enc_index);
1401
1396
 
1402
1397
  opts = rb_funcall(self, spg_id_opts, 0);
@@ -1613,6 +1608,40 @@ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1613
1608
  return self;
1614
1609
  }
1615
1610
 
1611
+ #define def_spg_yield_hash_rows(max_fields) static VALUE spg_yield_hash_rows_ ## max_fields(VALUE self, PGresult *res, int enc_index) { \
1612
+ VALUE colsyms[max_fields]; \
1613
+ VALUE colconvert[max_fields]; \
1614
+ return spg_yield_hash_rows_internal(self, res, enc_index, colsyms, colconvert); \
1615
+ }
1616
+
1617
+ def_spg_yield_hash_rows(16)
1618
+ def_spg_yield_hash_rows(64)
1619
+ def_spg_yield_hash_rows(256)
1620
+ def_spg_yield_hash_rows(1664)
1621
+
1622
+ static VALUE spg_yield_hash_rows(VALUE self, VALUE rres, VALUE ignore) {
1623
+ PGresult *res;
1624
+ long nfields;
1625
+ int enc_index;
1626
+
1627
+ if (!RTEST(rres)) {
1628
+ return self;
1629
+ }
1630
+ res = pgresult_get(rres);
1631
+
1632
+ enc_index = spg_use_pg_get_result_enc_idx ? pg_get_result_enc_idx(rres) : enc_get_index(rres);
1633
+
1634
+ nfields = PQnfields(res);
1635
+ if (nfields <= 16) return spg_yield_hash_rows_16(self, res, enc_index);
1636
+ else if (nfields <= 64) return spg_yield_hash_rows_64(self, res, enc_index);
1637
+ else if (nfields <= 256) return spg_yield_hash_rows_256(self, res, enc_index);
1638
+ else if (nfields <= 1664) return spg_yield_hash_rows_1664(self, res, enc_index);
1639
+ else rb_raise(rb_eRangeError, "more than 1664 columns in query (%ld columns detected)", nfields);
1640
+
1641
+ /* UNREACHABLE */
1642
+ return self;
1643
+ }
1644
+
1616
1645
  static VALUE spg_supports_streaming_p(VALUE self) {
1617
1646
  return
1618
1647
  #if HAVE_PQSETSINGLEROWMODE
@@ -1632,12 +1661,39 @@ static VALUE spg_set_single_row_mode(VALUE self) {
1632
1661
  return Qnil;
1633
1662
  }
1634
1663
 
1635
- static VALUE spg__yield_each_row(VALUE self) {
1636
- PGresult *res;
1637
- VALUE rres;
1638
- VALUE rconn;
1639
- VALUE colsyms[SPG_MAX_FIELDS];
1640
- VALUE colconvert[SPG_MAX_FIELDS];
1664
+ struct spg__yield_each_row_stream_data {
1665
+ VALUE self;
1666
+ VALUE *colsyms;
1667
+ VALUE *colconvert;
1668
+ VALUE pg_value;
1669
+ int enc_index;
1670
+ char type;
1671
+ };
1672
+
1673
+ static void spg__yield_each_row_stream(VALUE rres, int ntuples, int nfields, void *rdata) {
1674
+ struct spg__yield_each_row_stream_data* data = (struct spg__yield_each_row_stream_data *)rdata;
1675
+ VALUE h = rb_hash_new();
1676
+ VALUE self = data->self;
1677
+ VALUE *colsyms = data->colsyms;
1678
+ VALUE *colconvert= data->colconvert;
1679
+ PGresult *res = pgresult_get(rres);
1680
+ int enc_index = data->enc_index;
1681
+ long j;
1682
+
1683
+ for(j=0; j<nfields; j++) {
1684
+ rb_hash_aset(h, colsyms[j], spg__col_value(self, res, 0, j, colconvert , enc_index));
1685
+ }
1686
+
1687
+ if(data->type == SPG_YIELD_MODEL) {
1688
+ VALUE model = rb_obj_alloc(data->pg_value);
1689
+ rb_ivar_set(model, spg_id_values, h);
1690
+ rb_yield(model);
1691
+ } else {
1692
+ rb_yield(h);
1693
+ }
1694
+ }
1695
+
1696
+ static VALUE spg__yield_each_row_internal(VALUE self, VALUE rconn, VALUE rres, PGresult *res, int enc_index, VALUE *colsyms, VALUE *colconvert) {
1641
1697
  long nfields;
1642
1698
  long j;
1643
1699
  VALUE h;
@@ -1645,19 +1701,9 @@ static VALUE spg__yield_each_row(VALUE self) {
1645
1701
  VALUE pg_type;
1646
1702
  VALUE pg_value = Qnil;
1647
1703
  char type = SPG_YIELD_NORMAL;
1648
- int enc_index;
1649
-
1650
- rconn = rb_ary_entry(self, 1);
1651
- self = rb_ary_entry(self, 0);
1704
+ struct spg__yield_each_row_stream_data data;
1652
1705
 
1653
- rres = rb_funcall(rconn, spg_id_get_result, 0);
1654
- if (rres == Qnil) {
1655
- goto end_yield_each_row;
1656
- }
1657
- rb_funcall(rres, spg_id_check, 0);
1658
- res = pgresult_get(rres);
1659
-
1660
- enc_index = spg_use_pg_get_result_enc_idx ? pg_get_result_enc_idx(rres) : enc_get_index(rres);
1706
+ nfields = PQnfields(res);
1661
1707
 
1662
1708
  /* Only handle regular and model types. All other types require compiling all
1663
1709
  * of the results at once, which is not a use case for streaming. The streaming
@@ -1671,14 +1717,20 @@ static VALUE spg__yield_each_row(VALUE self) {
1671
1717
  }
1672
1718
  }
1673
1719
 
1674
- nfields = PQnfields(res);
1675
- if (nfields > SPG_MAX_FIELDS) {
1676
- rb_funcall(rres, spg_id_clear, 0);
1677
- rb_raise(rb_eRangeError, "more than %d columns in query", SPG_MAX_FIELDS);
1678
- }
1679
-
1680
1720
  spg_set_column_info(self, res, colsyms, colconvert, enc_index);
1681
1721
 
1722
+ if (spg_use_pg_stream_any) {
1723
+ data.self = self;
1724
+ data.colsyms = colsyms;
1725
+ data.colconvert = colconvert;
1726
+ data.pg_value = pg_value;
1727
+ data.enc_index = enc_index;
1728
+ data.type = type;
1729
+
1730
+ pgresult_stream_any(rres, spg__yield_each_row_stream, &data);
1731
+ return self;
1732
+ }
1733
+
1682
1734
  while (PQntuples(res) != 0) {
1683
1735
  h = rb_hash_new();
1684
1736
  for(j=0; j<nfields; j++) {
@@ -1698,14 +1750,57 @@ static VALUE spg__yield_each_row(VALUE self) {
1698
1750
 
1699
1751
  rres = rb_funcall(rconn, spg_id_get_result, 0);
1700
1752
  if (rres == Qnil) {
1701
- goto end_yield_each_row;
1753
+ return self;
1702
1754
  }
1703
1755
  rb_funcall(rres, spg_id_check, 0);
1704
1756
  res = pgresult_get(rres);
1705
1757
  }
1706
1758
  rb_funcall(rres, spg_id_clear, 0);
1707
1759
 
1708
- end_yield_each_row:
1760
+ return self;
1761
+ }
1762
+
1763
+ #define def_spg__yield_each_row(max_fields) static VALUE spg__yield_each_row_ ## max_fields(VALUE self, VALUE rconn, VALUE rres, PGresult *res, int enc_index) { \
1764
+ VALUE colsyms[max_fields]; \
1765
+ VALUE colconvert[max_fields]; \
1766
+ return spg__yield_each_row_internal(self, rconn, rres, res, enc_index, colsyms, colconvert); \
1767
+ }
1768
+
1769
+ def_spg__yield_each_row(16)
1770
+ def_spg__yield_each_row(64)
1771
+ def_spg__yield_each_row(256)
1772
+ def_spg__yield_each_row(1664)
1773
+
1774
+ static VALUE spg__yield_each_row(VALUE self) {
1775
+ PGresult *res;
1776
+ VALUE rres;
1777
+ VALUE rconn;
1778
+ int enc_index;
1779
+ long nfields;
1780
+
1781
+ rconn = rb_ary_entry(self, 1);
1782
+ self = rb_ary_entry(self, 0);
1783
+
1784
+ rres = rb_funcall(rconn, spg_id_get_result, 0);
1785
+ if (rres == Qnil) {
1786
+ return self;
1787
+ }
1788
+ rb_funcall(rres, spg_id_check, 0);
1789
+ res = pgresult_get(rres);
1790
+
1791
+ enc_index = spg_use_pg_get_result_enc_idx ? pg_get_result_enc_idx(rres) : enc_get_index(rres);
1792
+
1793
+ nfields = PQnfields(res);
1794
+ if (nfields <= 16) return spg__yield_each_row_16(self, rconn, rres, res, enc_index);
1795
+ else if (nfields <= 64) return spg__yield_each_row_64(self, rconn, rres, res, enc_index);
1796
+ else if (nfields <= 256) return spg__yield_each_row_256(self, rconn, rres, res, enc_index);
1797
+ else if (nfields <= 1664) return spg__yield_each_row_1664(self, rconn, rres, res, enc_index);
1798
+ else {
1799
+ rb_funcall(rres, spg_id_clear, 0);
1800
+ rb_raise(rb_eRangeError, "more than 1664 columns in query (%ld columns detected)", nfields);
1801
+ }
1802
+
1803
+ /* UNREACHABLE */
1709
1804
  return self;
1710
1805
  }
1711
1806
 
@@ -1761,10 +1856,21 @@ void Init_sequel_pg(void) {
1761
1856
  }
1762
1857
  }
1763
1858
 
1764
- if (RTEST(rb_eval_string("defined?(PG::VERSION) && PG::VERSION.to_f >= 1.2"))) {
1765
- spg_use_pg_get_result_enc_idx = 1;
1859
+ c = rb_eval_string("defined?(PG::VERSION) && PG::VERSION.split('.').map(&:to_i)");
1860
+ if (RB_TYPE_P(c, T_ARRAY) && RARRAY_LEN(c) >= 3) {
1861
+ if (FIX2INT(RARRAY_AREF(c, 0)) > 1) {
1862
+ spg_use_pg_get_result_enc_idx = 1;
1863
+ spg_use_pg_stream_any = 1;
1864
+ } else if (FIX2INT(RARRAY_AREF(c, 0)) == 1) {
1865
+ if (FIX2INT(RARRAY_AREF(c, 1)) >= 2) {
1866
+ spg_use_pg_get_result_enc_idx = 1;
1867
+ }
1868
+ if (FIX2INT(RARRAY_AREF(c, 1)) > 3 || (FIX2INT(RARRAY_AREF(c, 1)) == 3 && FIX2INT(RARRAY_AREF(c, 2)) >= 4)) {
1869
+ spg_use_pg_stream_any = 1;
1870
+ }
1871
+ }
1766
1872
  }
1767
-
1873
+
1768
1874
  rb_const_set(spg_Postgres, rb_intern("SEQUEL_PG_VERSION_INTEGER"), INT2FIX(SEQUEL_PG_VERSION_INTEGER));
1769
1875
 
1770
1876
  spg_id_BigDecimal = rb_intern("BigDecimal");
@@ -73,12 +73,18 @@ module Sequel::Postgres::Streaming
73
73
 
74
74
  private
75
75
 
76
+ unless Sequel::Postgres::Adapter.method_defined?(:send_query_params)
77
+ def send_query_params(*args)
78
+ send_query(*args)
79
+ end
80
+ end
81
+
76
82
  if Sequel::Database.instance_methods.map(&:to_s).include?('log_connection_yield')
77
83
  # If using single row mode, send the query instead of executing it.
78
84
  def execute_query(sql, args)
79
85
  if @single_row_mode
80
86
  @single_row_mode = false
81
- @db.log_connection_yield(sql, self, args){args ? send_query(sql, args) : send_query(sql)}
87
+ @db.log_connection_yield(sql, self, args){args ? send_query_params(sql, args) : send_query(sql)}
82
88
  set_single_row_mode
83
89
  block
84
90
  self
@@ -122,7 +128,12 @@ module Sequel::Postgres::Streaming
122
128
  unless block_given?
123
129
  return enum_for(:paged_each, opts)
124
130
  end
125
- stream.each(&block)
131
+
132
+ if stream_results?
133
+ each(&block)
134
+ else
135
+ super
136
+ end
126
137
  end
127
138
 
128
139
  # Return a clone of the dataset that will use streaming to load
@@ -120,6 +120,9 @@ if defined?(Sequel::Postgres::PGArray)
120
120
  # pg_array extension previously loaded
121
121
 
122
122
  class Sequel::Postgres::PGArray::Creator
123
+ # Avoid method redefined verbose warning
124
+ alias call call if method_defined?(:call)
125
+
123
126
  # Override Creator to use sequel_pg's C-based parser instead of the pure ruby parser.
124
127
  def call(string)
125
128
  Sequel::Postgres::PGArray.new(Sequel::Postgres.parse_pg_array(string, @converter), @type)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.5
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-23 00:00:00.000000000 Z
11
+ date: 2022-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  requirements: []
104
- rubygems_version: 3.1.2
104
+ rubygems_version: 3.3.7
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: Faster SELECTs when using Sequel with pg