Age Owner Branch data TLA Line data Source code
1 : : /* src/interfaces/ecpg/compatlib/informix.c */
2 : :
3 : : #define POSTGRES_ECPG_INTERNAL
4 : : #include "postgres_fe.h"
5 : :
6 : : #include <math.h>
7 : : #include <ctype.h>
8 : : #include <limits.h>
9 : :
10 : : #include "ecpg_informix.h"
11 : : #include "ecpgerrno.h"
12 : : #include "ecpgtype.h"
13 : : #include "pgtypes_date.h"
14 : : #include "pgtypes_error.h"
15 : : #include "pgtypes_numeric.h"
16 : : #include "sqlca.h"
17 : : #include "sqltypes.h"
18 : :
19 : : /* this is also defined in ecpglib/misc.c, by defining it twice we don't have to export the symbol */
20 : :
21 : : static struct sqlca_t sqlca_init =
22 : : {
23 : : {
24 : : 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
25 : : },
26 : : sizeof(struct sqlca_t),
27 : : 0,
28 : : {
29 : : 0,
30 : : {
31 : : 0
32 : : }
33 : : },
34 : : {
35 : : 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
36 : : },
37 : : {
38 : : 0, 0, 0, 0, 0, 0
39 : : },
40 : : {
41 : : 0, 0, 0, 0, 0, 0, 0, 0
42 : : },
43 : : {
44 : : '0', '0', '0', '0', '0'
45 : : }
46 : : };
47 : : static int
6718 bruce@momjian.us 48 :CBC 247 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
49 : : {
50 : : numeric *a1,
51 : : *a2;
52 : : int i;
53 : :
7593 meskes@postgresql.or 54 [ - + ]: 247 : if ((a1 = PGTYPESnumeric_new()) == NULL)
7510 meskes@postgresql.or 55 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
56 : :
7593 meskes@postgresql.or 57 [ - + ]:CBC 247 : if ((a2 = PGTYPESnumeric_new()) == NULL)
58 : : {
7593 meskes@postgresql.or 59 :UBC 0 : PGTYPESnumeric_free(a1);
7510 60 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
61 : : }
62 : :
7593 meskes@postgresql.or 63 [ - + ]:CBC 247 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
64 : : {
7593 meskes@postgresql.or 65 :UBC 0 : PGTYPESnumeric_free(a1);
66 : 0 : PGTYPESnumeric_free(a2);
7510 67 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
68 : : }
69 : :
7593 meskes@postgresql.or 70 [ - + ]:CBC 247 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
71 : : {
7593 meskes@postgresql.or 72 :UBC 0 : PGTYPESnumeric_free(a1);
73 : 0 : PGTYPESnumeric_free(a2);
7510 74 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
75 : : }
76 : :
7559 bruce@momjian.us 77 :CBC 247 : i = (*ptr) (a1, a2);
78 : :
7593 meskes@postgresql.or 79 : 247 : PGTYPESnumeric_free(a1);
80 : 247 : PGTYPESnumeric_free(a2);
81 : :
2432 peter_e@gmx.net 82 : 247 : return i;
83 : : }
84 : :
85 : : static int
6718 bruce@momjian.us 86 : 901 : deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
87 : : {
88 : : numeric *a1,
89 : : *a2,
90 : : *nres;
91 : : int i;
92 : :
93 : : /*
94 : : * we must NOT set the result to NULL here because it may be the same
95 : : * variable as one of the arguments
96 : : */
7472 meskes@postgresql.or 97 [ + + + + ]: 901 : if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
7585 98 : 116 : return 0;
99 : :
7593 100 [ - + ]: 785 : if ((a1 = PGTYPESnumeric_new()) == NULL)
7510 meskes@postgresql.or 101 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
102 : :
7593 meskes@postgresql.or 103 [ - + ]:CBC 785 : if ((a2 = PGTYPESnumeric_new()) == NULL)
104 : : {
7593 meskes@postgresql.or 105 :UBC 0 : PGTYPESnumeric_free(a1);
7510 106 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
107 : : }
108 : :
7593 meskes@postgresql.or 109 [ - + ]:CBC 785 : if ((nres = PGTYPESnumeric_new()) == NULL)
110 : : {
7593 meskes@postgresql.or 111 :UBC 0 : PGTYPESnumeric_free(a1);
112 : 0 : PGTYPESnumeric_free(a2);
7510 113 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
114 : : }
115 : :
7593 meskes@postgresql.or 116 [ - + ]:CBC 785 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
117 : : {
7593 meskes@postgresql.or 118 :UBC 0 : PGTYPESnumeric_free(a1);
119 : 0 : PGTYPESnumeric_free(a2);
120 : 0 : PGTYPESnumeric_free(nres);
7510 121 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
122 : : }
123 : :
7593 meskes@postgresql.or 124 [ - + ]:CBC 785 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
125 : : {
7593 meskes@postgresql.or 126 :UBC 0 : PGTYPESnumeric_free(a1);
127 : 0 : PGTYPESnumeric_free(a2);
128 : 0 : PGTYPESnumeric_free(nres);
7510 129 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
130 : : }
131 : :
7559 bruce@momjian.us 132 :CBC 785 : i = (*ptr) (a1, a2, nres);
133 : :
134 [ + + ]: 785 : if (i == 0) /* No error */
135 : : {
136 : :
137 : : /* set the result to null in case it errors out later */
7336 meskes@postgresql.or 138 : 771 : rsetnull(CDECIMALTYPE, (char *) result);
7593 139 : 771 : PGTYPESnumeric_to_decimal(nres, result);
140 : : }
141 : :
142 : 785 : PGTYPESnumeric_free(nres);
143 : 785 : PGTYPESnumeric_free(a1);
144 : 785 : PGTYPESnumeric_free(a2);
145 : :
2432 peter_e@gmx.net 146 : 785 : return i;
147 : : }
148 : :
149 : : /* we start with the numeric functions */
150 : : int
6718 bruce@momjian.us 151 : 226 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
152 : : {
6452 meskes@postgresql.or 153 : 226 : errno = 0;
7593 154 : 226 : deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
155 : :
156 [ + + ]: 226 : if (errno == PGTYPES_NUM_OVERFLOW)
7510 157 : 62 : return ECPG_INFORMIX_NUM_OVERFLOW;
6452 158 [ - + ]: 164 : else if (errno == PGTYPES_NUM_UNDERFLOW)
7510 meskes@postgresql.or 159 :UBC 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
6452 meskes@postgresql.or 160 [ - + ]:CBC 164 : else if (errno != 0)
6452 meskes@postgresql.or 161 :UBC 0 : return -1;
162 : : else
7559 bruce@momjian.us 163 :CBC 164 : return 0;
164 : : }
165 : :
166 : : int
6718 167 : 247 : deccmp(decimal *arg1, decimal *arg2)
168 : : {
2432 peter_e@gmx.net 169 : 247 : return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
170 : : }
171 : :
172 : : void
6718 bruce@momjian.us 173 :UBC 0 : deccopy(decimal *src, decimal *target)
174 : : {
7523 meskes@postgresql.or 175 : 0 : memcpy(target, src, sizeof(decimal));
7686 176 : 0 : }
177 : :
178 : : int
2357 peter_e@gmx.net 179 :CBC 16 : deccvasc(const char *cp, int len, decimal *np)
180 : : {
181 : : char *str;
6402 bruce@momjian.us 182 : 16 : int ret = 0;
183 : : numeric *result;
184 : :
7513 meskes@postgresql.or 185 : 16 : rsetnull(CDECIMALTYPE, (char *) np);
7586 186 [ - + ]: 16 : if (risnull(CSTRINGTYPE, cp))
7586 meskes@postgresql.or 187 :UBC 0 : return 0;
188 : :
1431 tgl@sss.pgh.pa.us 189 :CBC 16 : str = pnstrdup(cp, len); /* decimal_in always converts the complete
190 : : * string */
7686 meskes@postgresql.or 191 [ - + ]: 16 : if (!str)
7510 meskes@postgresql.or 192 :UBC 0 : ret = ECPG_INFORMIX_NUM_UNDERFLOW;
193 : : else
194 : : {
6452 meskes@postgresql.or 195 :CBC 16 : errno = 0;
7675 196 : 16 : result = PGTYPESnumeric_from_asc(str, NULL);
197 [ + + ]: 16 : if (!result)
198 : : {
7686 199 [ - + - ]: 1 : switch (errno)
200 : : {
7559 bruce@momjian.us 201 :UBC 0 : case PGTYPES_NUM_OVERFLOW:
7510 meskes@postgresql.or 202 : 0 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
7559 bruce@momjian.us 203 : 0 : break;
7559 bruce@momjian.us 204 :CBC 1 : case PGTYPES_NUM_BAD_NUMERIC:
7510 meskes@postgresql.or 205 : 1 : ret = ECPG_INFORMIX_BAD_NUMERIC;
7559 bruce@momjian.us 206 : 1 : break;
7559 bruce@momjian.us 207 :UBC 0 : default:
7510 meskes@postgresql.or 208 : 0 : ret = ECPG_INFORMIX_BAD_EXPONENT;
7559 bruce@momjian.us 209 : 0 : break;
210 : : }
211 : : }
212 : : else
213 : : {
5995 bruce@momjian.us 214 :CBC 15 : int i = PGTYPESnumeric_to_decimal(result, np);
215 : :
5309 meskes@postgresql.or 216 : 15 : PGTYPESnumeric_free(result);
6088 217 [ + + ]: 15 : if (i != 0)
218 : 1 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
219 : : }
220 : : }
221 : :
7593 222 : 16 : free(str);
7686 223 : 16 : return ret;
224 : : }
225 : :
226 : : int
6718 bruce@momjian.us 227 :UBC 0 : deccvdbl(double dbl, decimal *np)
228 : : {
229 : : numeric *nres;
7559 230 : 0 : int result = 1;
231 : :
7513 meskes@postgresql.or 232 : 0 : rsetnull(CDECIMALTYPE, (char *) np);
7559 bruce@momjian.us 233 [ # # ]: 0 : if (risnull(CDOUBLETYPE, (char *) &dbl))
7585 meskes@postgresql.or 234 : 0 : return 0;
235 : :
6507 236 : 0 : nres = PGTYPESnumeric_new();
7593 237 [ # # ]: 0 : if (nres == NULL)
7510 238 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
239 : :
7593 240 : 0 : result = PGTYPESnumeric_from_double(dbl, nres);
241 [ # # ]: 0 : if (result == 0)
242 : 0 : result = PGTYPESnumeric_to_decimal(nres, np);
243 : :
244 : 0 : PGTYPESnumeric_free(nres);
2432 peter_e@gmx.net 245 : 0 : return result;
246 : : }
247 : :
248 : : int
6718 bruce@momjian.us 249 :CBC 14 : deccvint(int in, decimal *np)
250 : : {
251 : : numeric *nres;
7559 252 : 14 : int result = 1;
253 : :
7513 meskes@postgresql.or 254 : 14 : rsetnull(CDECIMALTYPE, (char *) np);
7559 bruce@momjian.us 255 [ - + ]: 14 : if (risnull(CINTTYPE, (char *) &in))
7585 meskes@postgresql.or 256 :UBC 0 : return 0;
257 : :
6507 meskes@postgresql.or 258 :CBC 14 : nres = PGTYPESnumeric_new();
7593 259 [ - + ]: 14 : if (nres == NULL)
7510 meskes@postgresql.or 260 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
261 : :
7593 meskes@postgresql.or 262 :CBC 14 : result = PGTYPESnumeric_from_int(in, nres);
263 [ + - ]: 14 : if (result == 0)
264 : 14 : result = PGTYPESnumeric_to_decimal(nres, np);
265 : :
266 : 14 : PGTYPESnumeric_free(nres);
2432 peter_e@gmx.net 267 : 14 : return result;
268 : : }
269 : :
270 : : int
6718 bruce@momjian.us 271 : 11 : deccvlong(long lng, decimal *np)
272 : : {
273 : : numeric *nres;
7559 274 : 11 : int result = 1;
275 : :
7513 meskes@postgresql.or 276 : 11 : rsetnull(CDECIMALTYPE, (char *) np);
7559 bruce@momjian.us 277 [ - + ]: 11 : if (risnull(CLONGTYPE, (char *) &lng))
7585 meskes@postgresql.or 278 :UBC 0 : return 0;
279 : :
6507 meskes@postgresql.or 280 :CBC 11 : nres = PGTYPESnumeric_new();
7593 281 [ - + ]: 11 : if (nres == NULL)
7510 meskes@postgresql.or 282 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
283 : :
7593 meskes@postgresql.or 284 :CBC 11 : result = PGTYPESnumeric_from_long(lng, nres);
285 [ + - ]: 11 : if (result == 0)
286 : 11 : result = PGTYPESnumeric_to_decimal(nres, np);
287 : :
288 : 11 : PGTYPESnumeric_free(nres);
2432 peter_e@gmx.net 289 : 11 : return result;
290 : : }
291 : :
292 : : int
6718 bruce@momjian.us 293 : 225 : decdiv(decimal *n1, decimal *n2, decimal *result)
294 : : {
295 : : int i;
296 : :
6452 meskes@postgresql.or 297 : 225 : errno = 0;
7472 298 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_div);
299 : :
7686 300 [ + + ]: 225 : if (i != 0)
301 [ + - - ]: 14 : switch (errno)
302 : : {
7559 bruce@momjian.us 303 : 14 : case PGTYPES_NUM_DIVIDE_ZERO:
7510 meskes@postgresql.or 304 : 14 : return ECPG_INFORMIX_DIVIDE_ZERO;
305 : : break;
7559 bruce@momjian.us 306 :UBC 0 : case PGTYPES_NUM_OVERFLOW:
7510 meskes@postgresql.or 307 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
308 : : break;
7559 bruce@momjian.us 309 : 0 : default:
7510 meskes@postgresql.or 310 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
311 : : break;
312 : : }
313 : :
7593 meskes@postgresql.or 314 :CBC 211 : return 0;
315 : : }
316 : :
317 : : int
6718 bruce@momjian.us 318 : 225 : decmul(decimal *n1, decimal *n2, decimal *result)
319 : : {
320 : : int i;
321 : :
6452 meskes@postgresql.or 322 : 225 : errno = 0;
7472 323 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
324 : :
7686 325 [ - + ]: 225 : if (i != 0)
7686 meskes@postgresql.or 326 [ # # ]:UBC 0 : switch (errno)
327 : : {
7559 bruce@momjian.us 328 : 0 : case PGTYPES_NUM_OVERFLOW:
7510 meskes@postgresql.or 329 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
330 : : break;
7559 bruce@momjian.us 331 : 0 : default:
7510 meskes@postgresql.or 332 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
333 : : break;
334 : : }
335 : :
7593 meskes@postgresql.or 336 :CBC 225 : return 0;
337 : : }
338 : :
339 : : int
6718 bruce@momjian.us 340 : 225 : decsub(decimal *n1, decimal *n2, decimal *result)
341 : : {
342 : : int i;
343 : :
6452 meskes@postgresql.or 344 : 225 : errno = 0;
7472 345 : 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
346 : :
7686 347 [ - + ]: 225 : if (i != 0)
7686 meskes@postgresql.or 348 [ # # ]:UBC 0 : switch (errno)
349 : : {
7559 bruce@momjian.us 350 : 0 : case PGTYPES_NUM_OVERFLOW:
7510 meskes@postgresql.or 351 : 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
352 : : break;
7559 bruce@momjian.us 353 : 0 : default:
7510 meskes@postgresql.or 354 : 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
355 : : break;
356 : : }
357 : :
7593 meskes@postgresql.or 358 :CBC 225 : return 0;
359 : : }
360 : :
361 : : int
6718 bruce@momjian.us 362 : 939 : dectoasc(decimal *np, char *cp, int len, int right)
363 : : {
364 : : char *str;
365 : : numeric *nres;
366 : :
7513 meskes@postgresql.or 367 : 939 : rsetnull(CSTRINGTYPE, (char *) cp);
7559 bruce@momjian.us 368 [ + + ]: 939 : if (risnull(CDECIMALTYPE, (char *) np))
7586 meskes@postgresql.or 369 : 140 : return 0;
370 : :
6507 371 : 799 : nres = PGTYPESnumeric_new();
372 [ - + ]: 799 : if (nres == NULL)
6507 meskes@postgresql.or 373 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
374 : :
7593 meskes@postgresql.or 375 [ - + ]:CBC 799 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
376 : : {
6507 meskes@postgresql.or 377 :UBC 0 : PGTYPESnumeric_free(nres);
7510 378 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
379 : : }
380 : :
7686 meskes@postgresql.or 381 [ + + ]:CBC 799 : if (right >= 0)
7593 382 : 78 : str = PGTYPESnumeric_to_asc(nres, right);
383 : : else
7472 384 : 721 : str = PGTYPESnumeric_to_asc(nres, nres->dscale);
385 : :
7593 386 : 799 : PGTYPESnumeric_free(nres);
7686 387 [ - + ]: 799 : if (!str)
7686 meskes@postgresql.or 388 :UBC 0 : return -1;
389 : :
390 : : /*
391 : : * TODO: have to take care of len here and create exponential notation if
392 : : * necessary
393 : : */
6452 meskes@postgresql.or 394 [ + + ]:CBC 799 : if ((int) (strlen(str) + 1) > len)
395 : : {
396 [ + + ]: 111 : if (len > 1)
397 : : {
398 : 109 : cp[0] = '*';
399 : 109 : cp[1] = '\0';
400 : : }
401 : 111 : free(str);
402 : 111 : return -1;
403 : : }
404 : : else
405 : : {
406 : 688 : strcpy(cp, str);
407 : 688 : free(str);
408 : 688 : return 0;
409 : : }
410 : : }
411 : :
412 : : int
6718 bruce@momjian.us 413 : 13 : dectodbl(decimal *np, double *dblp)
414 : : {
415 : : int i;
6507 meskes@postgresql.or 416 : 13 : numeric *nres = PGTYPESnumeric_new();
417 : :
7593 418 [ - + ]: 13 : if (nres == NULL)
7510 meskes@postgresql.or 419 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
420 : :
7593 meskes@postgresql.or 421 [ - + ]:CBC 13 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
422 : : {
6507 meskes@postgresql.or 423 :UBC 0 : PGTYPESnumeric_free(nres);
7510 424 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
425 : : }
426 : :
7593 meskes@postgresql.or 427 :CBC 13 : i = PGTYPESnumeric_to_double(nres, dblp);
428 : 13 : PGTYPESnumeric_free(nres);
429 : :
430 : 13 : return i;
431 : : }
432 : :
433 : : int
6718 bruce@momjian.us 434 : 16 : dectoint(decimal *np, int *ip)
435 : : {
436 : : int ret;
7523 meskes@postgresql.or 437 : 16 : numeric *nres = PGTYPESnumeric_new();
438 : : int errnum;
439 : :
7593 440 [ - + ]: 16 : if (nres == NULL)
7510 meskes@postgresql.or 441 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
442 : :
7593 meskes@postgresql.or 443 [ - + ]:CBC 16 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
444 : : {
6507 meskes@postgresql.or 445 :UBC 0 : PGTYPESnumeric_free(nres);
7510 446 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
447 : : }
448 : :
20 dgustafsson@postgres 449 :GNC 16 : errno = 0;
7593 meskes@postgresql.or 450 :CBC 16 : ret = PGTYPESnumeric_to_int(nres, ip);
20 dgustafsson@postgres 451 :GNC 16 : errnum = errno;
6502 meskes@postgresql.or 452 :CBC 16 : PGTYPESnumeric_free(nres);
453 : :
20 dgustafsson@postgres 454 [ + + + - ]:GNC 16 : if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
7510 meskes@postgresql.or 455 :GBC 3 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
456 : :
7686 meskes@postgresql.or 457 :CBC 16 : return ret;
458 : : }
459 : :
460 : : int
6718 bruce@momjian.us 461 : 14 : dectolong(decimal *np, long *lngp)
462 : : {
463 : : int ret;
6507 meskes@postgresql.or 464 : 14 : numeric *nres = PGTYPESnumeric_new();
465 : : int errnum;
466 : :
7593 467 [ - + ]: 14 : if (nres == NULL)
7510 meskes@postgresql.or 468 :UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
469 : :
7593 meskes@postgresql.or 470 [ - + ]:CBC 14 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
471 : : {
6507 meskes@postgresql.or 472 :UBC 0 : PGTYPESnumeric_free(nres);
7510 473 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
474 : : }
475 : :
20 dgustafsson@postgres 476 :GNC 14 : errno = 0;
7593 meskes@postgresql.or 477 :CBC 14 : ret = PGTYPESnumeric_to_long(nres, lngp);
20 dgustafsson@postgres 478 :GNC 14 : errnum = errno;
6507 meskes@postgresql.or 479 :CBC 14 : PGTYPESnumeric_free(nres);
480 : :
20 dgustafsson@postgres 481 [ + + + - ]:GNC 14 : if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
7510 meskes@postgresql.or 482 :GBC 3 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
483 : :
7686 meskes@postgresql.or 484 :CBC 14 : return ret;
485 : : }
486 : :
487 : : /* Now the date functions */
488 : : int
7522 489 : 18 : rdatestr(date d, char *str)
490 : : {
7559 bruce@momjian.us 491 : 18 : char *tmp = PGTYPESdate_to_asc(d);
492 : :
7686 meskes@postgresql.or 493 [ - + ]: 18 : if (!tmp)
7510 meskes@postgresql.or 494 :UBC 0 : return ECPG_INFORMIX_DATE_CONVERT;
495 : :
496 : : /* move to user allocated buffer */
7578 meskes@postgresql.or 497 :CBC 18 : strcpy(str, tmp);
498 : 18 : free(tmp);
499 : :
7686 500 : 18 : return 0;
501 : : }
502 : :
503 : : /*
504 : : *
505 : : * the input for this function is mmddyyyy and any non-numeric
506 : : * character can be used as a separator
507 : : *
508 : : */
509 : : int
2357 peter_e@gmx.net 510 : 2 : rstrdate(const char *str, date * d)
511 : : {
6452 meskes@postgresql.or 512 : 2 : return rdefmtdate(d, "mm/dd/yyyy", str);
513 : : }
514 : :
515 : : void
6756 bruce@momjian.us 516 :UBC 0 : rtoday(date * d)
517 : : {
7686 meskes@postgresql.or 518 : 0 : PGTYPESdate_today(d);
519 : 0 : }
520 : :
521 : : int
1172 tgl@sss.pgh.pa.us 522 : 0 : rjulmdy(date d, short *mdy)
523 : : {
524 : : int mdy_int[3];
525 : :
7577 meskes@postgresql.or 526 : 0 : PGTYPESdate_julmdy(d, mdy_int);
7559 bruce@momjian.us 527 : 0 : mdy[0] = (short) mdy_int[0];
528 : 0 : mdy[1] = (short) mdy_int[1];
529 : 0 : mdy[2] = (short) mdy_int[2];
7686 meskes@postgresql.or 530 : 0 : return 0;
531 : : }
532 : :
533 : : int
2357 peter_e@gmx.net 534 :CBC 22 : rdefmtdate(date * d, const char *fmt, const char *str)
535 : : {
536 : : /* TODO: take care of DBCENTURY environment variable */
537 : : /* PGSQL functions allow all centuries */
538 : :
6452 meskes@postgresql.or 539 : 22 : errno = 0;
7684 540 [ + + ]: 22 : if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
7686 541 : 17 : return 0;
542 : :
543 [ + + + + : 5 : switch (errno)
- ]
544 : : {
7559 bruce@momjian.us 545 : 2 : case PGTYPES_DATE_ERR_ENOSHORTDATE:
7510 meskes@postgresql.or 546 : 2 : return ECPG_INFORMIX_ENOSHORTDATE;
7686 547 : 1 : case PGTYPES_DATE_ERR_EARGS:
548 : : case PGTYPES_DATE_ERR_ENOTDMY:
7510 549 : 1 : return ECPG_INFORMIX_ENOTDMY;
7559 bruce@momjian.us 550 : 1 : case PGTYPES_DATE_BAD_DAY:
7510 meskes@postgresql.or 551 : 1 : return ECPG_INFORMIX_BAD_DAY;
7559 bruce@momjian.us 552 : 1 : case PGTYPES_DATE_BAD_MONTH:
7510 meskes@postgresql.or 553 : 1 : return ECPG_INFORMIX_BAD_MONTH;
7559 bruce@momjian.us 554 :UBC 0 : default:
7510 meskes@postgresql.or 555 : 0 : return ECPG_INFORMIX_BAD_YEAR;
556 : : }
557 : : }
558 : :
559 : : int
2357 peter_e@gmx.net 560 :CBC 12 : rfmtdate(date d, const char *fmt, char *str)
561 : : {
6452 meskes@postgresql.or 562 : 12 : errno = 0;
7684 563 [ + - ]: 12 : if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
7686 564 : 12 : return 0;
565 : :
7686 meskes@postgresql.or 566 [ # # ]:UBC 0 : if (errno == ENOMEM)
7510 567 : 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
568 : :
569 : 0 : return ECPG_INFORMIX_DATE_CONVERT;
570 : : }
571 : :
572 : : int
1172 tgl@sss.pgh.pa.us 573 :CBC 1 : rmdyjul(short *mdy, date * d)
574 : : {
575 : : int mdy_int[3];
576 : :
7577 meskes@postgresql.or 577 : 1 : mdy_int[0] = mdy[0];
578 : 1 : mdy_int[1] = mdy[1];
579 : 1 : mdy_int[2] = mdy[2];
580 : 1 : PGTYPESdate_mdyjul(mdy_int, d);
7686 581 : 1 : return 0;
582 : : }
583 : :
584 : : int
7522 meskes@postgresql.or 585 :UBC 0 : rdayofweek(date d)
586 : : {
2432 peter_e@gmx.net 587 : 0 : return PGTYPESdate_dayofweek(d);
588 : : }
589 : :
590 : : /* And the datetime stuff */
591 : :
592 : : void
6756 bruce@momjian.us 593 : 0 : dtcurrent(timestamp * ts)
594 : : {
7559 595 : 0 : PGTYPEStimestamp_current(ts);
7686 meskes@postgresql.or 596 : 0 : }
597 : :
598 : : int
6756 bruce@momjian.us 599 : 0 : dtcvasc(char *str, timestamp * ts)
600 : : {
601 : : timestamp ts_tmp;
602 : : int i;
7559 603 : 0 : char **endptr = &str;
604 : :
6452 meskes@postgresql.or 605 : 0 : errno = 0;
7559 bruce@momjian.us 606 : 0 : ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
607 : 0 : i = errno;
608 [ # # ]: 0 : if (i)
609 : : /* TODO: rewrite to Informix error codes */
610 : 0 : return i;
611 [ # # ]: 0 : if (**endptr)
612 : : {
613 : : /* extra characters exist at the end */
7510 meskes@postgresql.or 614 : 0 : return ECPG_INFORMIX_EXTRA_CHARS;
615 : : }
616 : : /* TODO: other Informix error codes missing */
617 : :
618 : : /* everything went fine */
7559 bruce@momjian.us 619 : 0 : *ts = ts_tmp;
620 : :
7686 meskes@postgresql.or 621 : 0 : return 0;
622 : : }
623 : :
624 : : int
6452 625 : 0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
626 : : {
627 : 0 : return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
628 : : }
629 : :
630 : : int
6756 bruce@momjian.us 631 : 0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
632 : : {
7684 meskes@postgresql.or 633 : 0 : return PGTYPEStimestamp_sub(ts1, ts2, iv);
634 : : }
635 : :
636 : : int
6756 bruce@momjian.us 637 : 0 : dttoasc(timestamp * ts, char *output)
638 : : {
7559 639 : 0 : char *asctime = PGTYPEStimestamp_to_asc(*ts);
640 : :
641 : 0 : strcpy(output, asctime);
7578 meskes@postgresql.or 642 : 0 : free(asctime);
7686 643 : 0 : return 0;
644 : : }
645 : :
646 : : int
6756 bruce@momjian.us 647 : 0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
648 : : {
7684 meskes@postgresql.or 649 : 0 : return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
650 : : }
651 : :
652 : : int
6756 bruce@momjian.us 653 :CBC 1 : intoasc(interval * i, char *str)
654 : : {
655 : : char *tmp;
656 : :
6452 meskes@postgresql.or 657 : 1 : errno = 0;
3229 658 : 1 : tmp = PGTYPESinterval_to_asc(i);
659 : :
660 [ - + ]: 1 : if (!tmp)
7684 meskes@postgresql.or 661 :UBC 0 : return -errno;
662 : :
55 michael@paquier.xyz 663 :CBC 1 : strcpy(str, tmp);
3229 meskes@postgresql.or 664 : 1 : free(tmp);
7686 665 : 1 : return 0;
666 : : }
667 : :
668 : : static struct
669 : : {
670 : : long val;
671 : : int maxdigits;
672 : : int digits;
673 : : int remaining;
674 : : char sign;
675 : : char *val_string;
676 : : } value;
677 : :
678 : : /**
679 : : * initialize the struct, which holds the different forms
680 : : * of the long value
681 : : */
682 : : static int
7168 bruce@momjian.us 683 : 10 : initValue(long lng_val)
684 : : {
685 : : int i,
686 : : j;
687 : : long l,
688 : : dig;
689 : :
690 : : /* set some obvious things */
691 : 10 : value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
692 [ - + ]: 10 : value.sign = lng_val >= 0 ? '+' : '-';
693 : 10 : value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
694 : :
695 : : /* determine the number of digits */
696 : 10 : i = 0;
697 : 10 : l = 1;
698 : : do
699 : : {
700 : 70 : i++;
701 : 70 : l *= 10;
702 : : }
703 [ + + + - ]: 70 : while ((l - 1) < value.val && l <= LONG_MAX / 10);
704 : :
705 [ + - ]: 10 : if (l <= LONG_MAX / 10)
706 : : {
707 : 10 : value.digits = i;
708 : 10 : l /= 10;
709 : : }
710 : : else
7168 bruce@momjian.us 711 :UBC 0 : value.digits = i + 1;
712 : :
7168 bruce@momjian.us 713 :CBC 10 : value.remaining = value.digits;
714 : :
715 : : /* convert the long to string */
5995 716 [ - + ]: 10 : if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
6038 meskes@postgresql.or 717 :UBC 0 : return -1;
7168 bruce@momjian.us 718 :CBC 10 : dig = value.val;
719 [ + + ]: 80 : for (i = value.digits, j = 0; i > 0; i--, j++)
720 : : {
721 : 70 : value.val_string[j] = dig / l + '0';
722 : 70 : dig = dig % l;
723 : 70 : l /= 10;
724 : : }
725 : 10 : value.val_string[value.digits] = '\0';
6038 meskes@postgresql.or 726 : 10 : return 0;
727 : : }
728 : :
729 : : /* return the position of the right-most dot in some string */
730 : : static int
2357 peter_e@gmx.net 731 : 10 : getRightMostDot(const char *str)
732 : : {
7559 bruce@momjian.us 733 : 10 : size_t len = strlen(str);
734 : : int i,
735 : : j;
736 : :
737 : 10 : j = 0;
738 [ + + ]: 126 : for (i = len - 1; i >= 0; i--)
739 : : {
740 [ + + ]: 120 : if (str[i] == '.')
741 : 4 : return len - j - 1;
7649 meskes@postgresql.or 742 : 116 : j++;
743 : : }
744 : 6 : return -1;
745 : : }
746 : :
747 : : /* And finally some misc functions */
748 : : int
2357 peter_e@gmx.net 749 : 10 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
750 : : {
7559 bruce@momjian.us 751 : 10 : size_t fmt_len = strlen(fmt);
752 : : size_t temp_len;
753 : : int i,
754 : : j, /* position in temp */
755 : : k,
756 : : dotpos;
757 : 10 : int leftalign = 0,
758 : 10 : blank = 0,
759 : 10 : sign = 0,
760 : 10 : entitydone = 0,
761 : 10 : signdone = 0,
762 : 10 : brackets_ok = 0;
763 : : char *temp;
764 : 10 : char tmp[2] = " ";
765 : 10 : char lastfmt = ' ',
766 : 10 : fmtchar = ' ';
767 : :
768 : 10 : temp = (char *) malloc(fmt_len + 1);
5643 meskes@postgresql.or 769 [ - + ]: 10 : if (!temp)
770 : : {
5643 meskes@postgresql.or 771 :UBC 0 : errno = ENOMEM;
772 : 0 : return -1;
773 : : }
774 : :
775 : : /* put all info about the long in a struct */
5643 meskes@postgresql.or 776 [ - + ]:CBC 10 : if (initValue(lng_val) == -1)
777 : : {
5643 meskes@postgresql.or 778 :UBC 0 : free(temp);
6038 779 : 0 : errno = ENOMEM;
780 : 0 : return -1;
781 : : }
782 : :
783 : : /* '<' is the only format, where we have to align left */
7559 bruce@momjian.us 784 [ + + ]:CBC 10 : if (strchr(fmt, (int) '<'))
7649 meskes@postgresql.or 785 : 3 : leftalign = 1;
786 : :
787 : : /* '(' requires ')' */
7559 bruce@momjian.us 788 [ + + + - ]: 10 : if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
7649 meskes@postgresql.or 789 : 1 : brackets_ok = 1;
790 : :
791 : : /* get position of the right-most dot in the format-string */
792 : : /* and fill the temp-string wit '0's up to there. */
793 : 10 : dotpos = getRightMostDot(fmt);
794 : :
795 : : /* start to parse the format-string */
796 : 10 : temp[0] = '\0';
7559 bruce@momjian.us 797 : 10 : k = value.digits - 1; /* position in the value_string */
798 [ + + ]: 189 : for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
799 : : {
800 : : /* qualify, where we are in the value_string */
801 [ + + ]: 179 : if (k < 0)
802 : : {
7649 meskes@postgresql.or 803 : 90 : blank = 1;
5337 804 [ + + ]: 90 : if (k == -1)
7649 805 : 30 : sign = 1;
6452 806 [ + + ]: 90 : if (leftalign)
807 : : {
808 : : /* can't use strncat(,,0) here, Solaris would freak out */
809 [ + - ]: 23 : if (sign)
810 [ - + ]: 23 : if (signdone)
811 : : {
6452 meskes@postgresql.or 812 :UBC 0 : temp[j] = '\0';
813 : 0 : break;
814 : : }
815 : : }
816 : : }
817 : : /* if we're right side of the right-most dot, print '0' */
7559 bruce@momjian.us 818 [ + + + + ]:CBC 179 : if (dotpos >= 0 && dotpos <= i)
819 : : {
820 [ + + ]: 11 : if (dotpos < i)
821 : : {
822 [ + + ]: 7 : if (fmt[i] == ')')
823 [ + - ]: 1 : tmp[0] = value.sign == '-' ? ')' : ' ';
824 : : else
825 : 6 : tmp[0] = '0';
826 : : }
827 : : else
7649 meskes@postgresql.or 828 : 4 : tmp[0] = '.';
829 : 11 : strcat(temp, tmp);
830 : 11 : continue;
831 : : }
832 : : /* the ',' needs special attention, if it is in the blank area */
7559 bruce@momjian.us 833 [ + + + + ]: 168 : if (blank && fmt[i] == ',')
834 : 4 : fmtchar = lastfmt;
835 : : else
836 : 164 : fmtchar = fmt[i];
837 : : /* waiting for the sign */
6452 meskes@postgresql.or 838 [ + + + + : 168 : if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
+ - + - +
+ + + ]
839 : 21 : continue;
840 : : /* analyse this format-char */
7559 bruce@momjian.us 841 [ + + + + : 147 : switch (fmtchar)
+ + + - +
+ + ]
842 : : {
7649 meskes@postgresql.or 843 : 8 : case ',':
844 : 8 : tmp[0] = ',';
845 : 8 : k++;
846 : 8 : break;
847 : 24 : case '*':
7559 bruce@momjian.us 848 [ + + ]: 24 : if (blank)
849 : 10 : tmp[0] = '*';
850 : : else
851 : 14 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 852 : 24 : break;
853 : 11 : case '&':
7559 bruce@momjian.us 854 [ + + ]: 11 : if (blank)
855 : 4 : tmp[0] = '0';
856 : : else
857 : 7 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 858 : 11 : break;
859 : 48 : case '#':
7559 bruce@momjian.us 860 [ + + ]: 48 : if (blank)
861 : 30 : tmp[0] = ' ';
862 : : else
863 : 18 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 864 : 48 : break;
865 : 6 : case '-':
7559 bruce@momjian.us 866 [ + + + - : 6 : if (sign && value.sign == '-' && !signdone)
+ + ]
867 : : {
7649 meskes@postgresql.or 868 : 2 : tmp[0] = '-';
869 : 2 : signdone = 1;
870 : : }
7559 bruce@momjian.us 871 [ + + ]: 4 : else if (blank)
872 : 3 : tmp[0] = ' ';
873 : : else
874 : 1 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 875 : 6 : break;
876 : 8 : case '+':
7559 bruce@momjian.us 877 [ + + + + ]: 8 : if (sign && !signdone)
878 : : {
7649 meskes@postgresql.or 879 : 3 : tmp[0] = value.sign;
880 : 3 : signdone = 1;
881 : : }
7559 bruce@momjian.us 882 [ + + ]: 5 : else if (blank)
883 : 3 : tmp[0] = ' ';
884 : : else
885 : 2 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 886 : 8 : break;
887 : 1 : case '(':
7559 bruce@momjian.us 888 [ + - + - : 1 : if (sign && brackets_ok && value.sign == '-')
+ - ]
889 : 1 : tmp[0] = '(';
7559 bruce@momjian.us 890 [ # # ]:UBC 0 : else if (blank)
891 : 0 : tmp[0] = ' ';
892 : : else
893 : 0 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 894 :CBC 1 : break;
7649 meskes@postgresql.or 895 :UBC 0 : case ')':
7559 bruce@momjian.us 896 [ # # # # ]: 0 : if (brackets_ok && value.sign == '-')
897 : 0 : tmp[0] = ')';
898 : : else
899 : 0 : tmp[0] = ' ';
7649 meskes@postgresql.or 900 : 0 : break;
7649 meskes@postgresql.or 901 :CBC 15 : case '$':
7559 bruce@momjian.us 902 [ + + + + ]: 15 : if (blank && !entitydone)
903 : : {
7649 meskes@postgresql.or 904 : 3 : tmp[0] = '$';
905 : 3 : entitydone = 1;
906 : : }
7559 bruce@momjian.us 907 [ + + ]: 12 : else if (blank)
908 : 5 : tmp[0] = ' ';
909 : : else
910 : 7 : tmp[0] = value.val_string[k];
7649 meskes@postgresql.or 911 : 15 : break;
6452 912 : 21 : case '<':
913 : 21 : tmp[0] = value.val_string[k];
914 : 21 : break;
7559 bruce@momjian.us 915 : 5 : default:
916 : 5 : tmp[0] = fmt[i];
917 : : }
7649 meskes@postgresql.or 918 : 147 : strcat(temp, tmp);
919 : 147 : lastfmt = fmt[i];
920 : 147 : k--;
921 : : }
922 : : /* safety-net */
923 : 10 : temp[fmt_len] = '\0';
924 : :
925 : : /* reverse the temp-string and put it into the outbuf */
926 : 10 : temp_len = strlen(temp);
927 : 10 : outbuf[0] = '\0';
7559 bruce@momjian.us 928 [ + + ]: 168 : for (i = temp_len - 1; i >= 0; i--)
929 : : {
7649 meskes@postgresql.or 930 : 158 : tmp[0] = temp[i];
7559 bruce@momjian.us 931 : 158 : strcat(outbuf, tmp);
932 : : }
7649 meskes@postgresql.or 933 : 10 : outbuf[temp_len] = '\0';
934 : :
935 : : /* cleaning up */
7562 tgl@sss.pgh.pa.us 936 : 10 : free(temp);
7649 meskes@postgresql.or 937 : 10 : free(value.val_string);
938 : :
7686 939 : 10 : return 0;
940 : : }
941 : :
942 : : void
7641 943 : 1 : rupshift(char *str)
944 : : {
945 [ + + ]: 16 : for (; *str != '\0'; str++)
7406 tgl@sss.pgh.pa.us 946 [ + + ]: 15 : if (islower((unsigned char) *str))
947 : 9 : *str = toupper((unsigned char) *str);
7641 meskes@postgresql.or 948 : 1 : }
949 : :
950 : : int
951 : 8 : byleng(char *str, int len)
952 : : {
7559 bruce@momjian.us 953 [ + - + + ]: 18 : for (len--; str[len] && str[len] == ' '; len--);
954 : 8 : return (len + 1);
955 : : }
956 : :
957 : : void
7641 meskes@postgresql.or 958 : 4 : ldchar(char *src, int len, char *dest)
959 : : {
6402 bruce@momjian.us 960 : 4 : int dlen = byleng(src, len);
961 : :
6452 meskes@postgresql.or 962 : 4 : memmove(dest, src, dlen);
963 : 4 : dest[dlen] = '\0';
7641 964 : 4 : }
965 : :
966 : : int
7686 meskes@postgresql.or 967 :UBC 0 : rgetmsg(int msgnum, char *s, int maxsize)
968 : : {
969 : : (void) msgnum; /* keep the compiler quiet */
970 : : (void) s; /* keep the compiler quiet */
971 : : (void) maxsize; /* keep the compiler quiet */
972 : 0 : return 0;
973 : : }
974 : :
975 : : int
976 : 0 : rtypalign(int offset, int type)
977 : : {
978 : : (void) offset; /* keep the compiler quiet */
979 : : (void) type; /* keep the compiler quiet */
980 : 0 : return 0;
981 : : }
982 : :
983 : : int
984 : 0 : rtypmsize(int type, int len)
985 : : {
986 : : (void) type; /* keep the compiler quiet */
987 : : (void) len; /* keep the compiler quiet */
988 : 0 : return 0;
989 : : }
990 : :
991 : : int
7641 992 : 0 : rtypwidth(int sqltype, int sqllen)
993 : : {
994 : : (void) sqltype; /* keep the compiler quiet */
995 : : (void) sqllen; /* keep the compiler quiet */
996 : 0 : return 0;
997 : : }
998 : :
999 : : void
7611 1000 : 0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
1001 : : {
5192 1002 : 0 : ECPGset_var(number, pointer, lineno);
7611 1003 : 0 : }
1004 : :
1005 : : void *
1006 : 0 : ECPG_informix_get_var(int number)
1007 : : {
5192 1008 : 0 : return ECPGget_var(number);
1009 : : }
1010 : :
1011 : : void
5357 1012 : 0 : ECPG_informix_reset_sqlca(void)
1013 : : {
1014 : 0 : struct sqlca_t *sqlca = ECPGget_sqlca();
1015 : :
3226 1016 [ # # ]: 0 : if (sqlca == NULL)
1017 : 0 : return;
1018 : :
5357 1019 : 0 : memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
1020 : : }
1021 : :
1022 : : int
7559 bruce@momjian.us 1023 :CBC 1763 : rsetnull(int t, char *ptr)
1024 : : {
7231 meskes@postgresql.or 1025 : 1763 : ECPGset_noind_null(t, ptr);
7599 1026 : 1763 : return 0;
1027 : : }
1028 : :
1029 : : int
2357 peter_e@gmx.net 1030 : 2746 : risnull(int t, const char *ptr)
1031 : : {
2432 1032 : 2746 : return ECPGis_noind_null(t, ptr);
1033 : : }
|