Skip to content

Commit 669d4b0

Browse files
committed
Patches for issues in PG.
1 parent 0b73efc commit 669d4b0

File tree

1 file changed

+224
-0
lines changed

1 file changed

+224
-0
lines changed

lib/cext/patches/pg_patches.rb

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,202 @@ class PgPatches
1515
case Qfalse_int_const : mybool = 0; break;
1616
EOF
1717

18+
PG_TEXT_ENC_INTEGER_OLD = <<-EOF
19+
static int
20+
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
21+
{
22+
if(out){
23+
if(TYPE(*intermediate) == T_STRING){
24+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
25+
}else{
26+
char *start = out;
27+
int len;
28+
int neg = 0;
29+
long long ll = NUM2LL(*intermediate);
30+
31+
if (ll < 0) {
32+
/* We don't expect problems with the most negative integer not being representable
33+
* as a positive integer, because Fixnum is only up to 63 bits.
34+
*/
35+
ll = -ll;
36+
neg = 1;
37+
}
38+
39+
/* Compute the result string backwards. */
40+
do {
41+
long long remainder;
42+
long long oldval = ll;
43+
44+
ll /= 10;
45+
remainder = oldval - ll * 10;
46+
*out++ = '0' + remainder;
47+
} while (ll != 0);
48+
49+
if (neg)
50+
*out++ = '-';
51+
52+
len = out - start;
53+
54+
/* Reverse string. */
55+
out--;
56+
while (start < out)
57+
{
58+
char swap = *start;
59+
60+
*start++ = *out;
61+
*out-- = swap;
62+
}
63+
64+
return len;
65+
}
66+
}else{
67+
*intermediate = pg_obj_to_i(value);
68+
if(TYPE(*intermediate) == T_FIXNUM){
69+
int len;
70+
long long sll = NUM2LL(*intermediate);
71+
long long ll = sll < 0 ? -sll : sll;
72+
if( ll < 100000000 ){
73+
if( ll < 10000 ){
74+
if( ll < 100 ){
75+
len = ll < 10 ? 1 : 2;
76+
}else{
77+
len = ll < 1000 ? 3 : 4;
78+
}
79+
}else{
80+
if( ll < 1000000 ){
81+
len = ll < 100000 ? 5 : 6;
82+
}else{
83+
len = ll < 10000000 ? 7 : 8;
84+
}
85+
}
86+
}else{
87+
if( ll < 1000000000000LL ){
88+
if( ll < 10000000000LL ){
89+
len = ll < 1000000000LL ? 9 : 10;
90+
}else{
91+
len = ll < 100000000000LL ? 11 : 12;
92+
}
93+
}else{
94+
if( ll < 100000000000000LL ){
95+
len = ll < 10000000000000LL ? 13 : 14;
96+
}else{
97+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
98+
}
99+
}
100+
}
101+
return sll < 0 ? len+1 : len;
102+
}else{
103+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
104+
}
105+
}
106+
}
107+
EOF
108+
109+
PG_TEXT_ENC_INTEGER_NEW = <<-EOF
110+
static int
111+
pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediate, int enc_idx)
112+
{
113+
if(out){
114+
if(TYPE(*intermediate) == T_STRING){
115+
return pg_coder_enc_to_s(this, value, out, intermediate, enc_idx);
116+
}else{
117+
char *start = out;
118+
int len;
119+
int neg = 0;
120+
long long ll = NUM2LL(*intermediate);
121+
unsigned long long ull = ll;
122+
123+
if (ll < 0) {
124+
ull = ~ll;
125+
ull++;
126+
neg = 1;
127+
}
128+
129+
/* Compute the result string backwards. */
130+
do {
131+
unsigned long long remainder;
132+
unsigned long long oldval = ull;
133+
134+
ull /= 10;
135+
remainder = oldval - ull * 10;
136+
*out++ = '0' + remainder;
137+
} while (ull != 0);
138+
139+
if (neg)
140+
*out++ = '-';
141+
142+
len = out - start;
143+
144+
/* Reverse string. */
145+
out--;
146+
while (start < out)
147+
{
148+
char swap = *start;
149+
150+
*start++ = *out;
151+
*out-- = swap;
152+
}
153+
154+
return len;
155+
}
156+
}else{
157+
*intermediate = pg_obj_to_i(value);
158+
if(TYPE(*intermediate) == T_FIXNUM){
159+
int len;
160+
long long sll = NUM2LL(*intermediate);
161+
unsigned long long ull = sll < 0 ? ((unsigned long long) ~sll) + 1 : (unsigned long long) sll;
162+
if( ull < 100000000 ){
163+
if( ull < 10000 ){
164+
if( ull < 100 ){
165+
len = ull < 10 ? 1 : 2;
166+
}else{
167+
len = ull < 1000 ? 3 : 4;
168+
}
169+
}else{
170+
if( ull < 1000000 ){
171+
len = ull < 100000 ? 5 : 6;
172+
}else{
173+
len = ull < 10000000 ? 7 : 8;
174+
}
175+
}
176+
}else{
177+
if( ull < 1000000000000LL ){
178+
if( ull < 10000000000LL ){
179+
len = ull < 1000000000LL ? 9 : 10;
180+
}else{
181+
len = ull < 100000000000LL ? 11 : 12;
182+
}
183+
}else{
184+
if( ull < 100000000000000LL ){
185+
len = ull < 10000000000000LL ? 13 : 14;
186+
}else{
187+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
188+
}
189+
}
190+
}
191+
return sll < 0 ? len+1 : len;
192+
}else{
193+
return pg_coder_enc_to_s(this, *intermediate, NULL, intermediate, enc_idx);
194+
}
195+
}
196+
}
197+
EOF
198+
199+
PG_TEXT_DECODER_FREE_OLD = <<-EOF
200+
static VALUE
201+
pg_text_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
202+
EOF
203+
204+
PG_TEXT_DECODER_FREE_NEW = <<-EOF
205+
static VALUE pg_tr_pq_freemem(VALUE mem) {
206+
PQfreemem((void *)mem);
207+
return Qfalse;
208+
}
209+
210+
static VALUE
211+
pg_text_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
212+
EOF
213+
18214
PATCHES = {
19215
gem: 'pg',
20216
patches: {
@@ -24,6 +220,34 @@ class PgPatches
24220
replacement: PG_BINARY_ENCODER_PATCH
25221
}
26222
],
223+
'pg_result.c' => [
224+
{
225+
match: 'xmalloc(',
226+
replacement: 'calloc(1,'
227+
},
228+
],
229+
'pg_tuple.c' => [
230+
{
231+
match: 'xmalloc(',
232+
replacement: 'calloc(1,'
233+
},
234+
],
235+
'pg_text_decoder.c' => [
236+
{
237+
match: PG_TEXT_DECODER_FREE_OLD,
238+
replacement: PG_TEXT_DECODER_FREE_NEW
239+
},
240+
{
241+
match: '(VALUE(*)())PQfreemem',
242+
replacement: 'pg_tr_pq_freemem'
243+
}
244+
],
245+
'pg_text_encoder.c' => [
246+
{
247+
match: PG_TEXT_ENC_INTEGER_OLD,
248+
replacement: PG_TEXT_ENC_INTEGER_NEW
249+
},
250+
],
27251
'pg_type_map_by_class.c' => [
28252
{
29253
match: '#define CACHE_LOOKUP(this, klass) ( &this->cache_row[(klass >> 8) & 0xff] )',

0 commit comments

Comments
 (0)