@@ -15,6 +15,202 @@ class PgPatches
15
15
case Qfalse_int_const : mybool = 0; break;
16
16
EOF
17
17
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
+
18
214
PATCHES = {
19
215
gem : 'pg' ,
20
216
patches : {
@@ -24,6 +220,34 @@ class PgPatches
24
220
replacement : PG_BINARY_ENCODER_PATCH
25
221
}
26
222
] ,
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
+ ] ,
27
251
'pg_type_map_by_class.c' => [
28
252
{
29
253
match : '#define CACHE_LOOKUP(this, klass) ( &this->cache_row[(klass >> 8) & 0xff] )' ,
0 commit comments